diff --git a/packages/picasso/src/LexicalEditor/LexicalEditor.test.tsx b/packages/picasso/src/LexicalEditor/LexicalEditor.test.tsx
index eee8d45be5c..01adaa7a9df 100644
--- a/packages/picasso/src/LexicalEditor/LexicalEditor.test.tsx
+++ b/packages/picasso/src/LexicalEditor/LexicalEditor.test.tsx
@@ -9,6 +9,7 @@ import LexicalTextLengthPlugin from '../LexicalTextLengthPlugin'
import LexicalHeadingsReplacementPlugin from '../LexicalHeadingsReplacementPlugin'
import ToolbarPlugin from '../LexicalEditorToolbarPlugin'
import LexicalListPlugin from '../LexicalListPlugin'
+import type { CustomEmojiGroup } from './types'
jest.mock('../LexicalEditorToolbarPlugin', () => ({
__esModule: true,
@@ -18,6 +19,10 @@ jest.mock('../LexicalListPlugin', () => ({
__esModule: true,
default: jest.fn(() =>
LexicalListPlugin
),
}))
+jest.mock('../LexicalEmojiPlugin', () => ({
+ __esModule: true,
+ default: jest.fn(() => LexicalEmojiPlugin
),
+}))
jest.mock('@lexical/react/LexicalComposerContext', () => ({
__esModule: true,
@@ -136,6 +141,8 @@ describe('LexicalEditor', () => {
expect(mockedToolbarPlugin).toHaveBeenCalledWith(
{
disabled: true,
+ customEmojis: undefined,
+ plugins: [],
toolbarRef: {
current: null,
},
@@ -152,6 +159,30 @@ describe('LexicalEditor', () => {
expect(mockedToolbarPlugin).toHaveBeenCalledWith(
{
disabled: true,
+ customEmojis: undefined,
+ plugins: [],
+ toolbarRef: {
+ current: null,
+ },
+ },
+ {}
+ )
+ })
+ })
+
+ describe('when customEmojis and plugins prop is passed', () => {
+ it('renders ToolbarPlugin with correct props', () => {
+ renderLexicalEditor({
+ disabled: true,
+ customEmojis: ['foo' as unknown as CustomEmojiGroup],
+ plugins: ['link'],
+ })
+
+ expect(mockedToolbarPlugin).toHaveBeenCalledWith(
+ {
+ disabled: true,
+ customEmojis: ['foo'],
+ plugins: ['link'],
toolbarRef: {
current: null,
},
diff --git a/packages/picasso/src/LexicalEditor/LexicalEditor.tsx b/packages/picasso/src/LexicalEditor/LexicalEditor.tsx
index 9b34644248a..a1e9844314a 100644
--- a/packages/picasso/src/LexicalEditor/LexicalEditor.tsx
+++ b/packages/picasso/src/LexicalEditor/LexicalEditor.tsx
@@ -9,10 +9,10 @@ import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'
import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin'
import { ContentEditable } from '@lexical/react/LexicalContentEditable'
import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'
-import { HeadingNode } from '@lexical/rich-text'
import { $generateHtmlFromNodes } from '@lexical/html'
-import { ListItemNode, ListNode } from '@lexical/list'
import { $isRootTextContentEmpty } from '@lexical/text'
+import { ListItemNode, ListNode } from '@lexical/list'
+import { HeadingNode } from '@lexical/rich-text'
import { createLexicalTheme } from './utils'
import noop from '../utils/noop'
@@ -20,11 +20,18 @@ import Container from '../Container'
import Typography from '../Typography'
import { useTypographyClasses, useOnFocus } from './hooks'
import styles from './styles'
-import type { ChangeHandler, TextLengthChangeHandler } from './types'
+import type {
+ ChangeHandler,
+ EditorPlugin,
+ TextLengthChangeHandler,
+ CustomEmojiGroup,
+} from './types'
import ToolbarPlugin from '../LexicalEditorToolbarPlugin'
import LexicalTextLengthPlugin from '../LexicalTextLengthPlugin'
import LexicalListPlugin from '../LexicalListPlugin'
import LexicalHeadingsReplacementPlugin from '../LexicalHeadingsReplacementPlugin'
+import { CustomEmojiNode } from '../LexicalEmojiPlugin/nodes/CustomEmojiNode'
+import LexicalEmojiPlugin from '../LexicalEmojiPlugin'
const useStyles = makeStyles(styles, {
name: 'LexicalEditor',
@@ -65,8 +72,7 @@ export type Props = BaseProps & {
onTextLengthChange: TextLengthChangeHandler
/** The placeholder attribute specifies a short hint that describes the expected value of a text editor. */
placeholder?: string
- /** List of plugins to enable on the editor */
- // plugins?: EditorPlugin[]
+
testIds?: {
editor?: string
// headerSelect?: string
@@ -75,7 +81,9 @@ export type Props = BaseProps & {
// unorderedListButton?: string
// orderedListButton?: string
}
- // customEmojis?: CustomEmojiGroup[]
+ customEmojis?: CustomEmojiGroup[]
+ /** List of plugins to enable on the editor */
+ plugins?: EditorPlugin[]
}
const LexicalEditor = forwardRef(function LexicalEditor(
@@ -83,7 +91,7 @@ const LexicalEditor = forwardRef(function LexicalEditor(
ref
) {
const {
- // plugins,
+ plugins = [],
autoFocus = false,
// defaultValue,
disabled = false,
@@ -105,7 +113,7 @@ const LexicalEditor = forwardRef(function LexicalEditor(
// @todo don't know what to do with NAME prop
// name,
// highlight,
- // customEmojis,
+ customEmojis,
} = props
const classes = useStyles()
@@ -125,21 +133,22 @@ const LexicalEditor = forwardRef(function LexicalEditor(
typographyClassNames,
classes,
}),
- [typographyClassNames, classes.paragraph]
+ [typographyClassNames, classes]
)
- const editorConfig: InitialConfigType = useMemo(
- () => ({
+ const editorConfig = useMemo(() => {
+ const config: InitialConfigType = {
theme,
onError(error: Error) {
throw error
},
namespace: 'editor',
- nodes: [ListNode, ListItemNode, HeadingNode],
+ nodes: [CustomEmojiNode, ListNode, ListItemNode, HeadingNode],
editable: !disabled,
- }),
- [theme, disabled]
- )
+ }
+
+ return config
+ }, [theme, disabled])
const handleChange = useCallback(
(editorState, editor) => {
@@ -170,6 +179,8 @@ const LexicalEditor = forwardRef(function LexicalEditor(
toolbarRef={toolbarRef}
// remount Toolbar when disabled
key={`${disabled || !isFocused}`}
+ customEmojis={customEmojis}
+ plugins={plugins}
/>
{autoFocus && }
@@ -177,6 +188,7 @@ const LexicalEditor = forwardRef(function LexicalEditor(
+
{
italic: {
fontStyle: 'italic',
},
+ customEmoji: {
+ '& > img': {
+ verticalAlign: 'bottom',
+ width: '22px',
+ height: '22px',
+ },
+ },
})
}
diff --git a/packages/picasso/src/LexicalEditor/types.ts b/packages/picasso/src/LexicalEditor/types.ts
index 935bb66cc3f..9014525a868 100644
--- a/packages/picasso/src/LexicalEditor/types.ts
+++ b/packages/picasso/src/LexicalEditor/types.ts
@@ -1,3 +1,35 @@
+export type SettingName = 'link' | 'emoji'
+
export type ChangeHandler = (html: string) => void
export type { TextLengthChangeHandler } from '../LexicalTextLengthPlugin'
+
+export type EditorPlugin = SettingName
+
+export type CustomEmoji = {
+ id: string
+ name: string
+ keywords: string[]
+ skins: [
+ {
+ src: string
+ }
+ ]
+}
+
+export type CustomEmojiGroup = {
+ id: string
+ name: string
+ emojis: CustomEmoji[]
+}
+
+export type Emoji = {
+ id: string
+ name: string
+ native?: string
+ unified?: string
+ keywords: string[]
+ shortcodes: string
+ emoticons?: string[]
+ src?: string
+}
diff --git a/packages/picasso/src/LexicalEditor/utils/createLexicalTheme.ts b/packages/picasso/src/LexicalEditor/utils/createLexicalTheme.ts
index 2087fddc4d0..2c88f25695d 100644
--- a/packages/picasso/src/LexicalEditor/utils/createLexicalTheme.ts
+++ b/packages/picasso/src/LexicalEditor/utils/createLexicalTheme.ts
@@ -34,6 +34,7 @@ export const createLexicalTheme = ({
ul: classes.ul,
ol: classes.ol,
},
+ customEmoji: classes.customEmoji,
}
return theme
diff --git a/packages/picasso/src/LexicalEditor/utils/synchronizeToolbarState.test.ts b/packages/picasso/src/LexicalEditor/utils/synchronizeToolbarState.test.ts
index 4bfa687ac44..df12a6f5c4e 100644
--- a/packages/picasso/src/LexicalEditor/utils/synchronizeToolbarState.test.ts
+++ b/packages/picasso/src/LexicalEditor/utils/synchronizeToolbarState.test.ts
@@ -14,6 +14,10 @@ import { ToolbarActions } from './toolbarState'
import { synchronizeToolbarState } from './synchronizeToolbarState'
import { getLexicalNode } from './getLexicalNode'
+// jest.mock('../nodes/CustomEmojiNode', () => ({
+// default: jest.fn(),
+// }))
+
jest.mock('lexical', () => ({
$getSelection: jest.fn(),
$isRangeSelection: jest.fn(),
diff --git a/packages/picasso/src/LexicalEditorToolbarPlugin/LexicalEditorToolbarPlugin.tsx b/packages/picasso/src/LexicalEditorToolbarPlugin/LexicalEditorToolbarPlugin.tsx
index 66f800c822c..9c5d4b7b393 100644
--- a/packages/picasso/src/LexicalEditorToolbarPlugin/LexicalEditorToolbarPlugin.tsx
+++ b/packages/picasso/src/LexicalEditorToolbarPlugin/LexicalEditorToolbarPlugin.tsx
@@ -21,19 +21,32 @@ import {
toolbarStateReducer,
} from '../LexicalEditor/utils'
import { noop } from '../utils'
+import type {
+ CustomEmojiGroup,
+ EditorPlugin,
+ Emoji,
+} from '../LexicalEditor/types'
+import {
+ INSERT_CUSTOM_EMOJI_COMMAND,
+ INSERT_EMOJI_COMMAND,
+} from '../LexicalEmojiPlugin/commands'
import type { HeaderValue } from '../RichTextEditorToolbar'
import RichTextEditorToolbar, {
ALLOWED_HEADER_TYPE,
} from '../RichTextEditorToolbar'
type Props = {
+ customEmojis?: CustomEmojiGroup[]
disabled?: boolean
toolbarRef: React.RefObject
+ plugins?: EditorPlugin[]
}
const LexicalEditorToolbarPlugin = ({
disabled = false,
toolbarRef,
+ customEmojis,
+ plugins,
}: Props) => {
const [editor] = useLexicalComposerContext()
const [{ bold, italic, list, header }, dispatch] = useReducer(
@@ -73,6 +86,24 @@ const LexicalEditorToolbarPlugin = ({
)
}
+ const handleInsertEmoji = (emoji: Emoji) => {
+ const isNativeEmoji = emoji.native
+ const isCustomEmoji = emoji.src
+
+ if (isNativeEmoji) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ editor.dispatchCommand(INSERT_EMOJI_COMMAND, emoji.native!)
+ }
+
+ if (isCustomEmoji) {
+ editor.dispatchCommand(INSERT_CUSTOM_EMOJI_COMMAND, {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ src: emoji.src!,
+ id: emoji.id,
+ })
+ }
+ }
+
const handleHeaderClick = ({
target: { value },
}: ChangeEvent<{
@@ -108,8 +139,10 @@ const LexicalEditorToolbarPlugin = ({
onLinkClick={noop}
onHeaderChange={handleHeaderClick}
disabled={disabled}
- onInsertEmoji={noop}
+ onInsertEmoji={handleInsertEmoji}
ref={toolbarRef}
+ customEmojis={customEmojis}
+ plugins={plugins}
/>
)
}
diff --git a/packages/picasso/src/LexicalEmojiPlugin/LexicalEmojiPlugin.test.ts b/packages/picasso/src/LexicalEmojiPlugin/LexicalEmojiPlugin.test.ts
new file mode 100644
index 00000000000..4ef4d2658e0
--- /dev/null
+++ b/packages/picasso/src/LexicalEmojiPlugin/LexicalEmojiPlugin.test.ts
@@ -0,0 +1,77 @@
+import { renderHook } from '@testing-library/react-hooks'
+import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
+import { $createTextNode, $insertNodes, COMMAND_PRIORITY_EDITOR } from 'lexical'
+
+import LexicalEmojiPlugin, {
+ INSERT_CUSTOM_EMOJI_COMMAND,
+ INSERT_EMOJI_COMMAND,
+} from './index'
+import { $createCustomEmojiNode } from './nodes/CustomEmojiNode'
+
+jest.mock('@lexical/react/LexicalComposerContext', () => ({
+ useLexicalComposerContext: jest.fn(() => [{}]),
+}))
+
+jest.mock('@lexical/utils', () => ({
+ mergeRegister: jest.fn(),
+}))
+
+jest.mock('lexical', () => ({
+ $createTextNode: jest.fn(),
+ $insertNodes: jest.fn(),
+ COMMAND_PRIORITY_EDITOR: jest.fn(),
+ createCommand: jest.fn(),
+}))
+
+jest.mock('./nodes/CustomEmojiNode', () => ({
+ $createCustomEmojiNode: jest.fn(),
+}))
+
+describe('LexicalEmojiPlugin', () => {
+ const mockEditor = {
+ registerCommand: jest.fn(),
+ }
+
+ beforeEach(() => {
+ jest.resetAllMocks()
+ ;(useLexicalComposerContext as jest.Mock).mockReturnValue([mockEditor])
+ })
+
+ it('registers commands on mount', () => {
+ renderHook(() => LexicalEmojiPlugin())
+
+ expect(mockEditor.registerCommand).toHaveBeenCalledTimes(2)
+ expect(mockEditor.registerCommand).toHaveBeenCalledWith(
+ INSERT_EMOJI_COMMAND,
+ expect.any(Function),
+ COMMAND_PRIORITY_EDITOR
+ )
+ expect(mockEditor.registerCommand).toHaveBeenCalledWith(
+ INSERT_CUSTOM_EMOJI_COMMAND,
+ expect.any(Function),
+ COMMAND_PRIORITY_EDITOR
+ )
+ })
+
+ it('inserts a text node when the native emoji command is called', () => {
+ renderHook(() => LexicalEmojiPlugin())
+ const nativeEmojiCommand = mockEditor.registerCommand.mock.calls[0][1]
+
+ nativeEmojiCommand('😃')
+
+ expect($createTextNode).toHaveBeenCalledWith('😃')
+ expect($insertNodes).toHaveBeenCalledWith([$createTextNode()])
+ })
+
+ it('inserts a custom emoji node when the custom emoji command is called', () => {
+ const payload = { id: 'custom emoji', src: 'https://example.com/emoji.png' }
+
+ renderHook(() => LexicalEmojiPlugin())
+ const customEmojiCommand = mockEditor.registerCommand.mock.calls[1][1]
+
+ customEmojiCommand(payload)
+
+ expect($createCustomEmojiNode).toHaveBeenCalledWith(payload)
+ expect($insertNodes).toHaveBeenCalledWith([$createCustomEmojiNode(payload)])
+ })
+})
diff --git a/packages/picasso/src/LexicalEmojiPlugin/LexicalEmojiPlugin.tsx b/packages/picasso/src/LexicalEmojiPlugin/LexicalEmojiPlugin.tsx
new file mode 100644
index 00000000000..f7c4392a848
--- /dev/null
+++ b/packages/picasso/src/LexicalEmojiPlugin/LexicalEmojiPlugin.tsx
@@ -0,0 +1,41 @@
+import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
+import { mergeRegister } from '@lexical/utils'
+import { useEffect } from 'react'
+import { $createTextNode, $insertNodes, COMMAND_PRIORITY_EDITOR } from 'lexical'
+
+import { INSERT_CUSTOM_EMOJI_COMMAND, INSERT_EMOJI_COMMAND } from './commands'
+import { $createCustomEmojiNode } from './nodes/CustomEmojiNode'
+import type { CustomEmojiPayload } from './types'
+
+const LexicalEmojiPlugin = () => {
+ const [editor] = useLexicalComposerContext()
+
+ useEffect(() => {
+ return mergeRegister(
+ editor.registerCommand(
+ INSERT_EMOJI_COMMAND,
+ (nativeEmoji: string) => {
+ $insertNodes([$createTextNode(nativeEmoji)])
+
+ return true
+ },
+ COMMAND_PRIORITY_EDITOR
+ ),
+ editor.registerCommand(
+ INSERT_CUSTOM_EMOJI_COMMAND,
+ (customEmojiPayload: CustomEmojiPayload) => {
+ const emojiNode = $createCustomEmojiNode(customEmojiPayload)
+
+ $insertNodes([emojiNode])
+
+ return true
+ },
+ COMMAND_PRIORITY_EDITOR
+ )
+ )
+ }, [editor])
+
+ return null
+}
+
+export default LexicalEmojiPlugin
diff --git a/packages/picasso/src/LexicalEmojiPlugin/commands/index.ts b/packages/picasso/src/LexicalEmojiPlugin/commands/index.ts
new file mode 100644
index 00000000000..1bb6fa4277e
--- /dev/null
+++ b/packages/picasso/src/LexicalEmojiPlugin/commands/index.ts
@@ -0,0 +1,11 @@
+import { createCommand } from 'lexical'
+import type { LexicalCommand } from 'lexical'
+
+import type { CustomEmojiPayload } from '../nodes/CustomEmojiNode'
+
+export const INSERT_EMOJI_COMMAND: LexicalCommand = createCommand(
+ 'INSERT_EMOJI_COMMAND'
+)
+
+export const INSERT_CUSTOM_EMOJI_COMMAND: LexicalCommand =
+ createCommand('INSERT_CUSTOM_EMOJI_COMMAND')
diff --git a/packages/picasso/src/LexicalEmojiPlugin/index.ts b/packages/picasso/src/LexicalEmojiPlugin/index.ts
new file mode 100644
index 00000000000..4fe8385887b
--- /dev/null
+++ b/packages/picasso/src/LexicalEmojiPlugin/index.ts
@@ -0,0 +1,3 @@
+export { default } from './LexicalEmojiPlugin'
+export * from './commands'
+export * from './nodes'
diff --git a/packages/picasso/src/LexicalEmojiPlugin/nodes/CustomEmojiNode.tsx b/packages/picasso/src/LexicalEmojiPlugin/nodes/CustomEmojiNode.tsx
new file mode 100644
index 00000000000..07f1e271342
--- /dev/null
+++ b/packages/picasso/src/LexicalEmojiPlugin/nodes/CustomEmojiNode.tsx
@@ -0,0 +1,153 @@
+import React from 'react'
+import { $applyNodeReplacement, DecoratorNode } from 'lexical'
+import type {
+ DOMConversionMap,
+ DOMConversionOutput,
+ DOMExportOutput,
+ EditorConfig,
+ LexicalNode,
+ NodeKey,
+ SerializedElementNode,
+ Spread,
+} from 'lexical'
+
+export interface CustomEmojiPayload {
+ src: string
+ id: string
+}
+
+type SerializedCustomEmojiNode = Spread<
+ {
+ src: string
+ id: string
+ },
+ SerializedElementNode
+>
+
+const convertImageElement = (domNode: Node): null | DOMConversionOutput => {
+ if (domNode instanceof HTMLImageElement) {
+ const src = domNode.getAttribute('src')
+ const id = domNode.getAttribute('data-emoji-name')
+
+ if (src && id) {
+ return {
+ node: $createCustomEmojiNode({
+ src,
+ id,
+ }),
+ }
+ }
+
+ return null
+ }
+
+ return null
+}
+
+export class CustomEmojiNode extends DecoratorNode {
+ __src: string
+ __id: string
+
+ static getType() {
+ return 'custom-emoji'
+ }
+
+ static clone(node: CustomEmojiNode): CustomEmojiNode {
+ return new CustomEmojiNode(node.__src, node.__id)
+ }
+
+ constructor(src: string, id: string, key?: NodeKey) {
+ super(key)
+ this.__src = src
+ this.__id = id
+ }
+
+ static importJSON(
+ serializedNode: SerializedCustomEmojiNode
+ ): CustomEmojiNode {
+ const { src, id } = serializedNode
+
+ const node = $createCustomEmojiNode({ src, id })
+
+ return node
+ }
+
+ createDOM(config: EditorConfig): HTMLElement {
+ const span = document.createElement('span')
+
+ const theme = config.theme
+ const className = theme.customEmoji
+
+ if (className !== undefined) {
+ span.className = className
+ }
+
+ return span
+ }
+
+ // update() {}
+
+ updateDOM() {
+ return false
+ }
+
+ exportDOM(): DOMExportOutput {
+ const element = document.createElement('img')
+
+ element.setAttribute('src', this.__src)
+ element.setAttribute('data-src', this.__src)
+ element.setAttribute('data-emoji-name', this.__id)
+
+ return { element }
+ }
+
+ static importDOM(): DOMConversionMap | null {
+ return {
+ img: () => ({
+ conversion: convertImageElement,
+ priority: 0,
+ }),
+ }
+ }
+
+ exportJSON(): SerializedCustomEmojiNode {
+ return {
+ version: 1,
+ type: 'custom-emoji',
+ src: this.__src,
+ id: this.__id,
+ children: [],
+ direction: this.__direction,
+ format: '',
+ indent: this.__indent,
+ }
+ }
+
+ // isInline() {
+ // return true
+ // }
+
+ // canIndent() {
+ // return false
+ // }
+
+ decorate() {
+ return (
+
+ )
+ }
+}
+
+export const $isCustomEmojiNode = (
+ node: LexicalNode | null | undefined
+): node is CustomEmojiNode => {
+ return node instanceof CustomEmojiNode
+}
+
+export const $createCustomEmojiNode = ({
+ src,
+ id,
+}: CustomEmojiPayload): CustomEmojiNode => {
+ // return new CustomEmojiNode(src, id)
+ return $applyNodeReplacement(new CustomEmojiNode(src, id))
+}
diff --git a/packages/picasso/src/LexicalEmojiPlugin/nodes/index.ts b/packages/picasso/src/LexicalEmojiPlugin/nodes/index.ts
new file mode 100644
index 00000000000..bd2ba9c89d3
--- /dev/null
+++ b/packages/picasso/src/LexicalEmojiPlugin/nodes/index.ts
@@ -0,0 +1 @@
+export { CustomEmojiNode } from './CustomEmojiNode'
diff --git a/packages/picasso/src/LexicalEmojiPlugin/types.ts b/packages/picasso/src/LexicalEmojiPlugin/types.ts
new file mode 100644
index 00000000000..8f3ff95a4f9
--- /dev/null
+++ b/packages/picasso/src/LexicalEmojiPlugin/types.ts
@@ -0,0 +1 @@
+export type { CustomEmojiPayload } from './nodes/CustomEmojiNode'
diff --git a/packages/picasso/src/RichTextEditor/RichTextEditor.tsx b/packages/picasso/src/RichTextEditor/RichTextEditor.tsx
index a0391f7c38a..35ed55fb8d4 100644
--- a/packages/picasso/src/RichTextEditor/RichTextEditor.tsx
+++ b/packages/picasso/src/RichTextEditor/RichTextEditor.tsx
@@ -6,8 +6,6 @@ import { useHasMultilineCounter } from '@toptal/picasso-shared'
import cx from 'classnames'
import noop from '../utils/noop'
-// @todo: remove this import once we remove the old QuillEditor
-import type { CustomEmojiGroup, EditorPlugin } from '../QuillEditor'
import styles from './styles'
import { useCounter } from './hooks'
import type { ASTType } from '../RichText'
@@ -15,7 +13,11 @@ import { usePropDeprecationWarning } from '../utils/use-deprecation-warnings'
import type { Status } from '../OutlinedInput'
import type { CounterMessageSetter } from './types'
import LexicalEditor from '../LexicalEditor'
-import type { ChangeHandler } from '../LexicalEditor'
+import type {
+ ChangeHandler,
+ CustomEmojiGroup,
+ EditorPlugin,
+} from '../LexicalEditor'
import InputMultilineAdornment from '../InputMultilineAdornment'
export interface Props extends BaseProps {
@@ -96,7 +98,7 @@ export const RichTextEditor = forwardRef(
function RichTextEditor(props, ref) {
const {
'data-testid': dataTestId,
- // plugins,
+ plugins,
autoFocus = false,
className,
// defaultValue,
@@ -117,7 +119,7 @@ export const RichTextEditor = forwardRef(
setHasMultilineCounter,
name,
highlight,
- // customEmojis,
+ customEmojis,
} = props
const classes = useStyles()
@@ -188,13 +190,15 @@ export const RichTextEditor = forwardRef(
testIds={testIds}
disabled={disabled}
autoFocus={autoFocus}
+ plugins={plugins}
+ customEmojis={customEmojis}
/>
{hiddenInputId && (
// Native `for` attribute on label does not work for div target
)}
diff --git a/packages/picasso/src/RichTextEditor/styles.ts b/packages/picasso/src/RichTextEditor/styles.ts
index fac2f317156..7ca017fc7ab 100644
--- a/packages/picasso/src/RichTextEditor/styles.ts
+++ b/packages/picasso/src/RichTextEditor/styles.ts
@@ -38,6 +38,12 @@ export default (theme: Theme) => {
...outline(palette.primary.main),
},
+ hiddenInput: {
+ position: 'absolute',
+ opacity: 0,
+ zIndex: -1,
+ },
+
...highlightAutofillStyles(theme),
})
}
diff --git a/packages/picasso/src/RichTextEditorEmojiPicker/RichTextEditorEmojiPicker.tsx b/packages/picasso/src/RichTextEditorEmojiPicker/RichTextEditorEmojiPicker.tsx
index a114bbc1f3b..3ac4b984032 100644
--- a/packages/picasso/src/RichTextEditorEmojiPicker/RichTextEditorEmojiPicker.tsx
+++ b/packages/picasso/src/RichTextEditorEmojiPicker/RichTextEditorEmojiPicker.tsx
@@ -8,12 +8,13 @@ import cx from 'classnames'
import Container from '../Container'
import TextEditorButton from '../RichTextEditorButton'
-import type { CustomEmojiGroup } from '../QuillEditor'
+import type { CustomEmojiGroup, Emoji } from '../LexicalEditor'
interface Props {
richEditorId: string
customEmojis?: CustomEmojiGroup[]
- onInsertEmoji: (emoji: string) => void
+ onInsertEmoji: (emoji: Emoji) => void
+ disabled?: boolean
}
const TRIGGER_EMOJI_PICKER_ID = 'trigger-emoji-picker'
@@ -48,6 +49,7 @@ export const RichtTextEditorEmojiPicker = ({
richEditorId,
customEmojis,
onInsertEmoji,
+ disabled,
}: Props) => {
const [showEmojiPicker, setShowEmojiPicker] = React.useState(false)
@@ -61,7 +63,7 @@ export const RichtTextEditorEmojiPicker = ({
setShowEmojiPicker(false)
}
- const handleEmojiInsert = (emoji: string) => {
+ const handleEmojiInsert = (emoji: Emoji) => {
onInsertEmoji(emoji)
setShowEmojiPicker(false)
}
@@ -88,6 +90,7 @@ export const RichtTextEditorEmojiPicker = ({
onClick={handleEmojiPickerClick}
icon={🙂}
id={TRIGGER_EMOJI_PICKER_ID}
+ disabled={disabled}
/>
void
+ onInsertEmoji: (emoji: Emoji) => void
onHeaderChange: SelectOnChangeHandler
onUnorderedClick: ButtonHandlerType
onOrderedClick: ButtonHandlerType
@@ -146,6 +146,7 @@ export const RichTextEditorToolbar = forwardRef(
richEditorId={id}
customEmojis={customEmojis}
onInsertEmoji={onInsertEmoji}
+ disabled={disabled}
/>
)}