diff --git a/.changeset/chilly-peaches-report.md b/.changeset/chilly-peaches-report.md new file mode 100644 index 0000000000..c7722b8b20 --- /dev/null +++ b/.changeset/chilly-peaches-report.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-ai': patch +--- + +Missing export diff --git a/.changeset/rare-zebras-kneel.md b/.changeset/rare-zebras-kneel.md new file mode 100644 index 0000000000..b32db8b005 --- /dev/null +++ b/.changeset/rare-zebras-kneel.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-dnd': patch +--- + +Add `enableFile` option to check whether to enable the DnD plugin for files dragged in from outside the browser. diff --git a/.changeset/sour-bananas-arrive.md b/.changeset/sour-bananas-arrive.md new file mode 100644 index 0000000000..e7e7f60126 --- /dev/null +++ b/.changeset/sour-bananas-arrive.md @@ -0,0 +1,15 @@ +--- +'@udecode/plate-media': minor +--- +ImagePlugin: +- New `initialHeight` and `initialWidth` in `TImageElement` This will display a loading placeholder while the image is still loading, which helps maintain a consistent height. +- New Api: editor.insert.imageFromFiles + +PlaceholderPlugin: +- Mew `placeholderId` Used to track what was converted from that placeholder plugin. +- New `insertMedia` Used for inserting the placeholder at once. +- New `validateFiles` utils for validate the files meet the `mediaConfig`. + - If validation fails,stop insert placeholder and save the error message in uploadErrorMessage. +- New `option.multiple` `maxFileCount` Used to limit the number of placeholders inserted. +- New `option.disable` `disabledDndPlugin` Used to using the browser drop. +- New `error` use `editor.useOption` to watch and display a toast message. diff --git a/apps/www/public/r/styles/default/ai-demo.json b/apps/www/public/r/styles/default/ai-demo.json index a8d5cbe3f3..cce9c651a0 100644 --- a/apps/www/public/r/styles/default/ai-demo.json +++ b/apps/www/public/r/styles/default/ai-demo.json @@ -9,7 +9,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/align-demo.json b/apps/www/public/r/styles/default/align-demo.json index cdba8763c8..246bad5cc3 100644 --- a/apps/www/public/r/styles/default/align-demo.json +++ b/apps/www/public/r/styles/default/align-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-elements-demo.json b/apps/www/public/r/styles/default/basic-elements-demo.json index a6c3ffd3c1..32762cd457 100644 --- a/apps/www/public/r/styles/default/basic-elements-demo.json +++ b/apps/www/public/r/styles/default/basic-elements-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-marks-demo.json b/apps/www/public/r/styles/default/basic-marks-demo.json index 207926d3f7..711fad838e 100644 --- a/apps/www/public/r/styles/default/basic-marks-demo.json +++ b/apps/www/public/r/styles/default/basic-marks-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-nodes-demo.json b/apps/www/public/r/styles/default/basic-nodes-demo.json index a0f3490f12..e2f9d1406f 100644 --- a/apps/www/public/r/styles/default/basic-nodes-demo.json +++ b/apps/www/public/r/styles/default/basic-nodes-demo.json @@ -8,7 +8,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/block-menu-demo.json b/apps/www/public/r/styles/default/block-menu-demo.json index 067dd84263..e7341ac929 100644 --- a/apps/www/public/r/styles/default/block-menu-demo.json +++ b/apps/www/public/r/styles/default/block-menu-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/block-selection-demo.json b/apps/www/public/r/styles/default/block-selection-demo.json index 334a0a12b0..0b02d31b7d 100644 --- a/apps/www/public/r/styles/default/block-selection-demo.json +++ b/apps/www/public/r/styles/default/block-selection-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/column-demo.json b/apps/www/public/r/styles/default/column-demo.json index b5abebd582..2d7022f2b3 100644 --- a/apps/www/public/r/styles/default/column-demo.json +++ b/apps/www/public/r/styles/default/column-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/comment-demo.json b/apps/www/public/r/styles/default/comment-demo.json index a968ae50d2..9a5f1434af 100644 --- a/apps/www/public/r/styles/default/comment-demo.json +++ b/apps/www/public/r/styles/default/comment-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/copilot-demo.json b/apps/www/public/r/styles/default/copilot-demo.json index 0b8aff0524..3ab59fe52d 100644 --- a/apps/www/public/r/styles/default/copilot-demo.json +++ b/apps/www/public/r/styles/default/copilot-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/date-demo.json b/apps/www/public/r/styles/default/date-demo.json index 6a0a294da7..9f10a29f44 100644 --- a/apps/www/public/r/styles/default/date-demo.json +++ b/apps/www/public/r/styles/default/date-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/dnd-demo.json b/apps/www/public/r/styles/default/dnd-demo.json index 8d0dc9f8cc..5adad760fd 100644 --- a/apps/www/public/r/styles/default/dnd-demo.json +++ b/apps/www/public/r/styles/default/dnd-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/emoji-demo.json b/apps/www/public/r/styles/default/emoji-demo.json index 87699abcef..be8331da22 100644 --- a/apps/www/public/r/styles/default/emoji-demo.json +++ b/apps/www/public/r/styles/default/emoji-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/excalidraw-demo.json b/apps/www/public/r/styles/default/excalidraw-demo.json index c95cc2312f..483dfdf8b4 100644 --- a/apps/www/public/r/styles/default/excalidraw-demo.json +++ b/apps/www/public/r/styles/default/excalidraw-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/floating-toolbar-demo.json b/apps/www/public/r/styles/default/floating-toolbar-demo.json index 803522ec21..6a4e3f647b 100644 --- a/apps/www/public/r/styles/default/floating-toolbar-demo.json +++ b/apps/www/public/r/styles/default/floating-toolbar-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/font-demo.json b/apps/www/public/r/styles/default/font-demo.json index 28700db28d..339d0836f5 100644 --- a/apps/www/public/r/styles/default/font-demo.json +++ b/apps/www/public/r/styles/default/font-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/highlight-demo.json b/apps/www/public/r/styles/default/highlight-demo.json index 4f1152382a..028ad7a93f 100644 --- a/apps/www/public/r/styles/default/highlight-demo.json +++ b/apps/www/public/r/styles/default/highlight-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/hr-demo.json b/apps/www/public/r/styles/default/hr-demo.json index 3e59b3d150..52829371d9 100644 --- a/apps/www/public/r/styles/default/hr-demo.json +++ b/apps/www/public/r/styles/default/hr-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/image-element.json b/apps/www/public/r/styles/default/image-element.json index 7944632052..fff20059b4 100644 --- a/apps/www/public/r/styles/default/image-element.json +++ b/apps/www/public/r/styles/default/image-element.json @@ -20,7 +20,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { withHOC } from '@udecode/plate-common/react';\nimport { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react';\nimport { ResizableProvider, useResizableStore } from '@udecode/plate-resizable';\n\nimport { Caption, CaptionTextarea } from './caption';\nimport { MediaPopover } from './media-popover';\nimport { PlateElement } from './plate-element';\nimport {\n Resizable,\n ResizeHandle,\n mediaResizeHandleVariants,\n} from './resizable';\n\nexport const ImageElement = withHOC(\n ResizableProvider,\n withRef(\n ({ children, className, nodeProps, ...props }, ref) => {\n const { align = 'center', focused, readOnly, selected } = useMediaState();\n\n const width = useResizableStore().get.width();\n\n return (\n \n \n \n \n \n \n \n \n\n \n \n \n \n\n {children}\n \n \n );\n }\n )\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { withHOC } from '@udecode/plate-common/react';\nimport { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react';\nimport { ResizableProvider, useResizableStore } from '@udecode/plate-resizable';\n\nimport { Caption, CaptionTextarea } from './caption';\nimport { MediaPopover } from './media-popover';\nimport { PlateElement } from './plate-element';\nimport {\n Resizable,\n ResizeHandle,\n mediaResizeHandleVariants,\n} from './resizable';\n\nexport const ImageElement = withHOC(\n ResizableProvider,\n withRef(\n ({ children, className, nodeProps, ...props }, ref) => {\n const { align = 'center', focused, readOnly, selected } = useMediaState();\n\n const width = useResizableStore().get.width();\n\n return (\n \n \n \n \n \n \n \n \n\n \n {\n e.preventDefault();\n }}\n placeholder=\"Write a caption...\"\n />\n \n \n\n {children}\n \n \n );\n }\n )\n);\n", "path": "plate-ui/image-element.tsx", "target": "components/plate-ui/image-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/indent-demo.json b/apps/www/public/r/styles/default/indent-demo.json index 1abe6b9969..18196b42a1 100644 --- a/apps/www/public/r/styles/default/indent-demo.json +++ b/apps/www/public/r/styles/default/indent-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/kbd-demo.json b/apps/www/public/r/styles/default/kbd-demo.json index 32d062e655..60156a5318 100644 --- a/apps/www/public/r/styles/default/kbd-demo.json +++ b/apps/www/public/r/styles/default/kbd-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/line-height-demo.json b/apps/www/public/r/styles/default/line-height-demo.json index a5090ab9ec..1f04e4b158 100644 --- a/apps/www/public/r/styles/default/line-height-demo.json +++ b/apps/www/public/r/styles/default/line-height-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/link-demo.json b/apps/www/public/r/styles/default/link-demo.json index a0a7df6d85..95caf0998c 100644 --- a/apps/www/public/r/styles/default/link-demo.json +++ b/apps/www/public/r/styles/default/link-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/list-demo.json b/apps/www/public/r/styles/default/list-demo.json index 0184f1fc15..c3fb8fddf3 100644 --- a/apps/www/public/r/styles/default/list-demo.json +++ b/apps/www/public/r/styles/default/list-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/media-demo.json b/apps/www/public/r/styles/default/media-demo.json index 11a91dbbe7..c0a0dd5d85 100644 --- a/apps/www/public/r/styles/default/media-demo.json +++ b/apps/www/public/r/styles/default/media-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/mention-demo.json b/apps/www/public/r/styles/default/mention-demo.json index 24c4edfa1c..280d360a46 100644 --- a/apps/www/public/r/styles/default/mention-demo.json +++ b/apps/www/public/r/styles/default/mention-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/mode-demo.json b/apps/www/public/r/styles/default/mode-demo.json index 198b38b777..75e9ab694d 100644 --- a/apps/www/public/r/styles/default/mode-demo.json +++ b/apps/www/public/r/styles/default/mode-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/placeholder-demo.json b/apps/www/public/r/styles/default/placeholder-demo.json index 69adb67a15..f51c1454f1 100644 --- a/apps/www/public/r/styles/default/placeholder-demo.json +++ b/apps/www/public/r/styles/default/placeholder-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/playground-demo.json b/apps/www/public/r/styles/default/playground-demo.json index de016eaf22..aa7ce31453 100644 --- a/apps/www/public/r/styles/default/playground-demo.json +++ b/apps/www/public/r/styles/default/playground-demo.json @@ -1,7 +1,7 @@ { "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/resizable-demo.json b/apps/www/public/r/styles/default/resizable-demo.json index c43b06c13b..47692a0963 100644 --- a/apps/www/public/r/styles/default/resizable-demo.json +++ b/apps/www/public/r/styles/default/resizable-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/slash-command-demo.json b/apps/www/public/r/styles/default/slash-command-demo.json index 19f61e7051..18fab7b935 100644 --- a/apps/www/public/r/styles/default/slash-command-demo.json +++ b/apps/www/public/r/styles/default/slash-command-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/table-demo.json b/apps/www/public/r/styles/default/table-demo.json index 4a704643d0..c1eea129fd 100644 --- a/apps/www/public/r/styles/default/table-demo.json +++ b/apps/www/public/r/styles/default/table-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toc-demo.json b/apps/www/public/r/styles/default/toc-demo.json index 2c811f7f29..3284578ea0 100644 --- a/apps/www/public/r/styles/default/toc-demo.json +++ b/apps/www/public/r/styles/default/toc-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toggle-demo.json b/apps/www/public/r/styles/default/toggle-demo.json index 65644be55e..8e804bef8e 100644 --- a/apps/www/public/r/styles/default/toggle-demo.json +++ b/apps/www/public/r/styles/default/toggle-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/toolbar-demo.json b/apps/www/public/r/styles/default/toolbar-demo.json index d956c00d27..a1806716b9 100644 --- a/apps/www/public/r/styles/default/toolbar-demo.json +++ b/apps/www/public/r/styles/default/toolbar-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/upload-demo.json b/apps/www/public/r/styles/default/upload-demo.json index bbf71ebbdb..23344de3ce 100644 --- a/apps/www/public/r/styles/default/upload-demo.json +++ b/apps/www/public/r/styles/default/upload-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({ options: { enableScroller: true } }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", + "content": "'use client';\n\nimport React, { useRef } from 'react';\n\nimport type { ValueId } from '@/config/customizer-plugins';\n\nimport { cn } from '@udecode/cn';\nimport { AIChatPlugin, CopilotPlugin } from '@udecode/plate-ai/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { SingleLinePlugin } from '@udecode/plate-break/react';\nimport { CaptionPlugin } from '@udecode/plate-caption/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n ParagraphPlugin,\n Plate,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { IndentPlugin } from '@udecode/plate-indent/react';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LineHeightPlugin } from '@udecode/plate-line-height/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { BaseImagePlugin } from '@udecode/plate-media';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { MentionPlugin } from '@udecode/plate-mention/react';\nimport { NodeIdPlugin } from '@udecode/plate-node-id';\nimport { NormalizeTypesPlugin } from '@udecode/plate-normalizers';\nimport { PlaywrightPlugin } from '@udecode/plate-playwright';\nimport { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';\nimport {\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\nimport Prism from 'prismjs';\n\nimport { CheckPlugin } from '@/components/context/check-plugin';\nimport { settingsStore } from '@/components/context/settings-store';\nimport { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins';\nimport { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions';\nimport { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins';\nimport { createPlateUI } from '@/plate/create-plate-ui';\nimport { editableProps } from '@/plate/demo/editableProps';\nimport { isEnabled } from '@/plate/demo/is-enabled';\nimport { DragOverCursorPlugin } from '@/plate/demo/plugins/DragOverCursorPlugin';\nimport { exitBreakPlugin } from '@/plate/demo/plugins/exitBreakPlugin';\nimport { resetBlockTypePlugin } from '@/plate/demo/plugins/resetBlockTypePlugin';\nimport { softBreakPlugin } from '@/plate/demo/plugins/softBreakPlugin';\nimport { tabbablePlugin } from '@/plate/demo/plugins/tabbablePlugin';\nimport { commentsData, usersData } from '@/plate/demo/values/commentsValue';\nimport { usePlaygroundValue } from '@/plate/demo/values/usePlaygroundValue';\nimport { BlockContextMenu } from '@/components/plate-ui/block-context-menu';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\nimport {\n CursorOverlay,\n SelectionOverlayPlugin,\n} from '@/components/plate-ui/cursor-overlay';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { FixedToolbarButtons } from '@/components/plate-ui/fixed-toolbar-buttons';\nimport { FloatingToolbar } from '@/components/plate-ui/floating-toolbar';\nimport { FloatingToolbarButtons } from '@/components/plate-ui/floating-toolbar-buttons';\nimport { ImagePreview } from '@/components/plate-ui/image-preview';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLi,\n TodoMarker,\n} from '@/components/plate-ui/indent-todo-marker';\nimport { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';\n\nimport { usePlaygroundEnabled } from './usePlaygroundEnabled';\n\nexport const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {\n const enabledPlugins = settingsStore.use.checkedPlugins();\n const overridePlugins = usePlaygroundEnabled(id);\n const autoformatOptions = getAutoformatOptions(id, enabledPlugins);\n\n const value = usePlaygroundValue(id);\n const key = settingsStore.use.version();\n const editorId = id || 'playground-' + key;\n\n return usePlateEditor(\n {\n id: editorId,\n override: {\n components: createPlateUI({\n draggable: isEnabled('dnd', id),\n placeholder: isEnabled('placeholder', id),\n }),\n plugins: overridePlugins,\n },\n plugins: [\n // AI\n ...(id === 'ai' || enabledPlugins[AIChatPlugin.key] ? aiPlugins : []),\n ...(id === 'copilot' || enabledPlugins[CopilotPlugin.key]\n ? copilotPlugins\n : []),\n // Nodes\n HeadingPlugin,\n TocPlugin.configure({\n options: {\n scrollContainerSelector: `#${scrollSelector}`,\n topOffset: 80,\n },\n }),\n BlockquotePlugin,\n CodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n HorizontalRulePlugin,\n LinkPlugin.extend({\n render: { afterEditable: () => },\n }),\n ...(id === 'list' ? [ListPlugin] : []),\n ImagePlugin.extend({\n options: {\n disableUploadInsert: true,\n },\n render: { afterEditable: ImagePreview },\n }),\n MediaEmbedPlugin,\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin, MediaEmbedPlugin],\n },\n }),\n DatePlugin,\n MentionPlugin.configure({\n options: {\n triggerPreviousCharPattern: /^$|^[\\s\"']$/,\n },\n }),\n SlashPlugin,\n TablePlugin.configure({\n options: {\n enableMerging: id === 'tableMerge',\n },\n }),\n ColumnPlugin,\n SelectionOverlayPlugin,\n\n TodoListPlugin,\n TogglePlugin,\n ExcalidrawPlugin,\n // Marks\n BoldPlugin,\n ItalicPlugin,\n UnderlinePlugin,\n StrikethroughPlugin,\n CodePlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n MediaEmbedPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n ImagePlugin.key,\n HEADING_KEYS.h6,\n ],\n },\n }),\n IndentPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n }),\n IndentListPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n BlockquotePlugin.key,\n CodeBlockPlugin.key,\n TogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLi,\n markerComponent: TodoMarker,\n type: 'todo',\n },\n },\n },\n }),\n LineHeightPlugin.extend({\n inject: {\n nodeProps: {\n defaultNodeValue: 1.5,\n validNodeValues: [1, 1.2, 1.5, 2, 3],\n },\n targetPlugins: [\n ParagraphPlugin.key,\n HEADING_KEYS.h1,\n HEADING_KEYS.h2,\n HEADING_KEYS.h3,\n HEADING_KEYS.h4,\n HEADING_KEYS.h5,\n HEADING_KEYS.h6,\n ],\n },\n }),\n\n // Functionality\n AutoformatPlugin.configure({\n options: autoformatOptions,\n }),\n BlockSelectionPlugin.configure({\n options: {\n areaOptions: {\n behaviour: {\n scrolling: {\n speedDivider: 1.5,\n },\n startThreshold: 10,\n },\n boundaries: `#${scrollSelector}`,\n container: `#${scrollSelector}`,\n selectables: [`#${scrollSelector} .slate-selectable`],\n selectionAreaClass: 'slate-selection-area',\n },\n enableContextMenu: true,\n },\n }),\n BlockMenuPlugin.configure({\n render: { aboveEditable: BlockContextMenu },\n }),\n DndPlugin.configure({\n options: {\n enableScroller: true,\n onDropFiles: ({ dragItem, editor, target }) => {\n editor\n .getTransforms(BaseImagePlugin)\n .insert.imageFromFiles(dragItem.files, {\n at: target,\n nextBlock: false,\n });\n },\n },\n }),\n EmojiPlugin,\n exitBreakPlugin,\n NodeIdPlugin,\n NormalizeTypesPlugin.configure({\n options: {\n rules: [{ path: [0], strictType: HEADING_KEYS.h1 }],\n },\n }),\n resetBlockTypePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n DeletePlugin,\n SingleLinePlugin,\n softBreakPlugin,\n tabbablePlugin,\n TrailingBlockPlugin.configure({\n options: { type: ParagraphPlugin.key },\n }),\n DragOverCursorPlugin,\n\n // Collaboration\n CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: usersData,\n },\n }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // Testing\n PlaywrightPlugin.configure({\n enabled: process.env.NODE_ENV !== 'production',\n }),\n ],\n value: value,\n },\n []\n );\n};\n\nexport default function PlaygroundDemo({\n id,\n className,\n scrollSelector,\n}: {\n id?: ValueId;\n className?: string;\n scrollSelector?: string;\n}) {\n const containerRef = useRef(null);\n const enabled = settingsStore.use.checkedComponents();\n\n const editor = usePlaygroundEditor(\n id,\n scrollSelector ?? `blockSelection-${id}`\n );\n\n return (\n \n \n \n \n \n \n \n \n \n\n \n \n \n\n \n \n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n \n \n );\n}\n\nconst DemoIdContext = React.createContext(undefined);\n\nexport function DemoId({\n id,\n children,\n}: {\n children: React.ReactNode;\n id?: string;\n}) {\n return {children};\n}\n\nexport function useDemoId() {\n return React.useContext(DemoIdContext);\n}\n", "path": "example/playground-demo.tsx", "target": "components/playground-demo.tsx", "type": "registry:example" diff --git a/apps/www/src/lib/plate/demo/plugins/DragOverCursorPlugin.ts b/apps/www/src/lib/plate/demo/plugins/DragOverCursorPlugin.ts index 2c279a2a2d..808a74e897 100644 --- a/apps/www/src/lib/plate/demo/plugins/DragOverCursorPlugin.ts +++ b/apps/www/src/lib/plate/demo/plugins/DragOverCursorPlugin.ts @@ -15,6 +15,8 @@ export const DragOverCursorPlugin = createPlatePlugin({ }, onDragOver: ({ editor, event, plugin }) => { if (editor.getOptions(DndPlugin).isDragging) return; + // Only show cursor for text drag + if (!event.dataTransfer?.types.includes('text/plain')) return; const range = findEventRange(editor, event); diff --git a/apps/www/src/registry/default/example/playground-demo.tsx b/apps/www/src/registry/default/example/playground-demo.tsx index 8bd48ca5e0..6c39f56195 100644 --- a/apps/www/src/registry/default/example/playground-demo.tsx +++ b/apps/www/src/registry/default/example/playground-demo.tsx @@ -50,6 +50,7 @@ import { LineHeightPlugin } from '@udecode/plate-line-height/react'; import { LinkPlugin } from '@udecode/plate-link/react'; import { ListPlugin, TodoListPlugin } from '@udecode/plate-list/react'; import { MarkdownPlugin } from '@udecode/plate-markdown'; +import { BaseImagePlugin } from '@udecode/plate-media'; import { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react'; import { MentionPlugin } from '@udecode/plate-mention/react'; import { NodeIdPlugin } from '@udecode/plate-node-id'; @@ -150,6 +151,9 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { }), ...(id === 'list' ? [ListPlugin] : []), ImagePlugin.extend({ + options: { + disableUploadInsert: true, + }, render: { afterEditable: ImagePreview }, }), MediaEmbedPlugin, @@ -294,7 +298,19 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => { BlockMenuPlugin.configure({ render: { aboveEditable: BlockContextMenu }, }), - DndPlugin.configure({ options: { enableScroller: true } }), + DndPlugin.configure({ + options: { + enableScroller: true, + onDropFiles: ({ dragItem, editor, target }) => { + editor + .getTransforms(BaseImagePlugin) + .insert.imageFromFiles(dragItem.files, { + at: target, + nextBlock: false, + }); + }, + }, + }), EmojiPlugin, exitBreakPlugin, NodeIdPlugin, diff --git a/apps/www/src/registry/default/plate-ui/image-element.tsx b/apps/www/src/registry/default/plate-ui/image-element.tsx index 48129dd57b..d5915ce915 100644 --- a/apps/www/src/registry/default/plate-ui/image-element.tsx +++ b/apps/www/src/registry/default/plate-ui/image-element.tsx @@ -63,6 +63,9 @@ export const ImageElement = withHOC( { + e.preventDefault(); + }} placeholder="Write a caption..." /> diff --git a/packages/ai/src/react/copilot/utils/index.ts b/packages/ai/src/react/copilot/utils/index.ts index 8dac5c2d04..9f452fa3c3 100644 --- a/packages/ai/src/react/copilot/utils/index.ts +++ b/packages/ai/src/react/copilot/utils/index.ts @@ -3,5 +3,6 @@ */ export * from './callCompletionApi'; +export * from './getNextWord'; export * from './triggerCopilotSuggestion'; export * from './withoutAbort'; diff --git a/packages/dnd/src/DndPlugin.tsx b/packages/dnd/src/DndPlugin.tsx index 8b4d98a952..82753138c4 100644 --- a/packages/dnd/src/DndPlugin.tsx +++ b/packages/dnd/src/DndPlugin.tsx @@ -1,8 +1,15 @@ import React from 'react'; import type { PluginConfig } from '@udecode/plate-common'; +import type { DropTargetMonitor } from 'react-dnd'; +import type { Path } from 'slate'; -import { createTPlatePlugin } from '@udecode/plate-common/react'; +import { + type PlateEditor, + createTPlatePlugin, +} from '@udecode/plate-common/react'; + +import type { DragItemNode, FileDragItemNode } from './types'; import { type ScrollerProps, DndScroller } from './components/Scroller'; @@ -13,6 +20,14 @@ export type DndConfig = PluginConfig< enableScroller?: boolean; isDragging?: boolean; scrollerProps?: Partial; + onDropFiles?: (props: { + id: string; + dragItem: FileDragItemNode; + editor: PlateEditor; + monitor: DropTargetMonitor; + nodeRef: any; + target?: Path; + }) => void; } >; diff --git a/packages/dnd/src/hooks/useDndNode.ts b/packages/dnd/src/hooks/useDndNode.ts index d652a70637..5c7f084704 100644 --- a/packages/dnd/src/hooks/useDndNode.ts +++ b/packages/dnd/src/hooks/useDndNode.ts @@ -1,4 +1,4 @@ -import { getEmptyImage } from 'react-dnd-html5-backend'; +import { NativeTypes, getEmptyImage } from 'react-dnd-html5-backend'; import type { DropTargetMonitor } from 'react-dnd'; @@ -48,7 +48,6 @@ export const useDndNode = ({ onDropHandler, }: UseDndNodeOptions) => { const editor = useEditorRef(); - const [dropLine, setDropLine] = useDraggableStore().use.dropLine(); const [{ isDragging }, dragRef, preview] = useDragNode(editor, { @@ -58,7 +57,7 @@ export const useDndNode = ({ }); const [{ isOver }, drop] = useDropNode(editor, { id, - accept: type, + accept: [type, NativeTypes.FILE], dropLine, nodeRef, onChangeDropLine: setDropLine, diff --git a/packages/dnd/src/hooks/useDropNode.ts b/packages/dnd/src/hooks/useDropNode.ts index f5eda81157..5f88c1ab7f 100644 --- a/packages/dnd/src/hooks/useDropNode.ts +++ b/packages/dnd/src/hooks/useDropNode.ts @@ -6,9 +6,15 @@ import { import type { PlateEditor } from '@udecode/plate-common/react'; -import type { DragItemNode, DropLineDirection } from '../types'; +import type { + DragItemNode, + DropLineDirection, + ElementDragItemNode, + FileDragItemNode, +} from '../types'; -import { onDropNode } from '../transforms/onDropNode'; +import { DndPlugin } from '../DndPlugin'; +import { getDropPath, onDropNode } from '../transforms/onDropNode'; import { onHoverNode } from '../transforms/onHoverNode'; export interface UseDropNodeOptions @@ -77,6 +83,30 @@ export const useDropNode = ( isOver: monitor.isOver(), }), drop: (dragItem, monitor) => { + // Don't call onDropNode if this is a file drop + + if (!(dragItem as ElementDragItemNode).id) { + const result = getDropPath(editor, { + id, + dragItem: dragItem as any, + monitor, + nodeRef, + }); + + const onDropFiles = editor.getOptions(DndPlugin).onDropFiles; + + if (!result || !onDropFiles) return; + + return onDropFiles({ + id, + dragItem: dragItem as FileDragItemNode, + editor, + monitor, + nodeRef, + target: result.to, + }); + } + const handled = !!onDropHandler && onDropHandler(editor, { @@ -88,7 +118,12 @@ export const useDropNode = ( if (handled) return; - onDropNode(editor, { id, dragItem, monitor, nodeRef }); + onDropNode(editor, { + id, + dragItem: dragItem as ElementDragItemNode, + monitor, + nodeRef, + }); }, hover(item: DragItemNode, monitor: DropTargetMonitor) { onHoverNode(editor, { diff --git a/packages/dnd/src/transforms/onDropNode.ts b/packages/dnd/src/transforms/onDropNode.ts index f36bf10e12..213bc4e686 100644 --- a/packages/dnd/src/transforms/onDropNode.ts +++ b/packages/dnd/src/transforms/onDropNode.ts @@ -5,12 +5,12 @@ import { focusEditor } from '@udecode/plate-common/react'; import { Path } from 'slate'; import type { UseDropNodeOptions } from '../hooks'; -import type { DragItemNode } from '../types'; +import type { ElementDragItemNode } from '../types'; import { getHoverDirection } from '../utils'; /** Callback called on drag an drop a node with id. */ -export const onDropNode = ( +export const getDropPath = ( editor: TEditor, { id, @@ -18,7 +18,7 @@ export const onDropNode = ( monitor, nodeRef, }: { - dragItem: DragItemNode; + dragItem: ElementDragItemNode; monitor: DropTargetMonitor; } & Pick ) => { @@ -61,9 +61,35 @@ export const onDropNode = ( Path.isBefore(dragPath, _dropPath) && Path.isSibling(dragPath, _dropPath); const to = before ? _dropPath : Path.next(_dropPath); - moveNodes(editor, { - at: dragPath, - to, - }); + return { dragPath, to }; } }; + +export const onDropNode = ( + editor: TEditor, + { + id, + dragItem, + monitor, + nodeRef, + }: { + dragItem: ElementDragItemNode; + monitor: DropTargetMonitor; + } & Pick +) => { + const result = getDropPath(editor, { + id, + dragItem, + monitor, + nodeRef, + }); + + if (!result) return; + + const { dragPath, to } = result; + + moveNodes(editor, { + at: dragPath, + to, + }); +}; diff --git a/packages/dnd/src/types.ts b/packages/dnd/src/types.ts index 21629a6bf8..f628e82f25 100644 --- a/packages/dnd/src/types.ts +++ b/packages/dnd/src/types.ts @@ -1,9 +1,17 @@ -export interface DragItemNode { +export type DragItemNode = ElementDragItemNode | FileDragItemNode; + +export interface ElementDragItemNode { /** Required to identify the node. */ id: string; [key: string]: unknown; } +export interface FileDragItemNode { + dataTransfer: DataTransfer[]; + files: FileList; + items: DataTransferItemList; +} + export type DropLineDirection = '' | 'bottom' | 'top'; export type DropDirection = 'bottom' | 'top' | undefined; diff --git a/packages/dnd/src/utils/getHoverDirection.ts b/packages/dnd/src/utils/getHoverDirection.ts index 0d0ea0db75..67ed5d8346 100644 --- a/packages/dnd/src/utils/getHoverDirection.ts +++ b/packages/dnd/src/utils/getHoverDirection.ts @@ -1,6 +1,10 @@ import type { DropTargetMonitor, XYCoord } from 'react-dnd'; -import type { DragItemNode, DropDirection } from '../types'; +import type { + DragItemNode, + DropDirection, + ElementDragItemNode, +} from '../types'; export interface GetHoverDirectionOptions { /** Hovering node id. */ @@ -26,7 +30,7 @@ export const getHoverDirection = ({ }: GetHoverDirectionOptions): DropDirection => { if (!nodeRef.current) return; - const dragId = dragItem.id; + const dragId = (dragItem as ElementDragItemNode).id; // Don't replace items with themselves if (dragId === id) return; diff --git a/packages/media/src/lib/image/BaseImagePlugin.ts b/packages/media/src/lib/image/BaseImagePlugin.ts index b461f12bae..1ab7d8a19a 100644 --- a/packages/media/src/lib/image/BaseImagePlugin.ts +++ b/packages/media/src/lib/image/BaseImagePlugin.ts @@ -1,10 +1,18 @@ -import { type PluginConfig, createTSlatePlugin } from '@udecode/plate-common'; +import { + type PluginConfig, + bindFirst, + createTSlatePlugin, +} from '@udecode/plate-common'; import type { MediaPluginOptions, TMediaElement } from '../media'; +import { insertImageFromFiles } from './transforms/insertImageFromFiles'; import { withImage } from './withImage'; -export interface TImageElement extends TMediaElement {} +export interface TImageElement extends TMediaElement { + initialHeight?: number; + initialWidth?: number; +} export type ImageConfig = PluginConfig< 'img', @@ -35,20 +43,26 @@ export const BaseImagePlugin = createTSlatePlugin({ isElement: true, isVoid: true, }, -}).extend(({ plugin }) => ({ - parsers: { - html: { - deserializer: { - parse: ({ element }) => ({ - type: plugin.node.type, - url: element.getAttribute('src'), - }), - rules: [ - { - validNodeName: 'IMG', - }, - ], +}) + .extendEditorTransforms(({ editor }) => ({ + insert: { + imageFromFiles: bindFirst(insertImageFromFiles, editor), + }, + })) + .extend(({ plugin }) => ({ + parsers: { + html: { + deserializer: { + parse: ({ element }) => ({ + type: plugin.node.type, + url: element.getAttribute('src'), + }), + rules: [ + { + validNodeName: 'IMG', + }, + ], + }, }, }, - }, -})); + })); diff --git a/packages/media/src/lib/image/transforms/index.ts b/packages/media/src/lib/image/transforms/index.ts index c334d0ebc8..c50b0acd9d 100644 --- a/packages/media/src/lib/image/transforms/index.ts +++ b/packages/media/src/lib/image/transforms/index.ts @@ -3,3 +3,4 @@ */ export * from './insertImage'; +export * from './insertImageFromFiles'; diff --git a/packages/media/src/lib/image/transforms/insertImageFromFiles.ts b/packages/media/src/lib/image/transforms/insertImageFromFiles.ts new file mode 100644 index 0000000000..45c2160b86 --- /dev/null +++ b/packages/media/src/lib/image/transforms/insertImageFromFiles.ts @@ -0,0 +1,33 @@ +import type { InsertNodesOptions, SlateEditor } from '@udecode/plate-common'; + +import { BaseImagePlugin } from '../BaseImagePlugin'; +import { insertImage } from './insertImage'; + +export const insertImageFromFiles = ( + editor: SlateEditor, + files: FileList, + options: InsertNodesOptions = {} +) => { + for (const file of files) { + const reader = new FileReader(); + const [mime] = file.type.split('/'); + + if (mime === 'image') { + reader.addEventListener('load', async () => { + if (!reader.result) { + return; + } + + const uploadImage = editor.getOptions(BaseImagePlugin).uploadImage; + + const uploadedUrl = uploadImage + ? await uploadImage(reader.result) + : reader.result; + + insertImage(editor, uploadedUrl, options); + }); + + reader.readAsDataURL(file); + } + } +}; diff --git a/packages/media/src/lib/image/withImageEmbed.spec.tsx b/packages/media/src/lib/image/withImageEmbed.spec.tsx index 94edff4ceb..31316e543a 100644 --- a/packages/media/src/lib/image/withImageEmbed.spec.tsx +++ b/packages/media/src/lib/image/withImageEmbed.spec.tsx @@ -27,7 +27,10 @@ describe('withImageEmbed', () => { it('should insert image from the text', () => { const editor = withImageEmbed( - getEditorPlugin(createSlateEditor({ editor: input }), BaseImagePlugin) + getEditorPlugin( + createSlateEditor({ editor: input }), + BaseImagePlugin as any + ) ); const data = { diff --git a/packages/media/src/lib/image/withImageUpload.ts b/packages/media/src/lib/image/withImageUpload.ts index 15f12b0e79..58d6c38d62 100644 --- a/packages/media/src/lib/image/withImageUpload.ts +++ b/packages/media/src/lib/image/withImageUpload.ts @@ -6,7 +6,7 @@ import { import type { ImageConfig } from './BaseImagePlugin'; -import { insertImage } from './transforms/insertImage'; +import { insertImageFromFiles } from './transforms'; /** * Allows for pasting images from clipboard. Not yet: dragging and dropping @@ -39,30 +39,9 @@ export const withImageUpload: ExtendEditor = ({ return insertData(dataTransfer); } - for (const file of files) { - const reader = new FileReader(); - const [mime] = file.type.split('/'); - - if (mime === 'image') { - reader.addEventListener('load', async () => { - if (!reader.result) { - return; - } - - const uploadImage = getOptions().uploadImage; - - const uploadedUrl = uploadImage - ? await uploadImage(reader.result) - : reader.result; - - insertImage(editor, uploadedUrl); - }); - - reader.readAsDataURL(file); - } - } + insertImageFromFiles(editor, files); } else { - insertData(dataTransfer); + return insertData(dataTransfer); } }; diff --git a/packages/media/src/lib/media/index.ts b/packages/media/src/lib/media/index.ts index 88c017703d..7f9a061e57 100644 --- a/packages/media/src/lib/media/index.ts +++ b/packages/media/src/lib/media/index.ts @@ -5,4 +5,3 @@ export * from './insertMedia'; export * from './parseMediaUrl'; export type * from './types'; - diff --git a/packages/media/src/lib/media/types.ts b/packages/media/src/lib/media/types.ts index 53fc5b6956..6f8dc576b6 100644 --- a/packages/media/src/lib/media/types.ts +++ b/packages/media/src/lib/media/types.ts @@ -6,6 +6,7 @@ export interface TMediaElement extends TElement { align?: 'center' | 'left' | 'right'; isUpload?: boolean; name?: string; + placeholderId?: string; } export interface MediaPluginOptions { diff --git a/packages/media/src/lib/placeholder/transforms/setMediaNode.ts b/packages/media/src/lib/placeholder/transforms/setMediaNode.ts index d5153681b8..6a8a43a3dc 100644 --- a/packages/media/src/lib/placeholder/transforms/setMediaNode.ts +++ b/packages/media/src/lib/placeholder/transforms/setMediaNode.ts @@ -7,8 +7,11 @@ import { type props = { type: string; url: string; + initialHeight?: number; + initialWidth?: number; isUpload?: boolean; name?: string; + placeholderId?: string; width?: number; }; diff --git a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx index 024c87e7f0..ea58a9a15a 100644 --- a/packages/media/src/react/placeholder/PlaceholderPlugin.tsx +++ b/packages/media/src/react/placeholder/PlaceholderPlugin.tsx @@ -1,5 +1,150 @@ -import { toPlatePlugin } from '@udecode/plate-common/react'; +import { type ExtendConfig, bindFirst } from '@udecode/plate-common'; +import { findEventRange, toTPlatePlugin } from '@udecode/plate-common/react'; -import { BasePlaceholderPlugin } from '../../lib/placeholder/BasePlaceholderPlugin'; +import type { AllowedFileType } from './internal/mimes'; +import type { MediaItemConfig, UploadError } from './type'; -export const PlaceholderPlugin = toPlatePlugin(BasePlaceholderPlugin); +import { type PlaceholderConfig, BasePlaceholderPlugin } from '../../lib'; +import { AudioPlugin, FilePlugin, ImagePlugin, VideoPlugin } from '../plugins'; +import { insertMedia } from './transforms/insertMedia'; + +export type PlaceholderApi = { + addUploadingFile: (id: string, file: File) => void; + getUploadingFile: (id: string) => File | undefined; + removeUploadingFile: (id: string) => void; +}; + +export type PlaceholderTransforms = { + insertMedia: (files: FileList) => void; +}; + +export type UploadConfig = Partial>; + +export const PlaceholderPlugin = toTPlatePlugin< + ExtendConfig< + PlaceholderConfig, + { + disabledDndPlugin: boolean; + uploadConfig: UploadConfig; + uploadingFiles: Record; + error?: UploadError | null; + maxFileCount?: number; + // Whether multiple files of the same type can be uploaded. + multiple?: boolean; + }, + { placeholder: PlaceholderApi } + > +>(BasePlaceholderPlugin, { + options: { + disabledDndPlugin: false, + error: null, + maxFileCount: 5, + multiple: true, + uploadConfig: { + audio: { + maxFileCount: 1, + maxFileSize: '8MB', + mediaType: AudioPlugin.key, + minFileCount: 1, + }, + blob: { + maxFileCount: 1, + maxFileSize: '8MB', + mediaType: FilePlugin.key, + minFileCount: 1, + }, + image: { + maxFileCount: 3, + maxFileSize: '4MB', + mediaType: ImagePlugin.key, + minFileCount: 1, + }, + pdf: { + maxFileCount: 1, + maxFileSize: '4MB', + mediaType: FilePlugin.key, + minFileCount: 1, + }, + text: { + maxFileCount: 1, + maxFileSize: '64KB', + mediaType: FilePlugin.key, + minFileCount: 1, + }, + video: { + maxFileCount: 1, + maxFileSize: '16MB', + mediaType: VideoPlugin.key, + minFileCount: 1, + }, + }, + uploadingFiles: {}, + }, +}) + .extendEditorTransforms(({ editor }) => ({ + insert: { + media: bindFirst(insertMedia, editor), + }, + })) + .extendApi(({ getOption, setOption }) => ({ + addUploadingFile: (id: string, file: File) => { + const uploadingFiles = getOption('uploadingFiles'); + + setOption('uploadingFiles', { + ...uploadingFiles, + [id]: file, + }); + }, + getUploadingFile: (id: string) => { + const uploadingFiles = getOption('uploadingFiles'); + + return uploadingFiles[id]; + }, + removeUploadingFile: (id: string) => { + const uploadingFiles = getOption('uploadingFiles'); + + delete uploadingFiles[id]; + + setOption('uploadingFiles', uploadingFiles); + }, + })) + .extend(({ getOption }) => ({ + handlers: { + onDrop: ({ editor, event, tf }) => { + // using DnD plugin by default + if (!getOption('disabledDndPlugin')) return; + + const { files } = event.dataTransfer; + + if (files.length === 0) return false; + + /** Without this, the dropped file replaces the page */ + event.preventDefault(); + event.stopPropagation(); + /** + * When we drop a file, the selection won't move automatically to the + * drop location. Find the location from the event and upload the files + * at that location. + */ + const at = findEventRange(editor, event); + + if (!at) return false; + + tf.insert.media(files); + + return true; + }, + onPaste: ({ event, tf }) => { + const { files } = event.clipboardData; + + if (files.length === 0) return false; + + event.preventDefault(); + event.stopPropagation(); + + tf.insert.media(files); + + return true; + }, + }, + })); diff --git a/packages/media/src/react/placeholder/hooks/index.ts b/packages/media/src/react/placeholder/hooks/index.ts new file mode 100644 index 0000000000..cfb6baabf5 --- /dev/null +++ b/packages/media/src/react/placeholder/hooks/index.ts @@ -0,0 +1,6 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './usePlaceholderElement'; +export * from './usePlaceholderPopover'; diff --git a/packages/media/src/react/placeholder/usePlaceholderElement.ts b/packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts similarity index 81% rename from packages/media/src/react/placeholder/usePlaceholderElement.ts rename to packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts index 587f609b2a..659769a74d 100644 --- a/packages/media/src/react/placeholder/usePlaceholderElement.ts +++ b/packages/media/src/react/placeholder/hooks/usePlaceholderElement.ts @@ -1,11 +1,8 @@ import { useEditorRef, useElement } from '@udecode/plate-common/react'; import { useFocused, useReadOnly, useSelected } from 'slate-react'; -import { - type TPlaceholderElement, - BasePlaceholderPlugin, -} from '../../lib/placeholder/BasePlaceholderPlugin'; -import { usePlaceholderStore } from './placeholderStore'; +import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; +import { usePlaceholderStore } from '../placeholderStore'; export const usePlaceholderElementState = () => { const element = useElement(); @@ -17,6 +14,7 @@ export const usePlaceholderElementState = () => { const progresses = usePlaceholderStore().get.progresses(); const isUploading = usePlaceholderStore().get.isUploading(); const updatedFiles = usePlaceholderStore().get.updatedFiles(); + const setSize = usePlaceholderStore().set.size(); const { mediaType } = useElement( BasePlaceholderPlugin.key @@ -34,6 +32,7 @@ export const usePlaceholderElementState = () => { progressing, readOnly, selected, + setSize, updatedFiles, }; }; diff --git a/packages/media/src/react/placeholder/usePlaceholderPopover.ts b/packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts similarity index 81% rename from packages/media/src/react/placeholder/usePlaceholderPopover.ts rename to packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts index 28da92fcfb..3721fd772b 100644 --- a/packages/media/src/react/placeholder/usePlaceholderPopover.ts +++ b/packages/media/src/react/placeholder/hooks/usePlaceholderPopover.ts @@ -6,11 +6,8 @@ import { } from '@udecode/plate-common/react'; import { useFocused, useReadOnly, useSelected } from 'slate-react'; -import { - type TPlaceholderElement, - BasePlaceholderPlugin, -} from '../../lib/placeholder/BasePlaceholderPlugin'; -import { usePlaceholderStore } from './placeholderStore'; +import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; +import { usePlaceholderStore } from '../placeholderStore'; export const usePlaceholderPopoverState = () => { const editor = useEditorRef(); @@ -19,7 +16,6 @@ export const usePlaceholderPopoverState = () => { const focused = useFocused(); const selectionCollapsed = useEditorSelector( - // eslint-disable-next-line @typescript-eslint/no-shadow (editor) => !isSelectionExpanded(editor), [] ); @@ -31,6 +27,8 @@ export const usePlaceholderPopoverState = () => { const setIsUploading = usePlaceholderStore().set.isUploading(); const setUpdatedFiles = usePlaceholderStore().set.updatedFiles(); + const size = usePlaceholderStore().get.size(); + return { id, editor, @@ -43,5 +41,6 @@ export const usePlaceholderPopoverState = () => { setIsUploading, setProgresses, setUpdatedFiles, + size, }; }; diff --git a/packages/media/src/react/placeholder/index.ts b/packages/media/src/react/placeholder/index.ts index 2a9025d94b..f960f0d3ab 100644 --- a/packages/media/src/react/placeholder/index.ts +++ b/packages/media/src/react/placeholder/index.ts @@ -4,5 +4,7 @@ export * from './PlaceholderPlugin'; export * from './placeholderStore'; -export * from './usePlaceholderElement'; -export * from './usePlaceholderPopover'; +export * from './type'; +export * from './hooks/index'; +export * from './transforms/index'; +export * from './utils/index'; diff --git a/packages/media/src/react/placeholder/internal/application.ts b/packages/media/src/react/placeholder/internal/application.ts new file mode 100644 index 0000000000..b10a7469c6 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/application.ts @@ -0,0 +1,2654 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ +export const application = { + 'application/andrew-inset': { + extensions: ['ez'], + source: 'iana', + }, + 'application/applixware': { + extensions: ['aw'], + source: 'apache', + }, + 'application/atom+xml': { + extensions: ['atom'], + source: 'iana', + }, + 'application/atomcat+xml': { + extensions: ['atomcat'], + source: 'iana', + }, + 'application/atomdeleted+xml': { + extensions: ['atomdeleted'], + source: 'iana', + }, + 'application/atomsvc+xml': { + extensions: ['atomsvc'], + source: 'iana', + }, + 'application/atsc-dwd+xml': { + extensions: ['dwd'], + source: 'iana', + }, + 'application/atsc-held+xml': { + extensions: ['held'], + source: 'iana', + }, + 'application/atsc-rsat+xml': { + extensions: ['rsat'], + source: 'iana', + }, + 'application/calendar+xml': { + extensions: ['xcs'], + source: 'iana', + }, + 'application/ccxml+xml': { + extensions: ['ccxml'], + source: 'iana', + }, + 'application/cdfx+xml': { + extensions: ['cdfx'], + source: 'iana', + }, + 'application/cdmi-capability': { + extensions: ['cdmia'], + source: 'iana', + }, + 'application/cdmi-container': { + extensions: ['cdmic'], + source: 'iana', + }, + 'application/cdmi-domain': { + extensions: ['cdmid'], + source: 'iana', + }, + 'application/cdmi-object': { + extensions: ['cdmio'], + source: 'iana', + }, + 'application/cdmi-queue': { + extensions: ['cdmiq'], + source: 'iana', + }, + 'application/cpl+xml': { + extensions: ['cpl'], + source: 'iana', + }, + 'application/cu-seeme': { + extensions: ['cu'], + source: 'apache', + }, + 'application/dash+xml': { + extensions: ['mpd'], + source: 'iana', + }, + 'application/dash-patch+xml': { + extensions: ['mpp'], + source: 'iana', + }, + 'application/davmount+xml': { + extensions: ['davmount'], + source: 'iana', + }, + 'application/dicom': { + extensions: ['dcm'], + source: 'iana', + }, + 'application/docbook+xml': { + extensions: ['dbk'], + source: 'apache', + }, + 'application/dssc+der': { + extensions: ['dssc'], + source: 'iana', + }, + 'application/dssc+xml': { + extensions: ['xdssc'], + source: 'iana', + }, + 'application/ecmascript': { + extensions: ['es', 'ecma'], + source: 'iana', + }, + 'application/emma+xml': { + extensions: ['emma'], + source: 'iana', + }, + 'application/emotionml+xml': { + extensions: ['emotionml'], + source: 'iana', + }, + 'application/epub+zip': { + extensions: ['epub'], + source: 'iana', + }, + 'application/exi': { + extensions: ['exi'], + source: 'iana', + }, + 'application/express': { + extensions: ['exp'], + source: 'iana', + }, + 'application/fdt+xml': { + extensions: ['fdt'], + source: 'iana', + }, + 'application/font-tdpfr': { + extensions: ['pfr'], + source: 'iana', + }, + 'application/geo+json': { + extensions: ['geojson'], + source: 'iana', + }, + 'application/gml+xml': { + extensions: ['gml'], + source: 'iana', + }, + 'application/gpx+xml': { + extensions: ['gpx'], + source: 'apache', + }, + 'application/gxf': { + extensions: ['gxf'], + source: 'apache', + }, + 'application/gzip': { + extensions: ['gz'], + source: 'iana', + }, + 'application/hyperstudio': { + extensions: ['stk'], + source: 'iana', + }, + 'application/inkml+xml': { + extensions: ['ink', 'inkml'], + source: 'iana', + }, + 'application/ipfix': { + extensions: ['ipfix'], + source: 'iana', + }, + 'application/its+xml': { + extensions: ['its'], + source: 'iana', + }, + 'application/java-archive': { + extensions: ['jar', 'war', 'ear'], + source: 'apache', + }, + 'application/java-serialized-object': { + extensions: ['ser'], + source: 'apache', + }, + 'application/java-vm': { + extensions: ['class'], + source: 'apache', + }, + 'application/javascript': { + charset: 'UTF-8', + extensions: ['js', 'mjs'], + source: 'iana', + }, + 'application/json': { + charset: 'UTF-8', + extensions: ['json', 'map'], + source: 'iana', + }, + 'application/jsonml+json': { + extensions: ['jsonml'], + source: 'apache', + }, + 'application/ld+json': { + extensions: ['jsonld'], + source: 'iana', + }, + 'application/lgr+xml': { + extensions: ['lgr'], + source: 'iana', + }, + 'application/lost+xml': { + extensions: ['lostxml'], + source: 'iana', + }, + 'application/mac-binhex40': { + extensions: ['hqx'], + source: 'iana', + }, + 'application/mac-compactpro': { + extensions: ['cpt'], + source: 'apache', + }, + 'application/mads+xml': { + extensions: ['mads'], + source: 'iana', + }, + 'application/manifest+json': { + charset: 'UTF-8', + extensions: ['webmanifest'], + source: 'iana', + }, + 'application/marc': { + extensions: ['mrc'], + source: 'iana', + }, + 'application/marcxml+xml': { + extensions: ['mrcx'], + source: 'iana', + }, + 'application/mathematica': { + extensions: ['ma', 'nb', 'mb'], + source: 'iana', + }, + 'application/mathml+xml': { + extensions: ['mathml'], + source: 'iana', + }, + 'application/mbox': { + extensions: ['mbox'], + source: 'iana', + }, + 'application/media-policy-dataset+xml': { + extensions: ['mpf'], + source: 'iana', + }, + 'application/mediaservercontrol+xml': { + extensions: ['mscml'], + source: 'iana', + }, + 'application/metalink+xml': { + extensions: ['metalink'], + source: 'apache', + }, + 'application/metalink4+xml': { + extensions: ['meta4'], + source: 'iana', + }, + 'application/mets+xml': { + extensions: ['mets'], + source: 'iana', + }, + 'application/mmt-aei+xml': { + extensions: ['maei'], + source: 'iana', + }, + 'application/mmt-usd+xml': { + extensions: ['musd'], + source: 'iana', + }, + 'application/mods+xml': { + extensions: ['mods'], + source: 'iana', + }, + 'application/mp4': { + extensions: ['mp4s', 'm4p'], + source: 'iana', + }, + 'application/mp21': { + extensions: ['m21', 'mp21'], + source: 'iana', + }, + 'application/msword': { + extensions: ['doc', 'dot'], + source: 'iana', + }, + 'application/mxf': { + extensions: ['mxf'], + source: 'iana', + }, + 'application/n-quads': { + extensions: ['nq'], + source: 'iana', + }, + 'application/n-triples': { + extensions: ['nt'], + source: 'iana', + }, + 'application/node': { + extensions: ['cjs'], + source: 'iana', + }, + 'application/octet-stream': { + extensions: [ + 'bin', + 'dms', + 'lrf', + 'mar', + 'so', + 'dist', + 'distz', + 'pkg', + 'bpk', + 'dump', + 'elc', + 'deploy', + 'exe', + 'dll', + 'deb', + 'dmg', + 'iso', + 'img', + 'msi', + 'msp', + 'msm', + 'buffer', + ], + source: 'iana', + }, + 'application/oda': { + extensions: ['oda'], + source: 'iana', + }, + 'application/oebps-package+xml': { + extensions: ['opf'], + source: 'iana', + }, + 'application/ogg': { + extensions: ['ogx'], + source: 'iana', + }, + 'application/omdoc+xml': { + extensions: ['omdoc'], + source: 'apache', + }, + 'application/onenote': { + extensions: ['onetoc', 'onetoc2', 'onetmp', 'onepkg'], + source: 'apache', + }, + 'application/oxps': { + extensions: ['oxps'], + source: 'iana', + }, + 'application/p2p-overlay+xml': { + extensions: ['relo'], + source: 'iana', + }, + 'application/patch-ops-error+xml': { + extensions: ['xer'], + source: 'iana', + }, + 'application/pdf': { + extensions: ['pdf'], + source: 'iana', + }, + 'application/pgp-encrypted': { + extensions: ['pgp'], + source: 'iana', + }, + 'application/pgp-keys': { + extensions: ['asc'], + source: 'iana', + }, + 'application/pgp-signature': { + extensions: ['asc', 'sig'], + source: 'iana', + }, + 'application/pics-rules': { + extensions: ['prf'], + source: 'apache', + }, + 'application/pkcs7-mime': { + extensions: ['p7m', 'p7c'], + source: 'iana', + }, + 'application/pkcs7-signature': { + extensions: ['p7s'], + source: 'iana', + }, + 'application/pkcs8': { + extensions: ['p8'], + source: 'iana', + }, + 'application/pkcs10': { + extensions: ['p10'], + source: 'iana', + }, + 'application/pkix-attr-cert': { + extensions: ['ac'], + source: 'iana', + }, + 'application/pkix-cert': { + extensions: ['cer'], + source: 'iana', + }, + 'application/pkix-crl': { + extensions: ['crl'], + source: 'iana', + }, + 'application/pkix-pkipath': { + extensions: ['pkipath'], + source: 'iana', + }, + 'application/pkixcmp': { + extensions: ['pki'], + source: 'iana', + }, + 'application/pls+xml': { + extensions: ['pls'], + source: 'iana', + }, + 'application/postscript': { + extensions: ['ai', 'eps', 'ps'], + source: 'iana', + }, + 'application/provenance+xml': { + extensions: ['provx'], + source: 'iana', + }, + 'application/prs.cww': { + extensions: ['cww'], + source: 'iana', + }, + 'application/pskc+xml': { + extensions: ['pskcxml'], + source: 'iana', + }, + 'application/rdf+xml': { + extensions: ['rdf', 'owl'], + source: 'iana', + }, + 'application/reginfo+xml': { + extensions: ['rif'], + source: 'iana', + }, + 'application/relax-ng-compact-syntax': { + extensions: ['rnc'], + source: 'iana', + }, + 'application/resource-lists+xml': { + extensions: ['rl'], + source: 'iana', + }, + 'application/resource-lists-diff+xml': { + extensions: ['rld'], + source: 'iana', + }, + 'application/rls-services+xml': { + extensions: ['rs'], + source: 'iana', + }, + 'application/route-apd+xml': { + extensions: ['rapd'], + source: 'iana', + }, + 'application/route-s-tsid+xml': { + extensions: ['sls'], + source: 'iana', + }, + 'application/route-usd+xml': { + extensions: ['rusd'], + source: 'iana', + }, + 'application/rpki-ghostbusters': { + extensions: ['gbr'], + source: 'iana', + }, + 'application/rpki-manifest': { + extensions: ['mft'], + source: 'iana', + }, + 'application/rpki-roa': { + extensions: ['roa'], + source: 'iana', + }, + 'application/rsd+xml': { + extensions: ['rsd'], + source: 'apache', + }, + 'application/rss+xml': { + extensions: ['rss'], + source: 'apache', + }, + 'application/rtf': { + extensions: ['rtf'], + source: 'iana', + }, + 'application/sbml+xml': { + extensions: ['sbml'], + source: 'iana', + }, + 'application/scvp-cv-request': { + extensions: ['scq'], + source: 'iana', + }, + 'application/scvp-cv-response': { + extensions: ['scs'], + source: 'iana', + }, + 'application/scvp-vp-request': { + extensions: ['spq'], + source: 'iana', + }, + 'application/scvp-vp-response': { + extensions: ['spp'], + source: 'iana', + }, + 'application/sdp': { + extensions: ['sdp'], + source: 'iana', + }, + 'application/senml+xml': { + extensions: ['senmlx'], + source: 'iana', + }, + 'application/sensml+xml': { + extensions: ['sensmlx'], + source: 'iana', + }, + 'application/set-payment-initiation': { + extensions: ['setpay'], + source: 'iana', + }, + 'application/set-registration-initiation': { + extensions: ['setreg'], + source: 'iana', + }, + 'application/shf+xml': { + extensions: ['shf'], + source: 'iana', + }, + 'application/sieve': { + extensions: ['siv', 'sieve'], + source: 'iana', + }, + 'application/smil+xml': { + extensions: ['smi', 'smil'], + source: 'iana', + }, + 'application/sparql-query': { + extensions: ['rq'], + source: 'iana', + }, + 'application/sparql-results+xml': { + extensions: ['srx'], + source: 'iana', + }, + 'application/srgs': { + extensions: ['gram'], + source: 'iana', + }, + 'application/srgs+xml': { + extensions: ['grxml'], + source: 'iana', + }, + 'application/sru+xml': { + extensions: ['sru'], + source: 'iana', + }, + 'application/ssdl+xml': { + extensions: ['ssdl'], + source: 'apache', + }, + 'application/ssml+xml': { + extensions: ['ssml'], + source: 'iana', + }, + 'application/swid+xml': { + extensions: ['swidtag'], + source: 'iana', + }, + 'application/tei+xml': { + extensions: ['tei', 'teicorpus'], + source: 'iana', + }, + 'application/thraud+xml': { + extensions: ['tfi'], + source: 'iana', + }, + 'application/timestamped-data': { + extensions: ['tsd'], + source: 'iana', + }, + 'application/trig': { + extensions: ['trig'], + source: 'iana', + }, + 'application/ttml+xml': { + extensions: ['ttml'], + source: 'iana', + }, + 'application/urc-ressheet+xml': { + extensions: ['rsheet'], + source: 'iana', + }, + 'application/urc-targetdesc+xml': { + extensions: ['td'], + source: 'iana', + }, + 'application/vnd.3gpp.pic-bw-large': { + extensions: ['plb'], + source: 'iana', + }, + 'application/vnd.3gpp.pic-bw-small': { + extensions: ['psb'], + source: 'iana', + }, + 'application/vnd.3gpp.pic-bw-var': { + extensions: ['pvb'], + source: 'iana', + }, + 'application/vnd.3gpp2.tcap': { + extensions: ['tcap'], + source: 'iana', + }, + 'application/vnd.3m.post-it-notes': { + extensions: ['pwn'], + source: 'iana', + }, + 'application/vnd.1000minds.decision-model+xml': { + extensions: ['1km'], + source: 'iana', + }, + 'application/vnd.accpac.simply.aso': { + extensions: ['aso'], + source: 'iana', + }, + 'application/vnd.accpac.simply.imp': { + extensions: ['imp'], + source: 'iana', + }, + 'application/vnd.acucobol': { + extensions: ['acu'], + source: 'iana', + }, + 'application/vnd.acucorp': { + extensions: ['atc', 'acutc'], + source: 'iana', + }, + 'application/vnd.adobe.air-application-installer-package+zip': { + extensions: ['air'], + source: 'apache', + }, + 'application/vnd.adobe.formscentral.fcdt': { + extensions: ['fcdt'], + source: 'iana', + }, + 'application/vnd.adobe.fxp': { + extensions: ['fxp', 'fxpl'], + source: 'iana', + }, + 'application/vnd.adobe.xdp+xml': { + extensions: ['xdp'], + source: 'iana', + }, + 'application/vnd.adobe.xfdf': { + extensions: ['xfdf'], + source: 'iana', + }, + 'application/vnd.age': { + extensions: ['age'], + source: 'iana', + }, + 'application/vnd.ahead.space': { + extensions: ['ahead'], + source: 'iana', + }, + 'application/vnd.airzip.filesecure.azf': { + extensions: ['azf'], + source: 'iana', + }, + 'application/vnd.airzip.filesecure.azs': { + extensions: ['azs'], + source: 'iana', + }, + 'application/vnd.amazon.ebook': { + extensions: ['azw'], + source: 'apache', + }, + 'application/vnd.americandynamics.acc': { + extensions: ['acc'], + source: 'iana', + }, + 'application/vnd.amiga.ami': { + extensions: ['ami'], + source: 'iana', + }, + 'application/vnd.android.package-archive': { + extensions: ['apk'], + source: 'apache', + }, + 'application/vnd.anser-web-certificate-issue-initiation': { + extensions: ['cii'], + source: 'iana', + }, + 'application/vnd.anser-web-funds-transfer-initiation': { + extensions: ['fti'], + source: 'apache', + }, + 'application/vnd.antix.game-component': { + extensions: ['atx'], + source: 'iana', + }, + 'application/vnd.apple.installer+xml': { + extensions: ['mpkg'], + source: 'iana', + }, + 'application/vnd.apple.keynote': { + extensions: ['key'], + source: 'iana', + }, + 'application/vnd.apple.mpegurl': { + extensions: ['m3u8'], + source: 'iana', + }, + 'application/vnd.apple.numbers': { + extensions: ['numbers'], + source: 'iana', + }, + 'application/vnd.apple.pages': { + extensions: ['pages'], + source: 'iana', + }, + 'application/vnd.aristanetworks.swi': { + extensions: ['swi'], + source: 'iana', + }, + 'application/vnd.astraea-software.iota': { + extensions: ['iota'], + source: 'iana', + }, + 'application/vnd.audiograph': { + extensions: ['aep'], + source: 'iana', + }, + 'application/vnd.balsamiq.bmml+xml': { + extensions: ['bmml'], + source: 'iana', + }, + 'application/vnd.blueice.multipass': { + extensions: ['mpm'], + source: 'iana', + }, + 'application/vnd.bmi': { + extensions: ['bmi'], + source: 'iana', + }, + 'application/vnd.businessobjects': { + extensions: ['rep'], + source: 'iana', + }, + 'application/vnd.chemdraw+xml': { + extensions: ['cdxml'], + source: 'iana', + }, + 'application/vnd.chipnuts.karaoke-mmd': { + extensions: ['mmd'], + source: 'iana', + }, + 'application/vnd.cinderella': { + extensions: ['cdy'], + source: 'iana', + }, + 'application/vnd.citationstyles.style+xml': { + extensions: ['csl'], + source: 'iana', + }, + 'application/vnd.claymore': { + extensions: ['cla'], + source: 'iana', + }, + 'application/vnd.cloanto.rp9': { + extensions: ['rp9'], + source: 'iana', + }, + 'application/vnd.clonk.c4group': { + extensions: ['c4g', 'c4d', 'c4f', 'c4p', 'c4u'], + source: 'iana', + }, + 'application/vnd.cluetrust.cartomobile-config': { + extensions: ['c11amc'], + source: 'iana', + }, + 'application/vnd.cluetrust.cartomobile-config-pkg': { + extensions: ['c11amz'], + source: 'iana', + }, + 'application/vnd.commonspace': { + extensions: ['csp'], + source: 'iana', + }, + 'application/vnd.contact.cmsg': { + extensions: ['cdbcmsg'], + source: 'iana', + }, + 'application/vnd.cosmocaller': { + extensions: ['cmc'], + source: 'iana', + }, + 'application/vnd.crick.clicker': { + extensions: ['clkx'], + source: 'iana', + }, + 'application/vnd.crick.clicker.keyboard': { + extensions: ['clkk'], + source: 'iana', + }, + 'application/vnd.crick.clicker.palette': { + extensions: ['clkp'], + source: 'iana', + }, + 'application/vnd.crick.clicker.template': { + extensions: ['clkt'], + source: 'iana', + }, + 'application/vnd.crick.clicker.wordbank': { + extensions: ['clkw'], + source: 'iana', + }, + 'application/vnd.criticaltools.wbs+xml': { + extensions: ['wbs'], + source: 'iana', + }, + 'application/vnd.ctc-posml': { + extensions: ['pml'], + source: 'iana', + }, + 'application/vnd.cups-ppd': { + extensions: ['ppd'], + source: 'iana', + }, + 'application/vnd.curl.car': { + extensions: ['car'], + source: 'apache', + }, + 'application/vnd.curl.pcurl': { + extensions: ['pcurl'], + source: 'apache', + }, + 'application/vnd.dart': { + extensions: ['dart'], + source: 'iana', + }, + 'application/vnd.data-vision.rdz': { + extensions: ['rdz'], + source: 'iana', + }, + 'application/vnd.dbf': { + extensions: ['dbf'], + source: 'iana', + }, + 'application/vnd.dece.data': { + extensions: ['uvf', 'uvvf', 'uvd', 'uvvd'], + source: 'iana', + }, + 'application/vnd.dece.ttml+xml': { + extensions: ['uvt', 'uvvt'], + source: 'iana', + }, + 'application/vnd.dece.unspecified': { + extensions: ['uvx', 'uvvx'], + source: 'iana', + }, + 'application/vnd.dece.zip': { + extensions: ['uvz', 'uvvz'], + source: 'iana', + }, + 'application/vnd.denovo.fcselayout-link': { + extensions: ['fe_launch'], + source: 'iana', + }, + 'application/vnd.dna': { + extensions: ['dna'], + source: 'iana', + }, + 'application/vnd.dolby.mlp': { + extensions: ['mlp'], + source: 'apache', + }, + 'application/vnd.dpgraph': { + extensions: ['dpg'], + source: 'iana', + }, + 'application/vnd.dreamfactory': { + extensions: ['dfac'], + source: 'iana', + }, + 'application/vnd.ds-keypoint': { + extensions: ['kpxx'], + source: 'apache', + }, + 'application/vnd.dvb.ait': { + extensions: ['ait'], + source: 'iana', + }, + 'application/vnd.dvb.service': { + extensions: ['svc'], + source: 'iana', + }, + 'application/vnd.dynageo': { + extensions: ['geo'], + source: 'iana', + }, + 'application/vnd.ecowin.chart': { + extensions: ['mag'], + source: 'iana', + }, + 'application/vnd.enliven': { + extensions: ['nml'], + source: 'iana', + }, + 'application/vnd.epson.esf': { + extensions: ['esf'], + source: 'iana', + }, + 'application/vnd.epson.msf': { + extensions: ['msf'], + source: 'iana', + }, + 'application/vnd.epson.quickanime': { + extensions: ['qam'], + source: 'iana', + }, + 'application/vnd.epson.salt': { + extensions: ['slt'], + source: 'iana', + }, + 'application/vnd.epson.ssf': { + extensions: ['ssf'], + source: 'iana', + }, + 'application/vnd.eszigno3+xml': { + extensions: ['es3', 'et3'], + source: 'iana', + }, + 'application/vnd.ezpix-album': { + extensions: ['ez2'], + source: 'iana', + }, + 'application/vnd.ezpix-package': { + extensions: ['ez3'], + source: 'iana', + }, + 'application/vnd.fdf': { + extensions: ['fdf'], + source: 'iana', + }, + 'application/vnd.fdsn.mseed': { + extensions: ['mseed'], + source: 'iana', + }, + 'application/vnd.fdsn.seed': { + extensions: ['seed', 'dataless'], + source: 'iana', + }, + 'application/vnd.flographit': { + extensions: ['gph'], + source: 'iana', + }, + 'application/vnd.fluxtime.clip': { + extensions: ['ftc'], + source: 'iana', + }, + 'application/vnd.framemaker': { + extensions: ['fm', 'frame', 'maker', 'book'], + source: 'iana', + }, + 'application/vnd.frogans.fnc': { + extensions: ['fnc'], + source: 'iana', + }, + 'application/vnd.frogans.ltf': { + extensions: ['ltf'], + source: 'iana', + }, + 'application/vnd.fsc.weblaunch': { + extensions: ['fsc'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasys': { + extensions: ['oas'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasys2': { + extensions: ['oa2'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasys3': { + extensions: ['oa3'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasysgp': { + extensions: ['fg5'], + source: 'iana', + }, + 'application/vnd.fujitsu.oasysprs': { + extensions: ['bh2'], + source: 'iana', + }, + 'application/vnd.fujixerox.ddd': { + extensions: ['ddd'], + source: 'iana', + }, + 'application/vnd.fujixerox.docuworks': { + extensions: ['xdw'], + source: 'iana', + }, + 'application/vnd.fujixerox.docuworks.binder': { + extensions: ['xbd'], + source: 'iana', + }, + 'application/vnd.fuzzysheet': { + extensions: ['fzs'], + source: 'iana', + }, + 'application/vnd.genomatix.tuxedo': { + extensions: ['txd'], + source: 'iana', + }, + 'application/vnd.geogebra.file': { + extensions: ['ggb'], + source: 'iana', + }, + 'application/vnd.geogebra.tool': { + extensions: ['ggt'], + source: 'iana', + }, + 'application/vnd.geometry-explorer': { + extensions: ['gex', 'gre'], + source: 'iana', + }, + 'application/vnd.geonext': { + extensions: ['gxt'], + source: 'iana', + }, + 'application/vnd.geoplan': { + extensions: ['g2w'], + source: 'iana', + }, + 'application/vnd.geospace': { + extensions: ['g3w'], + source: 'iana', + }, + 'application/vnd.gmx': { + extensions: ['gmx'], + source: 'iana', + }, + 'application/vnd.google-earth.kml+xml': { + extensions: ['kml'], + source: 'iana', + }, + 'application/vnd.google-earth.kmz': { + extensions: ['kmz'], + source: 'iana', + }, + 'application/vnd.grafeq': { + extensions: ['gqf', 'gqs'], + source: 'iana', + }, + 'application/vnd.groove-account': { + extensions: ['gac'], + source: 'iana', + }, + 'application/vnd.groove-help': { + extensions: ['ghf'], + source: 'iana', + }, + 'application/vnd.groove-identity-message': { + extensions: ['gim'], + source: 'iana', + }, + 'application/vnd.groove-injector': { + extensions: ['grv'], + source: 'iana', + }, + 'application/vnd.groove-tool-message': { + extensions: ['gtm'], + source: 'iana', + }, + 'application/vnd.groove-tool-template': { + extensions: ['tpl'], + source: 'iana', + }, + 'application/vnd.groove-vcard': { + extensions: ['vcg'], + source: 'iana', + }, + 'application/vnd.hal+xml': { + extensions: ['hal'], + source: 'iana', + }, + 'application/vnd.handheld-entertainment+xml': { + extensions: ['zmm'], + source: 'iana', + }, + 'application/vnd.hbci': { + extensions: ['hbci'], + source: 'iana', + }, + 'application/vnd.hhe.lesson-player': { + extensions: ['les'], + source: 'iana', + }, + 'application/vnd.hp-hpgl': { + extensions: ['hpgl'], + source: 'iana', + }, + 'application/vnd.hp-hpid': { + extensions: ['hpid'], + source: 'iana', + }, + 'application/vnd.hp-hps': { + extensions: ['hps'], + source: 'iana', + }, + 'application/vnd.hp-jlyt': { + extensions: ['jlt'], + source: 'iana', + }, + 'application/vnd.hp-pcl': { + extensions: ['pcl'], + source: 'iana', + }, + 'application/vnd.hp-pclxl': { + extensions: ['pclxl'], + source: 'iana', + }, + 'application/vnd.hydrostatix.sof-data': { + extensions: ['sfd-hdstx'], + source: 'iana', + }, + 'application/vnd.ibm.minipay': { + extensions: ['mpy'], + source: 'iana', + }, + 'application/vnd.ibm.modcap': { + extensions: ['afp', 'listafp', 'list3820'], + source: 'iana', + }, + 'application/vnd.ibm.rights-management': { + extensions: ['irm'], + source: 'iana', + }, + 'application/vnd.ibm.secure-container': { + extensions: ['sc'], + source: 'iana', + }, + 'application/vnd.iccprofile': { + extensions: ['icc', 'icm'], + source: 'iana', + }, + 'application/vnd.igloader': { + extensions: ['igl'], + source: 'iana', + }, + 'application/vnd.immervision-ivp': { + extensions: ['ivp'], + source: 'iana', + }, + 'application/vnd.immervision-ivu': { + extensions: ['ivu'], + source: 'iana', + }, + 'application/vnd.insors.igm': { + extensions: ['igm'], + source: 'iana', + }, + 'application/vnd.intercon.formnet': { + extensions: ['xpw', 'xpx'], + source: 'iana', + }, + 'application/vnd.intergeo': { + extensions: ['i2g'], + source: 'iana', + }, + 'application/vnd.intu.qbo': { + extensions: ['qbo'], + source: 'iana', + }, + 'application/vnd.intu.qfx': { + extensions: ['qfx'], + source: 'iana', + }, + 'application/vnd.ipunplugged.rcprofile': { + extensions: ['rcprofile'], + source: 'iana', + }, + 'application/vnd.irepository.package+xml': { + extensions: ['irp'], + source: 'iana', + }, + 'application/vnd.is-xpr': { + extensions: ['xpr'], + source: 'iana', + }, + 'application/vnd.isac.fcs': { + extensions: ['fcs'], + source: 'iana', + }, + 'application/vnd.jam': { + extensions: ['jam'], + source: 'iana', + }, + 'application/vnd.jcp.javame.midlet-rms': { + extensions: ['rms'], + source: 'iana', + }, + 'application/vnd.jisp': { + extensions: ['jisp'], + source: 'iana', + }, + 'application/vnd.joost.joda-archive': { + extensions: ['joda'], + source: 'iana', + }, + 'application/vnd.kahootz': { + extensions: ['ktz', 'ktr'], + source: 'iana', + }, + 'application/vnd.kde.karbon': { + extensions: ['karbon'], + source: 'iana', + }, + 'application/vnd.kde.kchart': { + extensions: ['chrt'], + source: 'iana', + }, + 'application/vnd.kde.kformula': { + extensions: ['kfo'], + source: 'iana', + }, + 'application/vnd.kde.kivio': { + extensions: ['flw'], + source: 'iana', + }, + 'application/vnd.kde.kontour': { + extensions: ['kon'], + source: 'iana', + }, + 'application/vnd.kde.kpresenter': { + extensions: ['kpr', 'kpt'], + source: 'iana', + }, + 'application/vnd.kde.kspread': { + extensions: ['ksp'], + source: 'iana', + }, + 'application/vnd.kde.kword': { + extensions: ['kwd', 'kwt'], + source: 'iana', + }, + 'application/vnd.kenameaapp': { + extensions: ['htke'], + source: 'iana', + }, + 'application/vnd.kidspiration': { + extensions: ['kia'], + source: 'iana', + }, + 'application/vnd.kinar': { + extensions: ['kne', 'knp'], + source: 'iana', + }, + 'application/vnd.koan': { + extensions: ['skp', 'skd', 'skt', 'skm'], + source: 'iana', + }, + 'application/vnd.kodak-descriptor': { + extensions: ['sse'], + source: 'iana', + }, + 'application/vnd.las.las+xml': { + extensions: ['lasxml'], + source: 'iana', + }, + 'application/vnd.llamagraphics.life-balance.desktop': { + extensions: ['lbd'], + source: 'iana', + }, + 'application/vnd.llamagraphics.life-balance.exchange+xml': { + extensions: ['lbe'], + source: 'iana', + }, + 'application/vnd.lotus-1-2-3': { + extensions: ['123'], + source: 'iana', + }, + 'application/vnd.lotus-approach': { + extensions: ['apr'], + source: 'iana', + }, + 'application/vnd.lotus-freelance': { + extensions: ['pre'], + source: 'iana', + }, + 'application/vnd.lotus-notes': { + extensions: ['nsf'], + source: 'iana', + }, + 'application/vnd.lotus-organizer': { + extensions: ['org'], + source: 'iana', + }, + 'application/vnd.lotus-screencam': { + extensions: ['scm'], + source: 'iana', + }, + 'application/vnd.lotus-wordpro': { + extensions: ['lwp'], + source: 'iana', + }, + 'application/vnd.macports.portpkg': { + extensions: ['portpkg'], + source: 'iana', + }, + 'application/vnd.mapbox-vector-tile': { + extensions: ['mvt'], + source: 'iana', + }, + 'application/vnd.mcd': { + extensions: ['mcd'], + source: 'iana', + }, + 'application/vnd.medcalcdata': { + extensions: ['mc1'], + source: 'iana', + }, + 'application/vnd.mediastation.cdkey': { + extensions: ['cdkey'], + source: 'iana', + }, + 'application/vnd.mfer': { + extensions: ['mwf'], + source: 'iana', + }, + 'application/vnd.mfmp': { + extensions: ['mfm'], + source: 'iana', + }, + 'application/vnd.micrografx.flo': { + extensions: ['flo'], + source: 'iana', + }, + 'application/vnd.micrografx.igx': { + extensions: ['igx'], + source: 'iana', + }, + 'application/vnd.mif': { + extensions: ['mif'], + source: 'iana', + }, + 'application/vnd.mobius.daf': { + extensions: ['daf'], + source: 'iana', + }, + 'application/vnd.mobius.dis': { + extensions: ['dis'], + source: 'iana', + }, + 'application/vnd.mobius.mbk': { + extensions: ['mbk'], + source: 'iana', + }, + 'application/vnd.mobius.mqy': { + extensions: ['mqy'], + source: 'iana', + }, + 'application/vnd.mobius.msl': { + extensions: ['msl'], + source: 'iana', + }, + 'application/vnd.mobius.plc': { + extensions: ['plc'], + source: 'iana', + }, + 'application/vnd.mobius.txf': { + extensions: ['txf'], + source: 'iana', + }, + 'application/vnd.mophun.application': { + extensions: ['mpn'], + source: 'iana', + }, + 'application/vnd.mophun.certificate': { + extensions: ['mpc'], + source: 'iana', + }, + 'application/vnd.mozilla.xul+xml': { + extensions: ['xul'], + source: 'iana', + }, + 'application/vnd.ms-artgalry': { + extensions: ['cil'], + source: 'iana', + }, + 'application/vnd.ms-cab-compressed': { + extensions: ['cab'], + source: 'iana', + }, + 'application/vnd.ms-excel': { + extensions: ['xls', 'xlm', 'xla', 'xlc', 'xlt', 'xlw'], + source: 'iana', + }, + 'application/vnd.ms-excel.addin.macroenabled.12': { + extensions: ['xlam'], + source: 'iana', + }, + 'application/vnd.ms-excel.sheet.binary.macroenabled.12': { + extensions: ['xlsb'], + source: 'iana', + }, + 'application/vnd.ms-excel.sheet.macroenabled.12': { + extensions: ['xlsm'], + source: 'iana', + }, + 'application/vnd.ms-excel.template.macroenabled.12': { + extensions: ['xltm'], + source: 'iana', + }, + 'application/vnd.ms-fontobject': { + extensions: ['eot'], + source: 'iana', + }, + 'application/vnd.ms-htmlhelp': { + extensions: ['chm'], + source: 'iana', + }, + 'application/vnd.ms-ims': { + extensions: ['ims'], + source: 'iana', + }, + 'application/vnd.ms-lrm': { + extensions: ['lrm'], + source: 'iana', + }, + 'application/vnd.ms-officetheme': { + extensions: ['thmx'], + source: 'iana', + }, + 'application/vnd.ms-pki.seccat': { + extensions: ['cat'], + source: 'apache', + }, + 'application/vnd.ms-pki.stl': { + extensions: ['stl'], + source: 'apache', + }, + 'application/vnd.ms-powerpoint': { + extensions: ['ppt', 'pps', 'pot'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.addin.macroenabled.12': { + extensions: ['ppam'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.presentation.macroenabled.12': { + extensions: ['pptm'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.slide.macroenabled.12': { + extensions: ['sldm'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.slideshow.macroenabled.12': { + extensions: ['ppsm'], + source: 'iana', + }, + 'application/vnd.ms-powerpoint.template.macroenabled.12': { + extensions: ['potm'], + source: 'iana', + }, + 'application/vnd.ms-project': { + extensions: ['mpp', 'mpt'], + source: 'iana', + }, + 'application/vnd.ms-word.document.macroenabled.12': { + extensions: ['docm'], + source: 'iana', + }, + 'application/vnd.ms-word.template.macroenabled.12': { + extensions: ['dotm'], + source: 'iana', + }, + 'application/vnd.ms-works': { + extensions: ['wps', 'wks', 'wcm', 'wdb'], + source: 'iana', + }, + 'application/vnd.ms-wpl': { + extensions: ['wpl'], + source: 'iana', + }, + 'application/vnd.ms-xpsdocument': { + extensions: ['xps'], + source: 'iana', + }, + 'application/vnd.mseq': { + extensions: ['mseq'], + source: 'iana', + }, + 'application/vnd.musician': { + extensions: ['mus'], + source: 'iana', + }, + 'application/vnd.muvee.style': { + extensions: ['msty'], + source: 'iana', + }, + 'application/vnd.mynfc': { + extensions: ['taglet'], + source: 'iana', + }, + 'application/vnd.neurolanguage.nlu': { + extensions: ['nlu'], + source: 'iana', + }, + 'application/vnd.nitf': { + extensions: ['ntf', 'nitf'], + source: 'iana', + }, + 'application/vnd.noblenet-directory': { + extensions: ['nnd'], + source: 'iana', + }, + 'application/vnd.noblenet-sealer': { + extensions: ['nns'], + source: 'iana', + }, + 'application/vnd.noblenet-web': { + extensions: ['nnw'], + source: 'iana', + }, + 'application/vnd.nokia.n-gage.ac+xml': { + extensions: ['ac'], + source: 'iana', + }, + 'application/vnd.nokia.n-gage.data': { + extensions: ['ngdat'], + source: 'iana', + }, + 'application/vnd.nokia.n-gage.symbian.install': { + extensions: ['n-gage'], + source: 'iana', + }, + 'application/vnd.nokia.radio-preset': { + extensions: ['rpst'], + source: 'iana', + }, + 'application/vnd.nokia.radio-presets': { + extensions: ['rpss'], + source: 'iana', + }, + 'application/vnd.novadigm.edm': { + extensions: ['edm'], + source: 'iana', + }, + 'application/vnd.novadigm.edx': { + extensions: ['edx'], + source: 'iana', + }, + 'application/vnd.novadigm.ext': { + extensions: ['ext'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.chart': { + extensions: ['odc'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.chart-template': { + extensions: ['otc'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.database': { + extensions: ['odb'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.formula': { + extensions: ['odf'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.formula-template': { + extensions: ['odft'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.graphics': { + extensions: ['odg'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.graphics-template': { + extensions: ['otg'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.image': { + extensions: ['odi'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.image-template': { + extensions: ['oti'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.presentation': { + extensions: ['odp'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.presentation-template': { + extensions: ['otp'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.spreadsheet': { + extensions: ['ods'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.spreadsheet-template': { + extensions: ['ots'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.text': { + extensions: ['odt'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.text-master': { + extensions: ['odm'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.text-template': { + extensions: ['ott'], + source: 'iana', + }, + 'application/vnd.oasis.opendocument.text-web': { + extensions: ['oth'], + source: 'iana', + }, + 'application/vnd.olpc-sugar': { + extensions: ['xo'], + source: 'iana', + }, + 'application/vnd.oma.dd2+xml': { + extensions: ['dd2'], + source: 'iana', + }, + 'application/vnd.openblox.game+xml': { + extensions: ['obgx'], + source: 'iana', + }, + 'application/vnd.openofficeorg.extension': { + extensions: ['oxt'], + source: 'apache', + }, + 'application/vnd.openstreetmap.data+xml': { + extensions: ['osm'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.presentationml.presentation': { + extensions: ['pptx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.presentationml.slide': { + extensions: ['sldx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow': { + extensions: ['ppsx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.presentationml.template': { + extensions: ['potx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': { + extensions: ['xlsx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template': { + extensions: ['xltx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': { + extensions: ['docx'], + source: 'iana', + }, + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': { + extensions: ['dotx'], + source: 'iana', + }, + 'application/vnd.osgeo.mapguide.package': { + extensions: ['mgp'], + source: 'iana', + }, + 'application/vnd.osgi.dp': { + extensions: ['dp'], + source: 'iana', + }, + 'application/vnd.osgi.subsystem': { + extensions: ['esa'], + source: 'iana', + }, + 'application/vnd.palm': { + extensions: ['pdb', 'pqa', 'oprc'], + source: 'iana', + }, + 'application/vnd.pawaafile': { + extensions: ['paw'], + source: 'iana', + }, + 'application/vnd.pg.format': { + extensions: ['str'], + source: 'iana', + }, + 'application/vnd.pg.osasli': { + extensions: ['ei6'], + source: 'iana', + }, + 'application/vnd.picsel': { + extensions: ['efif'], + source: 'iana', + }, + 'application/vnd.pmi.widget': { + extensions: ['wg'], + source: 'iana', + }, + 'application/vnd.pocketlearn': { + extensions: ['plf'], + source: 'iana', + }, + 'application/vnd.powerbuilder6': { + extensions: ['pbd'], + source: 'iana', + }, + 'application/vnd.previewsystems.box': { + extensions: ['box'], + source: 'iana', + }, + 'application/vnd.proteus.magazine': { + extensions: ['mgz'], + source: 'iana', + }, + 'application/vnd.publishare-delta-tree': { + extensions: ['qps'], + source: 'iana', + }, + 'application/vnd.pvi.ptid1': { + extensions: ['ptid'], + source: 'iana', + }, + 'application/vnd.quark.quarkxpress': { + extensions: ['qxd', 'qxt', 'qwd', 'qwt', 'qxl', 'qxb'], + source: 'iana', + }, + 'application/vnd.rar': { + extensions: ['rar'], + source: 'iana', + }, + 'application/vnd.realvnc.bed': { + extensions: ['bed'], + source: 'iana', + }, + 'application/vnd.recordare.musicxml': { + extensions: ['mxl'], + source: 'iana', + }, + 'application/vnd.recordare.musicxml+xml': { + extensions: ['musicxml'], + source: 'iana', + }, + 'application/vnd.rig.cryptonote': { + extensions: ['cryptonote'], + source: 'iana', + }, + 'application/vnd.rim.cod': { + extensions: ['cod'], + source: 'apache', + }, + 'application/vnd.rn-realmedia': { + extensions: ['rm'], + source: 'apache', + }, + 'application/vnd.rn-realmedia-vbr': { + extensions: ['rmvb'], + source: 'apache', + }, + 'application/vnd.route66.link66+xml': { + extensions: ['link66'], + source: 'iana', + }, + 'application/vnd.sailingtracker.track': { + extensions: ['st'], + source: 'iana', + }, + 'application/vnd.seemail': { + extensions: ['see'], + source: 'iana', + }, + 'application/vnd.sema': { + extensions: ['sema'], + source: 'iana', + }, + 'application/vnd.semd': { + extensions: ['semd'], + source: 'iana', + }, + 'application/vnd.semf': { + extensions: ['semf'], + source: 'iana', + }, + 'application/vnd.shana.informed.formdata': { + extensions: ['ifm'], + source: 'iana', + }, + 'application/vnd.shana.informed.formtemplate': { + extensions: ['itp'], + source: 'iana', + }, + 'application/vnd.shana.informed.interchange': { + extensions: ['iif'], + source: 'iana', + }, + 'application/vnd.shana.informed.package': { + extensions: ['ipk'], + source: 'iana', + }, + 'application/vnd.simtech-mindmapper': { + extensions: ['twd', 'twds'], + source: 'iana', + }, + 'application/vnd.smaf': { + extensions: ['mmf'], + source: 'iana', + }, + 'application/vnd.smart.teacher': { + extensions: ['teacher'], + source: 'iana', + }, + 'application/vnd.software602.filler.form+xml': { + extensions: ['fo'], + source: 'iana', + }, + 'application/vnd.solent.sdkm+xml': { + extensions: ['sdkm', 'sdkd'], + source: 'iana', + }, + 'application/vnd.spotfire.dxp': { + extensions: ['dxp'], + source: 'iana', + }, + 'application/vnd.spotfire.sfs': { + extensions: ['sfs'], + source: 'iana', + }, + 'application/vnd.stardivision.calc': { + extensions: ['sdc'], + source: 'apache', + }, + 'application/vnd.stardivision.draw': { + extensions: ['sda'], + source: 'apache', + }, + 'application/vnd.stardivision.impress': { + extensions: ['sdd'], + source: 'apache', + }, + 'application/vnd.stardivision.math': { + extensions: ['smf'], + source: 'apache', + }, + 'application/vnd.stardivision.writer': { + extensions: ['sdw', 'vor'], + source: 'apache', + }, + 'application/vnd.stardivision.writer-global': { + extensions: ['sgl'], + source: 'apache', + }, + 'application/vnd.stepmania.package': { + extensions: ['smzip'], + source: 'iana', + }, + 'application/vnd.stepmania.stepchart': { + extensions: ['sm'], + source: 'iana', + }, + 'application/vnd.sun.wadl+xml': { + extensions: ['wadl'], + source: 'iana', + }, + 'application/vnd.sun.xml.calc': { + extensions: ['sxc'], + source: 'apache', + }, + 'application/vnd.sun.xml.calc.template': { + extensions: ['stc'], + source: 'apache', + }, + 'application/vnd.sun.xml.draw': { + extensions: ['sxd'], + source: 'apache', + }, + 'application/vnd.sun.xml.draw.template': { + extensions: ['std'], + source: 'apache', + }, + 'application/vnd.sun.xml.impress': { + extensions: ['sxi'], + source: 'apache', + }, + 'application/vnd.sun.xml.impress.template': { + extensions: ['sti'], + source: 'apache', + }, + 'application/vnd.sun.xml.math': { + extensions: ['sxm'], + source: 'apache', + }, + 'application/vnd.sun.xml.writer': { + extensions: ['sxw'], + source: 'apache', + }, + 'application/vnd.sun.xml.writer.global': { + extensions: ['sxg'], + source: 'apache', + }, + 'application/vnd.sun.xml.writer.template': { + extensions: ['stw'], + source: 'apache', + }, + 'application/vnd.sus-calendar': { + extensions: ['sus', 'susp'], + source: 'iana', + }, + 'application/vnd.svd': { + extensions: ['svd'], + source: 'iana', + }, + 'application/vnd.symbian.install': { + extensions: ['sis', 'sisx'], + source: 'apache', + }, + 'application/vnd.syncml+xml': { + charset: 'UTF-8', + extensions: ['xsm'], + source: 'iana', + }, + 'application/vnd.syncml.dm+wbxml': { + charset: 'UTF-8', + extensions: ['bdm'], + source: 'iana', + }, + 'application/vnd.syncml.dm+xml': { + charset: 'UTF-8', + extensions: ['xdm'], + source: 'iana', + }, + 'application/vnd.syncml.dmddf+xml': { + charset: 'UTF-8', + extensions: ['ddf'], + source: 'iana', + }, + 'application/vnd.tao.intent-module-archive': { + extensions: ['tao'], + source: 'iana', + }, + 'application/vnd.tcpdump.pcap': { + extensions: ['pcap', 'cap', 'dmp'], + source: 'iana', + }, + 'application/vnd.tmobile-livetv': { + extensions: ['tmo'], + source: 'iana', + }, + 'application/vnd.trid.tpt': { + extensions: ['tpt'], + source: 'iana', + }, + 'application/vnd.triscape.mxs': { + extensions: ['mxs'], + source: 'iana', + }, + 'application/vnd.trueapp': { + extensions: ['tra'], + source: 'iana', + }, + 'application/vnd.ufdl': { + extensions: ['ufd', 'ufdl'], + source: 'iana', + }, + 'application/vnd.uiq.theme': { + extensions: ['utz'], + source: 'iana', + }, + 'application/vnd.umajin': { + extensions: ['umj'], + source: 'iana', + }, + 'application/vnd.unity': { + extensions: ['unityweb'], + source: 'iana', + }, + 'application/vnd.uoml+xml': { + extensions: ['uoml'], + source: 'iana', + }, + 'application/vnd.vcx': { + extensions: ['vcx'], + source: 'iana', + }, + 'application/vnd.visio': { + extensions: ['vsd', 'vst', 'vss', 'vsw'], + source: 'iana', + }, + 'application/vnd.visionary': { + extensions: ['vis'], + source: 'iana', + }, + 'application/vnd.vsf': { + extensions: ['vsf'], + source: 'iana', + }, + 'application/vnd.wap.wbxml': { + charset: 'UTF-8', + extensions: ['wbxml'], + source: 'iana', + }, + 'application/vnd.wap.wmlc': { + extensions: ['wmlc'], + source: 'iana', + }, + 'application/vnd.wap.wmlscriptc': { + extensions: ['wmlsc'], + source: 'iana', + }, + 'application/vnd.webturbo': { + extensions: ['wtb'], + source: 'iana', + }, + 'application/vnd.wolfram.player': { + extensions: ['nbp'], + source: 'iana', + }, + 'application/vnd.wordperfect': { + extensions: ['wpd'], + source: 'iana', + }, + 'application/vnd.wqd': { + extensions: ['wqd'], + source: 'iana', + }, + 'application/vnd.wt.stf': { + extensions: ['stf'], + source: 'iana', + }, + 'application/vnd.xara': { + extensions: ['xar'], + source: 'iana', + }, + 'application/vnd.xfdl': { + extensions: ['xfdl'], + source: 'iana', + }, + 'application/vnd.yamaha.hv-dic': { + extensions: ['hvd'], + source: 'iana', + }, + 'application/vnd.yamaha.hv-script': { + extensions: ['hvs'], + source: 'iana', + }, + 'application/vnd.yamaha.hv-voice': { + extensions: ['hvp'], + source: 'iana', + }, + 'application/vnd.yamaha.openscoreformat': { + extensions: ['osf'], + source: 'iana', + }, + 'application/vnd.yamaha.openscoreformat.osfpvg+xml': { + extensions: ['osfpvg'], + source: 'iana', + }, + 'application/vnd.yamaha.smaf-audio': { + extensions: ['saf'], + source: 'iana', + }, + 'application/vnd.yamaha.smaf-phrase': { + extensions: ['spf'], + source: 'iana', + }, + 'application/vnd.yellowriver-custom-menu': { + extensions: ['cmp'], + source: 'iana', + }, + 'application/vnd.zul': { + extensions: ['zir', 'zirz'], + source: 'iana', + }, + 'application/vnd.zzazz.deck+xml': { + extensions: ['zaz'], + source: 'iana', + }, + 'application/voicexml+xml': { + extensions: ['vxml'], + source: 'iana', + }, + 'application/wasm': { + extensions: ['wasm'], + source: 'iana', + }, + 'application/watcherinfo+xml': { + extensions: ['wif'], + source: 'iana', + }, + 'application/widget': { + extensions: ['wgt'], + source: 'iana', + }, + 'application/winhlp': { + extensions: ['hlp'], + source: 'apache', + }, + 'application/wsdl+xml': { + extensions: ['wsdl'], + source: 'iana', + }, + 'application/wspolicy+xml': { + extensions: ['wspolicy'], + source: 'iana', + }, + 'application/x-7z-compressed': { + extensions: ['7z'], + source: 'apache', + }, + 'application/x-abiword': { + extensions: ['abw'], + source: 'apache', + }, + 'application/x-ace-compressed': { + extensions: ['ace'], + source: 'apache', + }, + 'application/x-apple-diskimage': { + extensions: ['dmg'], + source: 'apache', + }, + 'application/x-authorware-bin': { + extensions: ['aab', 'x32', 'u32', 'vox'], + source: 'apache', + }, + 'application/x-authorware-map': { + extensions: ['aam'], + source: 'apache', + }, + 'application/x-authorware-seg': { + extensions: ['aas'], + source: 'apache', + }, + 'application/x-bcpio': { + extensions: ['bcpio'], + source: 'apache', + }, + 'application/x-bittorrent': { + extensions: ['torrent'], + source: 'apache', + }, + 'application/x-blorb': { + extensions: ['blb', 'blorb'], + source: 'apache', + }, + 'application/x-bzip': { + extensions: ['bz'], + source: 'apache', + }, + 'application/x-bzip2': { + extensions: ['bz2', 'boz'], + source: 'apache', + }, + 'application/x-cbr': { + extensions: ['cbr', 'cba', 'cbt', 'cbz', 'cb7'], + source: 'apache', + }, + 'application/x-cdlink': { + extensions: ['vcd'], + source: 'apache', + }, + 'application/x-cfs-compressed': { + extensions: ['cfs'], + source: 'apache', + }, + 'application/x-chat': { + extensions: ['chat'], + source: 'apache', + }, + 'application/x-chess-pgn': { + extensions: ['pgn'], + source: 'apache', + }, + 'application/x-cocoa': { + extensions: ['cco'], + source: 'nginx', + }, + 'application/x-conference': { + extensions: ['nsc'], + source: 'apache', + }, + 'application/x-cpio': { + extensions: ['cpio'], + source: 'apache', + }, + 'application/x-csh': { + extensions: ['csh'], + source: 'apache', + }, + 'application/x-debian-package': { + extensions: ['deb', 'udeb'], + source: 'apache', + }, + 'application/x-dgc-compressed': { + extensions: ['dgc'], + source: 'apache', + }, + 'application/x-director': { + extensions: ['dir', 'dcr', 'dxr', 'cst', 'cct', 'cxt', 'w3d', 'fgd', 'swa'], + source: 'apache', + }, + 'application/x-doom': { + extensions: ['wad'], + source: 'apache', + }, + 'application/x-dtbncx+xml': { + extensions: ['ncx'], + source: 'apache', + }, + 'application/x-dtbook+xml': { + extensions: ['dtb'], + source: 'apache', + }, + 'application/x-dtbresource+xml': { + extensions: ['res'], + source: 'apache', + }, + 'application/x-dvi': { + extensions: ['dvi'], + source: 'apache', + }, + 'application/x-envoy': { + extensions: ['evy'], + source: 'apache', + }, + 'application/x-eva': { + extensions: ['eva'], + source: 'apache', + }, + 'application/x-font-bdf': { + extensions: ['bdf'], + source: 'apache', + }, + 'application/x-font-ghostscript': { + extensions: ['gsf'], + source: 'apache', + }, + 'application/x-font-linux-psf': { + extensions: ['psf'], + source: 'apache', + }, + 'application/x-font-pcf': { + extensions: ['pcf'], + source: 'apache', + }, + 'application/x-font-snf': { + extensions: ['snf'], + source: 'apache', + }, + 'application/x-font-type1': { + extensions: ['pfa', 'pfb', 'pfm', 'afm'], + source: 'apache', + }, + 'application/x-freearc': { + extensions: ['arc'], + source: 'apache', + }, + 'application/x-futuresplash': { + extensions: ['spl'], + source: 'apache', + }, + 'application/x-gca-compressed': { + extensions: ['gca'], + source: 'apache', + }, + 'application/x-glulx': { + extensions: ['ulx'], + source: 'apache', + }, + 'application/x-gnumeric': { + extensions: ['gnumeric'], + source: 'apache', + }, + 'application/x-gramps-xml': { + extensions: ['gramps'], + source: 'apache', + }, + 'application/x-gtar': { + extensions: ['gtar'], + source: 'apache', + }, + 'application/x-hdf': { + extensions: ['hdf'], + source: 'apache', + }, + 'application/x-install-instructions': { + extensions: ['install'], + source: 'apache', + }, + 'application/x-iso9660-image': { + extensions: ['iso'], + source: 'apache', + }, + 'application/x-java-archive-diff': { + extensions: ['jardiff'], + source: 'nginx', + }, + 'application/x-java-jnlp-file': { + extensions: ['jnlp'], + source: 'apache', + }, + 'application/x-latex': { + extensions: ['latex'], + source: 'apache', + }, + 'application/x-lzh-compressed': { + extensions: ['lzh', 'lha'], + source: 'apache', + }, + 'application/x-makeself': { + extensions: ['run'], + source: 'nginx', + }, + 'application/x-mie': { + extensions: ['mie'], + source: 'apache', + }, + 'application/x-mobipocket-ebook': { + extensions: ['prc', 'mobi'], + source: 'apache', + }, + 'application/x-ms-application': { + extensions: ['application'], + source: 'apache', + }, + 'application/x-ms-shortcut': { + extensions: ['lnk'], + source: 'apache', + }, + 'application/x-ms-wmd': { + extensions: ['wmd'], + source: 'apache', + }, + 'application/x-ms-wmz': { + extensions: ['wmz'], + source: 'apache', + }, + 'application/x-ms-xbap': { + extensions: ['xbap'], + source: 'apache', + }, + 'application/x-msaccess': { + extensions: ['mdb'], + source: 'apache', + }, + 'application/x-msbinder': { + extensions: ['obd'], + source: 'apache', + }, + 'application/x-mscardfile': { + extensions: ['crd'], + source: 'apache', + }, + 'application/x-msclip': { + extensions: ['clp'], + source: 'apache', + }, + 'application/x-msdownload': { + extensions: ['exe', 'dll', 'com', 'bat', 'msi'], + source: 'apache', + }, + 'application/x-msmediaview': { + extensions: ['mvb', 'm13', 'm14'], + source: 'apache', + }, + 'application/x-msmetafile': { + extensions: ['wmf', 'wmz', 'emf', 'emz'], + source: 'apache', + }, + 'application/x-msmoney': { + extensions: ['mny'], + source: 'apache', + }, + 'application/x-mspublisher': { + extensions: ['pub'], + source: 'apache', + }, + 'application/x-msschedule': { + extensions: ['scd'], + source: 'apache', + }, + 'application/x-msterminal': { + extensions: ['trm'], + source: 'apache', + }, + 'application/x-mswrite': { + extensions: ['wri'], + source: 'apache', + }, + 'application/x-netcdf': { + extensions: ['nc', 'cdf'], + source: 'apache', + }, + 'application/x-nzb': { + extensions: ['nzb'], + source: 'apache', + }, + 'application/x-perl': { + extensions: ['pl', 'pm'], + source: 'nginx', + }, + 'application/x-pilot': { + extensions: ['prc', 'pdb'], + source: 'nginx', + }, + 'application/x-pkcs7-certificates': { + extensions: ['p7b', 'spc'], + source: 'apache', + }, + 'application/x-pkcs7-certreqresp': { + extensions: ['p7r'], + source: 'apache', + }, + 'application/x-pkcs12': { + extensions: ['p12', 'pfx'], + source: 'apache', + }, + 'application/x-rar-compressed': { + extensions: ['rar'], + source: 'apache', + }, + 'application/x-redhat-package-manager': { + extensions: ['rpm'], + source: 'nginx', + }, + 'application/x-research-info-systems': { + extensions: ['ris'], + source: 'apache', + }, + 'application/x-sea': { + extensions: ['sea'], + source: 'nginx', + }, + 'application/x-sh': { + extensions: ['sh'], + source: 'apache', + }, + 'application/x-shar': { + extensions: ['shar'], + source: 'apache', + }, + 'application/x-shockwave-flash': { + extensions: ['swf'], + source: 'apache', + }, + 'application/x-silverlight-app': { + extensions: ['xap'], + source: 'apache', + }, + 'application/x-sql': { + extensions: ['sql'], + source: 'apache', + }, + 'application/x-stuffit': { + extensions: ['sit'], + source: 'apache', + }, + 'application/x-stuffitx': { + extensions: ['sitx'], + source: 'apache', + }, + 'application/x-subrip': { + extensions: ['srt'], + source: 'apache', + }, + 'application/x-sv4cpio': { + extensions: ['sv4cpio'], + source: 'apache', + }, + 'application/x-sv4crc': { + extensions: ['sv4crc'], + source: 'apache', + }, + 'application/x-t3vm-image': { + extensions: ['t3'], + source: 'apache', + }, + 'application/x-tads': { + extensions: ['gam'], + source: 'apache', + }, + 'application/x-tar': { + extensions: ['tar'], + source: 'apache', + }, + 'application/x-tcl': { + extensions: ['tcl', 'tk'], + source: 'apache', + }, + 'application/x-tex': { + extensions: ['tex'], + source: 'apache', + }, + 'application/x-tex-tfm': { + extensions: ['tfm'], + source: 'apache', + }, + 'application/x-texinfo': { + extensions: ['texinfo', 'texi'], + source: 'apache', + }, + 'application/x-tgif': { + extensions: ['obj'], + source: 'apache', + }, + 'application/x-ustar': { + extensions: ['ustar'], + source: 'apache', + }, + 'application/x-wais-source': { + extensions: ['src'], + source: 'apache', + }, + 'application/x-x509-ca-cert': { + extensions: ['der', 'crt', 'pem'], + source: 'iana', + }, + 'application/x-xfig': { + extensions: ['fig'], + source: 'apache', + }, + 'application/x-xliff+xml': { + extensions: ['xlf'], + source: 'apache', + }, + 'application/x-xpinstall': { + extensions: ['xpi'], + source: 'apache', + }, + 'application/x-xz': { + extensions: ['xz'], + source: 'apache', + }, + 'application/x-zmachine': { + extensions: ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'], + source: 'apache', + }, + 'application/xaml+xml': { + extensions: ['xaml'], + source: 'apache', + }, + 'application/xcap-att+xml': { + extensions: ['xav'], + source: 'iana', + }, + 'application/xcap-caps+xml': { + extensions: ['xca'], + source: 'iana', + }, + 'application/xcap-diff+xml': { + extensions: ['xdf'], + source: 'iana', + }, + 'application/xcap-el+xml': { + extensions: ['xel'], + source: 'iana', + }, + 'application/xcap-ns+xml': { + extensions: ['xns'], + source: 'iana', + }, + 'application/xenc+xml': { + extensions: ['xenc'], + source: 'iana', + }, + 'application/xhtml+xml': { + extensions: ['xhtml', 'xht'], + source: 'iana', + }, + 'application/xliff+xml': { + extensions: ['xlf'], + source: 'iana', + }, + 'application/xml': { + extensions: ['xml', 'xsl', 'xsd', 'rng'], + source: 'iana', + }, + 'application/xml-dtd': { + extensions: ['dtd'], + source: 'iana', + }, + 'application/xop+xml': { + extensions: ['xop'], + source: 'iana', + }, + 'application/xproc+xml': { + extensions: ['xpl'], + source: 'apache', + }, + 'application/xslt+xml': { + extensions: ['xsl', 'xslt'], + source: 'iana', + }, + 'application/xspf+xml': { + extensions: ['xspf'], + source: 'apache', + }, + 'application/xv+xml': { + extensions: ['mxml', 'xhvml', 'xvml', 'xvm'], + source: 'iana', + }, + 'application/yaml': { + extensions: ['yaml', 'yml'], + source: 'iana', + }, + 'application/yang': { + extensions: ['yang'], + source: 'iana', + }, + 'application/yin+xml': { + extensions: ['yin'], + source: 'iana', + }, + 'application/zip': { + extensions: ['zip'], + source: 'iana', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/audio.ts b/packages/media/src/react/placeholder/internal/audio.ts new file mode 100644 index 0000000000..f017c26729 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/audio.ts @@ -0,0 +1,154 @@ +export const audio = { + 'audio/3gpp': { + extensions: ['3gpp'], + source: 'iana', + }, + 'audio/adpcm': { + extensions: ['adp'], + source: 'apache', + }, + 'audio/amr': { + extensions: ['amr'], + source: 'iana', + }, + 'audio/basic': { + extensions: ['au', 'snd'], + source: 'iana', + }, + 'audio/midi': { + extensions: ['mid', 'midi', 'kar', 'rmi'], + source: 'apache', + }, + 'audio/mobile-xmf': { + extensions: ['mxmf'], + source: 'iana', + }, + 'audio/mp4': { + extensions: ['m4a', 'mp4a'], + source: 'iana', + }, + 'audio/mpeg': { + extensions: ['mpga', 'mp2', 'mp2a', 'mp3', 'm2a', 'm3a'], + source: 'iana', + }, + 'audio/ogg': { + extensions: ['oga', 'ogg', 'spx', 'opus'], + source: 'iana', + }, + 'audio/s3m': { + extensions: ['s3m'], + source: 'apache', + }, + 'audio/silk': { + extensions: ['sil'], + source: 'apache', + }, + 'audio/vnd.dece.audio': { + extensions: ['uva', 'uvva'], + source: 'iana', + }, + 'audio/vnd.digital-winds': { + extensions: ['eol'], + source: 'iana', + }, + 'audio/vnd.dra': { + extensions: ['dra'], + source: 'iana', + }, + 'audio/vnd.dts': { + extensions: ['dts'], + source: 'iana', + }, + 'audio/vnd.dts.hd': { + extensions: ['dtshd'], + source: 'iana', + }, + 'audio/vnd.lucent.voice': { + extensions: ['lvp'], + source: 'iana', + }, + 'audio/vnd.ms-playready.media.pya': { + extensions: ['pya'], + source: 'iana', + }, + 'audio/vnd.nuera.ecelp4800': { + extensions: ['ecelp4800'], + source: 'iana', + }, + 'audio/vnd.nuera.ecelp7470': { + extensions: ['ecelp7470'], + source: 'iana', + }, + 'audio/vnd.nuera.ecelp9600': { + extensions: ['ecelp9600'], + source: 'iana', + }, + 'audio/vnd.rip': { + extensions: ['rip'], + source: 'iana', + }, + 'audio/webm': { + extensions: ['weba'], + source: 'apache', + }, + 'audio/x-aac': { + extensions: ['aac'], + source: 'apache', + }, + 'audio/x-aiff': { + extensions: ['aif', 'aiff', 'aifc'], + source: 'apache', + }, + 'audio/x-caf': { + extensions: ['caf'], + source: 'apache', + }, + 'audio/x-flac': { + extensions: ['flac'], + source: 'apache', + }, + 'audio/x-gsm': { + extensions: ['gsm'], + source: 'apache', + }, + 'audio/x-m4a': { + extensions: ['m4a'], + source: 'nginx', + }, + 'audio/x-matroska': { + extensions: ['mka'], + source: 'apache', + }, + 'audio/x-mpegurl': { + extensions: ['m3u'], + source: 'apache', + }, + 'audio/x-ms-wax': { + extensions: ['wax'], + source: 'apache', + }, + 'audio/x-ms-wma': { + extensions: ['wma'], + source: 'apache', + }, + 'audio/x-pn-realaudio': { + extensions: ['ram', 'ra'], + source: 'apache', + }, + 'audio/x-pn-realaudio-plugin': { + extensions: ['rmp'], + source: 'apache', + }, + 'audio/x-realaudio': { + extensions: ['ra'], + source: 'nginx', + }, + 'audio/x-wav': { + extensions: ['wav'], + source: 'apache', + }, + 'audio/xm': { + extensions: ['xm'], + source: 'apache', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/image.ts b/packages/media/src/react/placeholder/internal/image.ts new file mode 100644 index 0000000000..a2b3e69a49 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/image.ts @@ -0,0 +1,342 @@ +export const image = { + 'image/aces': { + extensions: ['exr'], + source: 'iana', + }, + 'image/avci': { + extensions: ['avci'], + source: 'iana', + }, + 'image/avcs': { + extensions: ['avcs'], + source: 'iana', + }, + 'image/avif': { + extensions: ['avif'], + source: 'iana', + }, + 'image/bmp': { + extensions: ['bmp'], + source: 'iana', + }, + 'image/cgm': { + extensions: ['cgm'], + source: 'iana', + }, + 'image/dicom-rle': { + extensions: ['drle'], + source: 'iana', + }, + 'image/emf': { + extensions: ['emf'], + source: 'iana', + }, + 'image/fits': { + extensions: ['fits'], + source: 'iana', + }, + 'image/g3fax': { + extensions: ['g3'], + source: 'iana', + }, + 'image/gif': { + extensions: ['gif'], + source: 'iana', + }, + 'image/heic': { + extensions: ['heic'], + source: 'iana', + }, + 'image/heic-sequence': { + extensions: ['heics'], + source: 'iana', + }, + 'image/heif': { + extensions: ['heif'], + source: 'iana', + }, + 'image/heif-sequence': { + extensions: ['heifs'], + source: 'iana', + }, + 'image/hej2k': { + extensions: ['hej2'], + source: 'iana', + }, + 'image/hsj2': { + extensions: ['hsj2'], + source: 'iana', + }, + 'image/ief': { + extensions: ['ief'], + source: 'iana', + }, + 'image/jls': { + extensions: ['jls'], + source: 'iana', + }, + 'image/jp2': { + extensions: ['jp2', 'jpg2'], + source: 'iana', + }, + 'image/jpeg': { + extensions: ['jpeg', 'jpg', 'jpe', 'jfif', 'pjpeg', 'pjp'], + source: 'iana', + }, + 'image/jph': { + extensions: ['jph'], + source: 'iana', + }, + 'image/jphc': { + extensions: ['jhc'], + source: 'iana', + }, + 'image/jpm': { + extensions: ['jpm'], + source: 'iana', + }, + 'image/jpx': { + extensions: ['jpx', 'jpf'], + source: 'iana', + }, + 'image/jxr': { + extensions: ['jxr'], + source: 'iana', + }, + 'image/jxra': { + extensions: ['jxra'], + source: 'iana', + }, + 'image/jxrs': { + extensions: ['jxrs'], + source: 'iana', + }, + 'image/jxs': { + extensions: ['jxs'], + source: 'iana', + }, + 'image/jxsc': { + extensions: ['jxsc'], + source: 'iana', + }, + 'image/jxsi': { + extensions: ['jxsi'], + source: 'iana', + }, + 'image/jxss': { + extensions: ['jxss'], + source: 'iana', + }, + 'image/ktx': { + extensions: ['ktx'], + source: 'iana', + }, + 'image/ktx2': { + extensions: ['ktx2'], + source: 'iana', + }, + 'image/png': { + extensions: ['png'], + source: 'iana', + }, + 'image/prs.btif': { + extensions: ['btif'], + source: 'iana', + }, + 'image/prs.pti': { + extensions: ['pti'], + source: 'iana', + }, + 'image/sgi': { + extensions: ['sgi'], + source: 'apache', + }, + 'image/svg+xml': { + extensions: ['svg', 'svgz'], + source: 'iana', + }, + 'image/t38': { + extensions: ['t38'], + source: 'iana', + }, + 'image/tiff': { + extensions: ['tif', 'tiff'], + source: 'iana', + }, + 'image/tiff-fx': { + extensions: ['tfx'], + source: 'iana', + }, + 'image/vnd.adobe.photoshop': { + extensions: ['psd'], + source: 'iana', + }, + 'image/vnd.airzip.accelerator.azv': { + extensions: ['azv'], + source: 'iana', + }, + 'image/vnd.dece.graphic': { + extensions: ['uvi', 'uvvi', 'uvg', 'uvvg'], + source: 'iana', + }, + 'image/vnd.djvu': { + extensions: ['djvu', 'djv'], + source: 'iana', + }, + 'image/vnd.dvb.subtitle': { + extensions: ['sub'], + source: 'iana', + }, + 'image/vnd.dwg': { + extensions: ['dwg'], + source: 'iana', + }, + 'image/vnd.dxf': { + extensions: ['dxf'], + source: 'iana', + }, + 'image/vnd.fastbidsheet': { + extensions: ['fbs'], + source: 'iana', + }, + 'image/vnd.fpx': { + extensions: ['fpx'], + source: 'iana', + }, + 'image/vnd.fst': { + extensions: ['fst'], + source: 'iana', + }, + 'image/vnd.fujixerox.edmics-mmr': { + extensions: ['mmr'], + source: 'iana', + }, + 'image/vnd.fujixerox.edmics-rlc': { + extensions: ['rlc'], + source: 'iana', + }, + 'image/vnd.microsoft.icon': { + extensions: ['ico'], + source: 'iana', + }, + 'image/vnd.ms-modi': { + extensions: ['mdi'], + source: 'iana', + }, + 'image/vnd.ms-photo': { + extensions: ['wdp'], + source: 'apache', + }, + 'image/vnd.net-fpx': { + extensions: ['npx'], + source: 'iana', + }, + 'image/vnd.pco.b16': { + extensions: ['b16'], + source: 'iana', + }, + 'image/vnd.tencent.tap': { + extensions: ['tap'], + source: 'iana', + }, + 'image/vnd.valve.source.texture': { + extensions: ['vtf'], + source: 'iana', + }, + 'image/vnd.wap.wbmp': { + extensions: ['wbmp'], + source: 'iana', + }, + 'image/vnd.xiff': { + extensions: ['xif'], + source: 'iana', + }, + 'image/vnd.zbrush.pcx': { + extensions: ['pcx'], + source: 'iana', + }, + 'image/webp': { + extensions: ['webp'], + source: 'apache', + }, + 'image/wmf': { + extensions: ['wmf'], + source: 'iana', + }, + 'image/x-3ds': { + extensions: ['3ds'], + source: 'apache', + }, + 'image/x-cmu-raster': { + extensions: ['ras'], + source: 'apache', + }, + 'image/x-cmx': { + extensions: ['cmx'], + source: 'apache', + }, + 'image/x-freehand': { + extensions: ['fh', 'fhc', 'fh4', 'fh5', 'fh7'], + source: 'apache', + }, + 'image/x-icon': { + extensions: ['ico'], + source: 'apache', + }, + 'image/x-jng': { + extensions: ['jng'], + source: 'nginx', + }, + 'image/x-mrsid-image': { + extensions: ['sid'], + source: 'apache', + }, + 'image/x-ms-bmp': { + extensions: ['bmp'], + source: 'nginx', + }, + 'image/x-pcx': { + extensions: ['pcx'], + source: 'apache', + }, + 'image/x-pict': { + extensions: ['pic', 'pct'], + source: 'apache', + }, + 'image/x-portable-anymap': { + extensions: ['pnm'], + source: 'apache', + }, + 'image/x-portable-bitmap': { + extensions: ['pbm'], + source: 'apache', + }, + 'image/x-portable-graymap': { + extensions: ['pgm'], + source: 'apache', + }, + 'image/x-portable-pixmap': { + extensions: ['ppm'], + source: 'apache', + }, + 'image/x-rgb': { + extensions: ['rgb'], + source: 'apache', + }, + 'image/x-tga': { + extensions: ['tga'], + source: 'apache', + }, + 'image/x-xbitmap': { + extensions: ['xbm'], + source: 'apache', + }, + 'image/x-xpixmap': { + extensions: ['xpm'], + source: 'apache', + }, + 'image/x-xwindowdump': { + extensions: ['xwd'], + source: 'apache', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/mimes.ts b/packages/media/src/react/placeholder/internal/mimes.ts new file mode 100644 index 0000000000..9f1c1695c9 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/mimes.ts @@ -0,0 +1,32 @@ +import { application } from '../internal/application'; +import { audio } from '../internal/audio'; +import { image } from '../internal/image'; +import { misc } from '../internal/misc'; +import { video } from '../internal/video'; +import { text } from './text'; + +export const mimes = { + ...application, + ...audio, + ...image, + ...text, + ...video, + ...misc, +}; + +export type MimeType = keyof typeof mimes; + +export type FileExtension = (typeof mimes)[MimeType]['extensions'][number]; + +export const ALLOWED_FILE_TYPES = [ + 'image', + 'video', + 'audio', + 'pdf', + 'text', + 'blob', +] as const; + +export type AllowedFileType = (typeof ALLOWED_FILE_TYPES)[number]; + +export type FileRouterInputKey = AllowedFileType | MimeType; diff --git a/packages/media/src/react/placeholder/internal/misc.ts b/packages/media/src/react/placeholder/internal/misc.ts new file mode 100644 index 0000000000..2d8f15bbc5 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/misc.ts @@ -0,0 +1,199 @@ +/** Random types not worthy of their own file */ +export const misc = { + 'chemical/x-cdx': { + extensions: ['cdx'], + source: 'apache', + }, + 'chemical/x-cif': { + extensions: ['cif'], + source: 'apache', + }, + 'chemical/x-cmdf': { + extensions: ['cmdf'], + source: 'apache', + }, + 'chemical/x-cml': { + extensions: ['cml'], + source: 'apache', + }, + 'chemical/x-csml': { + extensions: ['csml'], + source: 'apache', + }, + 'chemical/x-xyz': { + extensions: ['xyz'], + source: 'apache', + }, + 'font/collection': { + extensions: ['ttc'], + source: 'iana', + }, + 'font/otf': { + extensions: ['otf'], + source: 'iana', + }, + 'font/ttf': { + extensions: ['ttf'], + source: 'iana', + }, + 'font/woff': { + extensions: ['woff'], + source: 'iana', + }, + 'font/woff2': { + extensions: ['woff2'], + source: 'iana', + }, + 'message/disposition-notification': { + extensions: ['disposition-notification'], + source: 'iana', + }, + 'message/global': { + extensions: ['u8msg'], + source: 'iana', + }, + 'message/global-delivery-status': { + extensions: ['u8dsn'], + source: 'iana', + }, + 'message/global-disposition-notification': { + extensions: ['u8mdn'], + source: 'iana', + }, + 'message/global-headers': { + extensions: ['u8hdr'], + source: 'iana', + }, + 'message/rfc822': { + extensions: ['eml', 'mime'], + source: 'iana', + }, + 'message/vnd.wfa.wsc': { + extensions: ['wsc'], + source: 'iana', + }, + 'model/3mf': { + extensions: ['3mf'], + source: 'iana', + }, + 'model/gltf+json': { + extensions: ['gltf'], + source: 'iana', + }, + 'model/gltf-binary': { + extensions: ['glb'], + source: 'iana', + }, + 'model/iges': { + extensions: ['igs', 'iges'], + source: 'iana', + }, + 'model/mesh': { + extensions: ['msh', 'mesh', 'silo'], + source: 'iana', + }, + 'model/mtl': { + extensions: ['mtl'], + source: 'iana', + }, + 'model/obj': { + extensions: ['obj'], + source: 'iana', + }, + 'model/step': { + extensions: ['.p21', '.stp', '.step', '.stpnc', '.210'], + source: 'iana', + }, + 'model/step+xml': { + extensions: ['stpx'], + source: 'iana', + }, + 'model/step+zip': { + extensions: ['stpz'], + source: 'iana', + }, + 'model/step-xml+zip': { + extensions: ['stpxz'], + source: 'iana', + }, + 'model/stl': { + extensions: ['stl'], + source: 'iana', + }, + 'model/vnd.collada+xml': { + extensions: ['dae'], + source: 'iana', + }, + 'model/vnd.dwf': { + extensions: ['dwf'], + source: 'iana', + }, + 'model/vnd.gdl': { + extensions: ['gdl'], + source: 'iana', + }, + 'model/vnd.gtw': { + extensions: ['gtw'], + source: 'iana', + }, + 'model/vnd.mts': { + extensions: ['mts'], + source: 'iana', + }, + 'model/vnd.opengex': { + extensions: ['ogex'], + source: 'iana', + }, + 'model/vnd.parasolid.transmit.binary': { + extensions: ['x_b'], + source: 'iana', + }, + 'model/vnd.parasolid.transmit.text': { + extensions: ['x_t'], + source: 'iana', + }, + 'model/vnd.sap.vds': { + extensions: ['vds'], + source: 'iana', + }, + 'model/vnd.usdz+zip': { + extensions: ['usdz'], + source: 'iana', + }, + 'model/vnd.valve.source.compiled-map': { + extensions: ['bsp'], + source: 'iana', + }, + 'model/vnd.vtu': { + extensions: ['vtu'], + source: 'iana', + }, + 'model/vrml': { + extensions: ['wrl', 'vrml'], + source: 'iana', + }, + 'model/x3d+binary': { + extensions: ['x3db', 'x3dbz'], + source: 'apache', + }, + 'model/x3d+fastinfoset': { + extensions: ['x3db'], + source: 'iana', + }, + 'model/x3d+vrml': { + extensions: ['x3dv', 'x3dvz'], + source: 'apache', + }, + 'model/x3d+xml': { + extensions: ['x3d', 'x3dz'], + source: 'iana', + }, + 'model/x3d-vrml': { + extensions: ['x3dv'], + source: 'iana', + }, + 'x-conference/x-cooltalk': { + extensions: ['ice'], + source: 'apache', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/text.ts b/packages/media/src/react/placeholder/internal/text.ts new file mode 100644 index 0000000000..bb1c17a185 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/text.ts @@ -0,0 +1,204 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ +export const text = { + 'text/cache-manifest': { + extensions: ['appcache', 'manifest'], + source: 'iana', + }, + 'text/calendar': { + extensions: ['ics', 'ifb'], + source: 'iana', + }, + 'text/css': { + charset: 'UTF-8', + extensions: ['css'], + source: 'iana', + }, + 'text/csv': { + extensions: ['csv'], + source: 'iana', + }, + 'text/html': { + extensions: ['html', 'htm', 'shtml'], + source: 'iana', + }, + 'text/markdown': { + extensions: ['markdown', 'md'], + source: 'iana', + }, + 'text/mathml': { + extensions: ['mml'], + source: 'nginx', + }, + 'text/n3': { + charset: 'UTF-8', + extensions: ['n3'], + source: 'iana', + }, + 'text/plain': { + extensions: ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini'], + source: 'iana', + }, + 'text/prs.lines.tag': { + extensions: ['dsc'], + source: 'iana', + }, + 'text/richtext': { + extensions: ['rtx'], + source: 'iana', + }, + 'text/rtf': { + extensions: ['rtf'], + source: 'iana', + }, + 'text/sgml': { + extensions: ['sgml', 'sgm'], + source: 'iana', + }, + 'text/shex': { + extensions: ['shex'], + source: 'iana', + }, + 'text/spdx': { + extensions: ['spdx'], + source: 'iana', + }, + 'text/tab-separated-values': { + extensions: ['tsv'], + source: 'iana', + }, + 'text/troff': { + extensions: ['t', 'tr', 'roff', 'man', 'me', 'ms'], + source: 'iana', + }, + 'text/turtle': { + charset: 'UTF-8', + extensions: ['ttl'], + source: 'iana', + }, + 'text/uri-list': { + extensions: ['uri', 'uris', 'urls'], + source: 'iana', + }, + 'text/vcard': { + extensions: ['vcard'], + source: 'iana', + }, + 'text/vnd.curl': { + extensions: ['curl'], + source: 'iana', + }, + 'text/vnd.curl.dcurl': { + extensions: ['dcurl'], + source: 'apache', + }, + 'text/vnd.curl.mcurl': { + extensions: ['mcurl'], + source: 'apache', + }, + 'text/vnd.curl.scurl': { + extensions: ['scurl'], + source: 'apache', + }, + 'text/vnd.dvb.subtitle': { + extensions: ['sub'], + source: 'iana', + }, + 'text/vnd.familysearch.gedcom': { + extensions: ['ged'], + source: 'iana', + }, + 'text/vnd.fly': { + extensions: ['fly'], + source: 'iana', + }, + 'text/vnd.fmi.flexstor': { + extensions: ['flx'], + source: 'iana', + }, + 'text/vnd.graphviz': { + extensions: ['gv'], + source: 'iana', + }, + 'text/vnd.in3d.3dml': { + extensions: ['3dml'], + source: 'iana', + }, + 'text/vnd.in3d.spot': { + extensions: ['spot'], + source: 'iana', + }, + 'text/vnd.sun.j2me.app-descriptor': { + charset: 'UTF-8', + extensions: ['jad'], + source: 'iana', + }, + 'text/vnd.wap.wml': { + extensions: ['wml'], + source: 'iana', + }, + 'text/vnd.wap.wmlscript': { + extensions: ['wmls'], + source: 'iana', + }, + 'text/vtt': { + charset: 'UTF-8', + extensions: ['vtt'], + source: 'iana', + }, + 'text/x-asm': { + extensions: ['s', 'asm'], + source: 'apache', + }, + 'text/x-c': { + extensions: ['c', 'cc', 'cxx', 'cpp', 'h', 'hh', 'dic'], + source: 'apache', + }, + 'text/x-component': { + extensions: ['htc'], + source: 'nginx', + }, + 'text/x-fortran': { + extensions: ['f', 'for', 'f77', 'f90'], + source: 'apache', + }, + 'text/x-java-source': { + extensions: ['java'], + source: 'apache', + }, + 'text/x-nfo': { + extensions: ['nfo'], + source: 'apache', + }, + 'text/x-opml': { + extensions: ['opml'], + source: 'apache', + }, + 'text/x-pascal': { + extensions: ['p', 'pas'], + source: 'apache', + }, + 'text/x-setext': { + extensions: ['etx'], + source: 'apache', + }, + 'text/x-sfv': { + extensions: ['sfv'], + source: 'apache', + }, + 'text/x-uuencode': { + extensions: ['uu'], + source: 'apache', + }, + 'text/x-vcalendar': { + extensions: ['vcs'], + source: 'apache', + }, + 'text/x-vcard': { + extensions: ['vcf'], + source: 'apache', + }, + 'text/xml': { + extensions: ['xml'], + source: 'iana', + }, +} as const; diff --git a/packages/media/src/react/placeholder/internal/utils.ts b/packages/media/src/react/placeholder/internal/utils.ts new file mode 100644 index 0000000000..d430f16156 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/utils.ts @@ -0,0 +1,90 @@ +import { type FileExtension, type MimeType, mimes } from './mimes'; + +/** Lookup the MIME type for a file path/extension. */ +export function lookup(path: string): MimeType | false { + if (!path || typeof path !== 'string') { + return false; + } + + // get the extension ("ext" or ".ext" or full path) + const extension = extname('x.' + path) + .toLowerCase() + .slice(1) as FileExtension; + + if (!extension) { + return false; + } + + return getTypes()[extension] || false; +} + +const extensions = {} as Record; +const types = {} as Record; + +export function getTypes(): Record { + populateMaps(extensions, types); + + return types; +} + +export const mimeTypes = mimes as unknown as Record< + MimeType, + { extensions: FileExtension[]; source: string } +>; + +let inittedMaps = false; +/** + * Populate the extensions and types maps. + * + * @private + */ + +function populateMaps( + extensions: Record, + types: Record +) { + if (inittedMaps) return; + + inittedMaps = true; + // source preference (least -> most) + const preference = ['nginx', 'apache', undefined, 'iana']; + + (Object.keys(mimeTypes) as MimeType[]).forEach((type) => { + const mime = mimeTypes[type]; + const exts = mime.extensions; + + if (!exts?.length) { + return; + } + + // mime -> extensions + extensions[type] = exts; + + // extension -> mime + + for (const extension of exts) { + if (types[extension]) { + const from = preference.indexOf(mimeTypes[types[extension]].source); + const to = preference.indexOf(mime.source); + + if ( + types[extension] !== 'application/octet-stream' && + (from > to || + (from === to && types[extension].startsWith('application/'))) + ) { + // skip the remapping + continue; + } + } + + // set the extension -> mime + types[extension] = type; + } + }); +} + +function extname(path: string) { + const index = path.lastIndexOf('.'); + + return index < 0 ? '' : path.slice(Math.max(0, index)); +} diff --git a/packages/media/src/react/placeholder/internal/video.ts b/packages/media/src/react/placeholder/internal/video.ts new file mode 100644 index 0000000000..ab2f3145e6 --- /dev/null +++ b/packages/media/src/react/placeholder/internal/video.ts @@ -0,0 +1,166 @@ +export const video = { + 'video/3gpp': { + extensions: ['3gp', '3gpp'], + source: 'iana', + }, + 'video/3gpp2': { + extensions: ['3g2'], + source: 'iana', + }, + 'video/h261': { + extensions: ['h261'], + source: 'iana', + }, + 'video/h263': { + extensions: ['h263'], + source: 'iana', + }, + 'video/h264': { + extensions: ['h264'], + source: 'iana', + }, + 'video/iso.segment': { + extensions: ['m4s'], + source: 'iana', + }, + 'video/jpeg': { + extensions: ['jpgv'], + source: 'iana', + }, + 'video/jpm': { + extensions: ['jpm', 'jpgm'], + source: 'apache', + }, + 'video/mj2': { + extensions: ['mj2', 'mjp2'], + source: 'iana', + }, + 'video/mp2t': { + extensions: ['ts'], + source: 'iana', + }, + 'video/mp4': { + extensions: ['mp4', 'mp4v', 'mpg4'], + source: 'iana', + }, + 'video/mpeg': { + extensions: ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v'], + source: 'iana', + }, + 'video/ogg': { + extensions: ['ogv'], + source: 'iana', + }, + 'video/quicktime': { + extensions: ['qt', 'mov'], + source: 'iana', + }, + 'video/vnd.dece.hd': { + extensions: ['uvh', 'uvvh'], + source: 'iana', + }, + 'video/vnd.dece.mobile': { + extensions: ['uvm', 'uvvm'], + source: 'iana', + }, + 'video/vnd.dece.pd': { + extensions: ['uvp', 'uvvp'], + source: 'iana', + }, + 'video/vnd.dece.sd': { + extensions: ['uvs', 'uvvs'], + source: 'iana', + }, + 'video/vnd.dece.video': { + extensions: ['uvv', 'uvvv'], + source: 'iana', + }, + 'video/vnd.dvb.file': { + extensions: ['dvb'], + source: 'iana', + }, + 'video/vnd.fvt': { + extensions: ['fvt'], + source: 'iana', + }, + 'video/vnd.mpegurl': { + extensions: ['mxu', 'm4u'], + source: 'iana', + }, + 'video/vnd.ms-playready.media.pyv': { + extensions: ['pyv'], + source: 'iana', + }, + 'video/vnd.uvvu.mp4': { + extensions: ['uvu', 'uvvu'], + source: 'iana', + }, + 'video/vnd.vivo': { + extensions: ['viv'], + source: 'iana', + }, + 'video/webm': { + extensions: ['webm'], + source: 'apache', + }, + 'video/x-f4v': { + extensions: ['f4v'], + source: 'apache', + }, + 'video/x-fli': { + extensions: ['fli'], + source: 'apache', + }, + 'video/x-flv': { + extensions: ['flv'], + source: 'apache', + }, + 'video/x-m4v': { + extensions: ['m4v'], + source: 'apache', + }, + 'video/x-matroska': { + extensions: ['mkv', 'mk3d', 'mks'], + source: 'apache', + }, + 'video/x-mng': { + extensions: ['mng'], + source: 'apache', + }, + 'video/x-ms-asf': { + extensions: ['asf', 'asx'], + source: 'apache', + }, + 'video/x-ms-vob': { + extensions: ['vob'], + source: 'apache', + }, + 'video/x-ms-wm': { + extensions: ['wm'], + source: 'apache', + }, + 'video/x-ms-wmv': { + extensions: ['wmv'], + source: 'apache', + }, + 'video/x-ms-wmx': { + extensions: ['wmx'], + source: 'apache', + }, + 'video/x-ms-wvx': { + extensions: ['wvx'], + source: 'apache', + }, + 'video/x-msvideo': { + extensions: ['avi'], + source: 'apache', + }, + 'video/x-sgi-movie': { + extensions: ['movie'], + source: 'apache', + }, + 'video/x-smv': { + extensions: ['smv'], + source: 'apache', + }, +} as const; diff --git a/packages/media/src/react/placeholder/placeholderStore.ts b/packages/media/src/react/placeholder/placeholderStore.ts index 1513ca5b04..e9bb53eaf1 100644 --- a/packages/media/src/react/placeholder/placeholderStore.ts +++ b/packages/media/src/react/placeholder/placeholderStore.ts @@ -2,6 +2,10 @@ import { createAtomStore } from '@udecode/plate-common/react'; type Progresses = Record; interface PlaceholderStore { + size: { + height: number; + width: number; + } | null; isUploading: boolean; progresses: Progresses; updatedFiles: File[]; @@ -12,6 +16,7 @@ export const { PlaceholderProvider, placeholderStore, usePlaceholderStore } = { isUploading: false, progresses: {}, + size: null, updatedFiles: [], } as PlaceholderStore, { name: 'placeholder' } diff --git a/packages/media/src/react/placeholder/transforms/index.ts b/packages/media/src/react/placeholder/transforms/index.ts new file mode 100644 index 0000000000..790670da5a --- /dev/null +++ b/packages/media/src/react/placeholder/transforms/index.ts @@ -0,0 +1,5 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './insertMedia'; diff --git a/packages/media/src/react/placeholder/transforms/insertMedia.ts b/packages/media/src/react/placeholder/transforms/insertMedia.ts new file mode 100644 index 0000000000..9c88405b7f --- /dev/null +++ b/packages/media/src/react/placeholder/transforms/insertMedia.ts @@ -0,0 +1,65 @@ +import type { PlateEditor } from '@udecode/plate-common/react'; + +import { insertNodes, nanoid, withoutNormalizing } from '@udecode/plate-common'; + +import { type TPlaceholderElement, BasePlaceholderPlugin } from '../../../lib'; +import { PlaceholderPlugin } from '../PlaceholderPlugin'; +import { UploadErrorCode } from '../type'; +import { createUploadError, isUploadError } from '../utils/createUploadError'; +import { getMediaType } from '../utils/getMediaType'; +import { validateFiles } from '../utils/validateFiles'; + +export const insertMedia = (editor: PlateEditor, files: FileList): any => { + const api = editor.getApi(PlaceholderPlugin); + const uploadConfig = editor.getOption(PlaceholderPlugin, 'uploadConfig'); + const multiple = editor.getOption(PlaceholderPlugin, 'multiple'); + + try { + validateFiles(files, uploadConfig); + } catch (error) { + if (!isUploadError(error)) throw error; + + return editor.setOption(PlaceholderPlugin, 'error', error); + } + + if (!multiple && files.length > 1) { + return editor.setOption( + PlaceholderPlugin, + 'error', + createUploadError(UploadErrorCode.TOO_MANY_FILES, { + fileType: null, + files: Array.from(files), + maxFileCount: 1, + }) + ); + } + + const maxFileCount = editor.getOption(PlaceholderPlugin, 'maxFileCount') ?? 3; + + if (files.length > maxFileCount) { + return editor.setOption( + PlaceholderPlugin, + 'error', + createUploadError(UploadErrorCode.TOO_MANY_FILES, { + fileType: null, + files: Array.from(files), + maxFileCount, + }) + ); + } + + Array.from(files).forEach((file) => { + const id = nanoid(); + + withoutNormalizing(editor, () => + insertNodes(editor, { + id, + children: [{ text: '' }], + mediaType: getMediaType(file, uploadConfig)!, + type: editor.getType(BasePlaceholderPlugin), + }) + ); + + api.placeholder.addUploadingFile(id, file); + }); +}; diff --git a/packages/media/src/react/placeholder/type.ts b/packages/media/src/react/placeholder/type.ts new file mode 100644 index 0000000000..b3ede8acd4 --- /dev/null +++ b/packages/media/src/react/placeholder/type.ts @@ -0,0 +1,77 @@ +import type { + AudioPlugin, + FilePlugin, + ImagePlugin, + VideoPlugin, +} from '../plugins'; +import type { AllowedFileType } from './internal/mimes'; + +export enum UploadErrorCode { + INVALID_FILE_TYPE = 400, + TOO_MANY_FILES = 402, + INVALID_FILE_SIZE = 403, + TOO_LESS_FILES = 405, + TOO_LARGE = 413, +} + +export type UploadError = + | { + data: { + allowedTypes: string[]; + files: File[]; + }; + code: UploadErrorCode.INVALID_FILE_TYPE; + } + | { + data: { + fileType: AllowedFileType; + files: File[]; + maxFileSize: string; + }; + code: UploadErrorCode.TOO_LARGE; + } + | { + data: { + fileType: AllowedFileType; + files: File[]; + minFileCount: number; + }; + code: UploadErrorCode.TOO_LESS_FILES; + } + | { + data: { + fileType: AllowedFileType | null; + files: File[]; + maxFileCount: number; + }; + code: UploadErrorCode.TOO_MANY_FILES; + } + | { + data: { + files: File[]; + }; + code: UploadErrorCode.INVALID_FILE_SIZE; + }; + +export type MediaKeys = + | typeof AudioPlugin.key + | typeof FilePlugin.key + | typeof ImagePlugin.key + | typeof VideoPlugin.key; + +type PowOf2 = 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024; + +export type SizeUnit = 'B' | 'GB' | 'KB' | 'MB'; + +export type FileSize = `${PowOf2}${SizeUnit}`; + +export type MediaItemConfig = { + // The type of media that this config is for. + mediaType: MediaKeys; + // The maximum number of files of this type that can be uploaded. + maxFileCount?: number; + // The maximum file size for a file of this type. FileSize is a string that can be parsed as a number followed by a unit of measurement (B, KB, MB, or GB) + maxFileSize?: FileSize; + // The minimum number of files of this type that must be uploaded. + minFileCount?: number; +}; diff --git a/packages/media/src/react/placeholder/utils/createUploadError.ts b/packages/media/src/react/placeholder/utils/createUploadError.ts new file mode 100644 index 0000000000..a0c1c66285 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/createUploadError.ts @@ -0,0 +1,27 @@ +import type { UploadError, UploadErrorCode } from '../type'; +// 首先定义一个类型,用于获取指定错误码对应的data类型 +type ErrorDataType = Extract< + UploadError, + { code: T } +>['data']; + +// 改写createUploadError函数 +export const createUploadError = ( + code: T, + data: ErrorDataType +): UploadError => { + return { code, data } as UploadError; +}; + +export const isUploadError = (error: unknown): error is UploadError => { + return ( + typeof error === 'object' && + error !== null && + 'code' in error && + 'data' in error && + typeof error.data === 'object' && + error.data !== null && + 'files' in error.data && + Array.isArray(error.data.files) + ); +}; diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts new file mode 100644 index 0000000000..998a3100be --- /dev/null +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.spec.ts @@ -0,0 +1,66 @@ +/* eslint-disable jest/valid-expect */ +/* eslint-disable jest/no-conditional-expect */ +import { UploadErrorCode } from '../type'; +import { bytesToFileSize, fileSizeToBytes } from './fileSizeToBytes'; + +describe('fileSizeToBytes', () => { + it('should convert bytes correctly', () => { + expect(fileSizeToBytes('1B', new File([], ''))).toBe(1); + expect(fileSizeToBytes('1024B', new File([], ''))).toBe(1024); + }); + + it('should convert kilobytes correctly', () => { + expect(fileSizeToBytes('1KB', new File([], ''))).toBe(1024); + }); + + it('should convert megabytes correctly', () => { + expect(fileSizeToBytes('1MB', new File([], ''))).toBe(1_048_576); + }); + + it('should convert gigabytes correctly', () => { + expect(fileSizeToBytes('1GB', new File([], ''))).toBe(1_073_741_824); + }); + + it('should be case insensitive', () => { + expect(fileSizeToBytes('1KB', new File([], ''))).toBe(1024); + }); + + it('should handle whitespace', () => {}); + + it('should throw InvalidFileSize for invalid formats', () => { + expect(() => { + try { + fileSizeToBytes('invalid' as any, new File([], '')); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.INVALID_FILE_SIZE); + } + }); + + expect(() => { + try { + fileSizeToBytes('-1KB' as any, new File([], '')); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.INVALID_FILE_SIZE); + } + }); + }); +}); + +describe('bytesToFileSize', () => { + it('should handle zero and negative one', () => { + expect(bytesToFileSize(0)).toBe('0B'); + expect(bytesToFileSize(-1)).toBe('0B'); + }); + + it('should convert bytes to human readable format', () => { + expect(bytesToFileSize(500)).toBe('500.00B'); + expect(bytesToFileSize(1024)).toBe('1.02KB'); + expect(bytesToFileSize(1_048_576)).toBe('1.05MB'); + expect(bytesToFileSize(1_073_741_824)).toBe('1.07GB'); + }); + + it('should round to 2 decimal places', () => { + expect(bytesToFileSize(1536)).toBe('1.54KB'); + expect(bytesToFileSize(2_621_440)).toBe('2.62MB'); + }); +}); diff --git a/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts new file mode 100644 index 0000000000..48bdbe3eb6 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/fileSizeToBytes.ts @@ -0,0 +1,39 @@ +/* eslint-disable @typescript-eslint/only-throw-error */ +import { type FileSize, UploadErrorCode } from '../type'; +import { createUploadError } from './createUploadError'; + +export const FILESIZE_UNITS = ['B', 'KB', 'MB', 'GB'] as const; + +export type FileSizeUnit = (typeof FILESIZE_UNITS)[number]; + +export const fileSizeToBytes = (fileSize: FileSize, file: File): number => { + const regex = new RegExp( + `^(\\d+)(\\.\\d+)?\\s*(${FILESIZE_UNITS.join('|')})$`, + 'i' + ); + + // make sure the string is in the format of 123KB + const match = fileSize.match(regex); + + if (!match) { + throw createUploadError(UploadErrorCode.INVALID_FILE_SIZE, { + files: [file], + }); + } + + const sizeValue = Number.parseFloat(match[1]); + const sizeUnit = match[3].toUpperCase() as FileSizeUnit; + const bytes = sizeValue * Math.pow(1024, FILESIZE_UNITS.indexOf(sizeUnit)); + + return Math.floor(bytes); +}; + +export const bytesToFileSize = (bytes: number) => { + if (bytes === 0 || bytes === -1) { + return '0B'; + } + + const i = Math.floor(Math.log(bytes) / Math.log(1000)); + + return `${(bytes / Math.pow(1000, i)).toFixed(2)}${FILESIZE_UNITS[i]}`; +}; diff --git a/packages/media/src/react/placeholder/utils/getMediaType.ts b/packages/media/src/react/placeholder/utils/getMediaType.ts new file mode 100644 index 0000000000..caa374d0fb --- /dev/null +++ b/packages/media/src/react/placeholder/utils/getMediaType.ts @@ -0,0 +1,14 @@ +import type { UploadConfig } from '../PlaceholderPlugin'; +import type { AllowedFileType, FileRouterInputKey } from '../internal/mimes'; +import type { MediaItemConfig, MediaKeys } from '../type'; + +import { matchFileType } from './matchFileType'; + +export const getMediaType = (file: File, config: UploadConfig): MediaKeys => { + const type = matchFileType( + file, + Object.keys(config) as FileRouterInputKey[] + ) as AllowedFileType; + + return (config[type] as MediaItemConfig).mediaType; +}; diff --git a/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts b/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts new file mode 100644 index 0000000000..35290ae8ee --- /dev/null +++ b/packages/media/src/react/placeholder/utils/groupFilesByType.spec.ts @@ -0,0 +1,90 @@ +/* eslint-disable jest/valid-expect */ +/* eslint-disable jest/no-conditional-expect */ +import type { UploadConfig } from '../PlaceholderPlugin'; + +import { UploadErrorCode } from '../type'; +import { groupFilesByType } from './groupFilesByType'; + +describe('groupFilesByType', () => { + const createFile = (name: string, type: string): File => { + return new File([], name, { type }); + }; + + it('should group files by their types', () => { + const files = [ + createFile('image.jpg', 'image/jpeg'), + createFile('video.mp4', 'video/mp4'), + createFile('doc.pdf', 'application/pdf'), + ]; + + const fileList = { + [Symbol.iterator]: function* () { + for (let i = 0; i < this.length; i++) { + yield this.item(i); + } + }, + item: (i: number) => files[i], + length: files.length, + } as FileList; + + const config: UploadConfig = { + image: { maxFileSize: '8B', mediaType: 'img' }, + pdf: { maxFileSize: '64B', mediaType: 'file' }, + video: { maxFileSize: '1024MB', mediaType: 'video' }, + }; + + const result = groupFilesByType(fileList, config); + + expect(result.image).toHaveLength(1); + expect(result.video).toHaveLength(1); + expect(result.pdf).toHaveLength(1); + expect(result.audio).toHaveLength(0); + expect(result.blob).toHaveLength(0); + expect(result.text).toHaveLength(0); + }); + + it('should throw InvalidFileTypeError for unsupported file types', () => { + const files = [createFile('text.txt', 'text/plain')]; + const fileList = { + [Symbol.iterator]: function* () { + for (let i = 0; i < this.length; i++) { + yield this.item(i); + } + }, + item: (i: number) => files[i], + length: files.length, + } as FileList; + + const config: UploadConfig = { + image: { maxFileSize: '8MB', mediaType: 'img' }, + }; + + expect(() => { + try { + groupFilesByType(fileList, config); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.INVALID_FILE_TYPE); + } + }); + }); + + it('should accept blob type as fallback', () => { + const files = [createFile('unknown.xyz', 'application/octet-stream')]; + const fileList = { + [Symbol.iterator]: function* () { + for (let i = 0; i < this.length; i++) { + yield this.item(i); + } + }, + item: (i: number) => files[i], + length: files.length, + } as FileList; + + const config: UploadConfig = { + blob: { maxFileSize: '1024MB', mediaType: 'file' }, + }; + + const result = groupFilesByType(fileList, config); + expect(result.blob).toHaveLength(1); + }); +}); diff --git a/packages/media/src/react/placeholder/utils/groupFilesByType.ts b/packages/media/src/react/placeholder/utils/groupFilesByType.ts new file mode 100644 index 0000000000..255edec079 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/groupFilesByType.ts @@ -0,0 +1,26 @@ +import type { UploadConfig } from '../PlaceholderPlugin'; +import type { AllowedFileType } from '../internal/mimes'; + +import { matchFileType } from './matchFileType'; + +export const groupFilesByType = ( + fileList: FileList, + config: UploadConfig +): Record => { + const FileTypeMap: Record = { + audio: [], + blob: [], + image: [], + pdf: [], + text: [], + video: [], + }; + + for (const file of fileList) { + const type = matchFileType(file, Object.keys(config) as AllowedFileType[]); + + FileTypeMap[type as AllowedFileType].push(file); + } + + return FileTypeMap; +}; diff --git a/packages/media/src/react/placeholder/utils/index.ts b/packages/media/src/react/placeholder/utils/index.ts new file mode 100644 index 0000000000..1229070e05 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/index.ts @@ -0,0 +1,11 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './createUploadError'; +export * from './fileSizeToBytes'; +export * from './getMediaType'; +export * from './groupFilesByType'; +export * from './matchFileType'; +export * from './validateFileItem'; +export * from './validateFiles'; diff --git a/packages/media/src/react/placeholder/utils/matchFileType.spec.ts b/packages/media/src/react/placeholder/utils/matchFileType.spec.ts new file mode 100644 index 0000000000..3d2230f73d --- /dev/null +++ b/packages/media/src/react/placeholder/utils/matchFileType.spec.ts @@ -0,0 +1,51 @@ +/* eslint-disable jest/valid-expect */ +/* eslint-disable jest/no-conditional-expect */ +import { UploadErrorCode } from '../type'; +import { matchFileType } from './matchFileType'; + +describe('matchFileType', () => { + const createFile = (name: string, type: string): File => { + return new File([], name, { type }); + }; + + it('should return blob if no mime type and blob is allowed', () => { + const file = createFile('test.txt', ''); + expect(matchFileType(file, ['blob'])).toBe('blob'); + }); + + it('should match exact mime type if specified in allowed types', () => { + const file = createFile('test.jpg', 'image/jpeg'); + expect(matchFileType(file, ['image/jpeg'])).toBe('image/jpeg'); + }); + + it('should match general type for images', () => { + const file = createFile('test.jpg', 'image/jpeg'); + expect(matchFileType(file, ['image'])).toBe('image'); + }); + + it('should match general type for videos', () => { + const file = createFile('test.mp4', 'video/mp4'); + expect(matchFileType(file, ['video'])).toBe('video'); + }); + + it('should handle PDF files specially', () => { + const file = createFile('test.pdf', 'application/pdf'); + expect(matchFileType(file, ['pdf'])).toBe('pdf'); + }); + + it('should return blob for unsupported type if blob is allowed', () => { + const file = createFile('test.txt', 'text/plain'); + expect(matchFileType(file, ['image', 'blob'])).toBe('blob'); + }); + + it('should return InvalidFileTypeError for unsupported type if blob is not allowed', () => { + const file = createFile('test.txt', 'text/plain'); + expect(() => { + try { + matchFileType(file, ['image']); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.INVALID_FILE_TYPE); + } + }); + }); +}); diff --git a/packages/media/src/react/placeholder/utils/matchFileType.ts b/packages/media/src/react/placeholder/utils/matchFileType.ts new file mode 100644 index 0000000000..69addee6e8 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/matchFileType.ts @@ -0,0 +1,51 @@ +/* eslint-disable @typescript-eslint/only-throw-error */ +import type { AllowedFileType, FileRouterInputKey } from '../internal/mimes'; + +import { lookup } from '../internal/utils'; +import { UploadErrorCode } from '../type'; +import { createUploadError } from './createUploadError'; + +export const matchFileType = ( + file: File, + allowedTypes: FileRouterInputKey[] +): FileRouterInputKey => { + // Type might be "" if the browser doesn't recognize the mime type + const mimeType = file.type || lookup(file.name); + + if (!mimeType) { + if (allowedTypes.includes('blob')) return 'blob'; + + throw createUploadError(UploadErrorCode.INVALID_FILE_TYPE, { + allowedTypes: allowedTypes, + files: [file], + }); + } + // If the user has specified a specific mime type, use that + if ( + allowedTypes.some((type) => type.includes('/')) && + allowedTypes.includes(mimeType as FileRouterInputKey) + ) { + return mimeType as FileRouterInputKey; + } + + // Otherwise, we have a "magic" type eg. "image" or "video" + const type = ( + mimeType.toLowerCase() === 'application/pdf' + ? 'pdf' + : mimeType.split('/')[0] + ) as AllowedFileType; + + if (!allowedTypes.includes(type)) { + // Blob is a catch-all for any file type not explicitly supported + if (allowedTypes.includes('blob')) { + return 'blob'; + } else { + throw createUploadError(UploadErrorCode.INVALID_FILE_TYPE, { + allowedTypes: allowedTypes, + files: [file], + }); + } + } + + return type; +}; diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts b/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts new file mode 100644 index 0000000000..d500fdd053 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/validateFileItem.spec.ts @@ -0,0 +1,70 @@ +/* eslint-disable jest/valid-expect */ +/* eslint-disable jest/no-conditional-expect */ +import { type MediaItemConfig, UploadErrorCode } from '../type'; +import { validateFileItem } from './validateFileItem'; + +describe('validateFileItem', () => { + const createFile = (name: string, size = 0): File => { + const file = new File([''], name, { type: '' }); + Object.defineProperty(file, 'size', { value: size }); + + return file; + }; + + it('should validate files within constraints', () => { + const files = [createFile('test.jpg', 500)]; + const config: MediaItemConfig = { + maxFileSize: '1KB', + mediaType: 'img', + }; + + expect(validateFileItem(files, config, 'image')).toBe(true); + }); + + it('should throw MaxFileCountExceeded when files exceed maximum', () => { + const files = [ + createFile('test1.jpg', 500), + createFile('test2.jpg', 500), + createFile('test3.jpg', 500), + ]; + const config: MediaItemConfig = { + maxFileCount: 2, + maxFileSize: '1KB', + mediaType: 'img', + }; + + expect(() => { + try { + validateFileItem(files, config, 'image'); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.TOO_MANY_FILES); + } + }); + }); + + it('should throw MaxFileSizeExceeded when any file exceeds size limit', () => { + const files = [createFile('test.jpg', 2048)]; + const config: MediaItemConfig = { + maxFileSize: '1KB', + mediaType: 'img', + }; + + expect(() => { + try { + validateFileItem(files, config, 'image'); + } catch (error: any) { + expect(error.code).toBe(UploadErrorCode.TOO_LARGE); + } + }); + }); + + it('should use default values for min and max file count', () => { + const files = [createFile('test.jpg', 500)]; + const config: MediaItemConfig = { + maxFileSize: '1KB', + mediaType: 'img', + }; + + expect(validateFileItem(files, config, 'image')).toBe(true); + }); +}); diff --git a/packages/media/src/react/placeholder/utils/validateFileItem.ts b/packages/media/src/react/placeholder/utils/validateFileItem.ts new file mode 100644 index 0000000000..42b94a97dc --- /dev/null +++ b/packages/media/src/react/placeholder/utils/validateFileItem.ts @@ -0,0 +1,40 @@ +/* eslint-disable @typescript-eslint/only-throw-error */ +import type { AllowedFileType } from '../internal/mimes'; + +import { type FileSize, type MediaItemConfig, UploadErrorCode } from '../type'; +import { createUploadError } from './createUploadError'; +import { bytesToFileSize, fileSizeToBytes } from './fileSizeToBytes'; + +export const validateFileItem = ( + files: File[], + config: MediaItemConfig, + key: AllowedFileType +): UploadErrorCode | true => { + const { maxFileCount = Infinity, maxFileSize, minFileCount = 1 } = config; + + if (files.length < minFileCount) + throw createUploadError(UploadErrorCode.TOO_LESS_FILES, { + fileType: key, + files: files, + minFileCount: minFileCount, + }); + if (files.length > maxFileCount) + throw createUploadError(UploadErrorCode.TOO_MANY_FILES, { + fileType: key, + files: files, + maxFileCount: maxFileCount, + }); + + for (const f of files) { + const bytes = fileSizeToBytes(maxFileSize as FileSize, f); + + if (f.size > bytes) + throw createUploadError(UploadErrorCode.TOO_LARGE, { + fileType: key, + files: [f], + maxFileSize: bytesToFileSize(bytes), + }); + } + + return true; +}; diff --git a/packages/media/src/react/placeholder/utils/validateFiles.ts b/packages/media/src/react/placeholder/utils/validateFiles.ts new file mode 100644 index 0000000000..7baf85c8f1 --- /dev/null +++ b/packages/media/src/react/placeholder/utils/validateFiles.ts @@ -0,0 +1,22 @@ +/* eslint-disable @typescript-eslint/only-throw-error */ +import type { UploadConfig } from '../PlaceholderPlugin'; +import type { AllowedFileType } from '../internal/mimes'; + +import { groupFilesByType } from './groupFilesByType'; +import { validateFileItem } from './validateFileItem'; + +export const validateFiles = (fileList: FileList, config: UploadConfig) => { + const fileTypeMap = groupFilesByType(fileList, config); + + const keys = Object.keys(fileTypeMap) as AllowedFileType[]; + + for (const key of keys) { + const itemConfig = config[key]; + + const itemFiles = fileTypeMap[key]; + + if (itemFiles.length === 0) continue; + + validateFileItem(itemFiles, itemConfig!, key); + } +}; diff --git a/packages/plate-utils/src/react/index.ts b/packages/plate-utils/src/react/index.ts index d6d440093d..e470d2d827 100644 --- a/packages/plate-utils/src/react/index.ts +++ b/packages/plate-utils/src/react/index.ts @@ -6,8 +6,8 @@ export * from './PlateElement'; export * from './PlateLeaf'; export * from './createNodeHOC'; export * from './createNodesHOC'; -export * from './selectSiblingNodePoint'; export * from './selectEditor'; +export * from './selectSiblingNodePoint'; export * from './useFormInputProps'; export * from './useMarkToolbarButton'; export * from './usePlaceholder'; diff --git a/packages/react-utils/src/index.ts b/packages/react-utils/src/index.ts index f32b143810..e6174df0a5 100644 --- a/packages/react-utils/src/index.ts +++ b/packages/react-utils/src/index.ts @@ -3,9 +3,9 @@ */ export * from './Box'; +export * from './MemoizedChildren'; export * from './PortalBody'; export * from './Text'; -export * from './MemoizedChildren'; export * from './composeEventHandlers'; export * from './createPrimitiveComponent'; export * from './createPrimitiveElement'; diff --git a/packages/selection/src/react/transforms/index.ts b/packages/selection/src/react/transforms/index.ts index d50706e0fd..6319706f37 100644 --- a/packages/selection/src/react/transforms/index.ts +++ b/packages/selection/src/react/transforms/index.ts @@ -3,6 +3,7 @@ */ export * from './duplicateBlockSelectionNodes'; +export * from './insertBlocksAndSelect'; export * from './removeBlockSelectionNodes'; export * from './selectBlockSelectionNodes'; export * from './setBlockSelectionNodes'; diff --git a/packages/slate/src/index.ts b/packages/slate/src/index.ts index d27f49f961..33ca390098 100644 --- a/packages/slate/src/index.ts +++ b/packages/slate/src/index.ts @@ -5,7 +5,7 @@ export * from './createTEditor'; export * from './interfaces/index'; export * from './queries/index'; +export * from './slate-history/index'; export * from './transforms/index'; export type * from './types/index'; export * from './utils/index'; -export * from './slate-history'; \ No newline at end of file diff --git a/packages/slate/src/interfaces/history-editor/index.ts b/packages/slate/src/interfaces/history-editor/index.ts index 4c2aeafd9e..651e7ba5da 100644 --- a/packages/slate/src/interfaces/history-editor/index.ts +++ b/packages/slate/src/interfaces/history-editor/index.ts @@ -6,6 +6,6 @@ export * from './isHistoryEditor'; export * from './isHistoryMerging'; export * from './isHistorySaving'; export * from './withMerging'; +export * from './withNewBatch'; export * from './withoutMergingHistory'; export * from './withoutSavingHistory'; -export * from './withNewBatch'; diff --git a/packages/slate/src/slate-history/index.ts b/packages/slate/src/slate-history/index.ts index 4dc515690e..487b83720c 100644 --- a/packages/slate/src/slate-history/index.ts +++ b/packages/slate/src/slate-history/index.ts @@ -1,3 +1,7 @@ -export * from './history' -export * from './history-editor' -export * from './with-history' +/** + * @file Automatically generated by barrelsby. + */ + +export * from './history-editor'; +export * from './history'; +export * from './with-history';