@payloadcms/richtext-lexical 3.68.0-internal-debug.2eb12b9 → 3.68.0-internal-debug.185cc5f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/features/blocks/client/component/index.js +1 -0
- package/dist/features/blocks/client/component/index.js.map +1 -1
- package/dist/features/blocks/client/componentInline/index.js +1 -0
- package/dist/features/blocks/client/componentInline/index.js.map +1 -1
- package/dist/features/blocks/client/markdown/markdownTransformer.js +1 -0
- package/dist/features/blocks/client/markdown/markdownTransformer.js.map +1 -1
- package/dist/features/blocks/premade/CodeBlock/Component/Block.js +1 -0
- package/dist/features/blocks/premade/CodeBlock/Component/Block.js.map +1 -1
- package/dist/features/blocks/premade/CodeBlock/Component/Collapse/index.js +1 -0
- package/dist/features/blocks/premade/CodeBlock/Component/Collapse/index.js.map +1 -1
- package/dist/features/blocks/premade/CodeBlock/Component/FloatingCollapse/index.js +1 -0
- package/dist/features/blocks/premade/CodeBlock/Component/FloatingCollapse/index.js.map +1 -1
- package/dist/features/blocks/server/markdown/markdownTransformer.js +1 -0
- package/dist/features/blocks/server/markdown/markdownTransformer.js.map +1 -1
- package/dist/features/debug/jsxConverter/client/plugin/index.js +1 -0
- package/dist/features/debug/jsxConverter/client/plugin/index.js.map +1 -1
- package/dist/features/debug/testRecorder/client/plugin/index.js +1 -0
- package/dist/features/debug/testRecorder/client/plugin/index.js.map +1 -1
- package/dist/features/debug/treeView/client/plugin/index.js +1 -0
- package/dist/features/debug/treeView/client/plugin/index.js.map +1 -1
- package/dist/features/experimental_table/client/plugins/TableActionMenuPlugin/index.js +1 -0
- package/dist/features/experimental_table/client/plugins/TableActionMenuPlugin/index.js.map +1 -1
- package/dist/features/experimental_table/client/plugins/TableCellResizerPlugin/index.js +1 -0
- package/dist/features/experimental_table/client/plugins/TableCellResizerPlugin/index.js.map +1 -1
- package/dist/features/experimental_table/client/plugins/TablePlugin/index.js +1 -0
- package/dist/features/experimental_table/client/plugins/TablePlugin/index.js.map +1 -1
- package/dist/features/horizontalRule/client/plugin/index.js +1 -0
- package/dist/features/horizontalRule/client/plugin/index.js.map +1 -1
- package/dist/features/link/client/plugins/autoLink/index.js +3 -0
- package/dist/features/link/client/plugins/autoLink/index.js.map +1 -1
- package/dist/features/link/client/plugins/floatingLinkEditor/index.js +1 -0
- package/dist/features/link/client/plugins/floatingLinkEditor/index.js.map +1 -1
- package/dist/features/link/server/baseFields.js +1 -0
- package/dist/features/link/server/baseFields.js.map +1 -1
- package/dist/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/Component.js +1 -0
- package/dist/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/Component.js.map +1 -1
- package/dist/features/migrations/slateToLexical/nodes/unknownConvertedNode/Component.js +1 -0
- package/dist/features/migrations/slateToLexical/nodes/unknownConvertedNode/Component.js.map +1 -1
- package/dist/features/relationship/client/components/RelationshipComponent.js +1 -0
- package/dist/features/relationship/client/components/RelationshipComponent.js.map +1 -1
- package/dist/features/toolbars/fixed/client/Toolbar/index.js +1 -0
- package/dist/features/toolbars/fixed/client/Toolbar/index.js.map +1 -1
- package/dist/features/toolbars/inline/client/Toolbar/index.js +1 -0
- package/dist/features/toolbars/inline/client/Toolbar/index.js.map +1 -1
- package/dist/features/toolbars/shared/ToolbarButton/index.js +1 -0
- package/dist/features/toolbars/shared/ToolbarButton/index.js.map +1 -1
- package/dist/features/toolbars/shared/ToolbarDropdown/index.js +1 -0
- package/dist/features/toolbars/shared/ToolbarDropdown/index.js.map +1 -1
- package/dist/features/upload/client/component/index.js +1 -0
- package/dist/features/upload/client/component/index.js.map +1 -1
- package/dist/features/upload/client/component/pending/index.js +1 -0
- package/dist/features/upload/client/component/pending/index.js.map +1 -1
- package/dist/field/Diff/converters/listitem/index.js +1 -0
- package/dist/field/Diff/converters/listitem/index.js.map +1 -1
- package/dist/field/Diff/converters/relationship/index.js +1 -0
- package/dist/field/Diff/converters/relationship/index.js.map +1 -1
- package/dist/field/Diff/converters/unknown/index.js +1 -0
- package/dist/field/Diff/converters/unknown/index.js.map +1 -1
- package/dist/field/Diff/converters/upload/index.js +1 -0
- package/dist/field/Diff/converters/upload/index.js.map +1 -1
- package/dist/field/Diff/index.js +1 -0
- package/dist/field/Diff/index.js.map +1 -1
- package/dist/field/Field.js +2 -0
- package/dist/field/Field.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lexical/LexicalEditor.js +1 -0
- package/dist/lexical/LexicalEditor.js.map +1 -1
- package/dist/lexical/plugins/DecoratorPlugin/index.js +1 -0
- package/dist/lexical/plugins/DecoratorPlugin/index.js.map +1 -1
- package/dist/lexical/plugins/InsertParagraphAtEnd/index.js +1 -0
- package/dist/lexical/plugins/InsertParagraphAtEnd/index.js.map +1 -1
- package/dist/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.js +2 -0
- package/dist/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.js.map +1 -1
- package/dist/lexical/plugins/SlashMenu/index.js +2 -0
- package/dist/lexical/plugins/SlashMenu/index.js.map +1 -1
- package/dist/lexical/plugins/handles/AddBlockHandlePlugin/index.js +1 -0
- package/dist/lexical/plugins/handles/AddBlockHandlePlugin/index.js.map +1 -1
- package/dist/lexical/plugins/handles/DraggableBlockPlugin/index.js +1 -0
- package/dist/lexical/plugins/handles/DraggableBlockPlugin/index.js.map +1 -1
- package/dist/lexical/ui/ContentEditable.js +1 -0
- package/dist/lexical/ui/ContentEditable.js.map +1 -1
- package/dist/packages/@lexical/markdown/MarkdownShortcuts.js +2 -0
- package/dist/packages/@lexical/markdown/MarkdownShortcuts.js.map +1 -1
- package/dist/packages/@lexical/markdown/importTextFormatTransformer.js +2 -0
- package/dist/packages/@lexical/markdown/importTextFormatTransformer.js.map +1 -1
- package/dist/packages/@lexical/markdown/importTextMatchTransformer.js +2 -0
- package/dist/packages/@lexical/markdown/importTextMatchTransformer.js.map +1 -1
- package/dist/utilities/migrateSlateToLexical/migrateDocumentFieldsRecursively.js +2 -0
- package/dist/utilities/migrateSlateToLexical/migrateDocumentFieldsRecursively.js.map +1 -1
- package/dist/utilities/upgradeLexicalData/upgradeDocumentFieldsRecursively.js +2 -0
- package/dist/utilities/upgradeLexicalData/upgradeDocumentFieldsRecursively.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/features/toolbars/fixed/client/Toolbar/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { useLexicalEditable } from '@lexical/react/useLexicalEditable'\nimport { useScrollInfo, useThrottledEffect, useTranslation } from '@payloadcms/ui'\nimport * as React from 'react'\nimport { useMemo } from 'react'\n\nimport type { EditorConfigContextType } from '../../../../../lexical/config/client/EditorConfigProvider.js'\nimport type { SanitizedClientEditorConfig } from '../../../../../lexical/config/types.js'\nimport type { PluginComponent } from '../../../../typesClient.js'\nimport type { ToolbarGroup, ToolbarGroupItem } from '../../../types.js'\nimport type { FixedToolbarFeatureProps } from '../../server/index.js'\n\nimport { useEditorConfigContext } from '../../../../../lexical/config/client/EditorConfigProvider.js'\nimport { ToolbarButton } from '../../../shared/ToolbarButton/index.js'\nimport './index.scss'\nimport { ToolbarDropdown } from '../../../shared/ToolbarDropdown/index.js'\n\nfunction ButtonGroupItem({\n anchorElem,\n editor,\n item,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n item: ToolbarGroupItem\n}): React.ReactNode {\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n )\n }\n\n if (!item.ChildComponent) {\n return null\n }\n\n return (\n <ToolbarButton editor={editor} item={item} key={item.key}>\n <item.ChildComponent />\n </ToolbarButton>\n )\n}\n\nfunction ToolbarGroupComponent({\n anchorElem,\n editor,\n editorConfig,\n group,\n index,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n editorConfig: SanitizedClientEditorConfig\n group: ToolbarGroup\n index: number\n}): React.ReactNode {\n const { i18n } = useTranslation<{}, string>()\n const {\n fieldProps: { featureClientSchemaMap, schemaPath },\n } = useEditorConfigContext()\n\n const [dropdownLabel, setDropdownLabel] = React.useState<string | undefined>(undefined)\n const [DropdownIcon, setDropdownIcon] = React.useState<React.FC | undefined>(undefined)\n\n React.useEffect(() => {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent!)\n } else {\n setDropdownIcon(undefined)\n }\n }, [group])\n\n const onActiveChange = React.useCallback(\n ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => {\n if (!activeItems.length) {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent!)\n setDropdownLabel(undefined)\n } else {\n setDropdownIcon(undefined)\n setDropdownLabel(undefined)\n }\n return\n }\n const item = activeItems[0]!\n\n let label = item.key\n if (item.label) {\n label =\n typeof item.label === 'function'\n ? item.label({ featureClientSchemaMap, i18n, schemaPath })\n : item.label\n }\n // Crop title to max. 25 characters\n if (label.length > 25) {\n label = label.substring(0, 25) + '...'\n }\n if (activeItems.length === 1) {\n setDropdownLabel(label)\n setDropdownIcon(() => item.ChildComponent)\n } else {\n setDropdownLabel(\n i18n.t('lexical:general:toolbarItemsActive', { count: activeItems.length }),\n )\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent!)\n } else {\n setDropdownIcon(undefined)\n }\n }\n },\n [group, i18n, featureClientSchemaMap, schemaPath],\n )\n\n return (\n <div\n className={`fixed-toolbar__group fixed-toolbar__group-${group.key}`}\n data-toolbar-group-key={group.key}\n key={group.key}\n >\n {group.type === 'dropdown' && group.items.length ? (\n DropdownIcon ? (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n Icon={DropdownIcon}\n itemsContainerClassNames={['fixed-toolbar__dropdown-items']}\n label={dropdownLabel}\n maxActiveItems={group.maxActiveItems ?? 1}\n onActiveChange={onActiveChange}\n />\n ) : (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n itemsContainerClassNames={['fixed-toolbar__dropdown-items']}\n label={dropdownLabel}\n maxActiveItems={group.maxActiveItems ?? 1}\n onActiveChange={onActiveChange}\n />\n )\n ) : null}\n {group.type === 'buttons' && group.items.length\n ? group.items.map((item) => {\n return (\n <ButtonGroupItem anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n })\n : null}\n {index < editorConfig.features.toolbarFixed?.groups.length - 1 && <div className=\"divider\" />}\n </div>\n )\n}\n\nfunction FixedToolbar({\n anchorElem,\n clientProps,\n editor,\n editorConfig,\n parentWithFixedToolbar,\n}: {\n anchorElem: HTMLElement\n clientProps?: FixedToolbarFeatureProps\n editor: LexicalEditor\n editorConfig: SanitizedClientEditorConfig\n parentWithFixedToolbar: EditorConfigContextType | false\n}): React.ReactNode {\n const currentToolbarRef = React.useRef<HTMLDivElement>(null)\n const isEditable = useLexicalEditable()\n\n const { y } = useScrollInfo()\n\n // Memoize the parent toolbar element\n const parentToolbarElem = useMemo(() => {\n if (!parentWithFixedToolbar || clientProps?.disableIfParentHasFixedToolbar) {\n return null\n }\n\n const parentEditorElem = parentWithFixedToolbar.editorContainerRef.current\n let sibling = parentEditorElem.previousElementSibling\n while (sibling) {\n if (sibling.classList.contains('fixed-toolbar')) {\n return sibling\n }\n sibling = sibling.previousElementSibling\n }\n return null\n }, [clientProps?.disableIfParentHasFixedToolbar, parentWithFixedToolbar])\n\n useThrottledEffect(\n () => {\n if (!parentToolbarElem) {\n // this also checks for clientProps?.disableIfParentHasFixedToolbar indirectly, see the parentToolbarElem useMemo\n return\n }\n const currentToolbarElem = currentToolbarRef.current\n if (!currentToolbarElem) {\n return\n }\n\n const currentRect = currentToolbarElem.getBoundingClientRect()\n const parentRect = parentToolbarElem.getBoundingClientRect()\n\n // we only need to check for vertical overlap\n const overlapping = !(\n currentRect.bottom < parentRect.top || currentRect.top > parentRect.bottom\n )\n\n if (overlapping) {\n currentToolbarElem.classList.remove('fixed-toolbar')\n currentToolbarElem.classList.add('fixed-toolbar', 'fixed-toolbar--overlapping')\n parentToolbarElem.classList.remove('fixed-toolbar')\n parentToolbarElem.classList.add('fixed-toolbar', 'fixed-toolbar--hide')\n } else {\n if (!currentToolbarElem.classList.contains('fixed-toolbar--overlapping')) {\n return\n }\n currentToolbarElem.classList.remove('fixed-toolbar--overlapping')\n currentToolbarElem.classList.add('fixed-toolbar')\n parentToolbarElem.classList.remove('fixed-toolbar--hide')\n parentToolbarElem.classList.add('fixed-toolbar')\n }\n },\n 50,\n [currentToolbarRef, parentToolbarElem, y],\n )\n\n return (\n <div\n className=\"fixed-toolbar\"\n onFocus={(event) => {\n // Prevent other focus events being triggered. Otherwise, if this was to be clicked while in a child editor,\n // the parent editor will be focused, and the child editor will lose focus.\n event.stopPropagation()\n }}\n ref={currentToolbarRef}\n >\n {isEditable && (\n <React.Fragment>\n {editorConfig?.features &&\n editorConfig.features?.toolbarFixed?.groups.map((group, i) => {\n return (\n <ToolbarGroupComponent\n anchorElem={anchorElem}\n editor={editor}\n editorConfig={editorConfig}\n group={group}\n index={i}\n key={group.key}\n />\n )\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n\nconst getParentEditorWithFixedToolbar = (\n editorConfigContext: EditorConfigContextType,\n): EditorConfigContextType | false => {\n if (editorConfigContext.parentEditor?.editorConfig) {\n if (editorConfigContext.parentEditor?.editorConfig.resolvedFeatureMap.has('toolbarFixed')) {\n return editorConfigContext.parentEditor\n } else {\n if (editorConfigContext.parentEditor) {\n return getParentEditorWithFixedToolbar(editorConfigContext.parentEditor)\n }\n }\n }\n return false\n}\n\nexport const FixedToolbarPlugin: PluginComponent<FixedToolbarFeatureProps> = ({ clientProps }) => {\n const [currentEditor] = useLexicalComposerContext()\n const editorConfigContext = useEditorConfigContext()\n const isEditable = useLexicalEditable()\n if (!isEditable) {\n return null\n }\n\n const { editorConfig: currentEditorConfig } = editorConfigContext\n\n const editor = clientProps.applyToFocusedEditor\n ? editorConfigContext.focusedEditor?.editor || currentEditor\n : currentEditor\n\n const editorConfig = clientProps.applyToFocusedEditor\n ? editorConfigContext.focusedEditor?.editorConfig || currentEditorConfig\n : currentEditorConfig\n\n const parentWithFixedToolbar = getParentEditorWithFixedToolbar(editorConfigContext)\n\n if (clientProps?.disableIfParentHasFixedToolbar) {\n if (parentWithFixedToolbar) {\n return null\n }\n }\n\n if (!editorConfig?.features?.toolbarFixed?.groups?.length) {\n return null\n }\n\n return (\n <FixedToolbar\n anchorElem={document.body}\n editor={editor}\n editorConfig={editorConfig}\n parentWithFixedToolbar={parentWithFixedToolbar}\n />\n )\n}\n"],"names":["useLexicalComposerContext","useLexicalEditable","useScrollInfo","useThrottledEffect","useTranslation","React","useMemo","useEditorConfigContext","ToolbarButton","ToolbarDropdown","ButtonGroupItem","anchorElem","editor","item","Component","key","ChildComponent","ToolbarGroupComponent","editorConfig","group","index","i18n","fieldProps","featureClientSchemaMap","schemaPath","dropdownLabel","setDropdownLabel","useState","undefined","DropdownIcon","setDropdownIcon","useEffect","type","items","length","onActiveChange","useCallback","activeItems","label","substring","t","count","div","className","data-toolbar-group-key","Icon","itemsContainerClassNames","maxActiveItems","map","features","toolbarFixed","groups","FixedToolbar","clientProps","parentWithFixedToolbar","currentToolbarRef","useRef","isEditable","y","parentToolbarElem","disableIfParentHasFixedToolbar","parentEditorElem","editorContainerRef","current","sibling","previousElementSibling","classList","contains","currentToolbarElem","currentRect","getBoundingClientRect","parentRect","overlapping","bottom","top","remove","add","onFocus","event","stopPropagation","ref","Fragment","i","getParentEditorWithFixedToolbar","editorConfigContext","parentEditor","resolvedFeatureMap","has","FixedToolbarPlugin","currentEditor","currentEditorConfig","applyToFocusedEditor","focusedEditor","document","body"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/features/toolbars/fixed/client/Toolbar/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { useLexicalEditable } from '@lexical/react/useLexicalEditable'\nimport { useScrollInfo, useThrottledEffect, useTranslation } from '@payloadcms/ui'\nimport * as React from 'react'\nimport { useMemo } from 'react'\n\nimport type { EditorConfigContextType } from '../../../../../lexical/config/client/EditorConfigProvider.js'\nimport type { SanitizedClientEditorConfig } from '../../../../../lexical/config/types.js'\nimport type { PluginComponent } from '../../../../typesClient.js'\nimport type { ToolbarGroup, ToolbarGroupItem } from '../../../types.js'\nimport type { FixedToolbarFeatureProps } from '../../server/index.js'\n\nimport { useEditorConfigContext } from '../../../../../lexical/config/client/EditorConfigProvider.js'\nimport { ToolbarButton } from '../../../shared/ToolbarButton/index.js'\nimport './index.scss'\nimport { ToolbarDropdown } from '../../../shared/ToolbarDropdown/index.js'\n\nfunction ButtonGroupItem({\n anchorElem,\n editor,\n item,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n item: ToolbarGroupItem\n}): React.ReactNode {\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n )\n }\n\n if (!item.ChildComponent) {\n return null\n }\n\n return (\n <ToolbarButton editor={editor} item={item} key={item.key}>\n <item.ChildComponent />\n </ToolbarButton>\n )\n}\n\nfunction ToolbarGroupComponent({\n anchorElem,\n editor,\n editorConfig,\n group,\n index,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n editorConfig: SanitizedClientEditorConfig\n group: ToolbarGroup\n index: number\n}): React.ReactNode {\n const { i18n } = useTranslation<{}, string>()\n const {\n fieldProps: { featureClientSchemaMap, schemaPath },\n } = useEditorConfigContext()\n\n const [dropdownLabel, setDropdownLabel] = React.useState<string | undefined>(undefined)\n const [DropdownIcon, setDropdownIcon] = React.useState<React.FC | undefined>(undefined)\n\n React.useEffect(() => {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent!)\n } else {\n setDropdownIcon(undefined)\n }\n }, [group])\n\n const onActiveChange = React.useCallback(\n ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => {\n if (!activeItems.length) {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent!)\n setDropdownLabel(undefined)\n } else {\n setDropdownIcon(undefined)\n setDropdownLabel(undefined)\n }\n return\n }\n const item = activeItems[0]!\n\n let label = item.key\n if (item.label) {\n label =\n typeof item.label === 'function'\n ? item.label({ featureClientSchemaMap, i18n, schemaPath })\n : item.label\n }\n // Crop title to max. 25 characters\n if (label.length > 25) {\n label = label.substring(0, 25) + '...'\n }\n if (activeItems.length === 1) {\n setDropdownLabel(label)\n setDropdownIcon(() => item.ChildComponent)\n } else {\n setDropdownLabel(\n i18n.t('lexical:general:toolbarItemsActive', { count: activeItems.length }),\n )\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent!)\n } else {\n setDropdownIcon(undefined)\n }\n }\n },\n [group, i18n, featureClientSchemaMap, schemaPath],\n )\n\n return (\n <div\n className={`fixed-toolbar__group fixed-toolbar__group-${group.key}`}\n data-toolbar-group-key={group.key}\n key={group.key}\n >\n {group.type === 'dropdown' && group.items.length ? (\n DropdownIcon ? (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n Icon={DropdownIcon}\n itemsContainerClassNames={['fixed-toolbar__dropdown-items']}\n label={dropdownLabel}\n maxActiveItems={group.maxActiveItems ?? 1}\n onActiveChange={onActiveChange}\n />\n ) : (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n itemsContainerClassNames={['fixed-toolbar__dropdown-items']}\n label={dropdownLabel}\n maxActiveItems={group.maxActiveItems ?? 1}\n onActiveChange={onActiveChange}\n />\n )\n ) : null}\n {group.type === 'buttons' && group.items.length\n ? group.items.map((item) => {\n return (\n <ButtonGroupItem anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n })\n : null}\n {index < editorConfig.features.toolbarFixed?.groups.length - 1 && <div className=\"divider\" />}\n </div>\n )\n}\n\nfunction FixedToolbar({\n anchorElem,\n clientProps,\n editor,\n editorConfig,\n parentWithFixedToolbar,\n}: {\n anchorElem: HTMLElement\n clientProps?: FixedToolbarFeatureProps\n editor: LexicalEditor\n editorConfig: SanitizedClientEditorConfig\n parentWithFixedToolbar: EditorConfigContextType | false\n}): React.ReactNode {\n const currentToolbarRef = React.useRef<HTMLDivElement>(null)\n const isEditable = useLexicalEditable()\n\n const { y } = useScrollInfo()\n\n // Memoize the parent toolbar element\n const parentToolbarElem = useMemo(() => {\n if (!parentWithFixedToolbar || clientProps?.disableIfParentHasFixedToolbar) {\n return null\n }\n\n const parentEditorElem = parentWithFixedToolbar.editorContainerRef.current\n let sibling = parentEditorElem.previousElementSibling\n while (sibling) {\n if (sibling.classList.contains('fixed-toolbar')) {\n return sibling\n }\n sibling = sibling.previousElementSibling\n }\n return null\n }, [clientProps?.disableIfParentHasFixedToolbar, parentWithFixedToolbar])\n\n useThrottledEffect(\n () => {\n if (!parentToolbarElem) {\n // this also checks for clientProps?.disableIfParentHasFixedToolbar indirectly, see the parentToolbarElem useMemo\n return\n }\n const currentToolbarElem = currentToolbarRef.current\n if (!currentToolbarElem) {\n return\n }\n\n const currentRect = currentToolbarElem.getBoundingClientRect()\n const parentRect = parentToolbarElem.getBoundingClientRect()\n\n // we only need to check for vertical overlap\n const overlapping = !(\n currentRect.bottom < parentRect.top || currentRect.top > parentRect.bottom\n )\n\n if (overlapping) {\n currentToolbarElem.classList.remove('fixed-toolbar')\n currentToolbarElem.classList.add('fixed-toolbar', 'fixed-toolbar--overlapping')\n parentToolbarElem.classList.remove('fixed-toolbar')\n parentToolbarElem.classList.add('fixed-toolbar', 'fixed-toolbar--hide')\n } else {\n if (!currentToolbarElem.classList.contains('fixed-toolbar--overlapping')) {\n return\n }\n currentToolbarElem.classList.remove('fixed-toolbar--overlapping')\n currentToolbarElem.classList.add('fixed-toolbar')\n parentToolbarElem.classList.remove('fixed-toolbar--hide')\n parentToolbarElem.classList.add('fixed-toolbar')\n }\n },\n 50,\n [currentToolbarRef, parentToolbarElem, y],\n )\n\n return (\n <div\n className=\"fixed-toolbar\"\n onFocus={(event) => {\n // Prevent other focus events being triggered. Otherwise, if this was to be clicked while in a child editor,\n // the parent editor will be focused, and the child editor will lose focus.\n event.stopPropagation()\n }}\n ref={currentToolbarRef}\n >\n {isEditable && (\n <React.Fragment>\n {editorConfig?.features &&\n editorConfig.features?.toolbarFixed?.groups.map((group, i) => {\n return (\n <ToolbarGroupComponent\n anchorElem={anchorElem}\n editor={editor}\n editorConfig={editorConfig}\n group={group}\n index={i}\n key={group.key}\n />\n )\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n\nconst getParentEditorWithFixedToolbar = (\n editorConfigContext: EditorConfigContextType,\n): EditorConfigContextType | false => {\n if (editorConfigContext.parentEditor?.editorConfig) {\n if (editorConfigContext.parentEditor?.editorConfig.resolvedFeatureMap.has('toolbarFixed')) {\n return editorConfigContext.parentEditor\n } else {\n if (editorConfigContext.parentEditor) {\n return getParentEditorWithFixedToolbar(editorConfigContext.parentEditor)\n }\n }\n }\n return false\n}\n\nexport const FixedToolbarPlugin: PluginComponent<FixedToolbarFeatureProps> = ({ clientProps }) => {\n const [currentEditor] = useLexicalComposerContext()\n const editorConfigContext = useEditorConfigContext()\n const isEditable = useLexicalEditable()\n if (!isEditable) {\n return null\n }\n\n const { editorConfig: currentEditorConfig } = editorConfigContext\n\n const editor = clientProps.applyToFocusedEditor\n ? editorConfigContext.focusedEditor?.editor || currentEditor\n : currentEditor\n\n const editorConfig = clientProps.applyToFocusedEditor\n ? editorConfigContext.focusedEditor?.editorConfig || currentEditorConfig\n : currentEditorConfig\n\n const parentWithFixedToolbar = getParentEditorWithFixedToolbar(editorConfigContext)\n\n if (clientProps?.disableIfParentHasFixedToolbar) {\n if (parentWithFixedToolbar) {\n return null\n }\n }\n\n if (!editorConfig?.features?.toolbarFixed?.groups?.length) {\n return null\n }\n\n return (\n <FixedToolbar\n anchorElem={document.body}\n editor={editor}\n editorConfig={editorConfig}\n parentWithFixedToolbar={parentWithFixedToolbar}\n />\n )\n}\n"],"names":["useLexicalComposerContext","useLexicalEditable","useScrollInfo","useThrottledEffect","useTranslation","React","useMemo","useEditorConfigContext","ToolbarButton","ToolbarDropdown","ButtonGroupItem","anchorElem","editor","item","Component","key","ChildComponent","ToolbarGroupComponent","editorConfig","group","index","i18n","fieldProps","featureClientSchemaMap","schemaPath","dropdownLabel","setDropdownLabel","useState","undefined","DropdownIcon","setDropdownIcon","useEffect","type","items","length","onActiveChange","useCallback","activeItems","label","substring","t","count","div","className","data-toolbar-group-key","Icon","itemsContainerClassNames","maxActiveItems","map","features","toolbarFixed","groups","FixedToolbar","clientProps","parentWithFixedToolbar","currentToolbarRef","useRef","isEditable","y","parentToolbarElem","disableIfParentHasFixedToolbar","parentEditorElem","editorContainerRef","current","sibling","previousElementSibling","classList","contains","currentToolbarElem","currentRect","getBoundingClientRect","parentRect","overlapping","bottom","top","remove","add","onFocus","event","stopPropagation","ref","Fragment","i","getParentEditorWithFixedToolbar","editorConfigContext","parentEditor","resolvedFeatureMap","has","FixedToolbarPlugin","currentEditor","currentEditorConfig","applyToFocusedEditor","focusedEditor","document","body"],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ import { useEditorConfigContext } from '../../../../../lexical/config/client/Edi
|
|
|
11
11
|
import { getDOMRangeRect } from '../../../../../lexical/utils/getDOMRangeRect.js';
|
|
12
12
|
import { setFloatingElemPosition } from '../../../../../lexical/utils/setFloatingElemPosition.js';
|
|
13
13
|
import { ToolbarButton } from '../../../shared/ToolbarButton/index.js';
|
|
14
|
+
import './index.scss';
|
|
14
15
|
import { ToolbarDropdown } from '../../../shared/ToolbarDropdown/index.js';
|
|
15
16
|
function ButtonGroupItem({ anchorElem, editor, item }) {
|
|
16
17
|
if (item.Component) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/features/toolbars/inline/client/Toolbar/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { useLexicalEditable } from '@lexical/react/useLexicalEditable'\nimport { mergeRegister } from '@lexical/utils'\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_LOW,\n getDOMSelection,\n SELECTION_CHANGE_COMMAND,\n} from 'lexical'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\n\nimport type { PluginComponentWithAnchor } from '../../../../typesClient.js'\nimport type { ToolbarGroup, ToolbarGroupItem } from '../../../types.js'\n\nimport { useEditorConfigContext } from '../../../../../lexical/config/client/EditorConfigProvider.js'\nimport { getDOMRangeRect } from '../../../../../lexical/utils/getDOMRangeRect.js'\nimport { setFloatingElemPosition } from '../../../../../lexical/utils/setFloatingElemPosition.js'\nimport { ToolbarButton } from '../../../shared/ToolbarButton/index.js'\nimport './index.scss'\nimport { ToolbarDropdown } from '../../../shared/ToolbarDropdown/index.js'\n\nfunction ButtonGroupItem({\n anchorElem,\n editor,\n item,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n item: ToolbarGroupItem\n}): React.ReactNode {\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n )\n }\n if (!item.ChildComponent) {\n return null\n }\n\n return (\n <ToolbarButton editor={editor} item={item} key={item.key}>\n <item.ChildComponent />\n </ToolbarButton>\n )\n}\n\nfunction ToolbarGroupComponent({\n anchorElem,\n editor,\n group,\n index,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n group: ToolbarGroup\n index: number\n}): React.ReactNode {\n const { editorConfig } = useEditorConfigContext()\n\n const [DropdownIcon, setDropdownIcon] = React.useState<React.FC | undefined>()\n\n React.useEffect(() => {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent)\n } else {\n setDropdownIcon(undefined)\n }\n }, [group])\n\n const onActiveChange = useCallback(\n ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => {\n if (!activeItems.length) {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent)\n } else {\n setDropdownIcon(undefined)\n }\n return\n }\n const item = activeItems[0]\n setDropdownIcon(() => item?.ChildComponent)\n },\n [group],\n )\n\n return (\n <div\n className={`inline-toolbar-popup__group inline-toolbar-popup__group-${group.key}`}\n data-toolbar-group-key={group.key}\n key={group.key}\n >\n {group.type === 'dropdown' && group.items.length ? (\n DropdownIcon ? (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n Icon={DropdownIcon}\n maxActiveItems={group.maxActiveItems ?? 1}\n onActiveChange={onActiveChange}\n />\n ) : (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n maxActiveItems={group.maxActiveItems ?? 1}\n onActiveChange={onActiveChange}\n />\n )\n ) : null}\n {group.type === 'buttons' && group.items.length\n ? group.items.map((item) => {\n return (\n <ButtonGroupItem anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n })\n : null}\n {index < editorConfig.features.toolbarInline?.groups.length - 1 && (\n <div className=\"divider\" />\n )}\n </div>\n )\n}\n\nfunction InlineToolbar({\n anchorElem,\n editor,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n}): React.ReactNode {\n const floatingToolbarRef = useRef<HTMLDivElement | null>(null)\n const caretRef = useRef<HTMLDivElement | null>(null)\n\n const { editorConfig } = useEditorConfigContext()\n\n const closeFloatingToolbar = useCallback(() => {\n if (floatingToolbarRef?.current) {\n const isOpacityZero = floatingToolbarRef.current.style.opacity === '0'\n const isPointerEventsNone = floatingToolbarRef.current.style.pointerEvents === 'none'\n\n if (!isOpacityZero) {\n floatingToolbarRef.current.style.opacity = '0'\n }\n if (!isPointerEventsNone) {\n floatingToolbarRef.current.style.pointerEvents = 'none'\n }\n }\n }, [floatingToolbarRef])\n\n const mouseMoveListener = useCallback(\n (e: MouseEvent) => {\n if (floatingToolbarRef?.current && (e.buttons === 1 || e.buttons === 3)) {\n const isOpacityZero = floatingToolbarRef.current.style.opacity === '0'\n const isPointerEventsNone = floatingToolbarRef.current.style.pointerEvents === 'none'\n if (!isOpacityZero || !isPointerEventsNone) {\n // Check if the mouse is not over the popup\n const x = e.clientX\n const y = e.clientY\n const elementUnderMouse = document.elementFromPoint(x, y)\n if (!floatingToolbarRef.current.contains(elementUnderMouse)) {\n // Mouse is not over the target element => not a normal click, but probably a drag\n closeFloatingToolbar()\n }\n }\n }\n },\n [closeFloatingToolbar],\n )\n\n const mouseUpListener = useCallback(() => {\n if (floatingToolbarRef?.current) {\n if (floatingToolbarRef.current.style.opacity !== '1') {\n floatingToolbarRef.current.style.opacity = '1'\n }\n if (floatingToolbarRef.current.style.pointerEvents !== 'auto') {\n floatingToolbarRef.current.style.pointerEvents = 'auto'\n }\n }\n }, [])\n\n useEffect(() => {\n document.addEventListener('mousemove', mouseMoveListener)\n document.addEventListener('mouseup', mouseUpListener)\n\n return () => {\n document.removeEventListener('mousemove', mouseMoveListener)\n document.removeEventListener('mouseup', mouseUpListener)\n }\n }, [floatingToolbarRef, mouseMoveListener, mouseUpListener])\n\n const $updateTextFormatFloatingToolbar = useCallback(() => {\n const selection = $getSelection()\n\n const nativeSelection = getDOMSelection(editor._window)\n\n if (floatingToolbarRef.current === null) {\n return\n }\n\n const possibleLinkEditor = anchorElem.querySelector(':scope > .link-editor')\n const isLinkEditorVisible =\n possibleLinkEditor !== null &&\n 'style' in possibleLinkEditor &&\n possibleLinkEditor?.style?.['opacity' as keyof typeof possibleLinkEditor.style] === '1'\n\n const rootElement = editor.getRootElement()\n if (\n selection !== null &&\n nativeSelection !== null &&\n !nativeSelection.isCollapsed &&\n rootElement !== null &&\n rootElement.contains(nativeSelection.anchorNode)\n ) {\n const rangeRect = getDOMRangeRect(nativeSelection, rootElement)\n\n // Position floating toolbar\n const offsetIfFlipped = setFloatingElemPosition({\n alwaysDisplayOnTop: isLinkEditorVisible,\n anchorElem,\n floatingElem: floatingToolbarRef.current,\n horizontalPosition: 'center',\n targetRect: rangeRect,\n })\n\n // Position caret\n if (caretRef.current) {\n setFloatingElemPosition({\n anchorElem: floatingToolbarRef.current,\n anchorFlippedOffset: offsetIfFlipped,\n floatingElem: caretRef.current,\n horizontalOffset: 5,\n horizontalPosition: 'center',\n specialHandlingForCaret: true,\n targetRect: rangeRect,\n verticalGap: 8,\n })\n }\n } else {\n closeFloatingToolbar()\n }\n }, [editor, closeFloatingToolbar, anchorElem])\n\n useEffect(() => {\n const scrollerElem = anchorElem.parentElement\n\n const update = () => {\n editor.getEditorState().read(() => {\n $updateTextFormatFloatingToolbar()\n })\n }\n\n window.addEventListener('resize', update)\n if (scrollerElem) {\n scrollerElem.addEventListener('scroll', update)\n }\n\n return () => {\n window.removeEventListener('resize', update)\n if (scrollerElem) {\n scrollerElem.removeEventListener('scroll', update)\n }\n }\n }, [editor, $updateTextFormatFloatingToolbar, anchorElem])\n\n useEffect(() => {\n editor.getEditorState().read(() => {\n $updateTextFormatFloatingToolbar()\n })\n return mergeRegister(\n editor.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n $updateTextFormatFloatingToolbar()\n })\n }),\n\n editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n $updateTextFormatFloatingToolbar()\n return false\n },\n COMMAND_PRIORITY_LOW,\n ),\n )\n }, [editor, $updateTextFormatFloatingToolbar])\n\n return (\n <div className=\"inline-toolbar-popup\" ref={floatingToolbarRef}>\n <div className=\"caret\" ref={caretRef} />\n {editorConfig?.features &&\n editorConfig.features?.toolbarInline?.groups.map((group, i) => {\n return (\n <ToolbarGroupComponent\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n index={i}\n key={group.key}\n />\n )\n })}\n </div>\n )\n}\n\nfunction useInlineToolbar(\n editor: LexicalEditor,\n anchorElem: HTMLElement,\n): null | React.ReactElement {\n const [isText, setIsText] = useState(false)\n const isEditable = useLexicalEditable()\n\n const updatePopup = useCallback(() => {\n editor.getEditorState().read(() => {\n // Should not to pop up the floating toolbar when using IME input\n if (editor.isComposing()) {\n return\n }\n const selection = $getSelection()\n const nativeSelection = getDOMSelection(editor._window)\n const rootElement = editor.getRootElement()\n\n if (\n nativeSelection !== null &&\n (!$isRangeSelection(selection) ||\n rootElement === null ||\n !rootElement.contains(nativeSelection.anchorNode))\n ) {\n setIsText(false)\n return\n }\n\n if (!$isRangeSelection(selection)) {\n return\n }\n\n if (selection.getTextContent() !== '') {\n const nodes = selection.getNodes()\n let foundNodeWithText = false\n for (const node of nodes) {\n if ($isTextNode(node)) {\n setIsText(true)\n foundNodeWithText = true\n break\n }\n }\n if (!foundNodeWithText) {\n setIsText(false)\n }\n } else {\n setIsText(false)\n }\n\n const rawTextContent = selection.getTextContent().replace(/\\n/g, '')\n if (!selection.isCollapsed() && rawTextContent === '') {\n setIsText(false)\n return\n }\n })\n }, [editor])\n\n useEffect(() => {\n document.addEventListener('selectionchange', updatePopup)\n document.addEventListener('mouseup', updatePopup)\n return () => {\n document.removeEventListener('selectionchange', updatePopup)\n document.removeEventListener('mouseup', updatePopup)\n }\n }, [updatePopup])\n\n useEffect(() => {\n return mergeRegister(\n editor.registerUpdateListener(() => {\n updatePopup()\n }),\n editor.registerRootListener(() => {\n if (editor.getRootElement() === null) {\n setIsText(false)\n }\n }),\n )\n }, [editor, updatePopup])\n\n if (!isText || !isEditable) {\n return null\n }\n\n return createPortal(<InlineToolbar anchorElem={anchorElem} editor={editor} />, anchorElem)\n}\n\nexport const InlineToolbarPlugin: PluginComponentWithAnchor<undefined> = ({ anchorElem }) => {\n const [editor] = useLexicalComposerContext()\n\n return useInlineToolbar(editor, anchorElem)\n}\n"],"names":["useLexicalComposerContext","useLexicalEditable","mergeRegister","$getSelection","$isRangeSelection","$isTextNode","COMMAND_PRIORITY_LOW","getDOMSelection","SELECTION_CHANGE_COMMAND","useCallback","useEffect","useRef","useState","React","createPortal","useEditorConfigContext","getDOMRangeRect","setFloatingElemPosition","ToolbarButton","ToolbarDropdown","ButtonGroupItem","anchorElem","editor","item","Component","key","ChildComponent","ToolbarGroupComponent","group","index","editorConfig","DropdownIcon","setDropdownIcon","type","items","length","undefined","onActiveChange","activeItems","div","className","data-toolbar-group-key","Icon","maxActiveItems","map","features","toolbarInline","groups","InlineToolbar","floatingToolbarRef","caretRef","closeFloatingToolbar","current","isOpacityZero","style","opacity","isPointerEventsNone","pointerEvents","mouseMoveListener","e","buttons","x","clientX","y","clientY","elementUnderMouse","document","elementFromPoint","contains","mouseUpListener","addEventListener","removeEventListener","$updateTextFormatFloatingToolbar","selection","nativeSelection","_window","possibleLinkEditor","querySelector","isLinkEditorVisible","rootElement","getRootElement","isCollapsed","anchorNode","rangeRect","offsetIfFlipped","alwaysDisplayOnTop","floatingElem","horizontalPosition","targetRect","anchorFlippedOffset","horizontalOffset","specialHandlingForCaret","verticalGap","scrollerElem","parentElement","update","getEditorState","read","window","registerUpdateListener","editorState","registerCommand","ref","i","useInlineToolbar","isText","setIsText","isEditable","updatePopup","isComposing","getTextContent","nodes","getNodes","foundNodeWithText","node","rawTextContent","replace","registerRootListener","InlineToolbarPlugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/features/toolbars/inline/client/Toolbar/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { useLexicalEditable } from '@lexical/react/useLexicalEditable'\nimport { mergeRegister } from '@lexical/utils'\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_LOW,\n getDOMSelection,\n SELECTION_CHANGE_COMMAND,\n} from 'lexical'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\n\nimport type { PluginComponentWithAnchor } from '../../../../typesClient.js'\nimport type { ToolbarGroup, ToolbarGroupItem } from '../../../types.js'\n\nimport { useEditorConfigContext } from '../../../../../lexical/config/client/EditorConfigProvider.js'\nimport { getDOMRangeRect } from '../../../../../lexical/utils/getDOMRangeRect.js'\nimport { setFloatingElemPosition } from '../../../../../lexical/utils/setFloatingElemPosition.js'\nimport { ToolbarButton } from '../../../shared/ToolbarButton/index.js'\nimport './index.scss'\nimport { ToolbarDropdown } from '../../../shared/ToolbarDropdown/index.js'\n\nfunction ButtonGroupItem({\n anchorElem,\n editor,\n item,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n item: ToolbarGroupItem\n}): React.ReactNode {\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n )\n }\n if (!item.ChildComponent) {\n return null\n }\n\n return (\n <ToolbarButton editor={editor} item={item} key={item.key}>\n <item.ChildComponent />\n </ToolbarButton>\n )\n}\n\nfunction ToolbarGroupComponent({\n anchorElem,\n editor,\n group,\n index,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n group: ToolbarGroup\n index: number\n}): React.ReactNode {\n const { editorConfig } = useEditorConfigContext()\n\n const [DropdownIcon, setDropdownIcon] = React.useState<React.FC | undefined>()\n\n React.useEffect(() => {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent)\n } else {\n setDropdownIcon(undefined)\n }\n }, [group])\n\n const onActiveChange = useCallback(\n ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => {\n if (!activeItems.length) {\n if (group?.type === 'dropdown' && group.items.length && group.ChildComponent) {\n setDropdownIcon(() => group.ChildComponent)\n } else {\n setDropdownIcon(undefined)\n }\n return\n }\n const item = activeItems[0]\n setDropdownIcon(() => item?.ChildComponent)\n },\n [group],\n )\n\n return (\n <div\n className={`inline-toolbar-popup__group inline-toolbar-popup__group-${group.key}`}\n data-toolbar-group-key={group.key}\n key={group.key}\n >\n {group.type === 'dropdown' && group.items.length ? (\n DropdownIcon ? (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n Icon={DropdownIcon}\n maxActiveItems={group.maxActiveItems ?? 1}\n onActiveChange={onActiveChange}\n />\n ) : (\n <ToolbarDropdown\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n maxActiveItems={group.maxActiveItems ?? 1}\n onActiveChange={onActiveChange}\n />\n )\n ) : null}\n {group.type === 'buttons' && group.items.length\n ? group.items.map((item) => {\n return (\n <ButtonGroupItem anchorElem={anchorElem} editor={editor} item={item} key={item.key} />\n )\n })\n : null}\n {index < editorConfig.features.toolbarInline?.groups.length - 1 && (\n <div className=\"divider\" />\n )}\n </div>\n )\n}\n\nfunction InlineToolbar({\n anchorElem,\n editor,\n}: {\n anchorElem: HTMLElement\n editor: LexicalEditor\n}): React.ReactNode {\n const floatingToolbarRef = useRef<HTMLDivElement | null>(null)\n const caretRef = useRef<HTMLDivElement | null>(null)\n\n const { editorConfig } = useEditorConfigContext()\n\n const closeFloatingToolbar = useCallback(() => {\n if (floatingToolbarRef?.current) {\n const isOpacityZero = floatingToolbarRef.current.style.opacity === '0'\n const isPointerEventsNone = floatingToolbarRef.current.style.pointerEvents === 'none'\n\n if (!isOpacityZero) {\n floatingToolbarRef.current.style.opacity = '0'\n }\n if (!isPointerEventsNone) {\n floatingToolbarRef.current.style.pointerEvents = 'none'\n }\n }\n }, [floatingToolbarRef])\n\n const mouseMoveListener = useCallback(\n (e: MouseEvent) => {\n if (floatingToolbarRef?.current && (e.buttons === 1 || e.buttons === 3)) {\n const isOpacityZero = floatingToolbarRef.current.style.opacity === '0'\n const isPointerEventsNone = floatingToolbarRef.current.style.pointerEvents === 'none'\n if (!isOpacityZero || !isPointerEventsNone) {\n // Check if the mouse is not over the popup\n const x = e.clientX\n const y = e.clientY\n const elementUnderMouse = document.elementFromPoint(x, y)\n if (!floatingToolbarRef.current.contains(elementUnderMouse)) {\n // Mouse is not over the target element => not a normal click, but probably a drag\n closeFloatingToolbar()\n }\n }\n }\n },\n [closeFloatingToolbar],\n )\n\n const mouseUpListener = useCallback(() => {\n if (floatingToolbarRef?.current) {\n if (floatingToolbarRef.current.style.opacity !== '1') {\n floatingToolbarRef.current.style.opacity = '1'\n }\n if (floatingToolbarRef.current.style.pointerEvents !== 'auto') {\n floatingToolbarRef.current.style.pointerEvents = 'auto'\n }\n }\n }, [])\n\n useEffect(() => {\n document.addEventListener('mousemove', mouseMoveListener)\n document.addEventListener('mouseup', mouseUpListener)\n\n return () => {\n document.removeEventListener('mousemove', mouseMoveListener)\n document.removeEventListener('mouseup', mouseUpListener)\n }\n }, [floatingToolbarRef, mouseMoveListener, mouseUpListener])\n\n const $updateTextFormatFloatingToolbar = useCallback(() => {\n const selection = $getSelection()\n\n const nativeSelection = getDOMSelection(editor._window)\n\n if (floatingToolbarRef.current === null) {\n return\n }\n\n const possibleLinkEditor = anchorElem.querySelector(':scope > .link-editor')\n const isLinkEditorVisible =\n possibleLinkEditor !== null &&\n 'style' in possibleLinkEditor &&\n possibleLinkEditor?.style?.['opacity' as keyof typeof possibleLinkEditor.style] === '1'\n\n const rootElement = editor.getRootElement()\n if (\n selection !== null &&\n nativeSelection !== null &&\n !nativeSelection.isCollapsed &&\n rootElement !== null &&\n rootElement.contains(nativeSelection.anchorNode)\n ) {\n const rangeRect = getDOMRangeRect(nativeSelection, rootElement)\n\n // Position floating toolbar\n const offsetIfFlipped = setFloatingElemPosition({\n alwaysDisplayOnTop: isLinkEditorVisible,\n anchorElem,\n floatingElem: floatingToolbarRef.current,\n horizontalPosition: 'center',\n targetRect: rangeRect,\n })\n\n // Position caret\n if (caretRef.current) {\n setFloatingElemPosition({\n anchorElem: floatingToolbarRef.current,\n anchorFlippedOffset: offsetIfFlipped,\n floatingElem: caretRef.current,\n horizontalOffset: 5,\n horizontalPosition: 'center',\n specialHandlingForCaret: true,\n targetRect: rangeRect,\n verticalGap: 8,\n })\n }\n } else {\n closeFloatingToolbar()\n }\n }, [editor, closeFloatingToolbar, anchorElem])\n\n useEffect(() => {\n const scrollerElem = anchorElem.parentElement\n\n const update = () => {\n editor.getEditorState().read(() => {\n $updateTextFormatFloatingToolbar()\n })\n }\n\n window.addEventListener('resize', update)\n if (scrollerElem) {\n scrollerElem.addEventListener('scroll', update)\n }\n\n return () => {\n window.removeEventListener('resize', update)\n if (scrollerElem) {\n scrollerElem.removeEventListener('scroll', update)\n }\n }\n }, [editor, $updateTextFormatFloatingToolbar, anchorElem])\n\n useEffect(() => {\n editor.getEditorState().read(() => {\n $updateTextFormatFloatingToolbar()\n })\n return mergeRegister(\n editor.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n $updateTextFormatFloatingToolbar()\n })\n }),\n\n editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n $updateTextFormatFloatingToolbar()\n return false\n },\n COMMAND_PRIORITY_LOW,\n ),\n )\n }, [editor, $updateTextFormatFloatingToolbar])\n\n return (\n <div className=\"inline-toolbar-popup\" ref={floatingToolbarRef}>\n <div className=\"caret\" ref={caretRef} />\n {editorConfig?.features &&\n editorConfig.features?.toolbarInline?.groups.map((group, i) => {\n return (\n <ToolbarGroupComponent\n anchorElem={anchorElem}\n editor={editor}\n group={group}\n index={i}\n key={group.key}\n />\n )\n })}\n </div>\n )\n}\n\nfunction useInlineToolbar(\n editor: LexicalEditor,\n anchorElem: HTMLElement,\n): null | React.ReactElement {\n const [isText, setIsText] = useState(false)\n const isEditable = useLexicalEditable()\n\n const updatePopup = useCallback(() => {\n editor.getEditorState().read(() => {\n // Should not to pop up the floating toolbar when using IME input\n if (editor.isComposing()) {\n return\n }\n const selection = $getSelection()\n const nativeSelection = getDOMSelection(editor._window)\n const rootElement = editor.getRootElement()\n\n if (\n nativeSelection !== null &&\n (!$isRangeSelection(selection) ||\n rootElement === null ||\n !rootElement.contains(nativeSelection.anchorNode))\n ) {\n setIsText(false)\n return\n }\n\n if (!$isRangeSelection(selection)) {\n return\n }\n\n if (selection.getTextContent() !== '') {\n const nodes = selection.getNodes()\n let foundNodeWithText = false\n for (const node of nodes) {\n if ($isTextNode(node)) {\n setIsText(true)\n foundNodeWithText = true\n break\n }\n }\n if (!foundNodeWithText) {\n setIsText(false)\n }\n } else {\n setIsText(false)\n }\n\n const rawTextContent = selection.getTextContent().replace(/\\n/g, '')\n if (!selection.isCollapsed() && rawTextContent === '') {\n setIsText(false)\n return\n }\n })\n }, [editor])\n\n useEffect(() => {\n document.addEventListener('selectionchange', updatePopup)\n document.addEventListener('mouseup', updatePopup)\n return () => {\n document.removeEventListener('selectionchange', updatePopup)\n document.removeEventListener('mouseup', updatePopup)\n }\n }, [updatePopup])\n\n useEffect(() => {\n return mergeRegister(\n editor.registerUpdateListener(() => {\n updatePopup()\n }),\n editor.registerRootListener(() => {\n if (editor.getRootElement() === null) {\n setIsText(false)\n }\n }),\n )\n }, [editor, updatePopup])\n\n if (!isText || !isEditable) {\n return null\n }\n\n return createPortal(<InlineToolbar anchorElem={anchorElem} editor={editor} />, anchorElem)\n}\n\nexport const InlineToolbarPlugin: PluginComponentWithAnchor<undefined> = ({ anchorElem }) => {\n const [editor] = useLexicalComposerContext()\n\n return useInlineToolbar(editor, anchorElem)\n}\n"],"names":["useLexicalComposerContext","useLexicalEditable","mergeRegister","$getSelection","$isRangeSelection","$isTextNode","COMMAND_PRIORITY_LOW","getDOMSelection","SELECTION_CHANGE_COMMAND","useCallback","useEffect","useRef","useState","React","createPortal","useEditorConfigContext","getDOMRangeRect","setFloatingElemPosition","ToolbarButton","ToolbarDropdown","ButtonGroupItem","anchorElem","editor","item","Component","key","ChildComponent","ToolbarGroupComponent","group","index","editorConfig","DropdownIcon","setDropdownIcon","type","items","length","undefined","onActiveChange","activeItems","div","className","data-toolbar-group-key","Icon","maxActiveItems","map","features","toolbarInline","groups","InlineToolbar","floatingToolbarRef","caretRef","closeFloatingToolbar","current","isOpacityZero","style","opacity","isPointerEventsNone","pointerEvents","mouseMoveListener","e","buttons","x","clientX","y","clientY","elementUnderMouse","document","elementFromPoint","contains","mouseUpListener","addEventListener","removeEventListener","$updateTextFormatFloatingToolbar","selection","nativeSelection","_window","possibleLinkEditor","querySelector","isLinkEditorVisible","rootElement","getRootElement","isCollapsed","anchorNode","rangeRect","offsetIfFlipped","alwaysDisplayOnTop","floatingElem","horizontalPosition","targetRect","anchorFlippedOffset","horizontalOffset","specialHandlingForCaret","verticalGap","scrollerElem","parentElement","update","getEditorState","read","window","registerUpdateListener","editorState","registerCommand","ref","i","useInlineToolbar","isText","setIsText","isEditable","updatePopup","isComposing","getTextContent","nodes","getNodes","foundNodeWithText","node","rawTextContent","replace","registerRootListener","InlineToolbarPlugin"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import { mergeRegister } from '@lexical/utils';
|
|
|
4
4
|
import { $addUpdateTag, $getSelection } from 'lexical';
|
|
5
5
|
import React, { useCallback, useDeferredValue, useEffect, useMemo, useState } from 'react';
|
|
6
6
|
import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js';
|
|
7
|
+
import './index.scss';
|
|
7
8
|
import { useRunDeprioritized } from '../../../../utilities/useRunDeprioritized.js';
|
|
8
9
|
const baseClass = 'toolbar-popup__button';
|
|
9
10
|
export const ToolbarButton = ({ children, editor, item })=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/features/toolbars/shared/ToolbarButton/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport { mergeRegister } from '@lexical/utils'\nimport { $addUpdateTag, $getSelection } from 'lexical'\nimport React, { useCallback, useDeferredValue, useEffect, useMemo, useState } from 'react'\n\nimport type { ToolbarGroupItem } from '../../types.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport './index.scss'\nimport { useRunDeprioritized } from '../../../../utilities/useRunDeprioritized.js'\n\nconst baseClass = 'toolbar-popup__button'\n\nexport const ToolbarButton = ({\n children,\n editor,\n item,\n}: {\n children: React.JSX.Element\n editor: LexicalEditor\n item: ToolbarGroupItem\n}) => {\n const [_state, setState] = useState({ active: false, enabled: true })\n const deferredState = useDeferredValue(_state)\n\n const editorConfigContext = useEditorConfigContext()\n\n const className = useMemo(() => {\n return [\n baseClass,\n !deferredState.enabled ? 'disabled' : '',\n deferredState.active ? 'active' : '',\n item.key ? `${baseClass}-${item.key}` : '',\n ]\n .filter(Boolean)\n .join(' ')\n }, [deferredState, item.key])\n const updateStates = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n if (!selection) {\n return\n }\n const newActive = item.isActive\n ? item.isActive({ editor, editorConfigContext, selection })\n : false\n\n const newEnabled = item.isEnabled\n ? item.isEnabled({ editor, editorConfigContext, selection })\n : true\n\n setState((prev) => {\n if (prev.active === newActive && prev.enabled === newEnabled) {\n return prev\n }\n return { active: newActive, enabled: newEnabled }\n })\n })\n }, [editor, editorConfigContext, item])\n\n const runDeprioritized = useRunDeprioritized()\n\n useEffect(() => {\n // Run on mount\n void runDeprioritized(updateStates)\n\n const listener = () => runDeprioritized(updateStates)\n\n const cleanup = mergeRegister(editor.registerUpdateListener(listener))\n document.addEventListener('mouseup', listener)\n\n return () => {\n cleanup()\n document.removeEventListener('mouseup', listener)\n }\n }, [editor, runDeprioritized, updateStates])\n\n const handleClick = useCallback(() => {\n if (!_state.enabled) {\n return\n }\n\n editor.focus(() => {\n editor.update(() => {\n $addUpdateTag('toolbar')\n })\n // We need to wrap the onSelect in the callback, so the editor is properly focused before the onSelect is called.\n item.onSelect?.({\n editor,\n isActive: _state.active,\n })\n })\n }, [editor, item, _state])\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n // This fixes a bug where you are unable to click the button if you are in a NESTED editor (editor in blocks field in editor).\n // Thus only happens if you click on the SVG of the button. Clicking on the outside works. Related issue: https://github.com/payloadcms/payload/issues/4025\n // TODO: Find out why exactly it happens and why e.preventDefault() on the mouseDown fixes it. Write that down here, or potentially fix a root cause, if there is any.\n e.preventDefault()\n }, [])\n\n return (\n <button\n className={className}\n data-button-key={item.key}\n onClick={handleClick}\n onMouseDown={handleMouseDown}\n type=\"button\"\n >\n {children}\n </button>\n )\n}\n"],"names":["mergeRegister","$addUpdateTag","$getSelection","React","useCallback","useDeferredValue","useEffect","useMemo","useState","useEditorConfigContext","useRunDeprioritized","baseClass","ToolbarButton","children","editor","item","_state","setState","active","enabled","deferredState","editorConfigContext","className","key","filter","Boolean","join","updateStates","getEditorState","read","selection","newActive","isActive","newEnabled","isEnabled","prev","runDeprioritized","listener","cleanup","registerUpdateListener","document","addEventListener","removeEventListener","handleClick","focus","update","onSelect","handleMouseDown","e","preventDefault","button","data-button-key","onClick","onMouseDown","type"],"mappings":"AAAA;;AAGA,SAASA,aAAa,QAAQ,iBAAgB;AAC9C,SAASC,aAAa,EAAEC,aAAa,QAAQ,UAAS;AACtD,OAAOC,SAASC,WAAW,EAAEC,gBAAgB,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AAI1F,SAASC,sBAAsB,QAAQ,4DAA2D;
|
|
1
|
+
{"version":3,"sources":["../../../../../src/features/toolbars/shared/ToolbarButton/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\n\nimport { mergeRegister } from '@lexical/utils'\nimport { $addUpdateTag, $getSelection } from 'lexical'\nimport React, { useCallback, useDeferredValue, useEffect, useMemo, useState } from 'react'\n\nimport type { ToolbarGroupItem } from '../../types.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport './index.scss'\nimport { useRunDeprioritized } from '../../../../utilities/useRunDeprioritized.js'\n\nconst baseClass = 'toolbar-popup__button'\n\nexport const ToolbarButton = ({\n children,\n editor,\n item,\n}: {\n children: React.JSX.Element\n editor: LexicalEditor\n item: ToolbarGroupItem\n}) => {\n const [_state, setState] = useState({ active: false, enabled: true })\n const deferredState = useDeferredValue(_state)\n\n const editorConfigContext = useEditorConfigContext()\n\n const className = useMemo(() => {\n return [\n baseClass,\n !deferredState.enabled ? 'disabled' : '',\n deferredState.active ? 'active' : '',\n item.key ? `${baseClass}-${item.key}` : '',\n ]\n .filter(Boolean)\n .join(' ')\n }, [deferredState, item.key])\n const updateStates = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n if (!selection) {\n return\n }\n const newActive = item.isActive\n ? item.isActive({ editor, editorConfigContext, selection })\n : false\n\n const newEnabled = item.isEnabled\n ? item.isEnabled({ editor, editorConfigContext, selection })\n : true\n\n setState((prev) => {\n if (prev.active === newActive && prev.enabled === newEnabled) {\n return prev\n }\n return { active: newActive, enabled: newEnabled }\n })\n })\n }, [editor, editorConfigContext, item])\n\n const runDeprioritized = useRunDeprioritized()\n\n useEffect(() => {\n // Run on mount\n void runDeprioritized(updateStates)\n\n const listener = () => runDeprioritized(updateStates)\n\n const cleanup = mergeRegister(editor.registerUpdateListener(listener))\n document.addEventListener('mouseup', listener)\n\n return () => {\n cleanup()\n document.removeEventListener('mouseup', listener)\n }\n }, [editor, runDeprioritized, updateStates])\n\n const handleClick = useCallback(() => {\n if (!_state.enabled) {\n return\n }\n\n editor.focus(() => {\n editor.update(() => {\n $addUpdateTag('toolbar')\n })\n // We need to wrap the onSelect in the callback, so the editor is properly focused before the onSelect is called.\n item.onSelect?.({\n editor,\n isActive: _state.active,\n })\n })\n }, [editor, item, _state])\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n // This fixes a bug where you are unable to click the button if you are in a NESTED editor (editor in blocks field in editor).\n // Thus only happens if you click on the SVG of the button. Clicking on the outside works. Related issue: https://github.com/payloadcms/payload/issues/4025\n // TODO: Find out why exactly it happens and why e.preventDefault() on the mouseDown fixes it. Write that down here, or potentially fix a root cause, if there is any.\n e.preventDefault()\n }, [])\n\n return (\n <button\n className={className}\n data-button-key={item.key}\n onClick={handleClick}\n onMouseDown={handleMouseDown}\n type=\"button\"\n >\n {children}\n </button>\n )\n}\n"],"names":["mergeRegister","$addUpdateTag","$getSelection","React","useCallback","useDeferredValue","useEffect","useMemo","useState","useEditorConfigContext","useRunDeprioritized","baseClass","ToolbarButton","children","editor","item","_state","setState","active","enabled","deferredState","editorConfigContext","className","key","filter","Boolean","join","updateStates","getEditorState","read","selection","newActive","isActive","newEnabled","isEnabled","prev","runDeprioritized","listener","cleanup","registerUpdateListener","document","addEventListener","removeEventListener","handleClick","focus","update","onSelect","handleMouseDown","e","preventDefault","button","data-button-key","onClick","onMouseDown","type"],"mappings":"AAAA;;AAGA,SAASA,aAAa,QAAQ,iBAAgB;AAC9C,SAASC,aAAa,EAAEC,aAAa,QAAQ,UAAS;AACtD,OAAOC,SAASC,WAAW,EAAEC,gBAAgB,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AAI1F,SAASC,sBAAsB,QAAQ,4DAA2D;AAClG,OAAO,eAAc;AACrB,SAASC,mBAAmB,QAAQ,+CAA8C;AAElF,MAAMC,YAAY;AAElB,OAAO,MAAMC,gBAAgB,CAAC,EAC5BC,QAAQ,EACRC,MAAM,EACNC,IAAI,EAKL;IACC,MAAM,CAACC,QAAQC,SAAS,GAAGT,SAAS;QAAEU,QAAQ;QAAOC,SAAS;IAAK;IACnE,MAAMC,gBAAgBf,iBAAiBW;IAEvC,MAAMK,sBAAsBZ;IAE5B,MAAMa,YAAYf,QAAQ;QACxB,OAAO;YACLI;YACA,CAACS,cAAcD,OAAO,GAAG,aAAa;YACtCC,cAAcF,MAAM,GAAG,WAAW;YAClCH,KAAKQ,GAAG,GAAG,GAAGZ,UAAU,CAAC,EAAEI,KAAKQ,GAAG,EAAE,GAAG;SACzC,CACEC,MAAM,CAACC,SACPC,IAAI,CAAC;IACV,GAAG;QAACN;QAAeL,KAAKQ,GAAG;KAAC;IAC5B,MAAMI,eAAevB,YAAY;QAC/BU,OAAOc,cAAc,GAAGC,IAAI,CAAC;YAC3B,MAAMC,YAAY5B;YAClB,IAAI,CAAC4B,WAAW;gBACd;YACF;YACA,MAAMC,YAAYhB,KAAKiB,QAAQ,GAC3BjB,KAAKiB,QAAQ,CAAC;gBAAElB;gBAAQO;gBAAqBS;YAAU,KACvD;YAEJ,MAAMG,aAAalB,KAAKmB,SAAS,GAC7BnB,KAAKmB,SAAS,CAAC;gBAAEpB;gBAAQO;gBAAqBS;YAAU,KACxD;YAEJb,SAAS,CAACkB;gBACR,IAAIA,KAAKjB,MAAM,KAAKa,aAAaI,KAAKhB,OAAO,KAAKc,YAAY;oBAC5D,OAAOE;gBACT;gBACA,OAAO;oBAAEjB,QAAQa;oBAAWZ,SAASc;gBAAW;YAClD;QACF;IACF,GAAG;QAACnB;QAAQO;QAAqBN;KAAK;IAEtC,MAAMqB,mBAAmB1B;IAEzBJ,UAAU;QACR,eAAe;QACf,KAAK8B,iBAAiBT;QAEtB,MAAMU,WAAW,IAAMD,iBAAiBT;QAExC,MAAMW,UAAUtC,cAAcc,OAAOyB,sBAAsB,CAACF;QAC5DG,SAASC,gBAAgB,CAAC,WAAWJ;QAErC,OAAO;YACLC;YACAE,SAASE,mBAAmB,CAAC,WAAWL;QAC1C;IACF,GAAG;QAACvB;QAAQsB;QAAkBT;KAAa;IAE3C,MAAMgB,cAAcvC,YAAY;QAC9B,IAAI,CAACY,OAAOG,OAAO,EAAE;YACnB;QACF;QAEAL,OAAO8B,KAAK,CAAC;YACX9B,OAAO+B,MAAM,CAAC;gBACZ5C,cAAc;YAChB;YACA,iHAAiH;YACjHc,KAAK+B,QAAQ,GAAG;gBACdhC;gBACAkB,UAAUhB,OAAOE,MAAM;YACzB;QACF;IACF,GAAG;QAACJ;QAAQC;QAAMC;KAAO;IAEzB,MAAM+B,kBAAkB3C,YAAY,CAAC4C;QACnC,8HAA8H;QAC9H,2JAA2J;QAC3J,sKAAsK;QACtKA,EAAEC,cAAc;IAClB,GAAG,EAAE;IAEL,qBACE,KAACC;QACC5B,WAAWA;QACX6B,mBAAiBpC,KAAKQ,GAAG;QACzB6B,SAAST;QACTU,aAAaN;QACbO,MAAK;kBAEJzC;;AAGP,EAAC"}
|
|
@@ -7,6 +7,7 @@ import { useTranslation } from '@payloadcms/ui';
|
|
|
7
7
|
import { $getSelection } from 'lexical';
|
|
8
8
|
import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js';
|
|
9
9
|
import { useRunDeprioritized } from '../../../../utilities/useRunDeprioritized.js';
|
|
10
|
+
import './index.scss';
|
|
10
11
|
import { DropDown, DropDownItem } from './DropDown.js';
|
|
11
12
|
const ToolbarItem = ({ active, anchorElem, editor, enabled, item })=>{
|
|
12
13
|
const { i18n } = useTranslation();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/features/toolbars/shared/ToolbarDropdown/index.tsx"],"sourcesContent":["'use client'\nimport React, { useCallback, useDeferredValue, useEffect, useMemo } from 'react'\n\nconst baseClass = 'toolbar-popup__dropdown'\n\nimport type { LexicalEditor } from 'lexical'\n\nimport { mergeRegister } from '@lexical/utils'\nimport { useTranslation } from '@payloadcms/ui'\nimport { $getSelection } from 'lexical'\n\nimport type { ToolbarDropdownGroup, ToolbarGroupItem } from '../../types.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport { useRunDeprioritized } from '../../../../utilities/useRunDeprioritized.js'\nimport './index.scss'\nimport { DropDown, DropDownItem } from './DropDown.js'\n\nconst ToolbarItem = ({\n active,\n anchorElem,\n editor,\n enabled,\n item,\n}: {\n active?: boolean\n anchorElem: HTMLElement\n editor: LexicalEditor\n enabled?: boolean\n item: ToolbarGroupItem\n}) => {\n const { i18n } = useTranslation<{}, string>()\n const {\n fieldProps: { featureClientSchemaMap, schemaPath },\n } = useEditorConfigContext()\n\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component\n active={active}\n anchorElem={anchorElem}\n editor={editor}\n enabled={enabled}\n item={item}\n key={item.key}\n />\n )\n )\n }\n\n let title = item.key\n let croppedTitle = item.key\n if (item.label) {\n title =\n typeof item.label === 'function'\n ? item.label({ featureClientSchemaMap, i18n, schemaPath })\n : item.label\n }\n // Crop title to max. 25 characters\n if (title.length > 25) {\n croppedTitle = title.substring(0, 25) + '...'\n } else {\n croppedTitle = title\n }\n\n return (\n <DropDownItem\n active={active}\n editor={editor}\n enabled={enabled}\n Icon={item?.ChildComponent ? <item.ChildComponent /> : undefined}\n item={item}\n itemKey={item.key}\n key={item.key}\n tooltip={title}\n >\n <span className=\"text\">{croppedTitle}</span>\n </DropDownItem>\n )\n}\n\nconst MemoToolbarItem = React.memo(ToolbarItem)\n\nexport const ToolbarDropdown = ({\n anchorElem,\n classNames,\n editor,\n group,\n Icon,\n itemsContainerClassNames,\n label,\n maxActiveItems,\n onActiveChange,\n}: {\n anchorElem: HTMLElement\n classNames?: string[]\n editor: LexicalEditor\n group: ToolbarDropdownGroup\n Icon?: React.FC\n itemsContainerClassNames?: string[]\n label?: string\n /**\n * Maximum number of active items allowed. This is a performance optimization to prevent\n * unnecessary item active checks when the maximum number of active items is reached.\n */\n maxActiveItems?: number\n onActiveChange?: ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => void\n}) => {\n const [toolbarState, setToolbarState] = React.useState<{\n activeItemKeys: string[]\n enabledGroup: boolean\n enabledItemKeys: string[]\n }>({\n activeItemKeys: [],\n enabledGroup: true,\n enabledItemKeys: [],\n })\n const deferredToolbarState = useDeferredValue(toolbarState)\n\n const editorConfigContext = useEditorConfigContext()\n const { items, key: groupKey } = group\n\n const runDeprioritized = useRunDeprioritized()\n\n const updateStates = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n if (!selection) {\n return\n }\n\n const _activeItemKeys: string[] = []\n const _activeItems: ToolbarGroupItem[] = []\n const _enabledItemKeys: string[] = []\n\n for (const item of items) {\n if (item.isActive && (!maxActiveItems || _activeItemKeys.length < maxActiveItems)) {\n const isActive = item.isActive({ editor, editorConfigContext, selection })\n if (isActive) {\n _activeItemKeys.push(item.key)\n _activeItems.push(item)\n }\n }\n if (item.isEnabled) {\n const isEnabled = item.isEnabled({ editor, editorConfigContext, selection })\n if (isEnabled) {\n _enabledItemKeys.push(item.key)\n }\n } else {\n _enabledItemKeys.push(item.key)\n }\n }\n\n setToolbarState({\n activeItemKeys: _activeItemKeys,\n enabledGroup: group.isEnabled\n ? group.isEnabled({ editor, editorConfigContext, selection })\n : true,\n enabledItemKeys: _enabledItemKeys,\n })\n\n if (onActiveChange) {\n onActiveChange({ activeItems: _activeItems })\n }\n })\n }, [editor, editorConfigContext, group, items, maxActiveItems, onActiveChange])\n\n useEffect(() => {\n // Run on mount in order to update states when dropdown is opened\n void runDeprioritized(updateStates)\n\n return mergeRegister(\n editor.registerUpdateListener(async () => {\n await runDeprioritized(updateStates)\n }),\n )\n }, [editor, runDeprioritized, updateStates])\n\n const renderedItems = useMemo(() => {\n return items?.length\n ? items.map((item) => (\n <MemoToolbarItem\n active={deferredToolbarState.activeItemKeys.includes(item.key)}\n anchorElem={anchorElem}\n editor={editor}\n enabled={deferredToolbarState.enabledItemKeys.includes(item.key)}\n item={item}\n key={item.key}\n />\n ))\n : null\n }, [items, deferredToolbarState, anchorElem, editor])\n\n return (\n <DropDown\n buttonAriaLabel={`${groupKey} dropdown`}\n buttonClassName={[baseClass, `${baseClass}-${groupKey}`, ...(classNames || [])]\n .filter(Boolean)\n .join(' ')}\n disabled={!deferredToolbarState.enabledGroup}\n dropdownKey={groupKey}\n Icon={Icon}\n itemsContainerClassNames={[`${baseClass}-items`, ...(itemsContainerClassNames || [])]}\n key={groupKey}\n label={label}\n >\n {renderedItems}\n </DropDown>\n )\n}\n"],"names":["React","useCallback","useDeferredValue","useEffect","useMemo","baseClass","mergeRegister","useTranslation","$getSelection","useEditorConfigContext","useRunDeprioritized","DropDown","DropDownItem","ToolbarItem","active","anchorElem","editor","enabled","item","i18n","fieldProps","featureClientSchemaMap","schemaPath","Component","key","title","croppedTitle","label","length","substring","Icon","ChildComponent","undefined","itemKey","tooltip","span","className","MemoToolbarItem","memo","ToolbarDropdown","classNames","group","itemsContainerClassNames","maxActiveItems","onActiveChange","toolbarState","setToolbarState","useState","activeItemKeys","enabledGroup","enabledItemKeys","deferredToolbarState","editorConfigContext","items","groupKey","runDeprioritized","updateStates","getEditorState","read","selection","_activeItemKeys","_activeItems","_enabledItemKeys","isActive","push","isEnabled","activeItems","registerUpdateListener","renderedItems","map","includes","buttonAriaLabel","buttonClassName","filter","Boolean","join","disabled","dropdownKey"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/features/toolbars/shared/ToolbarDropdown/index.tsx"],"sourcesContent":["'use client'\nimport React, { useCallback, useDeferredValue, useEffect, useMemo } from 'react'\n\nconst baseClass = 'toolbar-popup__dropdown'\n\nimport type { LexicalEditor } from 'lexical'\n\nimport { mergeRegister } from '@lexical/utils'\nimport { useTranslation } from '@payloadcms/ui'\nimport { $getSelection } from 'lexical'\n\nimport type { ToolbarDropdownGroup, ToolbarGroupItem } from '../../types.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport { useRunDeprioritized } from '../../../../utilities/useRunDeprioritized.js'\nimport './index.scss'\nimport { DropDown, DropDownItem } from './DropDown.js'\n\nconst ToolbarItem = ({\n active,\n anchorElem,\n editor,\n enabled,\n item,\n}: {\n active?: boolean\n anchorElem: HTMLElement\n editor: LexicalEditor\n enabled?: boolean\n item: ToolbarGroupItem\n}) => {\n const { i18n } = useTranslation<{}, string>()\n const {\n fieldProps: { featureClientSchemaMap, schemaPath },\n } = useEditorConfigContext()\n\n if (item.Component) {\n return (\n item?.Component && (\n <item.Component\n active={active}\n anchorElem={anchorElem}\n editor={editor}\n enabled={enabled}\n item={item}\n key={item.key}\n />\n )\n )\n }\n\n let title = item.key\n let croppedTitle = item.key\n if (item.label) {\n title =\n typeof item.label === 'function'\n ? item.label({ featureClientSchemaMap, i18n, schemaPath })\n : item.label\n }\n // Crop title to max. 25 characters\n if (title.length > 25) {\n croppedTitle = title.substring(0, 25) + '...'\n } else {\n croppedTitle = title\n }\n\n return (\n <DropDownItem\n active={active}\n editor={editor}\n enabled={enabled}\n Icon={item?.ChildComponent ? <item.ChildComponent /> : undefined}\n item={item}\n itemKey={item.key}\n key={item.key}\n tooltip={title}\n >\n <span className=\"text\">{croppedTitle}</span>\n </DropDownItem>\n )\n}\n\nconst MemoToolbarItem = React.memo(ToolbarItem)\n\nexport const ToolbarDropdown = ({\n anchorElem,\n classNames,\n editor,\n group,\n Icon,\n itemsContainerClassNames,\n label,\n maxActiveItems,\n onActiveChange,\n}: {\n anchorElem: HTMLElement\n classNames?: string[]\n editor: LexicalEditor\n group: ToolbarDropdownGroup\n Icon?: React.FC\n itemsContainerClassNames?: string[]\n label?: string\n /**\n * Maximum number of active items allowed. This is a performance optimization to prevent\n * unnecessary item active checks when the maximum number of active items is reached.\n */\n maxActiveItems?: number\n onActiveChange?: ({ activeItems }: { activeItems: ToolbarGroupItem[] }) => void\n}) => {\n const [toolbarState, setToolbarState] = React.useState<{\n activeItemKeys: string[]\n enabledGroup: boolean\n enabledItemKeys: string[]\n }>({\n activeItemKeys: [],\n enabledGroup: true,\n enabledItemKeys: [],\n })\n const deferredToolbarState = useDeferredValue(toolbarState)\n\n const editorConfigContext = useEditorConfigContext()\n const { items, key: groupKey } = group\n\n const runDeprioritized = useRunDeprioritized()\n\n const updateStates = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n if (!selection) {\n return\n }\n\n const _activeItemKeys: string[] = []\n const _activeItems: ToolbarGroupItem[] = []\n const _enabledItemKeys: string[] = []\n\n for (const item of items) {\n if (item.isActive && (!maxActiveItems || _activeItemKeys.length < maxActiveItems)) {\n const isActive = item.isActive({ editor, editorConfigContext, selection })\n if (isActive) {\n _activeItemKeys.push(item.key)\n _activeItems.push(item)\n }\n }\n if (item.isEnabled) {\n const isEnabled = item.isEnabled({ editor, editorConfigContext, selection })\n if (isEnabled) {\n _enabledItemKeys.push(item.key)\n }\n } else {\n _enabledItemKeys.push(item.key)\n }\n }\n\n setToolbarState({\n activeItemKeys: _activeItemKeys,\n enabledGroup: group.isEnabled\n ? group.isEnabled({ editor, editorConfigContext, selection })\n : true,\n enabledItemKeys: _enabledItemKeys,\n })\n\n if (onActiveChange) {\n onActiveChange({ activeItems: _activeItems })\n }\n })\n }, [editor, editorConfigContext, group, items, maxActiveItems, onActiveChange])\n\n useEffect(() => {\n // Run on mount in order to update states when dropdown is opened\n void runDeprioritized(updateStates)\n\n return mergeRegister(\n editor.registerUpdateListener(async () => {\n await runDeprioritized(updateStates)\n }),\n )\n }, [editor, runDeprioritized, updateStates])\n\n const renderedItems = useMemo(() => {\n return items?.length\n ? items.map((item) => (\n <MemoToolbarItem\n active={deferredToolbarState.activeItemKeys.includes(item.key)}\n anchorElem={anchorElem}\n editor={editor}\n enabled={deferredToolbarState.enabledItemKeys.includes(item.key)}\n item={item}\n key={item.key}\n />\n ))\n : null\n }, [items, deferredToolbarState, anchorElem, editor])\n\n return (\n <DropDown\n buttonAriaLabel={`${groupKey} dropdown`}\n buttonClassName={[baseClass, `${baseClass}-${groupKey}`, ...(classNames || [])]\n .filter(Boolean)\n .join(' ')}\n disabled={!deferredToolbarState.enabledGroup}\n dropdownKey={groupKey}\n Icon={Icon}\n itemsContainerClassNames={[`${baseClass}-items`, ...(itemsContainerClassNames || [])]}\n key={groupKey}\n label={label}\n >\n {renderedItems}\n </DropDown>\n )\n}\n"],"names":["React","useCallback","useDeferredValue","useEffect","useMemo","baseClass","mergeRegister","useTranslation","$getSelection","useEditorConfigContext","useRunDeprioritized","DropDown","DropDownItem","ToolbarItem","active","anchorElem","editor","enabled","item","i18n","fieldProps","featureClientSchemaMap","schemaPath","Component","key","title","croppedTitle","label","length","substring","Icon","ChildComponent","undefined","itemKey","tooltip","span","className","MemoToolbarItem","memo","ToolbarDropdown","classNames","group","itemsContainerClassNames","maxActiveItems","onActiveChange","toolbarState","setToolbarState","useState","activeItemKeys","enabledGroup","enabledItemKeys","deferredToolbarState","editorConfigContext","items","groupKey","runDeprioritized","updateStates","getEditorState","read","selection","_activeItemKeys","_activeItems","_enabledItemKeys","isActive","push","isEnabled","activeItems","registerUpdateListener","renderedItems","map","includes","buttonAriaLabel","buttonClassName","filter","Boolean","join","disabled","dropdownKey"],"mappings":"AAAA;;AACA,OAAOA,SAASC,WAAW,EAAEC,gBAAgB,EAAEC,SAAS,EAAEC,OAAO,QAAQ,QAAO;AAEhF,MAAMC,YAAY;AAIlB,SAASC,aAAa,QAAQ,iBAAgB;AAC9C,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,SAASC,aAAa,QAAQ,UAAS;AAIvC,SAASC,sBAAsB,QAAQ,4DAA2D;AAClG,SAASC,mBAAmB,QAAQ,+CAA8C;AAClF,OAAO,eAAc;AACrB,SAASC,QAAQ,EAAEC,YAAY,QAAQ,gBAAe;AAEtD,MAAMC,cAAc,CAAC,EACnBC,MAAM,EACNC,UAAU,EACVC,MAAM,EACNC,OAAO,EACPC,IAAI,EAOL;IACC,MAAM,EAAEC,IAAI,EAAE,GAAGZ;IACjB,MAAM,EACJa,YAAY,EAAEC,sBAAsB,EAAEC,UAAU,EAAE,EACnD,GAAGb;IAEJ,IAAIS,KAAKK,SAAS,EAAE;QAClB,OACEL,MAAMK,2BACJ,KAACL,KAAKK,SAAS;YACbT,QAAQA;YACRC,YAAYA;YACZC,QAAQA;YACRC,SAASA;YACTC,MAAMA;WACDA,KAAKM,GAAG;IAIrB;IAEA,IAAIC,QAAQP,KAAKM,GAAG;IACpB,IAAIE,eAAeR,KAAKM,GAAG;IAC3B,IAAIN,KAAKS,KAAK,EAAE;QACdF,QACE,OAAOP,KAAKS,KAAK,KAAK,aAClBT,KAAKS,KAAK,CAAC;YAAEN;YAAwBF;YAAMG;QAAW,KACtDJ,KAAKS,KAAK;IAClB;IACA,mCAAmC;IACnC,IAAIF,MAAMG,MAAM,GAAG,IAAI;QACrBF,eAAeD,MAAMI,SAAS,CAAC,GAAG,MAAM;IAC1C,OAAO;QACLH,eAAeD;IACjB;IAEA,qBACE,KAACb;QACCE,QAAQA;QACRE,QAAQA;QACRC,SAASA;QACTa,MAAMZ,MAAMa,+BAAiB,KAACb,KAAKa,cAAc,QAAMC;QACvDd,MAAMA;QACNe,SAASf,KAAKM,GAAG;QAEjBU,SAAST;kBAET,cAAA,KAACU;YAAKC,WAAU;sBAAQV;;OAHnBR,KAAKM,GAAG;AAMnB;AAEA,MAAMa,gCAAkBrC,MAAMsC,IAAI,CAACzB;AAEnC,OAAO,MAAM0B,kBAAkB,CAAC,EAC9BxB,UAAU,EACVyB,UAAU,EACVxB,MAAM,EACNyB,KAAK,EACLX,IAAI,EACJY,wBAAwB,EACxBf,KAAK,EACLgB,cAAc,EACdC,cAAc,EAef,GANC;;;GAGC;IAID,MAAM,CAACC,cAAcC,gBAAgB,GAAG9C,MAAM+C,QAAQ,CAInD;QACDC,gBAAgB,EAAE;QAClBC,cAAc;QACdC,iBAAiB,EAAE;IACrB;IACA,MAAMC,uBAAuBjD,iBAAiB2C;IAE9C,MAAMO,sBAAsB3C;IAC5B,MAAM,EAAE4C,KAAK,EAAE7B,KAAK8B,QAAQ,EAAE,GAAGb;IAEjC,MAAMc,mBAAmB7C;IAEzB,MAAM8C,eAAevD,YAAY;QAC/Be,OAAOyC,cAAc,GAAGC,IAAI,CAAC;YAC3B,MAAMC,YAAYnD;YAClB,IAAI,CAACmD,WAAW;gBACd;YACF;YAEA,MAAMC,kBAA4B,EAAE;YACpC,MAAMC,eAAmC,EAAE;YAC3C,MAAMC,mBAA6B,EAAE;YAErC,KAAK,MAAM5C,QAAQmC,MAAO;gBACxB,IAAInC,KAAK6C,QAAQ,IAAK,CAAA,CAACpB,kBAAkBiB,gBAAgBhC,MAAM,GAAGe,cAAa,GAAI;oBACjF,MAAMoB,WAAW7C,KAAK6C,QAAQ,CAAC;wBAAE/C;wBAAQoC;wBAAqBO;oBAAU;oBACxE,IAAII,UAAU;wBACZH,gBAAgBI,IAAI,CAAC9C,KAAKM,GAAG;wBAC7BqC,aAAaG,IAAI,CAAC9C;oBACpB;gBACF;gBACA,IAAIA,KAAK+C,SAAS,EAAE;oBAClB,MAAMA,YAAY/C,KAAK+C,SAAS,CAAC;wBAAEjD;wBAAQoC;wBAAqBO;oBAAU;oBAC1E,IAAIM,WAAW;wBACbH,iBAAiBE,IAAI,CAAC9C,KAAKM,GAAG;oBAChC;gBACF,OAAO;oBACLsC,iBAAiBE,IAAI,CAAC9C,KAAKM,GAAG;gBAChC;YACF;YAEAsB,gBAAgB;gBACdE,gBAAgBY;gBAChBX,cAAcR,MAAMwB,SAAS,GACzBxB,MAAMwB,SAAS,CAAC;oBAAEjD;oBAAQoC;oBAAqBO;gBAAU,KACzD;gBACJT,iBAAiBY;YACnB;YAEA,IAAIlB,gBAAgB;gBAClBA,eAAe;oBAAEsB,aAAaL;gBAAa;YAC7C;QACF;IACF,GAAG;QAAC7C;QAAQoC;QAAqBX;QAAOY;QAAOV;QAAgBC;KAAe;IAE9EzC,UAAU;QACR,iEAAiE;QACjE,KAAKoD,iBAAiBC;QAEtB,OAAOlD,cACLU,OAAOmD,sBAAsB,CAAC;YAC5B,MAAMZ,iBAAiBC;QACzB;IAEJ,GAAG;QAACxC;QAAQuC;QAAkBC;KAAa;IAE3C,MAAMY,gBAAgBhE,QAAQ;QAC5B,OAAOiD,OAAOzB,SACVyB,MAAMgB,GAAG,CAAC,CAACnD,qBACT,KAACmB;gBACCvB,QAAQqC,qBAAqBH,cAAc,CAACsB,QAAQ,CAACpD,KAAKM,GAAG;gBAC7DT,YAAYA;gBACZC,QAAQA;gBACRC,SAASkC,qBAAqBD,eAAe,CAACoB,QAAQ,CAACpD,KAAKM,GAAG;gBAC/DN,MAAMA;eACDA,KAAKM,GAAG,KAGjB;IACN,GAAG;QAAC6B;QAAOF;QAAsBpC;QAAYC;KAAO;IAEpD,qBACE,KAACL;QACC4D,iBAAiB,GAAGjB,SAAS,SAAS,CAAC;QACvCkB,iBAAiB;YAACnE;YAAW,GAAGA,UAAU,CAAC,EAAEiD,UAAU;eAAMd,cAAc,EAAE;SAAE,CAC5EiC,MAAM,CAACC,SACPC,IAAI,CAAC;QACRC,UAAU,CAACzB,qBAAqBF,YAAY;QAC5C4B,aAAavB;QACbxB,MAAMA;QACNY,0BAA0B;YAAC,GAAGrC,UAAU,MAAM,CAAC;eAAMqC,4BAA4B,EAAE;SAAE;QAErFf,OAAOA;kBAENyC;OAHId;AAMX,EAAC"}
|
|
@@ -12,6 +12,7 @@ import { FieldsDrawer } from '../../../../utilities/fieldsDrawer/Drawer.js';
|
|
|
12
12
|
import { useLexicalDocumentDrawer } from '../../../../utilities/fieldsDrawer/useLexicalDocumentDrawer.js';
|
|
13
13
|
import { useLexicalDrawer } from '../../../../utilities/fieldsDrawer/useLexicalDrawer.js';
|
|
14
14
|
import { INSERT_UPLOAD_WITH_DRAWER_COMMAND } from '../drawer/commands.js';
|
|
15
|
+
import './index.scss';
|
|
15
16
|
const initialParams = {
|
|
16
17
|
depth: 0
|
|
17
18
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/features/upload/client/component/index.tsx"],"sourcesContent":["'use client'\nimport type { ClientCollectionConfig, Data, FormState, JsonObject } from 'payload'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { useLexicalEditable } from '@lexical/react/useLexicalEditable'\nimport { getTranslation } from '@payloadcms/translations'\nimport {\n Button,\n formatDrawerSlug,\n Thumbnail,\n useConfig,\n useEditDepth,\n usePayloadAPI,\n useTranslation,\n} from '@payloadcms/ui'\nimport { $getNodeByKey, type ElementFormatType } from 'lexical'\nimport { isImage } from 'payload/shared'\nimport React, { useCallback, useId, useReducer, useRef, useState } from 'react'\n\nimport type { BaseClientFeatureProps } from '../../../typesClient.js'\nimport type { UploadData } from '../../server/nodes/UploadNode.js'\nimport type { UploadFeaturePropsClient } from '../index.js'\nimport type { UploadNode } from '../nodes/UploadNode.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport { FieldsDrawer } from '../../../../utilities/fieldsDrawer/Drawer.js'\nimport { useLexicalDocumentDrawer } from '../../../../utilities/fieldsDrawer/useLexicalDocumentDrawer.js'\nimport { useLexicalDrawer } from '../../../../utilities/fieldsDrawer/useLexicalDrawer.js'\nimport { INSERT_UPLOAD_WITH_DRAWER_COMMAND } from '../drawer/commands.js'\nimport './index.scss'\n\nconst initialParams = {\n depth: 0,\n}\n\nexport type ElementProps = {\n className: string\n data: UploadData\n format?: ElementFormatType\n nodeKey: string\n}\n\nexport const UploadComponent: React.FC<ElementProps> = (props) => {\n const {\n className: baseClass,\n data: { fields, relationTo, value },\n format,\n nodeKey,\n } = props\n\n if (typeof value === 'object') {\n throw new Error(\n 'Upload value should be a string or number. The Lexical Upload component should not receive the populated value object.',\n )\n }\n\n const {\n config: {\n routes: { api },\n serverURL,\n },\n getEntityConfig,\n } = useConfig()\n const uploadRef = useRef<HTMLDivElement | null>(null)\n const { uuid } = useEditorConfigContext()\n const editDepth = useEditDepth()\n const [editor] = useLexicalComposerContext()\n\n const {\n editorConfig,\n fieldProps: { schemaPath },\n } = useEditorConfigContext()\n const isEditable = useLexicalEditable()\n const { i18n, t } = useTranslation()\n const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)\n const [relatedCollection] = useState<ClientCollectionConfig>(() =>\n getEntityConfig({ collectionSlug: relationTo }),\n )\n\n const componentID = useId()\n\n const extraFieldsDrawerSlug = formatDrawerSlug({\n slug: `lexical-upload-drawer-` + uuid + componentID, // There can be multiple upload components, each with their own drawer, in one single editor => separate them by componentID\n depth: editDepth,\n })\n\n // Need to use hook to initialize useEffect that restores cursor position\n const { toggleDrawer } = useLexicalDrawer(extraFieldsDrawerSlug, true)\n\n const { closeDocumentDrawer, DocumentDrawer, DocumentDrawerToggler } = useLexicalDocumentDrawer({\n id: value,\n collectionSlug: relatedCollection.slug,\n })\n\n // Get the referenced document\n const [{ data }, { setParams }] = usePayloadAPI(\n `${serverURL}${api}/${relatedCollection.slug}/${value}`,\n { initialParams },\n )\n\n const thumbnailSRC = data?.thumbnailURL || data?.url\n\n const removeUpload = useCallback(() => {\n editor.update(() => {\n $getNodeByKey(nodeKey)?.remove()\n })\n }, [editor, nodeKey])\n\n const updateUpload = useCallback(\n (_data: Data) => {\n setParams({\n ...initialParams,\n cacheBust, // do this to get the usePayloadAPI to re-fetch the data even though the URL string hasn't changed\n })\n\n dispatchCacheBust()\n closeDocumentDrawer()\n },\n [setParams, cacheBust, closeDocumentDrawer],\n )\n\n const hasExtraFields = (\n editorConfig?.resolvedFeatureMap?.get('upload')\n ?.sanitizedClientFeatureProps as BaseClientFeatureProps<UploadFeaturePropsClient>\n ).collections?.[relatedCollection.slug]?.hasExtraFields\n\n const onExtraFieldsDrawerSubmit = useCallback(\n (_: FormState, data: JsonObject) => {\n // Update lexical node (with key nodeKey) with new data\n editor.update(() => {\n const uploadNode: null | UploadNode = $getNodeByKey(nodeKey)\n if (uploadNode) {\n const newData: UploadData = {\n ...uploadNode.getData(),\n fields: data,\n }\n uploadNode.setData(newData)\n }\n })\n },\n [editor, nodeKey],\n )\n\n const aspectRatio =\n thumbnailSRC && data?.width && data?.height\n ? data.width > data.height\n ? 'landscape'\n : 'portrait'\n : 'landscape'\n\n return (\n <div\n className={`${baseClass}__contents ${baseClass}__contents--${aspectRatio}`}\n data-align={format || undefined}\n data-filename={data?.filename}\n ref={uploadRef}\n >\n <div className={`${baseClass}__card`}>\n <div className={`${baseClass}__media`}>\n <Thumbnail\n collectionSlug={relationTo}\n fileSrc={isImage(data?.mimeType) ? thumbnailSRC : null}\n height={data?.height}\n size=\"none\"\n width={data?.width}\n />\n\n {isEditable && (\n <div className={`${baseClass}__overlay ${baseClass}__floater`}>\n <div className={`${baseClass}__actions`} role=\"toolbar\">\n {hasExtraFields ? (\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__upload-drawer-toggler`}\n disabled={!isEditable}\n el=\"button\"\n icon=\"edit\"\n onClick={toggleDrawer}\n round\n size=\"medium\"\n tooltip={t('fields:editRelationship')}\n />\n ) : null}\n\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__swap-drawer-toggler`}\n disabled={!isEditable}\n el=\"button\"\n icon=\"swap\"\n onClick={() => {\n editor.dispatchCommand(INSERT_UPLOAD_WITH_DRAWER_COMMAND, {\n replace: { nodeKey },\n })\n }}\n round\n size=\"medium\"\n tooltip={t('fields:swapUpload')}\n />\n\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__removeButton`}\n disabled={!isEditable}\n icon=\"x\"\n onClick={(e) => {\n e.preventDefault()\n removeUpload()\n }}\n round\n size=\"medium\"\n tooltip={t('fields:removeUpload')}\n />\n </div>\n </div>\n )}\n </div>\n\n <div className={`${baseClass}__metaOverlay ${baseClass}__floater`}>\n <DocumentDrawerToggler className={`${baseClass}__doc-drawer-toggler`}>\n <strong className={`${baseClass}__filename`}>\n {data?.filename || t('general:untitled')}\n </strong>\n </DocumentDrawerToggler>\n <div className={`${baseClass}__collectionLabel`}>\n {getTranslation(relatedCollection.labels.singular, i18n)}\n </div>\n </div>\n </div>\n\n {value ? <DocumentDrawer onSave={updateUpload} /> : null}\n {hasExtraFields ? (\n <FieldsDrawer\n data={fields}\n drawerSlug={extraFieldsDrawerSlug}\n drawerTitle={t('general:editLabel', {\n label: getTranslation(relatedCollection.labels.singular, i18n),\n })}\n featureKey=\"upload\"\n handleDrawerSubmit={onExtraFieldsDrawerSubmit}\n schemaPath={schemaPath}\n schemaPathSuffix={relatedCollection.slug}\n />\n ) : null}\n </div>\n )\n}\n"],"names":["useLexicalComposerContext","useLexicalEditable","getTranslation","Button","formatDrawerSlug","Thumbnail","useConfig","useEditDepth","usePayloadAPI","useTranslation","$getNodeByKey","isImage","React","useCallback","useId","useReducer","useRef","useState","useEditorConfigContext","FieldsDrawer","useLexicalDocumentDrawer","useLexicalDrawer","INSERT_UPLOAD_WITH_DRAWER_COMMAND","initialParams","depth","UploadComponent","props","className","baseClass","data","fields","relationTo","value","format","nodeKey","Error","config","routes","api","serverURL","getEntityConfig","uploadRef","uuid","editDepth","editor","editorConfig","fieldProps","schemaPath","isEditable","i18n","t","cacheBust","dispatchCacheBust","state","relatedCollection","collectionSlug","componentID","extraFieldsDrawerSlug","slug","toggleDrawer","closeDocumentDrawer","DocumentDrawer","DocumentDrawerToggler","id","setParams","thumbnailSRC","thumbnailURL","url","removeUpload","update","remove","updateUpload","_data","hasExtraFields","resolvedFeatureMap","get","sanitizedClientFeatureProps","collections","onExtraFieldsDrawerSubmit","_","uploadNode","newData","getData","setData","aspectRatio","width","height","div","data-align","undefined","data-filename","filename","ref","fileSrc","mimeType","size","role","buttonStyle","disabled","el","icon","onClick","round","tooltip","dispatchCommand","replace","e","preventDefault","strong","labels","singular","onSave","drawerSlug","drawerTitle","label","featureKey","handleDrawerSubmit","schemaPathSuffix"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/features/upload/client/component/index.tsx"],"sourcesContent":["'use client'\nimport type { ClientCollectionConfig, Data, FormState, JsonObject } from 'payload'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { useLexicalEditable } from '@lexical/react/useLexicalEditable'\nimport { getTranslation } from '@payloadcms/translations'\nimport {\n Button,\n formatDrawerSlug,\n Thumbnail,\n useConfig,\n useEditDepth,\n usePayloadAPI,\n useTranslation,\n} from '@payloadcms/ui'\nimport { $getNodeByKey, type ElementFormatType } from 'lexical'\nimport { isImage } from 'payload/shared'\nimport React, { useCallback, useId, useReducer, useRef, useState } from 'react'\n\nimport type { BaseClientFeatureProps } from '../../../typesClient.js'\nimport type { UploadData } from '../../server/nodes/UploadNode.js'\nimport type { UploadFeaturePropsClient } from '../index.js'\nimport type { UploadNode } from '../nodes/UploadNode.js'\n\nimport { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'\nimport { FieldsDrawer } from '../../../../utilities/fieldsDrawer/Drawer.js'\nimport { useLexicalDocumentDrawer } from '../../../../utilities/fieldsDrawer/useLexicalDocumentDrawer.js'\nimport { useLexicalDrawer } from '../../../../utilities/fieldsDrawer/useLexicalDrawer.js'\nimport { INSERT_UPLOAD_WITH_DRAWER_COMMAND } from '../drawer/commands.js'\nimport './index.scss'\n\nconst initialParams = {\n depth: 0,\n}\n\nexport type ElementProps = {\n className: string\n data: UploadData\n format?: ElementFormatType\n nodeKey: string\n}\n\nexport const UploadComponent: React.FC<ElementProps> = (props) => {\n const {\n className: baseClass,\n data: { fields, relationTo, value },\n format,\n nodeKey,\n } = props\n\n if (typeof value === 'object') {\n throw new Error(\n 'Upload value should be a string or number. The Lexical Upload component should not receive the populated value object.',\n )\n }\n\n const {\n config: {\n routes: { api },\n serverURL,\n },\n getEntityConfig,\n } = useConfig()\n const uploadRef = useRef<HTMLDivElement | null>(null)\n const { uuid } = useEditorConfigContext()\n const editDepth = useEditDepth()\n const [editor] = useLexicalComposerContext()\n\n const {\n editorConfig,\n fieldProps: { schemaPath },\n } = useEditorConfigContext()\n const isEditable = useLexicalEditable()\n const { i18n, t } = useTranslation()\n const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)\n const [relatedCollection] = useState<ClientCollectionConfig>(() =>\n getEntityConfig({ collectionSlug: relationTo }),\n )\n\n const componentID = useId()\n\n const extraFieldsDrawerSlug = formatDrawerSlug({\n slug: `lexical-upload-drawer-` + uuid + componentID, // There can be multiple upload components, each with their own drawer, in one single editor => separate them by componentID\n depth: editDepth,\n })\n\n // Need to use hook to initialize useEffect that restores cursor position\n const { toggleDrawer } = useLexicalDrawer(extraFieldsDrawerSlug, true)\n\n const { closeDocumentDrawer, DocumentDrawer, DocumentDrawerToggler } = useLexicalDocumentDrawer({\n id: value,\n collectionSlug: relatedCollection.slug,\n })\n\n // Get the referenced document\n const [{ data }, { setParams }] = usePayloadAPI(\n `${serverURL}${api}/${relatedCollection.slug}/${value}`,\n { initialParams },\n )\n\n const thumbnailSRC = data?.thumbnailURL || data?.url\n\n const removeUpload = useCallback(() => {\n editor.update(() => {\n $getNodeByKey(nodeKey)?.remove()\n })\n }, [editor, nodeKey])\n\n const updateUpload = useCallback(\n (_data: Data) => {\n setParams({\n ...initialParams,\n cacheBust, // do this to get the usePayloadAPI to re-fetch the data even though the URL string hasn't changed\n })\n\n dispatchCacheBust()\n closeDocumentDrawer()\n },\n [setParams, cacheBust, closeDocumentDrawer],\n )\n\n const hasExtraFields = (\n editorConfig?.resolvedFeatureMap?.get('upload')\n ?.sanitizedClientFeatureProps as BaseClientFeatureProps<UploadFeaturePropsClient>\n ).collections?.[relatedCollection.slug]?.hasExtraFields\n\n const onExtraFieldsDrawerSubmit = useCallback(\n (_: FormState, data: JsonObject) => {\n // Update lexical node (with key nodeKey) with new data\n editor.update(() => {\n const uploadNode: null | UploadNode = $getNodeByKey(nodeKey)\n if (uploadNode) {\n const newData: UploadData = {\n ...uploadNode.getData(),\n fields: data,\n }\n uploadNode.setData(newData)\n }\n })\n },\n [editor, nodeKey],\n )\n\n const aspectRatio =\n thumbnailSRC && data?.width && data?.height\n ? data.width > data.height\n ? 'landscape'\n : 'portrait'\n : 'landscape'\n\n return (\n <div\n className={`${baseClass}__contents ${baseClass}__contents--${aspectRatio}`}\n data-align={format || undefined}\n data-filename={data?.filename}\n ref={uploadRef}\n >\n <div className={`${baseClass}__card`}>\n <div className={`${baseClass}__media`}>\n <Thumbnail\n collectionSlug={relationTo}\n fileSrc={isImage(data?.mimeType) ? thumbnailSRC : null}\n height={data?.height}\n size=\"none\"\n width={data?.width}\n />\n\n {isEditable && (\n <div className={`${baseClass}__overlay ${baseClass}__floater`}>\n <div className={`${baseClass}__actions`} role=\"toolbar\">\n {hasExtraFields ? (\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__upload-drawer-toggler`}\n disabled={!isEditable}\n el=\"button\"\n icon=\"edit\"\n onClick={toggleDrawer}\n round\n size=\"medium\"\n tooltip={t('fields:editRelationship')}\n />\n ) : null}\n\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__swap-drawer-toggler`}\n disabled={!isEditable}\n el=\"button\"\n icon=\"swap\"\n onClick={() => {\n editor.dispatchCommand(INSERT_UPLOAD_WITH_DRAWER_COMMAND, {\n replace: { nodeKey },\n })\n }}\n round\n size=\"medium\"\n tooltip={t('fields:swapUpload')}\n />\n\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__removeButton`}\n disabled={!isEditable}\n icon=\"x\"\n onClick={(e) => {\n e.preventDefault()\n removeUpload()\n }}\n round\n size=\"medium\"\n tooltip={t('fields:removeUpload')}\n />\n </div>\n </div>\n )}\n </div>\n\n <div className={`${baseClass}__metaOverlay ${baseClass}__floater`}>\n <DocumentDrawerToggler className={`${baseClass}__doc-drawer-toggler`}>\n <strong className={`${baseClass}__filename`}>\n {data?.filename || t('general:untitled')}\n </strong>\n </DocumentDrawerToggler>\n <div className={`${baseClass}__collectionLabel`}>\n {getTranslation(relatedCollection.labels.singular, i18n)}\n </div>\n </div>\n </div>\n\n {value ? <DocumentDrawer onSave={updateUpload} /> : null}\n {hasExtraFields ? (\n <FieldsDrawer\n data={fields}\n drawerSlug={extraFieldsDrawerSlug}\n drawerTitle={t('general:editLabel', {\n label: getTranslation(relatedCollection.labels.singular, i18n),\n })}\n featureKey=\"upload\"\n handleDrawerSubmit={onExtraFieldsDrawerSubmit}\n schemaPath={schemaPath}\n schemaPathSuffix={relatedCollection.slug}\n />\n ) : null}\n </div>\n )\n}\n"],"names":["useLexicalComposerContext","useLexicalEditable","getTranslation","Button","formatDrawerSlug","Thumbnail","useConfig","useEditDepth","usePayloadAPI","useTranslation","$getNodeByKey","isImage","React","useCallback","useId","useReducer","useRef","useState","useEditorConfigContext","FieldsDrawer","useLexicalDocumentDrawer","useLexicalDrawer","INSERT_UPLOAD_WITH_DRAWER_COMMAND","initialParams","depth","UploadComponent","props","className","baseClass","data","fields","relationTo","value","format","nodeKey","Error","config","routes","api","serverURL","getEntityConfig","uploadRef","uuid","editDepth","editor","editorConfig","fieldProps","schemaPath","isEditable","i18n","t","cacheBust","dispatchCacheBust","state","relatedCollection","collectionSlug","componentID","extraFieldsDrawerSlug","slug","toggleDrawer","closeDocumentDrawer","DocumentDrawer","DocumentDrawerToggler","id","setParams","thumbnailSRC","thumbnailURL","url","removeUpload","update","remove","updateUpload","_data","hasExtraFields","resolvedFeatureMap","get","sanitizedClientFeatureProps","collections","onExtraFieldsDrawerSubmit","_","uploadNode","newData","getData","setData","aspectRatio","width","height","div","data-align","undefined","data-filename","filename","ref","fileSrc","mimeType","size","role","buttonStyle","disabled","el","icon","onClick","round","tooltip","dispatchCommand","replace","e","preventDefault","strong","labels","singular","onSave","drawerSlug","drawerTitle","label","featureKey","handleDrawerSubmit","schemaPathSuffix"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/features/upload/client/component/pending/index.tsx"],"sourcesContent":["'use client'\n\nimport { ShimmerEffect } from '@payloadcms/ui'\n\nimport '../index.scss'\n\nexport const PendingUploadComponent = (): React.ReactNode => {\n return (\n <div className={'lexical-upload'}>\n <ShimmerEffect height={'95px'} width={'203px'} />\n </div>\n )\n}\n"],"names":["ShimmerEffect","PendingUploadComponent","div","className","height","width"],"mappings":"AAAA;;AAEA,SAASA,aAAa,QAAQ,iBAAgB;
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/features/upload/client/component/pending/index.tsx"],"sourcesContent":["'use client'\n\nimport { ShimmerEffect } from '@payloadcms/ui'\n\nimport '../index.scss'\n\nexport const PendingUploadComponent = (): React.ReactNode => {\n return (\n <div className={'lexical-upload'}>\n <ShimmerEffect height={'95px'} width={'203px'} />\n </div>\n )\n}\n"],"names":["ShimmerEffect","PendingUploadComponent","div","className","height","width"],"mappings":"AAAA;;AAEA,SAASA,aAAa,QAAQ,iBAAgB;AAE9C,OAAO,gBAAe;AAEtB,OAAO,MAAMC,yBAAyB;IACpC,qBACE,KAACC;QAAIC,WAAW;kBACd,cAAA,KAACH;YAAcI,QAAQ;YAAQC,OAAO;;;AAG5C,EAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { CheckIcon } from '@payloadcms/ui/rsc';
|
|
3
|
+
import './index.scss';
|
|
3
4
|
export const ListItemDiffHTMLConverterAsync = {
|
|
4
5
|
listitem: async ({ node, nodesToHTML, parent, providedCSSString })=>{
|
|
5
6
|
const hasSubLists = node.children.some((child)=>child.type === 'list');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/field/Diff/converters/listitem/index.tsx"],"sourcesContent":["import { CheckIcon } from '@payloadcms/ui/rsc'\n\nimport type { HTMLConvertersAsync } from '../../../../features/converters/lexicalToHtml/async/types.js'\nimport type { SerializedListItemNode } from '../../../../nodeTypes.js'\n\nimport './index.scss'\n\nexport const ListItemDiffHTMLConverterAsync: HTMLConvertersAsync<SerializedListItemNode> = {\n listitem: async ({ node, nodesToHTML, parent, providedCSSString }) => {\n const hasSubLists = node.children.some((child) => child.type === 'list')\n\n const children = (\n await nodesToHTML({\n nodes: node.children,\n })\n ).join('')\n\n if ('listType' in parent && parent?.listType === 'check') {\n const ReactDOMServer = (await import('react-dom/server')).default\n\n const JSX = (\n <li\n aria-checked={node.checked ? true : false}\n className={`checkboxItem ${node.checked ? 'checkboxItem--checked' : 'checkboxItem--unchecked'}${\n hasSubLists ? ' checkboxItem--nested' : ''\n }`}\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role\n role=\"checkbox\"\n tabIndex={-1}\n value={node.value}\n >\n {hasSubLists ? (\n // When sublists exist, just render them safely as HTML\n <div dangerouslySetInnerHTML={{ __html: children }} />\n ) : (\n // Otherwise, show our custom styled checkbox\n <div className=\"checkboxItem__wrapper\">\n <div\n className=\"checkboxItem__icon\"\n data-checked={node.checked}\n data-enable-match=\"true\"\n >\n {node.checked && <CheckIcon />}\n </div>\n <span className=\"checkboxItem__label\">{children}</span>\n </div>\n )}\n </li>\n )\n\n const html = ReactDOMServer.renderToStaticMarkup(JSX)\n\n // Add style=\"list-style-type: none;${providedCSSString}\" to html\n const styleIndex = html.indexOf('class=\"list-item-checkbox')\n const classIndex = html.indexOf('class=\"list-item-checkbox', styleIndex)\n const classEndIndex = html.indexOf('\"', classIndex + 6)\n const className = html.substring(classIndex, classEndIndex)\n const classNameWithStyle = `${className} style=\"list-style-type: none;${providedCSSString}\"`\n const htmlWithStyle = html.replace(className, classNameWithStyle)\n\n return htmlWithStyle\n } else {\n return `<li\n class=\"${hasSubLists ? 'nestedListItem' : ''}\"\n style=\"${hasSubLists ? `list-style-type: none;${providedCSSString}` : providedCSSString}\"\n value=\"${node.value}\"\n data-enable-match=\"true\"\n >${children}</li>`\n }\n },\n}\n"],"names":["CheckIcon","ListItemDiffHTMLConverterAsync","listitem","node","nodesToHTML","parent","providedCSSString","hasSubLists","children","some","child","type","nodes","join","listType","ReactDOMServer","default","JSX","li","aria-checked","checked","className","role","tabIndex","value","div","dangerouslySetInnerHTML","__html","data-checked","data-enable-match","span","html","renderToStaticMarkup","styleIndex","indexOf","classIndex","classEndIndex","substring","classNameWithStyle","htmlWithStyle","replace"],"mappings":";AAAA,SAASA,SAAS,QAAQ,qBAAoB;
|
|
1
|
+
{"version":3,"sources":["../../../../../src/field/Diff/converters/listitem/index.tsx"],"sourcesContent":["import { CheckIcon } from '@payloadcms/ui/rsc'\n\nimport type { HTMLConvertersAsync } from '../../../../features/converters/lexicalToHtml/async/types.js'\nimport type { SerializedListItemNode } from '../../../../nodeTypes.js'\n\nimport './index.scss'\n\nexport const ListItemDiffHTMLConverterAsync: HTMLConvertersAsync<SerializedListItemNode> = {\n listitem: async ({ node, nodesToHTML, parent, providedCSSString }) => {\n const hasSubLists = node.children.some((child) => child.type === 'list')\n\n const children = (\n await nodesToHTML({\n nodes: node.children,\n })\n ).join('')\n\n if ('listType' in parent && parent?.listType === 'check') {\n const ReactDOMServer = (await import('react-dom/server')).default\n\n const JSX = (\n <li\n aria-checked={node.checked ? true : false}\n className={`checkboxItem ${node.checked ? 'checkboxItem--checked' : 'checkboxItem--unchecked'}${\n hasSubLists ? ' checkboxItem--nested' : ''\n }`}\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role\n role=\"checkbox\"\n tabIndex={-1}\n value={node.value}\n >\n {hasSubLists ? (\n // When sublists exist, just render them safely as HTML\n <div dangerouslySetInnerHTML={{ __html: children }} />\n ) : (\n // Otherwise, show our custom styled checkbox\n <div className=\"checkboxItem__wrapper\">\n <div\n className=\"checkboxItem__icon\"\n data-checked={node.checked}\n data-enable-match=\"true\"\n >\n {node.checked && <CheckIcon />}\n </div>\n <span className=\"checkboxItem__label\">{children}</span>\n </div>\n )}\n </li>\n )\n\n const html = ReactDOMServer.renderToStaticMarkup(JSX)\n\n // Add style=\"list-style-type: none;${providedCSSString}\" to html\n const styleIndex = html.indexOf('class=\"list-item-checkbox')\n const classIndex = html.indexOf('class=\"list-item-checkbox', styleIndex)\n const classEndIndex = html.indexOf('\"', classIndex + 6)\n const className = html.substring(classIndex, classEndIndex)\n const classNameWithStyle = `${className} style=\"list-style-type: none;${providedCSSString}\"`\n const htmlWithStyle = html.replace(className, classNameWithStyle)\n\n return htmlWithStyle\n } else {\n return `<li\n class=\"${hasSubLists ? 'nestedListItem' : ''}\"\n style=\"${hasSubLists ? `list-style-type: none;${providedCSSString}` : providedCSSString}\"\n value=\"${node.value}\"\n data-enable-match=\"true\"\n >${children}</li>`\n }\n },\n}\n"],"names":["CheckIcon","ListItemDiffHTMLConverterAsync","listitem","node","nodesToHTML","parent","providedCSSString","hasSubLists","children","some","child","type","nodes","join","listType","ReactDOMServer","default","JSX","li","aria-checked","checked","className","role","tabIndex","value","div","dangerouslySetInnerHTML","__html","data-checked","data-enable-match","span","html","renderToStaticMarkup","styleIndex","indexOf","classIndex","classEndIndex","substring","classNameWithStyle","htmlWithStyle","replace"],"mappings":";AAAA,SAASA,SAAS,QAAQ,qBAAoB;AAK9C,OAAO,eAAc;AAErB,OAAO,MAAMC,iCAA8E;IACzFC,UAAU,OAAO,EAAEC,IAAI,EAAEC,WAAW,EAAEC,MAAM,EAAEC,iBAAiB,EAAE;QAC/D,MAAMC,cAAcJ,KAAKK,QAAQ,CAACC,IAAI,CAAC,CAACC,QAAUA,MAAMC,IAAI,KAAK;QAEjE,MAAMH,WAAW,AACf,CAAA,MAAMJ,YAAY;YAChBQ,OAAOT,KAAKK,QAAQ;QACtB,EAAC,EACDK,IAAI,CAAC;QAEP,IAAI,cAAcR,UAAUA,QAAQS,aAAa,SAAS;YACxD,MAAMC,iBAAiB,AAAC,CAAA,MAAM,MAAM,CAAC,mBAAkB,EAAGC,OAAO;YAEjE,MAAMC,oBACJ,KAACC;gBACCC,gBAAchB,KAAKiB,OAAO,GAAG,OAAO;gBACpCC,WAAW,CAAC,aAAa,EAAElB,KAAKiB,OAAO,GAAG,0BAA0B,4BAClEb,cAAc,0BAA0B,IACxC;gBACF,kFAAkF;gBAClFe,MAAK;gBACLC,UAAU,CAAC;gBACXC,OAAOrB,KAAKqB,KAAK;0BAEhBjB,cACC,uDAAuD;8BACvD,KAACkB;oBAAIC,yBAAyB;wBAAEC,QAAQnB;oBAAS;qBAEjD,6CAA6C;8BAC7C,MAACiB;oBAAIJ,WAAU;;sCACb,KAACI;4BACCJ,WAAU;4BACVO,gBAAczB,KAAKiB,OAAO;4BAC1BS,qBAAkB;sCAEjB1B,KAAKiB,OAAO,kBAAI,KAACpB;;sCAEpB,KAAC8B;4BAAKT,WAAU;sCAAuBb;;;;;YAM/C,MAAMuB,OAAOhB,eAAeiB,oBAAoB,CAACf;YAEjD,iEAAiE;YACjE,MAAMgB,aAAaF,KAAKG,OAAO,CAAC;YAChC,MAAMC,aAAaJ,KAAKG,OAAO,CAAC,6BAA6BD;YAC7D,MAAMG,gBAAgBL,KAAKG,OAAO,CAAC,KAAKC,aAAa;YACrD,MAAMd,YAAYU,KAAKM,SAAS,CAACF,YAAYC;YAC7C,MAAME,qBAAqB,GAAGjB,UAAU,8BAA8B,EAAEf,kBAAkB,CAAC,CAAC;YAC5F,MAAMiC,gBAAgBR,KAAKS,OAAO,CAACnB,WAAWiB;YAE9C,OAAOC;QACT,OAAO;YACL,OAAO,CAAC;iBACG,EAAEhC,cAAc,mBAAmB,GAAG;iBACtC,EAAEA,cAAc,CAAC,sBAAsB,EAAED,mBAAmB,GAAGA,kBAAkB;iBACjF,EAAEH,KAAKqB,KAAK,CAAC;;SAErB,EAAEhB,SAAS,KAAK,CAAC;QACtB;IACF;AACF,EAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { getTranslation } from '@payloadcms/translations';
|
|
3
|
+
import './index.scss';
|
|
3
4
|
import { formatAdminURL } from 'payload/shared';
|
|
4
5
|
const baseClass = 'lexical-relationship-diff';
|
|
5
6
|
export const RelationshipDiffHTMLConverterAsync = ({ i18n, req })=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/field/Diff/converters/relationship/index.tsx"],"sourcesContent":["import type { FileData, PayloadRequest, TypeWithID } from 'payload'\n\nimport { getTranslation, type I18nClient } from '@payloadcms/translations'\n\nimport './index.scss'\n\nimport { formatAdminURL } from 'payload/shared'\n\nimport type { HTMLConvertersAsync } from '../../../../features/converters/lexicalToHtml/async/types.js'\nimport type { SerializedRelationshipNode } from '../../../../nodeTypes.js'\n\nconst baseClass = 'lexical-relationship-diff'\n\nexport const RelationshipDiffHTMLConverterAsync: (args: {\n i18n: I18nClient\n req: PayloadRequest\n}) => HTMLConvertersAsync<SerializedRelationshipNode> = ({ i18n, req }) => {\n return {\n relationship: async ({ node, populate, providedCSSString }) => {\n let data: (Record<string, any> & TypeWithID) | undefined = undefined\n\n const id = typeof node.value === 'object' ? node.value.id : node.value\n\n // If there's no valid upload data, populate return an empty string\n if (typeof node.value !== 'object') {\n if (!populate) {\n return ''\n }\n data = await populate<FileData & TypeWithID>({\n id,\n collectionSlug: node.relationTo,\n })\n } else {\n data = node.value as unknown as FileData & TypeWithID\n }\n\n const relatedCollection = req.payload.collections[node.relationTo]?.config\n\n const ReactDOMServer = (await import('react-dom/server')).default\n\n const JSX = (\n <div\n className={`${baseClass}${providedCSSString}`}\n data-enable-match=\"true\"\n data-id={id}\n data-slug={node.relationTo}\n >\n <div className={`${baseClass}__card`}>\n <div className={`${baseClass}__collectionLabel`}>\n {i18n.t('fields:labelRelationship', {\n label: relatedCollection?.labels?.singular\n ? getTranslation(relatedCollection?.labels?.singular, i18n)\n : relatedCollection?.slug,\n })}\n </div>\n {data &&\n relatedCollection?.admin?.useAsTitle &&\n data[relatedCollection.admin.useAsTitle] ? (\n <strong className={`${baseClass}__title`} data-enable-match=\"false\">\n <a\n className={`${baseClass}__link`}\n data-enable-match=\"false\"\n href={formatAdminURL({\n adminRoute: req.payload.config.routes.admin,\n path: `/collections/${relatedCollection?.slug}/${data.id}`,\n serverURL: req.payload.config.serverURL,\n })}\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n {data[relatedCollection.admin.useAsTitle]}\n </a>\n </strong>\n ) : (\n <strong>{id as string}</strong>\n )}\n </div>\n </div>\n )\n\n // Render to HTML\n const html = ReactDOMServer.renderToStaticMarkup(JSX)\n\n return html\n },\n }\n}\n"],"names":["getTranslation","formatAdminURL","baseClass","RelationshipDiffHTMLConverterAsync","i18n","req","relationship","node","populate","providedCSSString","data","undefined","id","value","collectionSlug","relationTo","relatedCollection","payload","collections","config","ReactDOMServer","default","JSX","div","className","data-enable-match","data-id","data-slug","t","label","labels","singular","slug","admin","useAsTitle","strong","a","href","adminRoute","routes","path","serverURL","rel","target","html","renderToStaticMarkup"],"mappings":";AAEA,SAASA,cAAc,QAAyB,2BAA0B;
|
|
1
|
+
{"version":3,"sources":["../../../../../src/field/Diff/converters/relationship/index.tsx"],"sourcesContent":["import type { FileData, PayloadRequest, TypeWithID } from 'payload'\n\nimport { getTranslation, type I18nClient } from '@payloadcms/translations'\n\nimport './index.scss'\n\nimport { formatAdminURL } from 'payload/shared'\n\nimport type { HTMLConvertersAsync } from '../../../../features/converters/lexicalToHtml/async/types.js'\nimport type { SerializedRelationshipNode } from '../../../../nodeTypes.js'\n\nconst baseClass = 'lexical-relationship-diff'\n\nexport const RelationshipDiffHTMLConverterAsync: (args: {\n i18n: I18nClient\n req: PayloadRequest\n}) => HTMLConvertersAsync<SerializedRelationshipNode> = ({ i18n, req }) => {\n return {\n relationship: async ({ node, populate, providedCSSString }) => {\n let data: (Record<string, any> & TypeWithID) | undefined = undefined\n\n const id = typeof node.value === 'object' ? node.value.id : node.value\n\n // If there's no valid upload data, populate return an empty string\n if (typeof node.value !== 'object') {\n if (!populate) {\n return ''\n }\n data = await populate<FileData & TypeWithID>({\n id,\n collectionSlug: node.relationTo,\n })\n } else {\n data = node.value as unknown as FileData & TypeWithID\n }\n\n const relatedCollection = req.payload.collections[node.relationTo]?.config\n\n const ReactDOMServer = (await import('react-dom/server')).default\n\n const JSX = (\n <div\n className={`${baseClass}${providedCSSString}`}\n data-enable-match=\"true\"\n data-id={id}\n data-slug={node.relationTo}\n >\n <div className={`${baseClass}__card`}>\n <div className={`${baseClass}__collectionLabel`}>\n {i18n.t('fields:labelRelationship', {\n label: relatedCollection?.labels?.singular\n ? getTranslation(relatedCollection?.labels?.singular, i18n)\n : relatedCollection?.slug,\n })}\n </div>\n {data &&\n relatedCollection?.admin?.useAsTitle &&\n data[relatedCollection.admin.useAsTitle] ? (\n <strong className={`${baseClass}__title`} data-enable-match=\"false\">\n <a\n className={`${baseClass}__link`}\n data-enable-match=\"false\"\n href={formatAdminURL({\n adminRoute: req.payload.config.routes.admin,\n path: `/collections/${relatedCollection?.slug}/${data.id}`,\n serverURL: req.payload.config.serverURL,\n })}\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n {data[relatedCollection.admin.useAsTitle]}\n </a>\n </strong>\n ) : (\n <strong>{id as string}</strong>\n )}\n </div>\n </div>\n )\n\n // Render to HTML\n const html = ReactDOMServer.renderToStaticMarkup(JSX)\n\n return html\n },\n }\n}\n"],"names":["getTranslation","formatAdminURL","baseClass","RelationshipDiffHTMLConverterAsync","i18n","req","relationship","node","populate","providedCSSString","data","undefined","id","value","collectionSlug","relationTo","relatedCollection","payload","collections","config","ReactDOMServer","default","JSX","div","className","data-enable-match","data-id","data-slug","t","label","labels","singular","slug","admin","useAsTitle","strong","a","href","adminRoute","routes","path","serverURL","rel","target","html","renderToStaticMarkup"],"mappings":";AAEA,SAASA,cAAc,QAAyB,2BAA0B;AAE1E,OAAO,eAAc;AAErB,SAASC,cAAc,QAAQ,iBAAgB;AAK/C,MAAMC,YAAY;AAElB,OAAO,MAAMC,qCAG2C,CAAC,EAAEC,IAAI,EAAEC,GAAG,EAAE;IACpE,OAAO;QACLC,cAAc,OAAO,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,iBAAiB,EAAE;YACxD,IAAIC,OAAuDC;YAE3D,MAAMC,KAAK,OAAOL,KAAKM,KAAK,KAAK,WAAWN,KAAKM,KAAK,CAACD,EAAE,GAAGL,KAAKM,KAAK;YAEtE,mEAAmE;YACnE,IAAI,OAAON,KAAKM,KAAK,KAAK,UAAU;gBAClC,IAAI,CAACL,UAAU;oBACb,OAAO;gBACT;gBACAE,OAAO,MAAMF,SAAgC;oBAC3CI;oBACAE,gBAAgBP,KAAKQ,UAAU;gBACjC;YACF,OAAO;gBACLL,OAAOH,KAAKM,KAAK;YACnB;YAEA,MAAMG,oBAAoBX,IAAIY,OAAO,CAACC,WAAW,CAACX,KAAKQ,UAAU,CAAC,EAAEI;YAEpE,MAAMC,iBAAiB,AAAC,CAAA,MAAM,MAAM,CAAC,mBAAkB,EAAGC,OAAO;YAEjE,MAAMC,oBACJ,KAACC;gBACCC,WAAW,GAAGtB,YAAYO,mBAAmB;gBAC7CgB,qBAAkB;gBAClBC,WAASd;gBACTe,aAAWpB,KAAKQ,UAAU;0BAE1B,cAAA,MAACQ;oBAAIC,WAAW,GAAGtB,UAAU,MAAM,CAAC;;sCAClC,KAACqB;4BAAIC,WAAW,GAAGtB,UAAU,iBAAiB,CAAC;sCAC5CE,KAAKwB,CAAC,CAAC,4BAA4B;gCAClCC,OAAOb,mBAAmBc,QAAQC,WAC9B/B,eAAegB,mBAAmBc,QAAQC,UAAU3B,QACpDY,mBAAmBgB;4BACzB;;wBAEDtB,QACDM,mBAAmBiB,OAAOC,cAC1BxB,IAAI,CAACM,kBAAkBiB,KAAK,CAACC,UAAU,CAAC,iBACtC,KAACC;4BAAOX,WAAW,GAAGtB,UAAU,OAAO,CAAC;4BAAEuB,qBAAkB;sCAC1D,cAAA,KAACW;gCACCZ,WAAW,GAAGtB,UAAU,MAAM,CAAC;gCAC/BuB,qBAAkB;gCAClBY,MAAMpC,eAAe;oCACnBqC,YAAYjC,IAAIY,OAAO,CAACE,MAAM,CAACoB,MAAM,CAACN,KAAK;oCAC3CO,MAAM,CAAC,aAAa,EAAExB,mBAAmBgB,KAAK,CAAC,EAAEtB,KAAKE,EAAE,EAAE;oCAC1D6B,WAAWpC,IAAIY,OAAO,CAACE,MAAM,CAACsB,SAAS;gCACzC;gCACAC,KAAI;gCACJC,QAAO;0CAENjC,IAAI,CAACM,kBAAkBiB,KAAK,CAACC,UAAU,CAAC;;2CAI7C,KAACC;sCAAQvB;;;;;YAMjB,iBAAiB;YACjB,MAAMgC,OAAOxB,eAAeyB,oBAAoB,CAACvB;YAEjD,OAAOsB;QACT;IACF;AACF,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/field/Diff/converters/unknown/index.tsx"],"sourcesContent":["import type { LexicalNode } from 'lexical'\nimport type { PayloadRequest } from 'payload'\n\nimport { type I18nClient } from '@payloadcms/translations'\n\nimport './index.scss'\n\nimport { createHash } from 'crypto'\n\nimport type { HTMLConvertersAsync } from '../../../../features/converters/lexicalToHtml/async/types.js'\nimport type { SerializedBlockNode } from '../../../../nodeTypes.js'\n\nconst baseClass = 'lexical-unknown-diff'\n\nexport const UnknownDiffHTMLConverterAsync: (args: {\n i18n: I18nClient\n req: PayloadRequest\n}) => HTMLConvertersAsync<LexicalNode> = ({ i18n, req }) => {\n return {\n unknown: async ({ node, providedCSSString }) => {\n const ReactDOMServer = (await import('react-dom/server')).default\n\n // hash fields to ensure they are diffed if they change\n const nodeFieldsHash = createHash('sha256')\n .update(JSON.stringify(node ?? {}))\n .digest('hex')\n\n let nodeType = node.type\n\n let nodeTypeSpecifier: null | string = null\n\n if (node.type === 'block') {\n nodeTypeSpecifier = (node as SerializedBlockNode).fields.blockType\n nodeType = 'Block'\n } else if (node.type === 'inlineBlock') {\n nodeTypeSpecifier = (node as SerializedBlockNode).fields.blockType\n nodeType = 'InlineBlock'\n }\n\n const JSX = (\n <div\n className={`${baseClass}${providedCSSString}`}\n data-enable-match=\"true\"\n data-fields-hash={`${nodeFieldsHash}`}\n >\n {nodeTypeSpecifier && (\n <span className={`${baseClass}__specifier`}>{nodeTypeSpecifier} </span>\n )}\n <span>{nodeType}</span>\n <div className={`${baseClass}__meta`}>\n <br />\n </div>\n </div>\n )\n\n // Render to HTML\n const html = ReactDOMServer.renderToStaticMarkup(JSX)\n\n return html\n },\n }\n}\n"],"names":["createHash","baseClass","UnknownDiffHTMLConverterAsync","i18n","req","unknown","node","providedCSSString","ReactDOMServer","default","nodeFieldsHash","update","JSON","stringify","digest","nodeType","type","nodeTypeSpecifier","fields","blockType","JSX","div","className","data-enable-match","data-fields-hash","span","br","html","renderToStaticMarkup"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../../../../src/field/Diff/converters/unknown/index.tsx"],"sourcesContent":["import type { LexicalNode } from 'lexical'\nimport type { PayloadRequest } from 'payload'\n\nimport { type I18nClient } from '@payloadcms/translations'\n\nimport './index.scss'\n\nimport { createHash } from 'crypto'\n\nimport type { HTMLConvertersAsync } from '../../../../features/converters/lexicalToHtml/async/types.js'\nimport type { SerializedBlockNode } from '../../../../nodeTypes.js'\n\nconst baseClass = 'lexical-unknown-diff'\n\nexport const UnknownDiffHTMLConverterAsync: (args: {\n i18n: I18nClient\n req: PayloadRequest\n}) => HTMLConvertersAsync<LexicalNode> = ({ i18n, req }) => {\n return {\n unknown: async ({ node, providedCSSString }) => {\n const ReactDOMServer = (await import('react-dom/server')).default\n\n // hash fields to ensure they are diffed if they change\n const nodeFieldsHash = createHash('sha256')\n .update(JSON.stringify(node ?? {}))\n .digest('hex')\n\n let nodeType = node.type\n\n let nodeTypeSpecifier: null | string = null\n\n if (node.type === 'block') {\n nodeTypeSpecifier = (node as SerializedBlockNode).fields.blockType\n nodeType = 'Block'\n } else if (node.type === 'inlineBlock') {\n nodeTypeSpecifier = (node as SerializedBlockNode).fields.blockType\n nodeType = 'InlineBlock'\n }\n\n const JSX = (\n <div\n className={`${baseClass}${providedCSSString}`}\n data-enable-match=\"true\"\n data-fields-hash={`${nodeFieldsHash}`}\n >\n {nodeTypeSpecifier && (\n <span className={`${baseClass}__specifier`}>{nodeTypeSpecifier} </span>\n )}\n <span>{nodeType}</span>\n <div className={`${baseClass}__meta`}>\n <br />\n </div>\n </div>\n )\n\n // Render to HTML\n const html = ReactDOMServer.renderToStaticMarkup(JSX)\n\n return html\n },\n }\n}\n"],"names":["createHash","baseClass","UnknownDiffHTMLConverterAsync","i18n","req","unknown","node","providedCSSString","ReactDOMServer","default","nodeFieldsHash","update","JSON","stringify","digest","nodeType","type","nodeTypeSpecifier","fields","blockType","JSX","div","className","data-enable-match","data-fields-hash","span","br","html","renderToStaticMarkup"],"mappings":";AAKA,OAAO,eAAc;AAErB,SAASA,UAAU,QAAQ,SAAQ;AAKnC,MAAMC,YAAY;AAElB,OAAO,MAAMC,gCAG4B,CAAC,EAAEC,IAAI,EAAEC,GAAG,EAAE;IACrD,OAAO;QACLC,SAAS,OAAO,EAAEC,IAAI,EAAEC,iBAAiB,EAAE;YACzC,MAAMC,iBAAiB,AAAC,CAAA,MAAM,MAAM,CAAC,mBAAkB,EAAGC,OAAO;YAEjE,uDAAuD;YACvD,MAAMC,iBAAiBV,WAAW,UAC/BW,MAAM,CAACC,KAAKC,SAAS,CAACP,QAAQ,CAAC,IAC/BQ,MAAM,CAAC;YAEV,IAAIC,WAAWT,KAAKU,IAAI;YAExB,IAAIC,oBAAmC;YAEvC,IAAIX,KAAKU,IAAI,KAAK,SAAS;gBACzBC,oBAAoB,AAACX,KAA6BY,MAAM,CAACC,SAAS;gBAClEJ,WAAW;YACb,OAAO,IAAIT,KAAKU,IAAI,KAAK,eAAe;gBACtCC,oBAAoB,AAACX,KAA6BY,MAAM,CAACC,SAAS;gBAClEJ,WAAW;YACb;YAEA,MAAMK,oBACJ,MAACC;gBACCC,WAAW,GAAGrB,YAAYM,mBAAmB;gBAC7CgB,qBAAkB;gBAClBC,oBAAkB,GAAGd,gBAAgB;;oBAEpCO,mCACC,MAACQ;wBAAKH,WAAW,GAAGrB,UAAU,WAAW,CAAC;;4BAAGgB;4BAAkB;;;kCAEjE,KAACQ;kCAAMV;;kCACP,KAACM;wBAAIC,WAAW,GAAGrB,UAAU,MAAM,CAAC;kCAClC,cAAA,KAACyB;;;;YAKP,iBAAiB;YACjB,MAAMC,OAAOnB,eAAeoB,oBAAoB,CAACR;YAEjD,OAAOO;QACT;IACF;AACF,EAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { File } from '@payloadcms/ui/rsc';
|
|
3
3
|
import { createHash } from 'crypto';
|
|
4
|
+
import './index.scss';
|
|
4
5
|
import { formatFilesize } from 'payload/shared';
|
|
5
6
|
import React from 'react';
|
|
6
7
|
const baseClass = 'lexical-upload-diff';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/field/Diff/converters/upload/index.tsx"],"sourcesContent":["import type { FileData, PayloadRequest, TypeWithID } from 'payload'\n\nimport { type I18nClient } from '@payloadcms/translations'\nimport { File } from '@payloadcms/ui/rsc'\nimport { createHash } from 'crypto'\n\nimport './index.scss'\n\nimport { formatFilesize } from 'payload/shared'\nimport React from 'react'\n\nimport type { HTMLConvertersAsync } from '../../../../features/converters/lexicalToHtml/async/types.js'\nimport type { UploadDataImproved } from '../../../../features/upload/server/nodes/UploadNode.js'\nimport type { SerializedUploadNode } from '../../../../nodeTypes.js'\n\nconst baseClass = 'lexical-upload-diff'\n\nexport const UploadDiffHTMLConverterAsync: (args: {\n i18n: I18nClient\n req: PayloadRequest\n}) => HTMLConvertersAsync<SerializedUploadNode> = ({ i18n, req }) => {\n return {\n upload: async ({ node, populate, providedCSSString }) => {\n const uploadNode = node as UploadDataImproved\n\n let uploadDoc: (FileData & TypeWithID) | undefined = undefined\n\n // If there's no valid upload data, populate return an empty string\n if (typeof uploadNode.value !== 'object') {\n if (!populate) {\n return ''\n }\n uploadDoc = await populate<FileData & TypeWithID>({\n id: uploadNode.value,\n collectionSlug: uploadNode.relationTo,\n })\n } else {\n uploadDoc = uploadNode.value as unknown as FileData & TypeWithID\n }\n\n if (!uploadDoc) {\n return ''\n }\n\n const relatedCollection = req.payload.collections[uploadNode.relationTo]?.config\n\n const thumbnailSRC: string =\n ('thumbnailURL' in uploadDoc && (uploadDoc?.thumbnailURL as string)) || uploadDoc?.url || ''\n\n const ReactDOMServer = (await import('react-dom/server')).default\n\n // hash fields to ensure they are diffed if they change\n const nodeFieldsHash = createHash('sha256')\n .update(JSON.stringify(node.fields ?? {}))\n .digest('hex')\n\n const JSX = (\n <div\n className={`${baseClass}${providedCSSString}`}\n data-enable-match=\"true\"\n data-fields-hash={`${nodeFieldsHash}`}\n data-filename={uploadDoc?.filename}\n data-lexical-upload-id={uploadNode.value}\n data-lexical-upload-relation-to={uploadNode.relationTo}\n data-src={thumbnailSRC}\n >\n <div className={`${baseClass}__card`}>\n <div className={`${baseClass}__thumbnail`}>\n {thumbnailSRC?.length ? (\n <img alt={uploadDoc?.filename} src={thumbnailSRC} />\n ) : (\n <File />\n )}\n </div>\n <div className={`${baseClass}__info`} data-enable-match=\"false\">\n <strong>{uploadDoc?.filename}</strong>\n <div className={`${baseClass}__meta`}>\n {formatFilesize(uploadDoc?.filesize)}\n {typeof uploadDoc?.width === 'number' && typeof uploadDoc?.height === 'number' && (\n <React.Fragment>\n - \n {uploadDoc?.width}x{uploadDoc?.height}\n </React.Fragment>\n )}\n {uploadDoc?.mimeType && (\n <React.Fragment>\n - \n {uploadDoc?.mimeType}\n </React.Fragment>\n )}\n </div>\n </div>\n </div>\n </div>\n )\n\n // Render to HTML\n const html = ReactDOMServer.renderToStaticMarkup(JSX)\n\n return html\n },\n }\n}\n"],"names":["File","createHash","formatFilesize","React","baseClass","UploadDiffHTMLConverterAsync","i18n","req","upload","node","populate","providedCSSString","uploadNode","uploadDoc","undefined","value","id","collectionSlug","relationTo","relatedCollection","payload","collections","config","thumbnailSRC","thumbnailURL","url","ReactDOMServer","default","nodeFieldsHash","update","JSON","stringify","fields","digest","JSX","div","className","data-enable-match","data-fields-hash","data-filename","filename","data-lexical-upload-id","data-lexical-upload-relation-to","data-src","length","img","alt","src","strong","filesize","width","height","Fragment","mimeType","html","renderToStaticMarkup"],"mappings":";AAGA,SAASA,IAAI,QAAQ,qBAAoB;AACzC,SAASC,UAAU,QAAQ,SAAQ;
|
|
1
|
+
{"version":3,"sources":["../../../../../src/field/Diff/converters/upload/index.tsx"],"sourcesContent":["import type { FileData, PayloadRequest, TypeWithID } from 'payload'\n\nimport { type I18nClient } from '@payloadcms/translations'\nimport { File } from '@payloadcms/ui/rsc'\nimport { createHash } from 'crypto'\n\nimport './index.scss'\n\nimport { formatFilesize } from 'payload/shared'\nimport React from 'react'\n\nimport type { HTMLConvertersAsync } from '../../../../features/converters/lexicalToHtml/async/types.js'\nimport type { UploadDataImproved } from '../../../../features/upload/server/nodes/UploadNode.js'\nimport type { SerializedUploadNode } from '../../../../nodeTypes.js'\n\nconst baseClass = 'lexical-upload-diff'\n\nexport const UploadDiffHTMLConverterAsync: (args: {\n i18n: I18nClient\n req: PayloadRequest\n}) => HTMLConvertersAsync<SerializedUploadNode> = ({ i18n, req }) => {\n return {\n upload: async ({ node, populate, providedCSSString }) => {\n const uploadNode = node as UploadDataImproved\n\n let uploadDoc: (FileData & TypeWithID) | undefined = undefined\n\n // If there's no valid upload data, populate return an empty string\n if (typeof uploadNode.value !== 'object') {\n if (!populate) {\n return ''\n }\n uploadDoc = await populate<FileData & TypeWithID>({\n id: uploadNode.value,\n collectionSlug: uploadNode.relationTo,\n })\n } else {\n uploadDoc = uploadNode.value as unknown as FileData & TypeWithID\n }\n\n if (!uploadDoc) {\n return ''\n }\n\n const relatedCollection = req.payload.collections[uploadNode.relationTo]?.config\n\n const thumbnailSRC: string =\n ('thumbnailURL' in uploadDoc && (uploadDoc?.thumbnailURL as string)) || uploadDoc?.url || ''\n\n const ReactDOMServer = (await import('react-dom/server')).default\n\n // hash fields to ensure they are diffed if they change\n const nodeFieldsHash = createHash('sha256')\n .update(JSON.stringify(node.fields ?? {}))\n .digest('hex')\n\n const JSX = (\n <div\n className={`${baseClass}${providedCSSString}`}\n data-enable-match=\"true\"\n data-fields-hash={`${nodeFieldsHash}`}\n data-filename={uploadDoc?.filename}\n data-lexical-upload-id={uploadNode.value}\n data-lexical-upload-relation-to={uploadNode.relationTo}\n data-src={thumbnailSRC}\n >\n <div className={`${baseClass}__card`}>\n <div className={`${baseClass}__thumbnail`}>\n {thumbnailSRC?.length ? (\n <img alt={uploadDoc?.filename} src={thumbnailSRC} />\n ) : (\n <File />\n )}\n </div>\n <div className={`${baseClass}__info`} data-enable-match=\"false\">\n <strong>{uploadDoc?.filename}</strong>\n <div className={`${baseClass}__meta`}>\n {formatFilesize(uploadDoc?.filesize)}\n {typeof uploadDoc?.width === 'number' && typeof uploadDoc?.height === 'number' && (\n <React.Fragment>\n - \n {uploadDoc?.width}x{uploadDoc?.height}\n </React.Fragment>\n )}\n {uploadDoc?.mimeType && (\n <React.Fragment>\n - \n {uploadDoc?.mimeType}\n </React.Fragment>\n )}\n </div>\n </div>\n </div>\n </div>\n )\n\n // Render to HTML\n const html = ReactDOMServer.renderToStaticMarkup(JSX)\n\n return html\n },\n }\n}\n"],"names":["File","createHash","formatFilesize","React","baseClass","UploadDiffHTMLConverterAsync","i18n","req","upload","node","populate","providedCSSString","uploadNode","uploadDoc","undefined","value","id","collectionSlug","relationTo","relatedCollection","payload","collections","config","thumbnailSRC","thumbnailURL","url","ReactDOMServer","default","nodeFieldsHash","update","JSON","stringify","fields","digest","JSX","div","className","data-enable-match","data-fields-hash","data-filename","filename","data-lexical-upload-id","data-lexical-upload-relation-to","data-src","length","img","alt","src","strong","filesize","width","height","Fragment","mimeType","html","renderToStaticMarkup"],"mappings":";AAGA,SAASA,IAAI,QAAQ,qBAAoB;AACzC,SAASC,UAAU,QAAQ,SAAQ;AAEnC,OAAO,eAAc;AAErB,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,OAAOC,WAAW,QAAO;AAMzB,MAAMC,YAAY;AAElB,OAAO,MAAMC,+BAGqC,CAAC,EAAEC,IAAI,EAAEC,GAAG,EAAE;IAC9D,OAAO;QACLC,QAAQ,OAAO,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,iBAAiB,EAAE;YAClD,MAAMC,aAAaH;YAEnB,IAAII,YAAiDC;YAErD,mEAAmE;YACnE,IAAI,OAAOF,WAAWG,KAAK,KAAK,UAAU;gBACxC,IAAI,CAACL,UAAU;oBACb,OAAO;gBACT;gBACAG,YAAY,MAAMH,SAAgC;oBAChDM,IAAIJ,WAAWG,KAAK;oBACpBE,gBAAgBL,WAAWM,UAAU;gBACvC;YACF,OAAO;gBACLL,YAAYD,WAAWG,KAAK;YAC9B;YAEA,IAAI,CAACF,WAAW;gBACd,OAAO;YACT;YAEA,MAAMM,oBAAoBZ,IAAIa,OAAO,CAACC,WAAW,CAACT,WAAWM,UAAU,CAAC,EAAEI;YAE1E,MAAMC,eACJ,AAAC,kBAAkBV,aAAcA,WAAWW,gBAA4BX,WAAWY,OAAO;YAE5F,MAAMC,iBAAiB,AAAC,CAAA,MAAM,MAAM,CAAC,mBAAkB,EAAGC,OAAO;YAEjE,uDAAuD;YACvD,MAAMC,iBAAiB3B,WAAW,UAC/B4B,MAAM,CAACC,KAAKC,SAAS,CAACtB,KAAKuB,MAAM,IAAI,CAAC,IACtCC,MAAM,CAAC;YAEV,MAAMC,oBACJ,KAACC;gBACCC,WAAW,GAAGhC,YAAYO,mBAAmB;gBAC7C0B,qBAAkB;gBAClBC,oBAAkB,GAAGV,gBAAgB;gBACrCW,iBAAe1B,WAAW2B;gBAC1BC,0BAAwB7B,WAAWG,KAAK;gBACxC2B,mCAAiC9B,WAAWM,UAAU;gBACtDyB,YAAUpB;0BAEV,cAAA,MAACY;oBAAIC,WAAW,GAAGhC,UAAU,MAAM,CAAC;;sCAClC,KAAC+B;4BAAIC,WAAW,GAAGhC,UAAU,WAAW,CAAC;sCACtCmB,cAAcqB,uBACb,KAACC;gCAAIC,KAAKjC,WAAW2B;gCAAUO,KAAKxB;+CAEpC,KAACvB;;sCAGL,MAACmC;4BAAIC,WAAW,GAAGhC,UAAU,MAAM,CAAC;4BAAEiC,qBAAkB;;8CACtD,KAACW;8CAAQnC,WAAW2B;;8CACpB,MAACL;oCAAIC,WAAW,GAAGhC,UAAU,MAAM,CAAC;;wCACjCF,eAAeW,WAAWoC;wCAC1B,OAAOpC,WAAWqC,UAAU,YAAY,OAAOrC,WAAWsC,WAAW,0BACpE,MAAChD,MAAMiD,QAAQ;;gDAAC;gDAEbvC,WAAWqC;gDAAM;gDAAErC,WAAWsC;;;wCAGlCtC,WAAWwC,0BACV,MAAClD,MAAMiD,QAAQ;;gDAAC;gDAEbvC,WAAWwC;;;;;;;;;;YAS1B,iBAAiB;YACjB,MAAMC,OAAO5B,eAAe6B,oBAAoB,CAACrB;YAEjD,OAAOoB;QACT;IACF;AACF,EAAC"}
|