diff --git a/.changeset/lovely-weeks-act.md b/.changeset/lovely-weeks-act.md new file mode 100644 index 0000000000..4ffb994ec2 --- /dev/null +++ b/.changeset/lovely-weeks-act.md @@ -0,0 +1,5 @@ +--- +'@udecode/slate-utils': patch +--- + +Fix `getSelectionFragment` to support collapsed selection diff --git a/.changeset/tiny-bees-return.md b/.changeset/tiny-bees-return.md new file mode 100644 index 0000000000..d565f327c5 --- /dev/null +++ b/.changeset/tiny-bees-return.md @@ -0,0 +1,5 @@ +--- +'shadcx': patch +--- + +shadcn sync diff --git a/apps/www/content/docs/collaboration.mdx b/apps/www/content/docs/collaboration.mdx index f3d4566cb4..cdcec9197d 100644 --- a/apps/www/content/docs/collaboration.mdx +++ b/apps/www/content/docs/collaboration.mdx @@ -34,14 +34,14 @@ const editor = createPlateEditor({ plugins: [ // ...otherPlugins, YjsPlugin.configure({ - options: { - hocuspocusProviderOptions: { + options: { + hocuspocusProviderOptions: { url: "https://hocuspocus.test/hocuspocus", name: "test", - } + }, }, }), - ] + ], }); ``` diff --git a/apps/www/content/docs/components/changelog.mdx b/apps/www/content/docs/components/changelog.mdx index cbaa4a40c3..16b4bdf9ac 100644 --- a/apps/www/content/docs/components/changelog.mdx +++ b/apps/www/content/docs/components/changelog.mdx @@ -13,8 +13,45 @@ Use the [CLI](https://platejs.org/docs/components/cli) to install the latest ver ### October 31 #15.6 -- Fixed and modified some styles in emoji and color picker -- Remove `Icons` file dependency. All icons are now imported from `lucide-react`. +- Added `lib/transforms.ts`. Contains useful transforms for common operations. +- Removed `Icons` file dependency. All icons are now imported from `lucide-react`. +- Fixed and modified some styles in emoji and color picker. +- Group styling: + - `dropdown-menu` + - `context-menu` + - `inline-combobox` +- Added groups and items to `slash-input-element` +- Spacing and sizing update: + - `ai-menu-items.tsx` + - `align-dropdown-menu.tsx` + - `block-context-menu.tsx` + - `button.tsx` + - `code-block-combobox.tsx` + - `color-dropdown-menu-items.tsx` + - `color-picker.tsx` + - `column-group-element.tsx` + - `command.tsx` + - `comment-more-dropdown.tsx` + - `context-menu.tsx` + - `dropdown-menu.tsx` + - `emoji-dropdown-menu.tsx` + - `emoji-input-element.tsx` + - `image-preview.tsx` + - `inline-combobox.tsx` + - `input.tsx` + - `insert-dropdown-menu.tsx` + - `line-height-dropdown-menu.tsx` + - `link-floating-toolbar.tsx` + - `media-popover.tsx` + - `mention-input-element.tsx` + - `mode-dropdown-menu.tsx` + - `more-dropdown-menu.tsx` + - `popover.tsx` + - `slash-input-element.tsx` + - `table-dropdown-menu.tsx` + - `table-element.tsx` + - `toggle-element.tsx` + - `toggle-toolbar-button.tsx` ### October 26 #15.5 diff --git a/apps/www/content/docs/components/cli.mdx b/apps/www/content/docs/components/cli.mdx index 7c84027086..7c880213ee 100644 --- a/apps/www/content/docs/components/cli.mdx +++ b/apps/www/content/docs/components/cli.mdx @@ -40,7 +40,9 @@ Options: -y, --yes skip confirmation prompt. (default: false) -c, --cwd the working directory. defaults to the current directory. -u, --url custom registry URL. (default: https://platejs.org/r) - -n, --name registry name. (default: plate-ui) + -n, --name registry name. (default: plate) + -s, --silent mute output (default: false) + --src-dir use the src directory when creating a new project (default: false) -h, --help display help for command ``` @@ -49,7 +51,7 @@ Options: Use the `add` command to add Plate UI components and dependencies to your project. ```bash -npx shadcx@latest add [component] +npx shadcx@latest add [component] -r plate ``` You will be presented with a list of components to choose from: @@ -84,6 +86,11 @@ Options: -o, --overwrite overwrite existing files. (default: false) -c, --cwd the working directory. defaults to the current directory. -p, --path the path to add the component to. + -a, --all add all available components (default: false) + -s, --silent mute output (default: false) + --src-dir use the src directory when creating a new project (default: false) + -r, --registry registry name or url + -l, --list list all available registries (default: false) -h, --help display help for command ``` @@ -98,7 +105,7 @@ npx shadcx@latest init -u https://platejs.org/r -n plate -c ./apps/www or ```bash -npx shadcx@latest add align-dropdown-menu -c ./apps/www +npx shadcx@latest add align-dropdown-menu -r plate -c ./apps/www ``` ## Example components.json @@ -119,7 +126,7 @@ Here's an example `components.json` file configured for [shadcn/ui](https://ui.s "utils": "@/lib/utils" }, "registries": { - "plate-ui": { + "plate": { "url": "https://platejs.org/r", "style": "default", "aliases": { diff --git a/apps/www/content/docs/components/components-json.mdx b/apps/www/content/docs/components/components-json.mdx index 84e75dff86..fe5f508ea6 100644 --- a/apps/www/content/docs/components/components-json.mdx +++ b/apps/www/content/docs/components/components-json.mdx @@ -196,7 +196,7 @@ The `registries` section allows you to configure multiple component registries f ```json title="components.json" { "registries": { - "plate-ui": { + "plate": { "url": "https://platejs.org/r", "style": "default", "aliases": { diff --git a/apps/www/content/docs/components/installation/next.mdx b/apps/www/content/docs/components/installation/next.mdx index 2dd08a123a..ca30664830 100644 --- a/apps/www/content/docs/components/installation/next.mdx +++ b/apps/www/content/docs/components/installation/next.mdx @@ -7,6 +7,10 @@ description: Install and configure Next.js. A [template](https://github.com/udecode/plate/tree/main/templates/plate-template) is available to help you get started quickly. + +**If you're using Next.js 15, see the [Next.js 15 + React 19](https://ui.shadcn.com/docs/installation/react-19) guide.** + + diff --git a/apps/www/content/docs/components/installation/vite.mdx b/apps/www/content/docs/components/installation/vite.mdx index 1ebbdde5c3..ef4af1849f 100644 --- a/apps/www/content/docs/components/installation/vite.mdx +++ b/apps/www/content/docs/components/installation/vite.mdx @@ -23,6 +23,28 @@ npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p ``` +Add this import header in your main css file, `src/index.css` in our case: + +```css {1-3} showLineNumbers +@tailwind base; +@tailwind components; +@tailwind utilities; +/* ... */ +``` + +Configure the tailwind template paths in `tailwind.config.js`: + +```js {3} +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./index.html", "./src/**/*.{ts,tsx,js,jsx}"], + theme: { + extend: {}, + }, + plugins: [], +} +``` + ### Edit tsconfig.json file The current version of Vite splits TypeScript configuration into three files, two of which need to be edited. diff --git a/apps/www/public/r/index.json b/apps/www/public/r/index.json index 5c089025b8..899d916862 100644 --- a/apps/www/public/r/index.json +++ b/apps/www/public/r/index.json @@ -701,30 +701,18 @@ }, { "dependencies": [ - "@udecode/plate-heading", "@udecode/plate-ai", + "@udecode/plate-block-quote", + "@udecode/plate-code-block", "@udecode/plate-date", - "@udecode/plate-indent-list" + "@udecode/plate-heading", + "@udecode/plate-indent-list", + "@udecode/plate-table", + "@udecode/plate-toggle" ], "doc": { "description": "A command input component for inserting various elements.", "docs": [ - { - "route": "/docs/ai", - "title": "AI" - }, - { - "route": "/docs/basic-elements", - "title": "Basic Elements" - }, - { - "route": "/docs/date", - "title": "Date" - }, - { - "route": "/docs/indent-list", - "title": "Indent List" - }, { "route": "https://pro.platejs.org/docs/components/slash-input-element" } @@ -744,7 +732,8 @@ "name": "slash-input-element", "registryDependencies": [ "inline-combobox", - "plate-element" + "plate-element", + "transforms" ], "type": "registry:ui" }, @@ -896,6 +885,7 @@ ], "name": "toggle-element", "registryDependencies": [ + "button", "plate-element" ], "type": "registry:ui" @@ -1641,16 +1631,14 @@ }, { "dependencies": [ - "@udecode/plate-basic-marks" + "@udecode/plate-basic-marks", + "@udecode/plate-font", + "@udecode/plate-indent-list", + "@udecode/plate-list", + "@udecode/plate-media" ], "doc": { "description": "A set of commonly used formatting buttons.", - "docs": [ - { - "route": "/docs/basic-marks", - "title": "Basic Marks" - } - ], "examples": [ "toolbar-demo" ] @@ -1664,9 +1652,25 @@ "name": "fixed-toolbar-buttons", "registryDependencies": [ "toolbar", + "ai-toolbar-button", + "align-dropdown-menu", + "color-dropdown-menu", + "comment-toolbar-button", + "emoji-dropdown-menu", + "indent-list-toolbar-button", + "indent-todo-toolbar-button", + "indent-toolbar-button", "insert-dropdown-menu", + "line-height-dropdown-menu", + "link-toolbar-button", + "list-toolbar-button", "mark-toolbar-button", + "media-toolbar-button", "mode-dropdown-menu", + "more-dropdown-menu", + "outdent-toolbar-button", + "table-dropdown-menu", + "toggle-toolbar-button", "turn-into-dropdown-menu" ], "type": "registry:ui" @@ -1715,6 +1719,10 @@ ], "name": "floating-toolbar-buttons", "registryDependencies": [ + "toolbar", + "ai-toolbar-button", + "comment-toolbar-button", + "link-toolbar-button", "mark-toolbar-button", "more-dropdown-menu", "turn-into-dropdown-menu" @@ -1929,18 +1937,21 @@ }, { "dependencies": [ + "@radix-ui/react-dropdown-menu", "@udecode/plate-block-quote", + "@udecode/plate-code-block", + "@udecode/plate-date", + "@udecode/plate-excalidraw", "@udecode/plate-heading", - "@radix-ui/react-dropdown-menu" + "@udecode/plate-horizontal-rule", + "@udecode/plate-indent-list", + "@udecode/plate-link", + "@udecode/plate-media", + "@udecode/plate-table", + "@udecode/plate-toggle" ], "doc": { "description": "A menu for inserting different types of blocks.", - "docs": [ - { - "route": "/docs/basic-elements", - "title": "Basic Elements" - } - ], "examples": [ "basic-nodes-demo" ] @@ -1954,7 +1965,8 @@ "name": "insert-dropdown-menu", "registryDependencies": [ "dropdown-menu", - "toolbar" + "toolbar", + "transforms" ], "type": "registry:ui" }, @@ -2199,8 +2211,10 @@ }, { "dependencies": [ + "@radix-ui/react-dropdown-menu", "@udecode/plate-basic-marks", - "@radix-ui/react-dropdown-menu" + "@udecode/plate-highlight", + "@udecode/plate-kbd" ], "doc": { "description": "A menu for additional text formatting options.", @@ -2400,22 +2414,16 @@ }, { "dependencies": [ + "@radix-ui/react-dropdown-menu", "@udecode/plate-block-quote", + "@udecode/plate-code-block", "@udecode/plate-heading", "@udecode/plate-indent-list", - "@radix-ui/react-dropdown-menu" + "@udecode/plate-toggle" ], "doc": { "description": "A menu for converting between different block types.", "docs": [ - { - "route": "/docs/basic-elements", - "title": "Basic Elements" - }, - { - "route": "/docs/indent-list", - "title": "Indent List" - }, { "route": "https://pro.platejs.org/docs/components/turn-into-dropdown-menu" } @@ -2434,7 +2442,8 @@ "name": "turn-into-dropdown-menu", "registryDependencies": [ "dropdown-menu", - "toolbar" + "toolbar", + "transforms" ], "type": "registry:ui" } diff --git a/apps/www/public/r/styles/default/ai-demo.json b/apps/www/public/r/styles/default/ai-demo.json index 60e5d75010..689dc46695 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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/ai-menu.json b/apps/www/public/r/styles/default/ai-menu.json index 099367a5f8..c79c572c0e 100644 --- a/apps/www/public/r/styles/default/ai-menu.json +++ b/apps/www/public/r/styles/default/ai-menu.json @@ -32,7 +32,7 @@ "type": "registry:ui" }, { - "content": "'use client';\n\nimport { useEffect, useMemo } from 'react';\n\nimport { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';\nimport {\n getAncestorNode,\n getEndPoint,\n getNodeString,\n} from '@udecode/plate-common';\nimport {\n type PlateEditor,\n focusEditor,\n useEditorPlugin,\n} from '@udecode/plate-common/react';\nimport { useIsSelecting } from '@udecode/plate-selection/react';\nimport {\n Album,\n BadgeHelp,\n Check,\n CornerUpLeft,\n FeatherIcon,\n ListEnd,\n ListMinus,\n ListPlus,\n PenLine,\n Wand,\n X,\n} from 'lucide-react';\n\nimport { CommandGroup, CommandItem } from './command';\n\nexport type EditorChatState =\n | 'cursorCommand'\n | 'cursorSuggestion'\n | 'selectionCommand'\n | 'selectionSuggestion';\n\nexport const aiChatItems = {\n accept: {\n icon: ,\n label: 'Accept',\n value: 'accept',\n onSelect: ({ editor }) => {\n editor.getTransforms(AIChatPlugin).aiChat.accept();\n focusEditor(editor, getEndPoint(editor, editor.selection!));\n },\n },\n continueWrite: {\n icon: ,\n label: 'Continue writing',\n value: 'continueWrite',\n onSelect: ({ editor }) => {\n const ancestorNode = getAncestorNode(editor);\n const isEmpty = getNodeString(ancestorNode![0]).trim().length === 0;\n\n void editor.getApi(AIChatPlugin).aiChat.submit({\n mode: 'insert',\n prompt: isEmpty\n ? `\n{editor}\n\nStart writing a new paragraph AFTER ONLY ONE SENTENCE`\n : 'Continue writing AFTER ONLY ONE SENTENCE. DONT REPEAT THE TEXT.',\n });\n },\n },\n discard: {\n icon: ,\n label: 'Discard',\n shortcut: 'Escape',\n value: 'discard',\n onSelect: ({ editor }) => {\n editor.getTransforms(AIPlugin).ai.undo();\n editor.getApi(AIChatPlugin).aiChat.hide();\n },\n },\n explain: {\n icon: ,\n label: 'Explain',\n value: 'explain',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: {\n default: 'Explain {editor}',\n selecting: 'Explain',\n },\n });\n },\n },\n fixSpelling: {\n icon: ,\n label: 'Fix spelling & grammar',\n value: 'fixSpelling',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Fix spelling and grammar',\n });\n },\n },\n improveWriting: {\n icon: ,\n label: 'Improve writing',\n value: 'improveWriting',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Improve the writing',\n });\n },\n },\n insertBelow: {\n icon: ,\n label: 'Insert below',\n value: 'insertBelow',\n onSelect: ({ aiEditor, editor }) => {\n void editor.getTransforms(AIChatPlugin).aiChat.insertBelow(aiEditor);\n },\n },\n makeLonger: {\n icon: ,\n label: 'Make longer',\n value: 'makeLonger',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Make longer',\n });\n },\n },\n makeShorter: {\n icon: ,\n label: 'Make shorter',\n value: 'makeShorter',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Make shorter',\n });\n },\n },\n replace: {\n icon: ,\n label: 'Replace selection',\n value: 'replace',\n onSelect: ({ aiEditor, editor }) => {\n void editor.getTransforms(AIChatPlugin).aiChat.replaceSelection(aiEditor);\n },\n },\n simplifyLanguage: {\n icon: ,\n label: 'Simplify language',\n value: 'simplifyLanguage',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Simplify the language',\n });\n },\n },\n summarize: {\n icon: ,\n label: 'Add a summary',\n value: 'summarize',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n mode: 'insert',\n prompt: {\n default: 'Summarize {editor}',\n selecting: 'Summarize',\n },\n });\n },\n },\n tryAgain: {\n icon: ,\n label: 'Try again',\n value: 'tryAgain',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.reload();\n },\n },\n} satisfies Record<\n string,\n {\n icon: React.ReactNode;\n label: string;\n value: string;\n component?: React.ComponentType<{ menuState: EditorChatState }>;\n filterItems?: boolean;\n items?: { label: string; value: string }[];\n shortcut?: string;\n onSelect?: ({\n aiEditor,\n editor,\n }: {\n aiEditor: PlateEditor;\n editor: PlateEditor;\n }) => void;\n }\n>;\n\nconst menuStateItems: Record<\n EditorChatState,\n {\n items: (typeof aiChatItems)[keyof typeof aiChatItems][];\n heading?: string;\n }[]\n> = {\n cursorCommand: [\n {\n items: [\n aiChatItems.continueWrite,\n aiChatItems.summarize,\n aiChatItems.explain,\n ],\n },\n ],\n cursorSuggestion: [\n {\n items: [aiChatItems.accept, aiChatItems.discard, aiChatItems.tryAgain],\n },\n ],\n selectionCommand: [\n {\n items: [\n aiChatItems.improveWriting,\n aiChatItems.makeLonger,\n aiChatItems.makeShorter,\n aiChatItems.fixSpelling,\n aiChatItems.simplifyLanguage,\n ],\n },\n ],\n selectionSuggestion: [\n {\n items: [\n aiChatItems.replace,\n aiChatItems.insertBelow,\n aiChatItems.discard,\n aiChatItems.tryAgain,\n ],\n },\n ],\n};\n\nexport const AIMenuItems = ({\n aiEditorRef,\n setValue,\n}: {\n aiEditorRef: React.MutableRefObject;\n setValue: (value: string) => void;\n}) => {\n const { editor, useOption } = useEditorPlugin(AIChatPlugin);\n const { messages } = useOption('chat');\n const isSelecting = useIsSelecting();\n\n const menuState = useMemo(() => {\n if (messages && messages.length > 0) {\n return isSelecting ? 'selectionSuggestion' : 'cursorSuggestion';\n }\n\n return isSelecting ? 'selectionCommand' : 'cursorCommand';\n }, [isSelecting, messages]);\n\n const menuGroups = useMemo(() => {\n const items = menuStateItems[menuState];\n\n return items;\n }, [menuState]);\n\n useEffect(() => {\n if (menuGroups.length > 0 && menuGroups[0].items.length > 0) {\n setValue(menuGroups[0].items[0].value);\n }\n }, [menuGroups, setValue]);\n\n return (\n <>\n {menuGroups.map((group, index) => (\n \n {group.items.map((menuItem) => (\n {\n menuItem.onSelect?.({\n aiEditor: aiEditorRef.current!,\n editor: editor,\n });\n }}\n >\n {menuItem.icon}\n {menuItem.label}\n \n ))}\n \n ))}\n \n );\n};\n", + "content": "'use client';\n\nimport { useEffect, useMemo } from 'react';\n\nimport { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';\nimport {\n getAncestorNode,\n getEndPoint,\n getNodeString,\n} from '@udecode/plate-common';\nimport {\n type PlateEditor,\n focusEditor,\n useEditorPlugin,\n} from '@udecode/plate-common/react';\nimport { useIsSelecting } from '@udecode/plate-selection/react';\nimport {\n Album,\n BadgeHelp,\n Check,\n CornerUpLeft,\n FeatherIcon,\n ListEnd,\n ListMinus,\n ListPlus,\n PenLine,\n Wand,\n X,\n} from 'lucide-react';\n\nimport { CommandGroup, CommandItem } from './command';\n\nexport type EditorChatState =\n | 'cursorCommand'\n | 'cursorSuggestion'\n | 'selectionCommand'\n | 'selectionSuggestion';\n\nexport const aiChatItems = {\n accept: {\n icon: ,\n label: 'Accept',\n value: 'accept',\n onSelect: ({ editor }) => {\n editor.getTransforms(AIChatPlugin).aiChat.accept();\n focusEditor(editor, getEndPoint(editor, editor.selection!));\n },\n },\n continueWrite: {\n icon: ,\n label: 'Continue writing',\n value: 'continueWrite',\n onSelect: ({ editor }) => {\n const ancestorNode = getAncestorNode(editor);\n const isEmpty = getNodeString(ancestorNode![0]).trim().length === 0;\n\n void editor.getApi(AIChatPlugin).aiChat.submit({\n mode: 'insert',\n prompt: isEmpty\n ? `\n{editor}\n\nStart writing a new paragraph AFTER ONLY ONE SENTENCE`\n : 'Continue writing AFTER ONLY ONE SENTENCE. DONT REPEAT THE TEXT.',\n });\n },\n },\n discard: {\n icon: ,\n label: 'Discard',\n shortcut: 'Escape',\n value: 'discard',\n onSelect: ({ editor }) => {\n editor.getTransforms(AIPlugin).ai.undo();\n editor.getApi(AIChatPlugin).aiChat.hide();\n },\n },\n explain: {\n icon: ,\n label: 'Explain',\n value: 'explain',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: {\n default: 'Explain {editor}',\n selecting: 'Explain',\n },\n });\n },\n },\n fixSpelling: {\n icon: ,\n label: 'Fix spelling & grammar',\n value: 'fixSpelling',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Fix spelling and grammar',\n });\n },\n },\n improveWriting: {\n icon: ,\n label: 'Improve writing',\n value: 'improveWriting',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Improve the writing',\n });\n },\n },\n insertBelow: {\n icon: ,\n label: 'Insert below',\n value: 'insertBelow',\n onSelect: ({ aiEditor, editor }) => {\n void editor.getTransforms(AIChatPlugin).aiChat.insertBelow(aiEditor);\n },\n },\n makeLonger: {\n icon: ,\n label: 'Make longer',\n value: 'makeLonger',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Make longer',\n });\n },\n },\n makeShorter: {\n icon: ,\n label: 'Make shorter',\n value: 'makeShorter',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Make shorter',\n });\n },\n },\n replace: {\n icon: ,\n label: 'Replace selection',\n value: 'replace',\n onSelect: ({ aiEditor, editor }) => {\n void editor.getTransforms(AIChatPlugin).aiChat.replaceSelection(aiEditor);\n },\n },\n simplifyLanguage: {\n icon: ,\n label: 'Simplify language',\n value: 'simplifyLanguage',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Simplify the language',\n });\n },\n },\n summarize: {\n icon: ,\n label: 'Add a summary',\n value: 'summarize',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n mode: 'insert',\n prompt: {\n default: 'Summarize {editor}',\n selecting: 'Summarize',\n },\n });\n },\n },\n tryAgain: {\n icon: ,\n label: 'Try again',\n value: 'tryAgain',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.reload();\n },\n },\n} satisfies Record<\n string,\n {\n icon: React.ReactNode;\n label: string;\n value: string;\n component?: React.ComponentType<{ menuState: EditorChatState }>;\n filterItems?: boolean;\n items?: { label: string; value: string }[];\n shortcut?: string;\n onSelect?: ({\n aiEditor,\n editor,\n }: {\n aiEditor: PlateEditor;\n editor: PlateEditor;\n }) => void;\n }\n>;\n\nconst menuStateItems: Record<\n EditorChatState,\n {\n items: (typeof aiChatItems)[keyof typeof aiChatItems][];\n heading?: string;\n }[]\n> = {\n cursorCommand: [\n {\n items: [\n aiChatItems.continueWrite,\n aiChatItems.summarize,\n aiChatItems.explain,\n ],\n },\n ],\n cursorSuggestion: [\n {\n items: [aiChatItems.accept, aiChatItems.discard, aiChatItems.tryAgain],\n },\n ],\n selectionCommand: [\n {\n items: [\n aiChatItems.improveWriting,\n aiChatItems.makeLonger,\n aiChatItems.makeShorter,\n aiChatItems.fixSpelling,\n aiChatItems.simplifyLanguage,\n ],\n },\n ],\n selectionSuggestion: [\n {\n items: [\n aiChatItems.replace,\n aiChatItems.insertBelow,\n aiChatItems.discard,\n aiChatItems.tryAgain,\n ],\n },\n ],\n};\n\nexport const AIMenuItems = ({\n aiEditorRef,\n setValue,\n}: {\n aiEditorRef: React.MutableRefObject;\n setValue: (value: string) => void;\n}) => {\n const { editor, useOption } = useEditorPlugin(AIChatPlugin);\n const { messages } = useOption('chat');\n const isSelecting = useIsSelecting();\n\n const menuState = useMemo(() => {\n if (messages && messages.length > 0) {\n return isSelecting ? 'selectionSuggestion' : 'cursorSuggestion';\n }\n\n return isSelecting ? 'selectionCommand' : 'cursorCommand';\n }, [isSelecting, messages]);\n\n const menuGroups = useMemo(() => {\n const items = menuStateItems[menuState];\n\n return items;\n }, [menuState]);\n\n useEffect(() => {\n if (menuGroups.length > 0 && menuGroups[0].items.length > 0) {\n setValue(menuGroups[0].items[0].value);\n }\n }, [menuGroups, setValue]);\n\n return (\n <>\n {menuGroups.map((group, index) => (\n \n {group.items.map((menuItem) => (\n {\n menuItem.onSelect?.({\n aiEditor: aiEditorRef.current!,\n editor: editor,\n });\n }}\n >\n {menuItem.icon}\n {menuItem.label}\n \n ))}\n \n ))}\n \n );\n};\n", "path": "plate-ui/ai-menu-items.tsx", "target": "components/plate-ui/ai-menu-items.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/align-demo.json b/apps/www/public/r/styles/default/align-demo.json index b2afb565fd..5755606c0d 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-dropdown-menu.json b/apps/www/public/r/styles/default/align-dropdown-menu.json index 0b754a8c72..3d4dba6aaf 100644 --- a/apps/www/public/r/styles/default/align-dropdown-menu.json +++ b/apps/www/public/r/styles/default/align-dropdown-menu.json @@ -16,7 +16,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n useAlignDropdownMenu,\n useAlignDropdownMenuState,\n} from '@udecode/plate-alignment/react';\nimport {\n AlignCenterIcon,\n AlignJustifyIcon,\n AlignLeftIcon,\n AlignRightIcon,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n icon: AlignLeftIcon,\n value: 'left',\n },\n {\n icon: AlignCenterIcon,\n value: 'center',\n },\n {\n icon: AlignRightIcon,\n value: 'right',\n },\n {\n icon: AlignJustifyIcon,\n value: 'justify',\n },\n];\n\nexport function AlignDropdownMenu({ children, ...props }: DropdownMenuProps) {\n const state = useAlignDropdownMenuState();\n const { radioGroupProps } = useAlignDropdownMenu(state);\n\n const openState = useOpenState();\n const IconValue =\n items.find((item) => item.value === radioGroupProps.value)?.icon ??\n AlignLeftIcon;\n\n return (\n \n \n \n \n \n \n\n \n \n {items.map(({ icon: Icon, value: itemValue }) => (\n \n \n \n ))}\n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n useAlignDropdownMenu,\n useAlignDropdownMenuState,\n} from '@udecode/plate-alignment/react';\nimport {\n AlignCenterIcon,\n AlignJustifyIcon,\n AlignLeftIcon,\n AlignRightIcon,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n icon: AlignLeftIcon,\n value: 'left',\n },\n {\n icon: AlignCenterIcon,\n value: 'center',\n },\n {\n icon: AlignRightIcon,\n value: 'right',\n },\n {\n icon: AlignJustifyIcon,\n value: 'justify',\n },\n];\n\nexport function AlignDropdownMenu({ children, ...props }: DropdownMenuProps) {\n const state = useAlignDropdownMenuState();\n const { radioGroupProps } = useAlignDropdownMenu(state);\n\n const openState = useOpenState();\n const IconValue =\n items.find((item) => item.value === radioGroupProps.value)?.icon ??\n AlignLeftIcon;\n\n return (\n \n \n \n \n \n \n\n \n \n {items.map(({ icon: Icon, value: itemValue }) => (\n \n \n \n ))}\n \n \n \n );\n}\n", "path": "plate-ui/align-dropdown-menu.tsx", "target": "components/plate-ui/align-dropdown-menu.tsx", "type": "registry:ui" 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 5fabe4c01a..debffee9d7 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 edfa27fe44..353af375ce 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 dcedbca989..68ea098eb8 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-context-menu.json b/apps/www/public/r/styles/default/block-context-menu.json index 593eb1b7d0..abf7a628ae 100644 --- a/apps/www/public/r/styles/default/block-context-menu.json +++ b/apps/www/public/r/styles/default/block-context-menu.json @@ -24,7 +24,7 @@ }, "files": [ { - "content": "'use client';\n\nimport { useCallback, useState } from 'react';\n\nimport { AIChatPlugin } from '@udecode/plate-ai/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { unsetNodes } from '@udecode/plate-common';\nimport {\n ParagraphPlugin,\n focusEditor,\n useEditorPlugin,\n} from '@udecode/plate-common/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport {\n BLOCK_CONTEXT_MENU_ID,\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\n\nimport {\n ContextMenu,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n} from './context-menu';\n\ntype Value = 'askAI' | null;\n\nexport function BlockContextMenu({ children }: { children: React.ReactNode }) {\n const { api, editor } = useEditorPlugin(BlockMenuPlugin);\n const [value, setValue] = useState(null);\n\n const handleTurnInto = useCallback(\n (type: string) => {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.getNodes()\n .forEach(([node, path]) => {\n if (node[IndentListPlugin.key]) {\n unsetNodes(editor, [IndentListPlugin.key, 'indent'], { at: path });\n }\n\n editor.tf.toggle.block({ type }, { at: path });\n });\n },\n [editor]\n );\n\n const handleAlign = useCallback(\n (align: 'center' | 'left' | 'right') => {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.setNodes({ align });\n },\n [editor]\n );\n\n return (\n \n {\n const dataset = (event.target as HTMLElement).dataset;\n\n const disabled = dataset?.slateEditor === 'true';\n\n if (disabled) return event.preventDefault();\n\n api.blockMenu.show(BLOCK_CONTEXT_MENU_ID, {\n x: event.clientX,\n y: event.clientY,\n });\n }}\n >\n {children}\n \n {\n e.preventDefault();\n\n if (value === 'askAI') {\n editor.getApi(AIChatPlugin).aiChat.show();\n }\n\n setValue(null);\n }}\n >\n {\n setValue('askAI');\n }}\n >\n Ask AI\n \n {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.removeNodes();\n focusEditor(editor);\n }}\n >\n Delete\n \n {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.duplicate(\n editor.getApi(BlockSelectionPlugin).blockSelection.getNodes()\n );\n }}\n >\n Duplicate\n ⌘ + D\n \n \n Turn into\n \n handleTurnInto(ParagraphPlugin.key)}\n >\n Paragraph\n \n\n handleTurnInto(HEADING_KEYS.h1)}>\n Heading 1\n \n handleTurnInto(HEADING_KEYS.h2)}>\n Heading 2\n \n handleTurnInto(HEADING_KEYS.h3)}>\n Heading 3\n \n handleTurnInto(BlockquotePlugin.key)}\n >\n Blockquote\n \n \n \n \n \n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.setIndent(1)\n }\n >\n Indent\n \n \n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.setIndent(-1)\n }\n >\n Outdent\n \n \n Align\n \n handleAlign('left')}>\n Left\n \n handleAlign('center')}>\n Center\n \n handleAlign('right')}>\n Right\n \n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport { useCallback, useState } from 'react';\n\nimport { AIChatPlugin } from '@udecode/plate-ai/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { unsetNodes } from '@udecode/plate-common';\nimport {\n ParagraphPlugin,\n focusEditor,\n useEditorPlugin,\n} from '@udecode/plate-common/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { IndentListPlugin } from '@udecode/plate-indent-list/react';\nimport {\n BLOCK_CONTEXT_MENU_ID,\n BlockMenuPlugin,\n BlockSelectionPlugin,\n} from '@udecode/plate-selection/react';\n\nimport {\n ContextMenu,\n ContextMenuContent,\n ContextMenuGroup,\n ContextMenuItem,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n} from './context-menu';\n\ntype Value = 'askAI' | null;\n\nexport function BlockContextMenu({ children }: { children: React.ReactNode }) {\n const { api, editor } = useEditorPlugin(BlockMenuPlugin);\n const [value, setValue] = useState(null);\n\n const handleTurnInto = useCallback(\n (type: string) => {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.getNodes()\n .forEach(([node, path]) => {\n if (node[IndentListPlugin.key]) {\n unsetNodes(editor, [IndentListPlugin.key, 'indent'], { at: path });\n }\n\n editor.tf.toggle.block({ type }, { at: path });\n });\n },\n [editor]\n );\n\n const handleAlign = useCallback(\n (align: 'center' | 'left' | 'right') => {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.setNodes({ align });\n },\n [editor]\n );\n\n return (\n \n {\n const dataset = (event.target as HTMLElement).dataset;\n\n const disabled = dataset?.slateEditor === 'true';\n\n if (disabled) return event.preventDefault();\n\n api.blockMenu.show(BLOCK_CONTEXT_MENU_ID, {\n x: event.clientX,\n y: event.clientY,\n });\n }}\n >\n {children}\n \n {\n e.preventDefault();\n\n if (value === 'askAI') {\n editor.getApi(AIChatPlugin).aiChat.show();\n }\n\n setValue(null);\n }}\n >\n \n {\n setValue('askAI');\n }}\n >\n Ask AI\n \n {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.removeNodes();\n focusEditor(editor);\n }}\n >\n Delete\n \n {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.duplicate(\n editor.getApi(BlockSelectionPlugin).blockSelection.getNodes()\n );\n }}\n >\n Duplicate\n {/* ⌘ + D */}\n \n \n Turn into\n \n handleTurnInto(ParagraphPlugin.key)}\n >\n Paragraph\n \n\n handleTurnInto(HEADING_KEYS.h1)}>\n Heading 1\n \n handleTurnInto(HEADING_KEYS.h2)}>\n Heading 2\n \n handleTurnInto(HEADING_KEYS.h3)}>\n Heading 3\n \n handleTurnInto(BlockquotePlugin.key)}\n >\n Blockquote\n \n \n \n \n\n \n \n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.setIndent(1)\n }\n >\n Indent\n \n \n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.setIndent(-1)\n }\n >\n Outdent\n \n \n Align\n \n handleAlign('left')}>\n Left\n \n handleAlign('center')}>\n Center\n \n handleAlign('right')}>\n Right\n \n \n \n \n \n \n );\n}\n", "path": "plate-ui/block-context-menu.tsx", "target": "components/plate-ui/block-context-menu.tsx", "type": "registry:ui" 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 c1f3f4d233..15f2535752 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 dd3117edf0..ae08de10a4 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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/button.json b/apps/www/public/r/styles/default/button.json index 31bbfa5436..3c14623f30 100644 --- a/apps/www/public/r/styles/default/button.json +++ b/apps/www/public/r/styles/default/button.json @@ -10,7 +10,7 @@ }, "files": [ { - "content": "import * as React from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn, withRef } from '@udecode/cn';\nimport { type VariantProps, cva } from 'class-variance-authority';\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n defaultVariants: {\n size: 'default',\n variant: 'default',\n },\n variants: {\n isMenu: {\n true: 'h-auto w-full cursor-pointer justify-start',\n },\n size: {\n default: 'h-10 px-4 py-2',\n icon: 'size-10',\n lg: 'h-11 rounded-md px-8',\n none: '',\n sm: 'h-9 rounded-md px-3',\n sms: 'size-9 rounded-md px-0',\n xs: 'h-8 rounded-md px-3 text-xs',\n },\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n inlineLink: 'text-base text-primary underline underline-offset-4',\n link: 'text-primary underline-offset-4 hover:underline',\n outline:\n 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n },\n },\n }\n);\n\nexport const Button = withRef<\n 'button',\n {\n asChild?: boolean;\n } & VariantProps\n>(({ asChild = false, className, isMenu, size, variant, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n\n return (\n \n );\n});\n", + "content": "import * as React from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn, withRef } from '@udecode/cn';\nimport { type VariantProps, cva } from 'class-variance-authority';\n\nexport const buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n defaultVariants: {\n size: 'sm',\n variant: 'default',\n },\n variants: {\n isMenu: {\n true: 'w-full cursor-pointer justify-start',\n },\n size: {\n icon: 'size-[28px] rounded-md px-1.5',\n lg: 'h-10 rounded-md px-4',\n md: 'h-8 px-3 text-sm',\n none: '',\n sm: 'h-[28px] rounded-md px-2.5',\n xs: 'h-8 rounded-md px-3 text-xs',\n },\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n inlineLink: 'text-base text-primary underline underline-offset-4',\n link: 'text-primary underline-offset-4 hover:underline',\n outline:\n 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n },\n },\n }\n);\n\nexport const Button = withRef<\n 'button',\n {\n asChild?: boolean;\n } & VariantProps\n>(({ asChild = false, className, isMenu, size, variant, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n\n return (\n \n );\n});\n", "path": "plate-ui/button.tsx", "target": "components/plate-ui/button.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/code-block-element.json b/apps/www/public/r/styles/default/code-block-element.json index 71d4be84d6..066e47065e 100644 --- a/apps/www/public/r/styles/default/code-block-element.json +++ b/apps/www/public/r/styles/default/code-block-element.json @@ -31,7 +31,7 @@ "type": "registry:ui" }, { - "content": "'use client';\n\n/* eslint-disable unicorn/prefer-export-from */\n\nimport React, { useState } from 'react';\n\nimport { cn } from '@udecode/cn';\nimport {\n useCodeBlockCombobox,\n useCodeBlockComboboxState,\n} from '@udecode/plate-code-block/react';\nimport { Check, ChevronsUpDown } from 'lucide-react';\n// Prism must be imported before all language files\nimport Prism from 'prismjs';\n\nimport { Button } from './button';\nimport {\n Command,\n CommandEmpty,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\n\nimport 'prismjs/components/prism-antlr4.js';\nimport 'prismjs/components/prism-bash.js';\nimport 'prismjs/components/prism-c.js';\nimport 'prismjs/components/prism-cmake.js';\nimport 'prismjs/components/prism-coffeescript.js';\nimport 'prismjs/components/prism-cpp.js';\nimport 'prismjs/components/prism-csharp.js';\nimport 'prismjs/components/prism-css.js';\nimport 'prismjs/components/prism-dart.js';\n\n// import 'prismjs/components/prism-django.js';\nimport 'prismjs/components/prism-docker.js';\n\n// import 'prismjs/components/prism-ejs.js';\nimport 'prismjs/components/prism-erlang.js';\nimport 'prismjs/components/prism-git.js';\nimport 'prismjs/components/prism-go.js';\nimport 'prismjs/components/prism-graphql.js';\nimport 'prismjs/components/prism-groovy.js';\nimport 'prismjs/components/prism-java.js';\nimport 'prismjs/components/prism-javascript.js';\nimport 'prismjs/components/prism-json.js';\nimport 'prismjs/components/prism-jsx.js';\nimport 'prismjs/components/prism-kotlin.js';\nimport 'prismjs/components/prism-latex.js';\nimport 'prismjs/components/prism-less.js';\nimport 'prismjs/components/prism-lua.js';\nimport 'prismjs/components/prism-makefile.js';\nimport 'prismjs/components/prism-markdown.js';\nimport 'prismjs/components/prism-matlab.js';\nimport 'prismjs/components/prism-mermaid.js';\nimport 'prismjs/components/prism-objectivec.js';\nimport 'prismjs/components/prism-perl.js';\n\n// import 'prismjs/components/prism-php.js';\nimport 'prismjs/components/prism-powershell.js';\nimport 'prismjs/components/prism-properties.js';\nimport 'prismjs/components/prism-protobuf.js';\nimport 'prismjs/components/prism-python.js';\nimport 'prismjs/components/prism-r.js';\nimport 'prismjs/components/prism-ruby.js';\nimport 'prismjs/components/prism-sass.js';\nimport 'prismjs/components/prism-scala.js';\nimport 'prismjs/components/prism-scheme.js';\nimport 'prismjs/components/prism-scss.js';\nimport 'prismjs/components/prism-sql.js';\nimport 'prismjs/components/prism-swift.js';\nimport 'prismjs/components/prism-tsx.js';\nimport 'prismjs/components/prism-typescript.js';\nimport 'prismjs/components/prism-wasm.js';\nimport 'prismjs/components/prism-yaml.js';\n\nexport { Prism };\n\nconst languages: { label: string; value: string }[] = [\n { label: 'Plain Text', value: 'text' },\n { label: 'Bash', value: 'bash' },\n { label: 'CSS', value: 'css' },\n { label: 'Git', value: 'git' },\n { label: 'GraphQL', value: 'graphql' },\n { label: 'HTML', value: 'html' },\n { label: 'JavaScript', value: 'javascript' },\n { label: 'JSON', value: 'json' },\n { label: 'JSX', value: 'jsx' },\n { label: 'Markdown', value: 'markdown' },\n { label: 'SQL', value: 'sql' },\n { label: 'SVG', value: 'svg' },\n { label: 'TSX', value: 'tsx' },\n { label: 'TypeScript', value: 'typescript' },\n { label: 'WebAssembly', value: 'wasm' },\n { label: 'ANTLR4', value: 'antlr4' },\n { label: 'C', value: 'c' },\n { label: 'CMake', value: 'cmake' },\n { label: 'CoffeeScript', value: 'coffeescript' },\n { label: 'C#', value: 'csharp' },\n { label: 'Dart', value: 'dart' },\n { label: 'Django', value: 'django' },\n { label: 'Docker', value: 'docker' },\n { label: 'EJS', value: 'ejs' },\n { label: 'Erlang', value: 'erlang' },\n { label: 'Go', value: 'go' },\n { label: 'Groovy', value: 'groovy' },\n { label: 'Java', value: 'java' },\n { label: 'Kotlin', value: 'kotlin' },\n { label: 'LaTeX', value: 'latex' },\n { label: 'Less', value: 'less' },\n { label: 'Lua', value: 'lua' },\n { label: 'Makefile', value: 'makefile' },\n { label: 'Markup', value: 'markup' },\n { label: 'MATLAB', value: 'matlab' },\n { label: 'Mermaid', value: 'mermaid' },\n { label: 'Objective-C', value: 'objectivec' },\n { label: 'Perl', value: 'perl' },\n { label: 'PHP', value: 'php' },\n { label: 'PowerShell', value: 'powershell' },\n { label: '.properties', value: 'properties' },\n { label: 'Protocol Buffers', value: 'protobuf' },\n { label: 'Python', value: 'python' },\n { label: 'R', value: 'r' },\n { label: 'Ruby', value: 'ruby' },\n { label: 'Sass (Sass)', value: 'sass' },\n // FIXME: Error with current scala grammar\n { label: 'Scala', value: 'scala' },\n { label: 'Scheme', value: 'scheme' },\n { label: 'Sass (Scss)', value: 'scss' },\n { label: 'Shell', value: 'shell' },\n { label: 'Swift', value: 'swift' },\n { label: 'XML', value: 'xml' },\n { label: 'YAML', value: 'yaml' },\n];\n\nexport function CodeBlockCombobox() {\n const state = useCodeBlockComboboxState();\n const { commandItemProps } = useCodeBlockCombobox(state);\n\n const [open, setOpen] = useState(false);\n const [value, setValue] = useState('');\n\n if (state.readOnly) return null;\n\n const items = languages.filter(\n (language) =>\n !value ||\n language.label.toLowerCase().includes(value.toLowerCase()) ||\n language.value.toLowerCase().includes(value.toLowerCase())\n );\n\n return (\n \n \n \n {state.value\n ? languages.find((language) => language.value === state.value)\n ?.label\n : 'Plain Text'}\n \n \n \n \n \n setValue(value)}\n placeholder=\"Search language...\"\n />\n No language found.\n\n \n {items.map((language) => (\n {\n commandItemProps.onSelect(_value);\n setOpen(false);\n }}\n >\n \n {language.label}\n \n ))}\n \n \n \n \n );\n}\n", + "content": "'use client';\n\n/* eslint-disable unicorn/prefer-export-from */\n\nimport React, { useState } from 'react';\n\nimport { cn } from '@udecode/cn';\nimport {\n useCodeBlockCombobox,\n useCodeBlockComboboxState,\n} from '@udecode/plate-code-block/react';\nimport { Check, ChevronsUpDown } from 'lucide-react';\n// Prism must be imported before all language files\nimport Prism from 'prismjs';\n\nimport { Button } from './button';\nimport {\n Command,\n CommandEmpty,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\n\nimport 'prismjs/components/prism-antlr4.js';\nimport 'prismjs/components/prism-bash.js';\nimport 'prismjs/components/prism-c.js';\nimport 'prismjs/components/prism-cmake.js';\nimport 'prismjs/components/prism-coffeescript.js';\nimport 'prismjs/components/prism-cpp.js';\nimport 'prismjs/components/prism-csharp.js';\nimport 'prismjs/components/prism-css.js';\nimport 'prismjs/components/prism-dart.js';\n\n// import 'prismjs/components/prism-django.js';\nimport 'prismjs/components/prism-docker.js';\n\n// import 'prismjs/components/prism-ejs.js';\nimport 'prismjs/components/prism-erlang.js';\nimport 'prismjs/components/prism-git.js';\nimport 'prismjs/components/prism-go.js';\nimport 'prismjs/components/prism-graphql.js';\nimport 'prismjs/components/prism-groovy.js';\nimport 'prismjs/components/prism-java.js';\nimport 'prismjs/components/prism-javascript.js';\nimport 'prismjs/components/prism-json.js';\nimport 'prismjs/components/prism-jsx.js';\nimport 'prismjs/components/prism-kotlin.js';\nimport 'prismjs/components/prism-latex.js';\nimport 'prismjs/components/prism-less.js';\nimport 'prismjs/components/prism-lua.js';\nimport 'prismjs/components/prism-makefile.js';\nimport 'prismjs/components/prism-markdown.js';\nimport 'prismjs/components/prism-matlab.js';\nimport 'prismjs/components/prism-mermaid.js';\nimport 'prismjs/components/prism-objectivec.js';\nimport 'prismjs/components/prism-perl.js';\n\n// import 'prismjs/components/prism-php.js';\nimport 'prismjs/components/prism-powershell.js';\nimport 'prismjs/components/prism-properties.js';\nimport 'prismjs/components/prism-protobuf.js';\nimport 'prismjs/components/prism-python.js';\nimport 'prismjs/components/prism-r.js';\nimport 'prismjs/components/prism-ruby.js';\nimport 'prismjs/components/prism-sass.js';\nimport 'prismjs/components/prism-scala.js';\nimport 'prismjs/components/prism-scheme.js';\nimport 'prismjs/components/prism-scss.js';\nimport 'prismjs/components/prism-sql.js';\nimport 'prismjs/components/prism-swift.js';\nimport 'prismjs/components/prism-tsx.js';\nimport 'prismjs/components/prism-typescript.js';\nimport 'prismjs/components/prism-wasm.js';\nimport 'prismjs/components/prism-yaml.js';\n\nexport { Prism };\n\nconst languages: { label: string; value: string }[] = [\n { label: 'Plain Text', value: 'text' },\n { label: 'Bash', value: 'bash' },\n { label: 'CSS', value: 'css' },\n { label: 'Git', value: 'git' },\n { label: 'GraphQL', value: 'graphql' },\n { label: 'HTML', value: 'html' },\n { label: 'JavaScript', value: 'javascript' },\n { label: 'JSON', value: 'json' },\n { label: 'JSX', value: 'jsx' },\n { label: 'Markdown', value: 'markdown' },\n { label: 'SQL', value: 'sql' },\n { label: 'SVG', value: 'svg' },\n { label: 'TSX', value: 'tsx' },\n { label: 'TypeScript', value: 'typescript' },\n { label: 'WebAssembly', value: 'wasm' },\n { label: 'ANTLR4', value: 'antlr4' },\n { label: 'C', value: 'c' },\n { label: 'CMake', value: 'cmake' },\n { label: 'CoffeeScript', value: 'coffeescript' },\n { label: 'C#', value: 'csharp' },\n { label: 'Dart', value: 'dart' },\n { label: 'Django', value: 'django' },\n { label: 'Docker', value: 'docker' },\n { label: 'EJS', value: 'ejs' },\n { label: 'Erlang', value: 'erlang' },\n { label: 'Go', value: 'go' },\n { label: 'Groovy', value: 'groovy' },\n { label: 'Java', value: 'java' },\n { label: 'Kotlin', value: 'kotlin' },\n { label: 'LaTeX', value: 'latex' },\n { label: 'Less', value: 'less' },\n { label: 'Lua', value: 'lua' },\n { label: 'Makefile', value: 'makefile' },\n { label: 'Markup', value: 'markup' },\n { label: 'MATLAB', value: 'matlab' },\n { label: 'Mermaid', value: 'mermaid' },\n { label: 'Objective-C', value: 'objectivec' },\n { label: 'Perl', value: 'perl' },\n { label: 'PHP', value: 'php' },\n { label: 'PowerShell', value: 'powershell' },\n { label: '.properties', value: 'properties' },\n { label: 'Protocol Buffers', value: 'protobuf' },\n { label: 'Python', value: 'python' },\n { label: 'R', value: 'r' },\n { label: 'Ruby', value: 'ruby' },\n { label: 'Sass (Sass)', value: 'sass' },\n // FIXME: Error with current scala grammar\n { label: 'Scala', value: 'scala' },\n { label: 'Scheme', value: 'scheme' },\n { label: 'Sass (Scss)', value: 'scss' },\n { label: 'Shell', value: 'shell' },\n { label: 'Swift', value: 'swift' },\n { label: 'XML', value: 'xml' },\n { label: 'YAML', value: 'yaml' },\n];\n\nexport function CodeBlockCombobox() {\n const state = useCodeBlockComboboxState();\n const { commandItemProps } = useCodeBlockCombobox(state);\n\n const [open, setOpen] = useState(false);\n const [value, setValue] = useState('');\n\n if (state.readOnly) return null;\n\n const items = languages.filter(\n (language) =>\n !value ||\n language.label.toLowerCase().includes(value.toLowerCase()) ||\n language.value.toLowerCase().includes(value.toLowerCase())\n );\n\n return (\n \n \n \n {state.value\n ? languages.find((language) => language.value === state.value)\n ?.label\n : 'Plain Text'}\n \n \n \n \n \n setValue(value)}\n placeholder=\"Search language...\"\n />\n No language found.\n\n \n {items.map((language) => (\n {\n commandItemProps.onSelect(_value);\n setOpen(false);\n }}\n >\n \n {language.label}\n \n ))}\n \n \n \n \n );\n}\n", "path": "plate-ui/code-block-combobox.tsx", "target": "components/plate-ui/code-block-combobox.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/color-dropdown-menu.json b/apps/www/public/r/styles/default/color-dropdown-menu.json index 4e45fff1f7..fe0bce8042 100644 --- a/apps/www/public/r/styles/default/color-dropdown-menu.json +++ b/apps/www/public/r/styles/default/color-dropdown-menu.json @@ -26,7 +26,7 @@ "type": "registry:ui" }, { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuItemProps } from '@radix-ui/react-dropdown-menu';\n\nimport { cn } from '@udecode/cn';\nimport { Check } from 'lucide-react';\n\nimport { buttonVariants } from './button';\nimport { DropdownMenuItem } from './dropdown-menu';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from './tooltip';\n\nexport type TColor = {\n isBrightColor: boolean;\n name: string;\n value: string;\n};\n\ntype ColorDropdownMenuItemProps = {\n isBrightColor: boolean;\n isSelected: boolean;\n updateColor: (color: string) => void;\n value: string;\n name?: string;\n} & DropdownMenuItemProps;\n\nexport function ColorDropdownMenuItem({\n className,\n isBrightColor,\n isSelected,\n name,\n updateColor,\n value,\n ...props\n}: ColorDropdownMenuItemProps) {\n const content = (\n {\n e.preventDefault();\n updateColor(value);\n }}\n {...props}\n >\n {isSelected ? : null}\n \n );\n\n return name ? (\n \n {content}\n {name}\n \n ) : (\n content\n );\n}\n\ntype ColorDropdownMenuItemsProps = {\n colors: TColor[];\n updateColor: (color: string) => void;\n color?: string;\n} & React.HTMLAttributes;\n\nexport function ColorDropdownMenuItems({\n className,\n color,\n colors,\n updateColor,\n ...props\n}: ColorDropdownMenuItemsProps) {\n return (\n \n \n {colors.map(({ isBrightColor, name, value }) => (\n \n ))}\n {props.children}\n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuItemProps } from '@radix-ui/react-dropdown-menu';\n\nimport { cn } from '@udecode/cn';\nimport { Check } from 'lucide-react';\n\nimport { buttonVariants } from './button';\nimport { DropdownMenuItem } from './dropdown-menu';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from './tooltip';\n\nexport type TColor = {\n isBrightColor: boolean;\n name: string;\n value: string;\n};\n\ntype ColorDropdownMenuItemProps = {\n isBrightColor: boolean;\n isSelected: boolean;\n updateColor: (color: string) => void;\n value: string;\n name?: string;\n} & DropdownMenuItemProps;\n\nexport function ColorDropdownMenuItem({\n className,\n isBrightColor,\n isSelected,\n name,\n updateColor,\n value,\n ...props\n}: ColorDropdownMenuItemProps) {\n const content = (\n {\n e.preventDefault();\n updateColor(value);\n }}\n {...props}\n >\n {isSelected ? : null}\n \n );\n\n return name ? (\n \n {content}\n {name}\n \n ) : (\n content\n );\n}\n\ntype ColorDropdownMenuItemsProps = {\n colors: TColor[];\n updateColor: (color: string) => void;\n color?: string;\n} & React.HTMLAttributes;\n\nexport function ColorDropdownMenuItems({\n className,\n color,\n colors,\n updateColor,\n ...props\n}: ColorDropdownMenuItemsProps) {\n return (\n \n \n {colors.map(({ isBrightColor, name, value }) => (\n \n ))}\n {props.children}\n \n \n );\n}\n", "path": "plate-ui/color-dropdown-menu-items.tsx", "target": "components/plate-ui/color-dropdown-menu-items.tsx", "type": "registry:ui" @@ -44,7 +44,7 @@ "type": "registry:ui" }, { - "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\n\nimport { Icons } from '@/components/icons';\n\nimport { buttonVariants } from './button';\nimport {\n type TColor,\n ColorDropdownMenuItems,\n} from './color-dropdown-menu-items';\nimport { ColorCustom } from './colors-custom';\nimport {\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from './dropdown-menu';\n\nexport const ColorPickerContent = withRef<\n 'div',\n {\n clearColor: () => void;\n colors: TColor[];\n customColors: TColor[];\n updateColor: (color: string) => void;\n updateCustomColor: (color: string) => void;\n color?: string;\n }\n>(\n (\n {\n className,\n clearColor,\n color,\n colors,\n customColors,\n updateColor,\n updateCustomColor,\n ...props\n },\n ref\n ) => {\n return (\n
\n Color Picker\n \n \n \n \n \n \n \n {color && (\n \n \n \n \n \n Clear\n \n \n \n )}\n
\n );\n }\n);\n\nexport const ColorPicker = React.memo(\n ColorPickerContent,\n (prev, next) =>\n prev.color === next.color &&\n prev.colors === next.colors &&\n prev.customColors === next.customColors\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\n\nimport { Icons } from '@/components/icons';\n\nimport { buttonVariants } from './button';\nimport {\n type TColor,\n ColorDropdownMenuItems,\n} from './color-dropdown-menu-items';\nimport { ColorCustom } from './colors-custom';\nimport { DropdownMenuGroup, DropdownMenuItem } from './dropdown-menu';\n\nexport const ColorPickerContent = withRef<\n 'div',\n {\n clearColor: () => void;\n colors: TColor[];\n customColors: TColor[];\n updateColor: (color: string) => void;\n updateCustomColor: (color: string) => void;\n color?: string;\n }\n>(\n (\n {\n className,\n clearColor,\n color,\n colors,\n customColors,\n updateColor,\n updateCustomColor,\n ...props\n },\n ref\n ) => {\n return (\n
\n \n \n \n \n \n \n {color && (\n \n \n \n Clear\n \n \n )}\n
\n );\n }\n);\n\nexport const ColorPicker = React.memo(\n ColorPickerContent,\n (prev, next) =>\n prev.color === next.color &&\n prev.colors === next.colors &&\n prev.customColors === next.customColors\n);\n", "path": "plate-ui/color-picker.tsx", "target": "components/plate-ui/color-picker.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/column-demo.json b/apps/www/public/r/styles/default/column-demo.json index 29e1a25518..4c8f54d3a5 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-group-element.json b/apps/www/public/r/styles/default/column-group-element.json index 73813790f7..dfd7e782d9 100644 --- a/apps/www/public/r/styles/default/column-group-element.json +++ b/apps/www/public/r/styles/default/column-group-element.json @@ -19,7 +19,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { TColumnElement } from '@udecode/plate-layout';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { useElement, useRemoveNodeButton } from '@udecode/plate-common/react';\nimport {\n ColumnItemPlugin,\n useColumnState,\n useDebouncePopoverOpen,\n} from '@udecode/plate-layout/react';\nimport { type LucideProps, Delete } from 'lucide-react';\nimport { useReadOnly } from 'slate-react';\n\nimport { Button } from './button';\nimport { PlateElement } from './plate-element';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\nimport { Separator } from './separator';\n\nexport const ColumnGroupElement = withRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n \n
{children}
\n
\n
\n );\n }\n);\n\nexport function ColumnFloatingToolbar({ children }: React.PropsWithChildren) {\n const readOnly = useReadOnly();\n\n const {\n setDoubleColumn,\n setDoubleSideDoubleColumn,\n setLeftSideDoubleColumn,\n setRightSideDoubleColumn,\n setThreeColumn,\n } = useColumnState();\n\n const element = useElement(ColumnItemPlugin.key);\n\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n const isOpen = useDebouncePopoverOpen();\n\n if (readOnly) return <>{children};\n\n return (\n \n {children}\n e.preventDefault()}\n align=\"center\"\n side=\"top\"\n sideOffset={10}\n >\n
\n \n \n \n \n \n \n \n\n \n \n
\n \n
\n );\n}\n\nconst DoubleColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n\nconst ThreeColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n\nconst RightSideDoubleColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n\nconst LeftSideDoubleColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n\nconst DoubleSideDoubleColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { TColumnElement } from '@udecode/plate-layout';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { useElement, useRemoveNodeButton } from '@udecode/plate-common/react';\nimport {\n ColumnItemPlugin,\n useColumnState,\n useDebouncePopoverOpen,\n} from '@udecode/plate-layout/react';\nimport { type LucideProps, Trash2Icon } from 'lucide-react';\nimport { useReadOnly } from 'slate-react';\n\nimport { Button } from './button';\nimport { PlateElement } from './plate-element';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\nimport { Separator } from './separator';\n\nexport const ColumnGroupElement = withRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n \n
{children}
\n
\n
\n );\n }\n);\n\nexport function ColumnFloatingToolbar({ children }: React.PropsWithChildren) {\n const readOnly = useReadOnly();\n\n const {\n setDoubleColumn,\n setDoubleSideDoubleColumn,\n setLeftSideDoubleColumn,\n setRightSideDoubleColumn,\n setThreeColumn,\n } = useColumnState();\n\n const element = useElement(ColumnItemPlugin.key);\n\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n const isOpen = useDebouncePopoverOpen();\n\n if (readOnly) return <>{children};\n\n return (\n \n {children}\n e.preventDefault()}\n align=\"center\"\n side=\"top\"\n sideOffset={10}\n >\n
\n \n \n \n \n \n \n \n \n \n\n \n \n
\n \n
\n );\n}\n\nconst DoubleColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n\nconst ThreeColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n\nconst RightSideDoubleColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n\nconst LeftSideDoubleColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n\nconst DoubleSideDoubleColumnOutlined = (props: LucideProps) => (\n \n \n \n);\n", "path": "plate-ui/column-group-element.tsx", "target": "components/plate-ui/column-group-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/command.json b/apps/www/public/r/styles/default/command.json index 4b21ce0813..65450d2bf5 100644 --- a/apps/www/public/r/styles/default/command.json +++ b/apps/www/public/r/styles/default/command.json @@ -8,7 +8,7 @@ }, "files": [ { - "content": "'use client';\n\nimport * as React from 'react';\n\nimport type { DialogProps } from '@radix-ui/react-dialog';\n\nimport {\n cn,\n createPrimitiveElement,\n withCn,\n withRef,\n withVariants,\n} from '@udecode/cn';\nimport { Command as CommandPrimitive } from 'cmdk';\nimport { Search } from 'lucide-react';\n\nimport { Dialog, DialogContent, DialogTitle } from './dialog';\nimport { inputVariants } from './input';\n\nexport const Command = withCn(\n CommandPrimitive,\n 'flex size-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground'\n);\n\nexport function CommandDialog({ children, ...props }: DialogProps) {\n return (\n \n \n Command Dialog\n \n {children}\n \n \n \n );\n}\n\nexport const CommandInput = withRef(\n ({ className, ...props }, ref) => (\n
\n \n \n
\n )\n);\n\nexport const InputCommand = withVariants(\n CommandPrimitive.Input,\n inputVariants,\n ['variant']\n);\n\nexport const CommandList = withCn(\n CommandPrimitive.List,\n 'max-h-[500px] overflow-y-auto overflow-x-hidden'\n);\n\nexport const CommandEmpty = withCn(\n CommandPrimitive.Empty,\n 'py-6 text-center text-sm'\n);\n\nexport const CommandGroup = withCn(\n CommandPrimitive.Group,\n 'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground'\n);\n\nexport const CommandSeparator = withCn(\n CommandPrimitive.Separator,\n '-mx-1 h-px bg-border'\n);\n\nexport const CommandItem = withCn(\n CommandPrimitive.Item,\n 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50'\n);\n\nexport const CommandShortcut = withCn(\n createPrimitiveElement('span'),\n 'ml-auto text-xs tracking-widest text-muted-foreground'\n);\n", + "content": "'use client';\n\nimport * as React from 'react';\n\nimport type { DialogProps } from '@radix-ui/react-dialog';\n\nimport {\n cn,\n createPrimitiveElement,\n withCn,\n withRef,\n withVariants,\n} from '@udecode/cn';\nimport { Command as CommandPrimitive } from 'cmdk';\nimport { Search } from 'lucide-react';\n\nimport { Dialog, DialogContent, DialogTitle } from './dialog';\nimport { inputVariants } from './input';\n\nexport const Command = withCn(\n CommandPrimitive,\n 'flex size-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground'\n);\n\nexport function CommandDialog({ children, ...props }: DialogProps) {\n return (\n \n \n Command Dialog\n \n {children}\n \n \n \n );\n}\n\nexport const CommandInput = withRef(\n ({ className, ...props }, ref) => (\n
\n \n \n
\n )\n);\n\nexport const InputCommand = withVariants(\n CommandPrimitive.Input,\n inputVariants,\n ['variant']\n);\n\nexport const CommandList = withCn(\n CommandPrimitive.List,\n 'max-h-[500px] overflow-y-auto overflow-x-hidden'\n);\n\nexport const CommandEmpty = withCn(\n CommandPrimitive.Empty,\n 'py-6 text-center text-sm'\n);\n\nexport const CommandGroup = withCn(\n CommandPrimitive.Group,\n 'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground'\n);\n\nexport const CommandSeparator = withCn(\n CommandPrimitive.Separator,\n '-mx-1 h-px bg-border'\n);\n\nexport const CommandItem = withCn(\n CommandPrimitive.Item,\n 'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0'\n);\n\nexport const CommandShortcut = withCn(\n createPrimitiveElement('span'),\n 'ml-auto text-xs tracking-widest text-muted-foreground'\n);\n", "path": "plate-ui/command.tsx", "target": "components/plate-ui/command.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/comment-demo.json b/apps/www/public/r/styles/default/comment-demo.json index 5e2eabc520..e6f284310a 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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/comments-popover.json b/apps/www/public/r/styles/default/comments-popover.json index f318396fb1..5496fa910b 100644 --- a/apps/www/public/r/styles/default/comments-popover.json +++ b/apps/www/public/r/styles/default/comments-popover.json @@ -39,7 +39,7 @@ "type": "registry:ui" }, { - "content": "'use client';\n\nimport React from 'react';\n\nimport { cn } from '@udecode/cn';\nimport {\n useCommentDeleteButton,\n useCommentDeleteButtonState,\n useCommentEditButton,\n useCommentEditButtonState,\n} from '@udecode/plate-comments/react';\nimport { MoreHorizontal } from 'lucide-react';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from './dropdown-menu';\n\nexport function CommentMoreDropdown() {\n const editButtonState = useCommentEditButtonState();\n const { props: editProps } = useCommentEditButton(editButtonState);\n const deleteButtonState = useCommentDeleteButtonState();\n const { props: deleteProps } = useCommentDeleteButton(deleteButtonState);\n\n return (\n \n \n \n \n \n Edit comment\n Delete comment\n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { cn } from '@udecode/cn';\nimport {\n useCommentDeleteButton,\n useCommentDeleteButtonState,\n useCommentEditButton,\n useCommentEditButtonState,\n} from '@udecode/plate-comments/react';\nimport { MoreHorizontal } from 'lucide-react';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from './dropdown-menu';\n\nexport function CommentMoreDropdown() {\n const editButtonState = useCommentEditButtonState();\n const { props: editProps } = useCommentEditButton(editButtonState);\n const deleteButtonState = useCommentDeleteButtonState();\n const { props: deleteProps } = useCommentDeleteButton(deleteButtonState);\n\n return (\n \n \n \n \n \n \n Edit comment\n Delete comment\n \n \n \n );\n}\n", "path": "plate-ui/comment-more-dropdown.tsx", "target": "components/plate-ui/comment-more-dropdown.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/copilot-demo.json b/apps/www/public/r/styles/default/copilot-demo.json index d10d9b6465..f7951a6062 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 3eb33f08ef..c7533d8a7f 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 c134308472..be955ab796 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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/dropdown-menu.json b/apps/www/public/r/styles/default/dropdown-menu.json index 3a1fa67093..186f6a0350 100644 --- a/apps/www/public/r/styles/default/dropdown-menu.json +++ b/apps/www/public/r/styles/default/dropdown-menu.json @@ -7,7 +7,7 @@ }, "files": [ { - "content": "'use client';\n\nimport * as React from 'react';\nimport { useCallback, useState } from 'react';\n\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport {\n cn,\n createPrimitiveElement,\n withCn,\n withProps,\n withRef,\n withVariants,\n} from '@udecode/cn';\nimport { cva } from 'class-variance-authority';\nimport { Check, ChevronRight } from 'lucide-react';\n\nexport const DropdownMenu = DropdownMenuPrimitive.Root;\n\nexport const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\n\nexport const DropdownMenuGroup = DropdownMenuPrimitive.Group;\n\nexport const DropdownMenuPortal = DropdownMenuPrimitive.Portal;\n\nexport const DropdownMenuSub = DropdownMenuPrimitive.Sub;\n\nexport const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;\n\nexport const DropdownMenuSubTrigger = withRef<\n typeof DropdownMenuPrimitive.SubTrigger,\n {\n inset?: boolean;\n }\n>(({ children, className, inset, ...props }, ref) => (\n \n {children}\n \n \n));\n\nexport const DropdownMenuSubContent = withCn(\n DropdownMenuPrimitive.SubContent,\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2'\n);\n\nconst DropdownMenuContentVariants = withProps(DropdownMenuPrimitive.Content, {\n className: cn(\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2'\n ),\n sideOffset: 4,\n});\n\nexport const DropdownMenuContent = withRef<\n typeof DropdownMenuPrimitive.Content\n>(({ ...props }, ref) => (\n \n {\n e.preventDefault();\n }}\n {...props}\n />\n \n));\n\nconst menuItemVariants = cva(\n cn(\n 'relative flex h-9 cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors',\n '[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n 'focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50'\n ),\n {\n variants: {\n inset: {\n true: 'pl-8',\n },\n },\n }\n);\n\nexport const DropdownMenuItem = withVariants(\n DropdownMenuPrimitive.Item,\n menuItemVariants,\n ['inset']\n);\n\nexport const DropdownMenuCheckboxItem = withRef<\n typeof DropdownMenuPrimitive.CheckboxItem\n>(({ children, className, ...props }, ref) => (\n \n \n \n \n \n \n {children}\n \n));\n\nexport const DropdownMenuRadioItem = withRef<\n typeof DropdownMenuPrimitive.RadioItem,\n {\n hideIcon?: boolean;\n }\n>(({ children, className, hideIcon, ...props }, ref) => (\n \n {!hideIcon && (\n \n \n \n \n \n )}\n {children}\n \n));\n\nconst dropdownMenuLabelVariants = cva(\n cn('select-none px-2 py-1.5 text-sm font-semibold'),\n {\n variants: {\n inset: {\n true: 'pl-8',\n },\n },\n }\n);\n\nexport const DropdownMenuLabel = withVariants(\n DropdownMenuPrimitive.Label,\n dropdownMenuLabelVariants,\n ['inset']\n);\n\nexport const DropdownMenuSeparator = withCn(\n DropdownMenuPrimitive.Separator,\n '-mx-1 my-1 h-px bg-muted'\n);\n\nexport const DropdownMenuShortcut = withCn(\n createPrimitiveElement('span'),\n 'ml-auto text-xs tracking-widest opacity-60'\n);\n\nexport const useOpenState = () => {\n const [open, setOpen] = useState(false);\n\n const onOpenChange = useCallback(\n (_value = !open) => {\n setOpen(_value);\n },\n [open]\n );\n\n return {\n open,\n onOpenChange,\n };\n};\n", + "content": "'use client';\n\nimport * as React from 'react';\nimport { useCallback, useState } from 'react';\n\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport {\n cn,\n createPrimitiveElement,\n withCn,\n withProps,\n withRef,\n withVariants,\n} from '@udecode/cn';\nimport { cva } from 'class-variance-authority';\nimport { Check, ChevronRight } from 'lucide-react';\n\nexport const DropdownMenu = DropdownMenuPrimitive.Root;\n\nexport const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\n\nexport const DropdownMenuGroup = React.forwardRef<\n HTMLDivElement,\n { label?: React.ReactNode } & React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.Group\n >\n>(({ label, ...props }, ref) => {\n return (\n <>\n \n\n \n {label && {label}}\n {props.children}\n \n \n );\n});\n\nexport const DropdownMenuPortal = DropdownMenuPrimitive.Portal;\n\nexport const DropdownMenuSub = DropdownMenuPrimitive.Sub;\n\nexport const DropdownMenuRadioGroup = React.forwardRef<\n HTMLDivElement,\n { label?: React.ReactNode } & React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.RadioGroup\n >\n>(({ label, ...props }, ref) => {\n return (\n <>\n \n\n \n {label && {label}}\n {props.children}\n \n \n );\n});\n\nexport const DropdownMenuSubTrigger = withRef<\n typeof DropdownMenuPrimitive.SubTrigger,\n {\n inset?: boolean;\n }\n>(({ children, className, inset, ...props }, ref) => (\n \n {children}\n \n \n));\n\nexport const DropdownMenuSubContent = withCn(\n DropdownMenuPrimitive.SubContent,\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover py-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2'\n);\n\nconst DropdownMenuContentVariants = withProps(DropdownMenuPrimitive.Content, {\n className: cn(\n 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2'\n ),\n sideOffset: 4,\n});\n\nexport const DropdownMenuContent = withRef<\n typeof DropdownMenuPrimitive.Content\n>(({ ...props }, ref) => (\n \n {\n e.preventDefault();\n }}\n {...props}\n />\n \n));\n\nconst menuItemVariants = cva(\n 'relative mx-1 flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n inset: {\n true: 'pl-8',\n },\n },\n }\n);\n\nexport const DropdownMenuItem = withVariants(\n DropdownMenuPrimitive.Item,\n menuItemVariants,\n ['inset']\n);\n\nexport const DropdownMenuCheckboxItem = withRef<\n typeof DropdownMenuPrimitive.CheckboxItem\n>(({ children, className, ...props }, ref) => (\n \n \n \n \n \n \n {children}\n \n));\n\nexport const DropdownMenuRadioItem = withRef<\n typeof DropdownMenuPrimitive.RadioItem,\n {\n hideIcon?: boolean;\n }\n>(({ children, className, hideIcon, ...props }, ref) => (\n \n {!hideIcon && (\n \n \n \n \n \n )}\n {children}\n \n));\n\nconst dropdownMenuLabelVariants = cva(\n cn(\n 'mx-1 select-none px-2 pb-2 pt-1.5 text-xs font-semibold text-muted-foreground'\n ),\n {\n variants: {\n inset: {\n true: 'pl-8',\n },\n },\n }\n);\n\nexport const DropdownMenuLabel = withVariants(\n DropdownMenuPrimitive.Label,\n dropdownMenuLabelVariants,\n ['inset']\n);\n\nexport const DropdownMenuSeparator = withCn(\n DropdownMenuPrimitive.Separator,\n '-mx-1 my-1 h-px bg-muted'\n);\n\nexport const DropdownMenuShortcut = withCn(\n createPrimitiveElement('span'),\n 'ml-auto text-xs tracking-widest opacity-60'\n);\n\nexport const useOpenState = () => {\n const [open, setOpen] = useState(false);\n\n const onOpenChange = useCallback(\n (_value = !open) => {\n setOpen(_value);\n },\n [open]\n );\n\n return {\n open,\n onOpenChange,\n };\n};\n", "path": "plate-ui/dropdown-menu.tsx", "target": "components/plate-ui/dropdown-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/emoji-demo.json b/apps/www/public/r/styles/default/emoji-demo.json index 1c3166ee25..5bfb455d4b 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-dropdown-menu.json b/apps/www/public/r/styles/default/emoji-dropdown-menu.json index f5af63c24d..b22e073727 100644 --- a/apps/www/public/r/styles/default/emoji-dropdown-menu.json +++ b/apps/www/public/r/styles/default/emoji-dropdown-menu.json @@ -21,7 +21,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport {\n type EmojiDropdownMenuOptions,\n useEmojiDropdownMenuState,\n} from '@udecode/plate-emoji/react';\nimport { Smile } from 'lucide-react';\n\nimport { emojiCategoryIcons, emojiSearchIcons } from './emoji-icons';\nimport { EmojiPicker } from './emoji-picker';\nimport { EmojiToolbarDropdown } from './emoji-toolbar-dropdown';\nimport { ToolbarButton } from './toolbar';\n\ntype EmojiDropdownMenuProps = {\n options?: EmojiDropdownMenuOptions;\n} & React.ComponentPropsWithoutRef;\n\nexport function EmojiDropdownMenu({\n options,\n ...props\n}: EmojiDropdownMenuProps) {\n const { emojiPickerState, isOpen, setIsOpen } =\n useEmojiDropdownMenuState(options);\n\n return (\n \n \n \n }\n isOpen={isOpen}\n setIsOpen={setIsOpen}\n >\n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport {\n type EmojiDropdownMenuOptions,\n useEmojiDropdownMenuState,\n} from '@udecode/plate-emoji/react';\nimport { Smile } from 'lucide-react';\n\nimport { emojiCategoryIcons, emojiSearchIcons } from './emoji-icons';\nimport { EmojiPicker } from './emoji-picker';\nimport { EmojiToolbarDropdown } from './emoji-toolbar-dropdown';\nimport { ToolbarButton } from './toolbar';\n\ntype EmojiDropdownMenuProps = {\n options?: EmojiDropdownMenuOptions;\n} & React.ComponentPropsWithoutRef;\n\nexport function EmojiDropdownMenu({\n options,\n ...props\n}: EmojiDropdownMenuProps) {\n const { emojiPickerState, isOpen, setIsOpen } =\n useEmojiDropdownMenuState(options);\n\n return (\n \n \n \n }\n isOpen={isOpen}\n setIsOpen={setIsOpen}\n >\n \n \n );\n}\n", "path": "plate-ui/emoji-dropdown-menu.tsx", "target": "components/plate-ui/emoji-dropdown-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/emoji-input-element.json b/apps/www/public/r/styles/default/emoji-input-element.json index aea4fa4bd7..1150025226 100644 --- a/apps/www/public/r/styles/default/emoji-input-element.json +++ b/apps/www/public/r/styles/default/emoji-input-element.json @@ -18,7 +18,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useMemo, useState } from 'react';\n\nimport { withRef } from '@udecode/cn';\nimport { EmojiInlineIndexSearch, insertEmoji } from '@udecode/plate-emoji';\n\nimport { useDebounce } from '@/hooks/use-debounce';\n\nimport {\n InlineCombobox,\n InlineComboboxContent,\n InlineComboboxEmpty,\n InlineComboboxInput,\n InlineComboboxItem,\n} from './inline-combobox';\nimport { PlateElement } from './plate-element';\n\nexport const EmojiInputElement = withRef(\n ({ className, ...props }, ref) => {\n const { children, editor, element } = props;\n const [value, setValue] = useState('');\n const debouncedValue = useDebounce(value, 100);\n const isPending = value !== debouncedValue;\n\n const filteredEmojis = useMemo(() => {\n if (debouncedValue.trim().length === 0) return [];\n\n return EmojiInlineIndexSearch.getInstance()\n .search(debouncedValue.replace(/:$/, ''))\n .get();\n }, [debouncedValue]);\n\n return (\n \n \n \n\n \n {!isPending && (\n No matching emoji found\n )}\n\n {filteredEmojis.map((emoji) => (\n insertEmoji(editor, emoji)}\n >\n {emoji.skins[0].native} {emoji.name}\n \n ))}\n \n \n\n {children}\n \n );\n }\n);\n", + "content": "'use client';\n\nimport React, { useMemo, useState } from 'react';\n\nimport { withRef } from '@udecode/cn';\nimport { EmojiInlineIndexSearch, insertEmoji } from '@udecode/plate-emoji';\n\nimport { useDebounce } from '@/hooks/use-debounce';\n\nimport {\n InlineCombobox,\n InlineComboboxContent,\n InlineComboboxEmpty,\n InlineComboboxGroup,\n InlineComboboxInput,\n InlineComboboxItem,\n} from './inline-combobox';\nimport { PlateElement } from './plate-element';\n\nexport const EmojiInputElement = withRef(\n ({ className, ...props }, ref) => {\n const { children, editor, element } = props;\n const [value, setValue] = useState('');\n const debouncedValue = useDebounce(value, 100);\n const isPending = value !== debouncedValue;\n\n const filteredEmojis = useMemo(() => {\n if (debouncedValue.trim().length === 0) return [];\n\n return EmojiInlineIndexSearch.getInstance()\n .search(debouncedValue.replace(/:$/, ''))\n .get();\n }, [debouncedValue]);\n\n return (\n \n \n \n\n \n {!isPending && (\n No results\n )}\n\n \n {filteredEmojis.map((emoji) => (\n insertEmoji(editor, emoji)}\n >\n {emoji.skins[0].native} {emoji.name}\n \n ))}\n \n \n \n\n {children}\n \n );\n }\n);\n", "path": "plate-ui/emoji-input-element.tsx", "target": "components/plate-ui/emoji-input-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/excalidraw-demo.json b/apps/www/public/r/styles/default/excalidraw-demo.json index 554c17e13b..cae34c2e0d 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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/fixed-toolbar-buttons.json b/apps/www/public/r/styles/default/fixed-toolbar-buttons.json index 7abca50c99..c4ca95c423 100644 --- a/apps/www/public/r/styles/default/fixed-toolbar-buttons.json +++ b/apps/www/public/r/styles/default/fixed-toolbar-buttons.json @@ -1,22 +1,20 @@ { "dependencies": [ - "@udecode/plate-basic-marks" + "@udecode/plate-basic-marks", + "@udecode/plate-font", + "@udecode/plate-indent-list", + "@udecode/plate-list", + "@udecode/plate-media" ], "doc": { "description": "A set of commonly used formatting buttons.", - "docs": [ - { - "route": "/docs/basic-marks", - "title": "Basic Marks" - } - ], "examples": [ "toolbar-demo" ] }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { useEditorReadOnly } from '@udecode/plate-common/react';\nimport { Bold, Code, Italic, Strikethrough, Underline } from 'lucide-react';\n\nimport { InsertDropdownMenu } from './insert-dropdown-menu';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { ModeDropdownMenu } from './mode-dropdown-menu';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FixedToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n
\n \n {!readOnly && (\n <>\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n )}\n\n
\n\n \n \n \n
\n
\n );\n}\n", + "content": "import React from 'react';\n\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { useEditorReadOnly } from '@udecode/plate-common/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n} from '@udecode/plate-font/react';\nimport { ListStyleType } from '@udecode/plate-indent-list';\nimport {\n BulletedListPlugin,\n NumberedListPlugin,\n} from '@udecode/plate-list/react';\nimport { ImagePlugin } from '@udecode/plate-media/react';\nimport {\n BaselineIcon,\n BoldIcon,\n Code2Icon,\n ItalicIcon,\n PaintBucketIcon,\n SparklesIcon,\n StrikethroughIcon,\n UnderlineIcon,\n} from 'lucide-react';\n\nimport { AIToolbarButton } from './ai-toolbar-button';\nimport { AlignDropdownMenu } from './align-dropdown-menu';\nimport { ColorDropdownMenu } from './color-dropdown-menu';\nimport { CommentToolbarButton } from './comment-toolbar-button';\nimport { EmojiDropdownMenu } from './emoji-dropdown-menu';\nimport { IndentListToolbarButton } from './indent-list-toolbar-button';\nimport { IndentTodoToolbarButton } from './indent-todo-toolbar-button';\nimport { IndentToolbarButton } from './indent-toolbar-button';\nimport { InsertDropdownMenu } from './insert-dropdown-menu';\nimport { LineHeightDropdownMenu } from './line-height-dropdown-menu';\nimport { LinkToolbarButton } from './link-toolbar-button';\nimport { ListToolbarButton } from './list-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { MediaToolbarButton } from './media-toolbar-button';\nimport { ModeDropdownMenu } from './mode-dropdown-menu';\nimport { MoreDropdownMenu } from './more-dropdown-menu';\nimport { OutdentToolbarButton } from './outdent-toolbar-button';\nimport { TableDropdownMenu } from './table-dropdown-menu';\nimport { ToggleToolbarButton } from './toggle-toolbar-button';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FixedToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n
\n {!readOnly && (\n <>\n \n \n \n Ask AI\n \n \n\n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n\n \n \n \n\n \n \n \n \n \n \n \n \n \n )}\n\n
\n\n \n \n \n \n
\n );\n}\n", "path": "plate-ui/fixed-toolbar-buttons.tsx", "target": "components/plate-ui/fixed-toolbar-buttons.tsx", "type": "registry:ui" @@ -25,9 +23,25 @@ "name": "fixed-toolbar-buttons", "registryDependencies": [ "toolbar", + "ai-toolbar-button", + "align-dropdown-menu", + "color-dropdown-menu", + "comment-toolbar-button", + "emoji-dropdown-menu", + "indent-list-toolbar-button", + "indent-todo-toolbar-button", + "indent-toolbar-button", "insert-dropdown-menu", + "line-height-dropdown-menu", + "link-toolbar-button", + "list-toolbar-button", "mark-toolbar-button", + "media-toolbar-button", "mode-dropdown-menu", + "more-dropdown-menu", + "outdent-toolbar-button", + "table-dropdown-menu", + "toggle-toolbar-button", "turn-into-dropdown-menu" ], "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/floating-toolbar-buttons.json b/apps/www/public/r/styles/default/floating-toolbar-buttons.json index 0d84554c21..d89a608710 100644 --- a/apps/www/public/r/styles/default/floating-toolbar-buttons.json +++ b/apps/www/public/r/styles/default/floating-toolbar-buttons.json @@ -16,7 +16,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { useEditorReadOnly } from '@udecode/plate-common/react';\nimport { Bold, Code, Italic, Strikethrough, Underline } from 'lucide-react';\n\nimport { ToolbarGroup } from './toolbar';\n\n// import { AIToolbarButton } from './ai-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FloatingToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n <>\n {!readOnly && (\n <>\n {/* \n \n \n Ask AI\n \n */}\n\n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n )}\n \n );\n}\n", + "content": "import React from 'react';\n\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { useEditorReadOnly } from '@udecode/plate-common/react';\nimport {\n BoldIcon,\n Code2Icon,\n ItalicIcon,\n SparklesIcon,\n StrikethroughIcon,\n UnderlineIcon,\n} from 'lucide-react';\n\nimport { AIToolbarButton } from './ai-toolbar-button';\nimport { CommentToolbarButton } from './comment-toolbar-button';\nimport { LinkToolbarButton } from './link-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { MoreDropdownMenu } from './more-dropdown-menu';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FloatingToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n <>\n {!readOnly && (\n <>\n \n \n \n Ask AI\n \n \n\n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n )}\n\n \n \n\n {!readOnly && }\n \n \n );\n}\n", "path": "plate-ui/floating-toolbar-buttons.tsx", "target": "components/plate-ui/floating-toolbar-buttons.tsx", "type": "registry:ui" @@ -24,6 +24,10 @@ ], "name": "floating-toolbar-buttons", "registryDependencies": [ + "toolbar", + "ai-toolbar-button", + "comment-toolbar-button", + "link-toolbar-button", "mark-toolbar-button", "more-dropdown-menu", "turn-into-dropdown-menu" 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 9e30d10508..b9595bd600 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 61e66a6d50..d12e3639eb 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 0d37a4ca88..98bec686b6 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 b5707a84ac..b7bdbdb34c 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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/indent-demo.json b/apps/www/public/r/styles/default/indent-demo.json index b429fee877..8974e6873a 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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/inline-combobox.json b/apps/www/public/r/styles/default/inline-combobox.json index 336f28433c..bd7693df45 100644 --- a/apps/www/public/r/styles/default/inline-combobox.json +++ b/apps/www/public/r/styles/default/inline-combobox.json @@ -22,7 +22,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, {\n type HTMLAttributes,\n type ReactNode,\n type RefObject,\n createContext,\n forwardRef,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport type { PointRef } from 'slate';\n\nimport {\n type ComboboxItemProps,\n Combobox,\n ComboboxItem,\n ComboboxPopover,\n ComboboxProvider,\n Portal,\n useComboboxContext,\n useComboboxStore,\n} from '@ariakit/react';\nimport { cn } from '@udecode/cn';\nimport { filterWords } from '@udecode/plate-combobox';\nimport {\n type UseComboboxInputResult,\n useComboboxInput,\n useHTMLInputCursorState,\n} from '@udecode/plate-combobox/react';\nimport {\n type TElement,\n createPointRef,\n getPointBefore,\n insertText,\n moveSelection,\n} from '@udecode/plate-common';\nimport {\n findNodePath,\n useComposedRef,\n useEditorRef,\n} from '@udecode/plate-common/react';\nimport { cva } from 'class-variance-authority';\n\ntype FilterFn = (\n item: { value: string; keywords?: string[] },\n search: string\n) => boolean;\n\ninterface InlineComboboxContextValue {\n filter: FilterFn | false;\n inputProps: UseComboboxInputResult['props'];\n inputRef: RefObject;\n removeInput: UseComboboxInputResult['removeInput'];\n setHasEmpty: (hasEmpty: boolean) => void;\n showTrigger: boolean;\n trigger: string;\n}\n\nconst InlineComboboxContext = createContext(\n null as any\n);\n\nexport const defaultFilter: FilterFn = ({ keywords = [], value }, search) =>\n [value, ...keywords].some((keyword) => filterWords(keyword, search));\n\ninterface InlineComboboxProps {\n children: ReactNode;\n element: TElement;\n trigger: string;\n filter?: FilterFn | false;\n hideWhenNoValue?: boolean;\n setValue?: (value: string) => void;\n showTrigger?: boolean;\n value?: string;\n}\n\nconst InlineCombobox = ({\n children,\n element,\n filter = defaultFilter,\n hideWhenNoValue = false,\n setValue: setValueProp,\n showTrigger = true,\n trigger,\n value: valueProp,\n}: InlineComboboxProps) => {\n const editor = useEditorRef();\n const inputRef = React.useRef(null);\n const cursorState = useHTMLInputCursorState(inputRef);\n\n const [valueState, setValueState] = useState('');\n const hasValueProp = valueProp !== undefined;\n const value = hasValueProp ? valueProp : valueState;\n\n const setValue = useCallback(\n (newValue: string) => {\n setValueProp?.(newValue);\n\n if (!hasValueProp) {\n setValueState(newValue);\n }\n },\n [setValueProp, hasValueProp]\n );\n\n /**\n * Track the point just before the input element so we know where to\n * insertText if the combobox closes due to a selection change.\n */\n const [insertPoint, setInsertPoint] = useState(null);\n\n useEffect(() => {\n const path = findNodePath(editor, element);\n\n if (!path) return;\n\n const point = getPointBefore(editor, path);\n\n if (!point) return;\n\n const pointRef = createPointRef(editor, point);\n setInsertPoint(pointRef);\n\n return () => {\n pointRef.unref();\n };\n }, [editor, element]);\n\n const { props: inputProps, removeInput } = useComboboxInput({\n cancelInputOnBlur: false,\n cursorState,\n ref: inputRef,\n onCancelInput: (cause) => {\n if (cause !== 'backspace') {\n insertText(editor, trigger + value, {\n at: insertPoint?.current ?? undefined,\n });\n }\n if (cause === 'arrowLeft' || cause === 'arrowRight') {\n moveSelection(editor, {\n distance: 1,\n reverse: cause === 'arrowLeft',\n });\n }\n },\n });\n\n const [hasEmpty, setHasEmpty] = useState(false);\n\n const contextValue: InlineComboboxContextValue = useMemo(\n () => ({\n filter,\n inputProps,\n inputRef,\n removeInput,\n setHasEmpty,\n showTrigger,\n trigger,\n }),\n [\n trigger,\n showTrigger,\n filter,\n inputRef,\n inputProps,\n removeInput,\n setHasEmpty,\n ]\n );\n\n const store = useComboboxStore({\n // open: ,\n setValue: (newValue) => startTransition(() => setValue(newValue)),\n });\n\n const items = store.useState('items');\n\n /**\n * If there is no active ID and the list of items changes, select the first\n * item.\n */\n useEffect(() => {\n if (!store.getState().activeId) {\n store.setActiveId(store.first());\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items, store]);\n\n return (\n \n 0 || hasEmpty) &&\n (!hideWhenNoValue || value.length > 0)\n }\n store={store}\n >\n \n {children}\n \n \n \n );\n};\n\nconst InlineComboboxInput = forwardRef<\n HTMLInputElement,\n HTMLAttributes\n>(({ className, ...props }, propRef) => {\n const {\n inputProps,\n inputRef: contextRef,\n showTrigger,\n trigger,\n } = useContext(InlineComboboxContext);\n\n const store = useComboboxContext()!;\n const value = store.useState('value');\n\n const ref = useComposedRef(propRef, contextRef);\n\n /**\n * To create an auto-resizing input, we render a visually hidden span\n * containing the input value and position the input element on top of it.\n * This works well for all cases except when input exceeds the width of the\n * container.\n */\n\n return (\n <>\n {showTrigger && trigger}\n\n \n \n {value || '\\u200B'}\n \n\n \n \n \n );\n});\n\nInlineComboboxInput.displayName = 'InlineComboboxInput';\n\nconst InlineComboboxContent: typeof ComboboxPopover = ({\n className,\n ...props\n}) => {\n // Portal prevents CSS from leaking into popover\n return (\n \n \n \n );\n};\n\nconst comboboxItemVariants = cva(\n 'relative flex h-9 select-none items-center rounded-sm px-2 py-1.5 text-sm text-foreground outline-none',\n {\n defaultVariants: {\n interactive: true,\n },\n variants: {\n interactive: {\n false: '',\n true: 'cursor-pointer transition-colors hover:bg-accent hover:text-accent-foreground data-[active-item=true]:bg-accent data-[active-item=true]:text-accent-foreground',\n },\n },\n }\n);\n\nexport type InlineComboboxItemProps = {\n focusEditor?: boolean;\n keywords?: string[];\n} & ComboboxItemProps &\n Required>;\n\nconst InlineComboboxItem = ({\n className,\n focusEditor = true,\n keywords,\n onClick,\n ...props\n}: InlineComboboxItemProps) => {\n const { value } = props;\n\n const { filter, removeInput } = useContext(InlineComboboxContext);\n\n const store = useComboboxContext()!;\n\n // Optimization: Do not subscribe to value if filter is false\n const search = filter && store.useState('value');\n\n const visible = useMemo(\n () => !filter || filter({ keywords, value }, search as string),\n [filter, value, keywords, search]\n );\n\n if (!visible) return null;\n\n return (\n {\n removeInput(focusEditor);\n onClick?.(event);\n }}\n {...props}\n />\n );\n};\n\nconst InlineComboboxEmpty = ({\n children,\n className,\n}: HTMLAttributes) => {\n const { setHasEmpty } = useContext(InlineComboboxContext);\n const store = useComboboxContext()!;\n const items = store.useState('items');\n\n useEffect(() => {\n setHasEmpty(true);\n\n return () => {\n setHasEmpty(false);\n };\n }, [setHasEmpty]);\n\n if (items.length > 0) return null;\n\n return (\n \n {children}\n \n );\n};\n\nexport {\n InlineCombobox,\n InlineComboboxContent,\n InlineComboboxEmpty,\n InlineComboboxInput,\n InlineComboboxItem,\n};\n", + "content": "'use client';\n\nimport React, {\n type HTMLAttributes,\n type ReactNode,\n type RefObject,\n createContext,\n forwardRef,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport type { PointRef } from 'slate';\n\nimport {\n type ComboboxItemProps,\n Combobox,\n ComboboxGroup,\n ComboboxGroupLabel,\n ComboboxItem,\n ComboboxPopover,\n ComboboxProvider,\n ComboboxRow,\n Portal,\n useComboboxContext,\n useComboboxStore,\n} from '@ariakit/react';\nimport { cn, withCn } from '@udecode/cn';\nimport { filterWords } from '@udecode/plate-combobox';\nimport {\n type UseComboboxInputResult,\n useComboboxInput,\n useHTMLInputCursorState,\n} from '@udecode/plate-combobox/react';\nimport {\n type TElement,\n createPointRef,\n getPointBefore,\n insertText,\n moveSelection,\n} from '@udecode/plate-common';\nimport {\n findNodePath,\n useComposedRef,\n useEditorRef,\n} from '@udecode/plate-common/react';\nimport { cva } from 'class-variance-authority';\n\ntype FilterFn = (\n item: { value: string; group?: string; keywords?: string[]; label?: string },\n search: string\n) => boolean;\n\ninterface InlineComboboxContextValue {\n filter: FilterFn | false;\n inputProps: UseComboboxInputResult['props'];\n inputRef: RefObject;\n removeInput: UseComboboxInputResult['removeInput'];\n setHasEmpty: (hasEmpty: boolean) => void;\n showTrigger: boolean;\n trigger: string;\n}\n\nconst InlineComboboxContext = createContext(\n null as any\n);\n\nexport const defaultFilter: FilterFn = (\n { group, keywords = [], label, value },\n search\n) => {\n const uniqueTerms = new Set(\n [value, ...keywords, group, label].filter(Boolean)\n );\n\n return Array.from(uniqueTerms).some((keyword) =>\n filterWords(keyword!, search)\n );\n};\n\ninterface InlineComboboxProps {\n children: ReactNode;\n element: TElement;\n trigger: string;\n filter?: FilterFn | false;\n hideWhenNoValue?: boolean;\n setValue?: (value: string) => void;\n showTrigger?: boolean;\n value?: string;\n}\n\nconst InlineCombobox = ({\n children,\n element,\n filter = defaultFilter,\n hideWhenNoValue = false,\n setValue: setValueProp,\n showTrigger = true,\n trigger,\n value: valueProp,\n}: InlineComboboxProps) => {\n const editor = useEditorRef();\n const inputRef = React.useRef(null);\n const cursorState = useHTMLInputCursorState(inputRef);\n\n const [valueState, setValueState] = useState('');\n const hasValueProp = valueProp !== undefined;\n const value = hasValueProp ? valueProp : valueState;\n\n const setValue = useCallback(\n (newValue: string) => {\n setValueProp?.(newValue);\n\n if (!hasValueProp) {\n setValueState(newValue);\n }\n },\n [setValueProp, hasValueProp]\n );\n\n /**\n * Track the point just before the input element so we know where to\n * insertText if the combobox closes due to a selection change.\n */\n const [insertPoint, setInsertPoint] = useState(null);\n\n useEffect(() => {\n const path = findNodePath(editor, element);\n\n if (!path) return;\n\n const point = getPointBefore(editor, path);\n\n if (!point) return;\n\n const pointRef = createPointRef(editor, point);\n setInsertPoint(pointRef);\n\n return () => {\n pointRef.unref();\n };\n }, [editor, element]);\n\n const { props: inputProps, removeInput } = useComboboxInput({\n cancelInputOnBlur: false,\n cursorState,\n ref: inputRef,\n onCancelInput: (cause) => {\n if (cause !== 'backspace') {\n insertText(editor, trigger + value, {\n at: insertPoint?.current ?? undefined,\n });\n }\n if (cause === 'arrowLeft' || cause === 'arrowRight') {\n moveSelection(editor, {\n distance: 1,\n reverse: cause === 'arrowLeft',\n });\n }\n },\n });\n\n const [hasEmpty, setHasEmpty] = useState(false);\n\n const contextValue: InlineComboboxContextValue = useMemo(\n () => ({\n filter,\n inputProps,\n inputRef,\n removeInput,\n setHasEmpty,\n showTrigger,\n trigger,\n }),\n [\n trigger,\n showTrigger,\n filter,\n inputRef,\n inputProps,\n removeInput,\n setHasEmpty,\n ]\n );\n\n const store = useComboboxStore({\n // open: ,\n setValue: (newValue) => startTransition(() => setValue(newValue)),\n });\n\n const items = store.useState('items');\n\n /**\n * If there is no active ID and the list of items changes, select the first\n * item.\n */\n useEffect(() => {\n if (!store.getState().activeId) {\n store.setActiveId(store.first());\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items, store]);\n\n return (\n \n 0 || hasEmpty) &&\n (!hideWhenNoValue || value.length > 0)\n }\n store={store}\n >\n \n {children}\n \n \n \n );\n};\n\nconst InlineComboboxInput = forwardRef<\n HTMLInputElement,\n HTMLAttributes\n>(({ className, ...props }, propRef) => {\n const {\n inputProps,\n inputRef: contextRef,\n showTrigger,\n trigger,\n } = useContext(InlineComboboxContext);\n\n const store = useComboboxContext()!;\n const value = store.useState('value');\n\n const ref = useComposedRef(propRef, contextRef);\n\n /**\n * To create an auto-resizing input, we render a visually hidden span\n * containing the input value and position the input element on top of it.\n * This works well for all cases except when input exceeds the width of the\n * container.\n */\n\n return (\n <>\n {showTrigger && trigger}\n\n \n \n {value || '\\u200B'}\n \n\n \n \n \n );\n});\n\nInlineComboboxInput.displayName = 'InlineComboboxInput';\n\nconst InlineComboboxContent: typeof ComboboxPopover = ({\n className,\n ...props\n}) => {\n // Portal prevents CSS from leaking into popover\n return (\n \n \n \n );\n};\n\nconst comboboxItemVariants = cva(\n 'relative mx-1 flex h-[28px] select-none items-center rounded-sm px-2 text-sm text-foreground outline-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n defaultVariants: {\n interactive: true,\n },\n variants: {\n interactive: {\n false: '',\n true: 'cursor-pointer transition-colors hover:bg-accent hover:text-accent-foreground data-[active-item=true]:bg-accent data-[active-item=true]:text-accent-foreground',\n },\n },\n }\n);\n\nexport type InlineComboboxItemProps = {\n focusEditor?: boolean;\n group?: string;\n keywords?: string[];\n label?: string;\n} & ComboboxItemProps &\n Required>;\n\nconst InlineComboboxItem = ({\n className,\n focusEditor = true,\n group,\n keywords,\n label,\n onClick,\n ...props\n}: InlineComboboxItemProps) => {\n const { value } = props;\n\n const { filter, removeInput } = useContext(InlineComboboxContext);\n\n const store = useComboboxContext()!;\n\n // Optimization: Do not subscribe to value if filter is false\n const search = filter && store.useState('value');\n\n const visible = useMemo(\n () =>\n !filter || filter({ group, keywords, label, value }, search as string),\n [filter, group, keywords, label, value, search]\n );\n\n if (!visible) return null;\n\n return (\n {\n removeInput(focusEditor);\n onClick?.(event);\n }}\n {...props}\n />\n );\n};\n\nconst InlineComboboxEmpty = ({\n children,\n className,\n}: HTMLAttributes) => {\n const { setHasEmpty } = useContext(InlineComboboxContext);\n const store = useComboboxContext()!;\n const items = store.useState('items');\n\n useEffect(() => {\n setHasEmpty(true);\n\n return () => {\n setHasEmpty(false);\n };\n }, [setHasEmpty]);\n\n if (items.length > 0) return null;\n\n return (\n \n {children}\n \n );\n};\n\nconst InlineComboboxRow = ComboboxRow;\n\nconst InlineComboboxGroup = withCn(\n ComboboxGroup,\n 'hidden py-1.5 [&:has([role=option])]:block [&:not(:last-child)]:border-b'\n);\n\nconst InlineComboboxGroupLabel = withCn(\n ComboboxGroupLabel,\n 'mb-2 mt-1.5 px-3 text-xs font-medium text-muted-foreground'\n);\n\nexport {\n InlineCombobox,\n InlineComboboxContent,\n InlineComboboxEmpty,\n InlineComboboxGroup,\n InlineComboboxGroupLabel,\n InlineComboboxInput,\n InlineComboboxItem,\n InlineComboboxRow,\n};\n", "path": "plate-ui/inline-combobox.tsx", "target": "components/plate-ui/inline-combobox.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/input.json b/apps/www/public/r/styles/default/input.json index 88231b2c99..199c0cee96 100644 --- a/apps/www/public/r/styles/default/input.json +++ b/apps/www/public/r/styles/default/input.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "import { withVariants } from '@udecode/cn';\nimport { cva } from 'class-variance-authority';\n\nexport const inputVariants = cva(\n 'flex w-full rounded-md bg-transparent text-sm file:border-0 file:bg-background file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n {\n defaultVariants: {\n h: 'md',\n variant: 'default',\n },\n variants: {\n h: {\n md: 'h-10 px-3 py-2',\n sm: 'h-9 px-3 py-2',\n },\n variant: {\n default:\n 'border border-input ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n ghost: 'border-none focus-visible:ring-transparent',\n },\n },\n }\n);\n\nexport const Input = withVariants('input', inputVariants, ['variant', 'h']);\n", + "content": "import { withVariants } from '@udecode/cn';\nimport { cva } from 'class-variance-authority';\n\nexport const inputVariants = cva(\n 'flex w-full rounded-md bg-transparent text-sm file:border-0 file:bg-background file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n {\n defaultVariants: {\n h: 'md',\n variant: 'default',\n },\n variants: {\n h: {\n md: 'h-10 px-3 py-2',\n sm: 'h-[28px] px-1.5 py-1',\n },\n variant: {\n default:\n 'border border-input ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n ghost: 'border-none focus-visible:ring-transparent',\n },\n },\n }\n);\n\nexport const Input = withVariants('input', inputVariants, ['variant', 'h']);\n", "path": "plate-ui/input.tsx", "target": "components/plate-ui/input.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/insert-dropdown-menu.json b/apps/www/public/r/styles/default/insert-dropdown-menu.json index 30e699df8e..2665a441c0 100644 --- a/apps/www/public/r/styles/default/insert-dropdown-menu.json +++ b/apps/www/public/r/styles/default/insert-dropdown-menu.json @@ -1,24 +1,27 @@ { "dependencies": [ + "@radix-ui/react-dropdown-menu", "@udecode/plate-block-quote", + "@udecode/plate-code-block", + "@udecode/plate-date", + "@udecode/plate-excalidraw", "@udecode/plate-heading", - "@radix-ui/react-dropdown-menu" + "@udecode/plate-horizontal-rule", + "@udecode/plate-indent-list", + "@udecode/plate-link", + "@udecode/plate-media", + "@udecode/plate-table", + "@udecode/plate-toggle" ], "doc": { "description": "A menu for inserting different types of blocks.", - "docs": [ - { - "route": "/docs/basic-elements", - "title": "Basic Elements" - } - ], "examples": [ "basic-nodes-demo" ] }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { insertEmptyElement } from '@udecode/plate-common';\nimport {\n ParagraphPlugin,\n focusEditor,\n useEditorRef,\n} from '@udecode/plate-common/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport {\n Heading1Icon,\n Heading2Icon,\n Heading3Icon,\n PilcrowIcon,\n Plus,\n QuoteIcon,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n items: [\n {\n description: 'Paragraph',\n icon: PilcrowIcon,\n label: 'Paragraph',\n value: ParagraphPlugin.key,\n },\n {\n description: 'Heading 1',\n icon: Heading1Icon,\n label: 'Heading 1',\n value: HEADING_KEYS.h1,\n },\n {\n description: 'Heading 2',\n icon: Heading2Icon,\n label: 'Heading 2',\n value: HEADING_KEYS.h2,\n },\n {\n description: 'Heading 3',\n icon: Heading3Icon,\n label: 'Heading 3',\n value: HEADING_KEYS.h3,\n },\n {\n description: 'Quote (⌘+⇧+.)',\n icon: QuoteIcon,\n label: 'Quote',\n value: BlockquotePlugin.key,\n },\n // {\n // value: TablePlugin.key,\n // label: 'Table',\n // description: 'Table',\n // icon: Icons.table,\n // },\n // {\n // value: 'ul',\n // label: 'Bulleted list',\n // description: 'Bulleted list',\n // icon: Icons.ul,\n // },\n // {\n // value: 'ol',\n // label: 'Numbered list',\n // description: 'Numbered list',\n // icon: Icons.ol,\n // },\n // {\n // value: HorizontalRulePlugin.key,\n // label: 'Divider',\n // description: 'Divider (---)',\n // icon: Icons.hr,\n // },\n ],\n label: 'Basic blocks',\n },\n // {\n // label: 'Media',\n // items: [\n // {\n // value: CodeBlockPlugin.key,\n // label: 'Code',\n // description: 'Code (```)',\n // icon: Icons.codeblock,\n // },\n // {\n // value: ImagePlugin.key,\n // label: 'Image',\n // description: 'Image',\n // icon: Icons.image,\n // },\n // {\n // value: MediaEmbedPlugin.key,\n // label: 'Embed',\n // description: 'Embed',\n // icon: Icons.embed,\n // },\n // {\n // value: ExcalidrawPlugin.key,\n // label: 'Excalidraw',\n // description: 'Excalidraw',\n // icon: Icons.excalidraw,\n // },\n // ],\n // },\n // {\n // label: 'Inline',\n // items: [\n // {\n // value: LinkPlugin.key,\n // label: 'Link',\n // description: 'Link',\n // icon: Icons.link,\n // },\n // ],\n // },\n];\n\nexport function InsertDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n {items.map(({ items: nestedItems, label }, index) => (\n \n {index !== 0 && }\n\n {label}\n {nestedItems.map(\n ({ icon: Icon, label: itemLabel, value: type }) => (\n {\n switch (type) {\n // case CodeBlockPlugin.key: {\n // insertEmptyCodeBlock(editor);\n //\n // break;\n // }\n // case ImagePlugin.key: {\n // await insertMedia(editor, { type: ImagePlugin.key });\n //\n // break;\n // }\n // case MediaEmbedPlugin.key: {\n // await insertMedia(editor, {\n // type: MediaEmbedPlugin.key,\n // });\n //\n // break;\n // }\n // case 'ul':\n // case 'ol': {\n // insertEmptyElement(editor, ParagraphPlugin.key, {\n // select: true,\n // nextBlock: true,\n // });\n //\n // if (settingsStore.get.checkedId(IndentListPlugin.key)) {\n // toggleIndentList(editor, {\n // listStyleType: type === 'ul' ? 'disc' : 'decimal',\n // });\n // } else if (settingsStore.get.checkedId('list')) {\n // toggleList(editor, { type });\n // }\n //\n // break;\n // }\n // case TablePlugin.key: {\n // insertTable(editor);\n //\n // break;\n // }\n // case LinkPlugin.key: {\n // triggerFloatingLink(editor, { focused: true });\n //\n // break;\n // }\n default: {\n insertEmptyElement(editor, type, {\n nextBlock: true,\n select: true,\n });\n }\n }\n\n focusEditor(editor);\n }}\n >\n \n {itemLabel}\n \n )\n )}\n \n ))}\n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport {\n type PlateEditor,\n ParagraphPlugin,\n focusEditor,\n useEditorRef,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { TocPlugin } from '@udecode/plate-heading/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { INDENT_LIST_KEYS, ListStyleType } from '@udecode/plate-indent-list';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport {\n CalendarIcon,\n ChevronRightIcon,\n Columns3Icon,\n FileCodeIcon,\n FilmIcon,\n Heading1Icon,\n Heading2Icon,\n Heading3Icon,\n ImageIcon,\n Link2Icon,\n ListIcon,\n ListOrderedIcon,\n MinusIcon,\n PenToolIcon,\n PilcrowIcon,\n PlusIcon,\n QuoteIcon,\n SquareIcon,\n TableIcon,\n TableOfContentsIcon,\n} from 'lucide-react';\n\nimport {\n insertBlock,\n insertInlineElement,\n} from '@/lib/transforms';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\ntype Group = {\n group: string;\n items: Item[];\n};\n\ninterface Item {\n icon: React.ReactNode;\n onSelect: (editor: PlateEditor, value: string) => void;\n value: string;\n focusEditor?: boolean;\n label?: string;\n}\n\nconst groups: Group[] = [\n {\n group: 'Basic blocks',\n items: [\n {\n icon: ,\n label: 'Paragraph',\n value: ParagraphPlugin.key,\n },\n {\n icon: ,\n label: 'Heading 1',\n value: HEADING_KEYS.h1,\n },\n {\n icon: ,\n label: 'Heading 2',\n value: HEADING_KEYS.h2,\n },\n {\n icon: ,\n label: 'Heading 3',\n value: HEADING_KEYS.h3,\n },\n {\n icon: ,\n label: 'Table',\n value: TablePlugin.key,\n },\n {\n icon: ,\n label: 'Code',\n value: CodeBlockPlugin.key,\n },\n {\n icon: ,\n label: 'Quote',\n value: BlockquotePlugin.key,\n },\n {\n icon: ,\n label: 'Divider',\n value: HorizontalRulePlugin.key,\n },\n ].map((item) => ({\n ...item,\n onSelect: (editor, value) => {\n insertBlock(editor, value);\n },\n })),\n },\n {\n group: 'Lists',\n items: [\n {\n icon: ,\n label: 'Bulleted list',\n value: ListStyleType.Disc,\n },\n {\n icon: ,\n label: 'Numbered list',\n value: ListStyleType.Decimal,\n },\n {\n icon: ,\n label: 'To-do list',\n value: INDENT_LIST_KEYS.todo,\n },\n {\n icon: ,\n label: 'Toggle list',\n value: TogglePlugin.key,\n },\n ].map((item) => ({\n ...item,\n onSelect: (editor, value) => {\n insertBlock(editor, value);\n },\n })),\n },\n {\n group: 'Media',\n items: [\n {\n icon: ,\n label: 'Image',\n value: ImagePlugin.key,\n },\n {\n icon: ,\n label: 'Embed',\n value: MediaEmbedPlugin.key,\n },\n {\n icon: ,\n label: 'Excalidraw',\n value: ExcalidrawPlugin.key,\n },\n ].map((item) => ({\n ...item,\n onSelect: (editor, value) => {\n insertBlock(editor, value);\n },\n })),\n },\n {\n group: 'Advanced blocks',\n items: [\n {\n icon: ,\n label: 'Table of contents',\n value: TocPlugin.key,\n },\n {\n icon: ,\n label: '3 columns',\n value: 'action_three_columns',\n },\n ].map((item) => ({\n ...item,\n onSelect: (editor, value) => {\n insertBlock(editor, value);\n },\n })),\n },\n {\n group: 'Inline',\n items: [\n {\n icon: ,\n label: 'Link',\n value: LinkPlugin.key,\n },\n {\n focusEditor: true,\n icon: ,\n label: 'Date',\n value: DatePlugin.key,\n },\n ].map((item) => ({\n ...item,\n onSelect: (editor, value) => {\n insertInlineElement(editor, value);\n },\n })),\n },\n];\n\nexport function InsertDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n {groups.map(({ group, items: nestedItems }) => (\n \n {nestedItems.map(({ icon, label, value, onSelect }) => (\n {\n onSelect(editor, value);\n focusEditor(editor);\n }}\n >\n {icon}\n {label}\n \n ))}\n \n ))}\n \n \n );\n}\n", "path": "plate-ui/insert-dropdown-menu.tsx", "target": "components/plate-ui/insert-dropdown-menu.tsx", "type": "registry:ui" @@ -27,7 +30,8 @@ "name": "insert-dropdown-menu", "registryDependencies": [ "dropdown-menu", - "toolbar" + "toolbar", + "transforms" ], "type": "registry:ui" } \ No newline at end of file diff --git a/apps/www/public/r/styles/default/kbd-demo.json b/apps/www/public/r/styles/default/kbd-demo.json index e9efebf8fb..9a14b87d44 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 178fd10286..81b703b38d 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-dropdown-menu.json b/apps/www/public/r/styles/default/line-height-dropdown-menu.json index 4eaa267d67..1c41e57079 100644 --- a/apps/www/public/r/styles/default/line-height-dropdown-menu.json +++ b/apps/www/public/r/styles/default/line-height-dropdown-menu.json @@ -17,7 +17,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n useLineHeightDropdownMenu,\n useLineHeightDropdownMenuState,\n} from '@udecode/plate-line-height/react';\nimport { WrapText } from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function LineHeightDropdownMenu({ ...props }: DropdownMenuProps) {\n const openState = useOpenState();\n const state = useLineHeightDropdownMenuState();\n const { radioGroupProps } = useLineHeightDropdownMenu(state);\n\n return (\n \n \n \n \n \n \n\n \n \n {state.values.map((_value) => (\n \n {_value}\n \n ))}\n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n useLineHeightDropdownMenu,\n useLineHeightDropdownMenuState,\n} from '@udecode/plate-line-height/react';\nimport { WrapText } from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function LineHeightDropdownMenu({ ...props }: DropdownMenuProps) {\n const openState = useOpenState();\n const state = useLineHeightDropdownMenuState();\n const { radioGroupProps } = useLineHeightDropdownMenu(state);\n\n return (\n \n \n \n \n \n \n\n \n \n {state.values.map((_value) => (\n \n {_value}\n \n ))}\n \n \n \n );\n}\n", "path": "plate-ui/line-height-dropdown-menu.tsx", "target": "components/plate-ui/line-height-dropdown-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/link-demo.json b/apps/www/public/r/styles/default/link-demo.json index a7c94ee9a8..db2459ad75 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-floating-toolbar.json b/apps/www/public/r/styles/default/link-floating-toolbar.json index 4e11f050cf..3b46ee11b2 100644 --- a/apps/www/public/r/styles/default/link-floating-toolbar.json +++ b/apps/www/public/r/styles/default/link-floating-toolbar.json @@ -21,7 +21,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { cn } from '@udecode/cn';\nimport { useFormInputProps } from '@udecode/plate-common/react';\nimport {\n type UseVirtualFloatingOptions,\n flip,\n offset,\n} from '@udecode/plate-floating';\nimport {\n type LinkFloatingToolbarState,\n FloatingLinkUrlInput,\n LinkOpenButton,\n useFloatingLinkEdit,\n useFloatingLinkEditState,\n useFloatingLinkInsert,\n useFloatingLinkInsertState,\n} from '@udecode/plate-link/react';\nimport { ExternalLink, Link, Text, Unlink } from 'lucide-react';\n\nimport { buttonVariants } from './button';\nimport { inputVariants } from './input';\nimport { popoverVariants } from './popover';\nimport { Separator } from './separator';\n\nconst floatingOptions: UseVirtualFloatingOptions = {\n middleware: [\n offset(12),\n flip({\n fallbackPlacements: ['bottom-end', 'top-start', 'top-end'],\n padding: 12,\n }),\n ],\n placement: 'bottom-start',\n};\n\nexport interface LinkFloatingToolbarProps {\n state?: LinkFloatingToolbarState;\n}\n\nexport function LinkFloatingToolbar({ state }: LinkFloatingToolbarProps) {\n const insertState = useFloatingLinkInsertState({\n ...state,\n floatingOptions: {\n ...floatingOptions,\n ...state?.floatingOptions,\n },\n });\n const {\n hidden,\n props: insertProps,\n ref: insertRef,\n textInputProps,\n } = useFloatingLinkInsert(insertState);\n\n const editState = useFloatingLinkEditState({\n ...state,\n floatingOptions: {\n ...floatingOptions,\n ...state?.floatingOptions,\n },\n });\n const {\n editButtonProps,\n props: editProps,\n ref: editRef,\n unlinkButtonProps,\n } = useFloatingLinkEdit(editState);\n const inputProps = useFormInputProps({\n preventDefaultOnEnterKeydown: true,\n });\n\n if (hidden) return null;\n\n const input = (\n
\n
\n
\n \n
\n\n \n
\n \n
\n
\n \n
\n \n
\n
\n );\n\n const editContent = editState.isEditing ? (\n input\n ) : (\n
\n \n Edit link\n \n\n \n\n \n \n \n\n \n\n \n \n \n
\n );\n\n return (\n <>\n \n {input}\n \n\n \n {editContent}\n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { cn } from '@udecode/cn';\nimport { useFormInputProps } from '@udecode/plate-common/react';\nimport {\n type UseVirtualFloatingOptions,\n flip,\n offset,\n} from '@udecode/plate-floating';\nimport {\n type LinkFloatingToolbarState,\n FloatingLinkUrlInput,\n LinkOpenButton,\n useFloatingLinkEdit,\n useFloatingLinkEditState,\n useFloatingLinkInsert,\n useFloatingLinkInsertState,\n} from '@udecode/plate-link/react';\nimport { ExternalLink, Link, Text, Unlink } from 'lucide-react';\n\nimport { buttonVariants } from './button';\nimport { inputVariants } from './input';\nimport { popoverVariants } from './popover';\nimport { Separator } from './separator';\n\nconst floatingOptions: UseVirtualFloatingOptions = {\n middleware: [\n offset(12),\n flip({\n fallbackPlacements: ['bottom-end', 'top-start', 'top-end'],\n padding: 12,\n }),\n ],\n placement: 'bottom-start',\n};\n\nexport interface LinkFloatingToolbarProps {\n state?: LinkFloatingToolbarState;\n}\n\nexport function LinkFloatingToolbar({ state }: LinkFloatingToolbarProps) {\n const insertState = useFloatingLinkInsertState({\n ...state,\n floatingOptions: {\n ...floatingOptions,\n ...state?.floatingOptions,\n },\n });\n const {\n hidden,\n props: insertProps,\n ref: insertRef,\n textInputProps,\n } = useFloatingLinkInsert(insertState);\n\n const editState = useFloatingLinkEditState({\n ...state,\n floatingOptions: {\n ...floatingOptions,\n ...state?.floatingOptions,\n },\n });\n const {\n editButtonProps,\n props: editProps,\n ref: editRef,\n unlinkButtonProps,\n } = useFloatingLinkEdit(editState);\n const inputProps = useFormInputProps({\n preventDefaultOnEnterKeydown: true,\n });\n\n if (hidden) return null;\n\n const input = (\n
\n
\n
\n \n
\n\n \n
\n \n
\n
\n \n
\n \n
\n
\n );\n\n const editContent = editState.isEditing ? (\n input\n ) : (\n
\n \n Edit link\n \n\n \n\n \n \n \n\n \n\n \n \n \n
\n );\n\n return (\n <>\n \n {input}\n \n\n \n {editContent}\n \n \n );\n}\n", "path": "plate-ui/link-floating-toolbar.tsx", "target": "components/plate-ui/link-floating-toolbar.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/list-demo.json b/apps/www/public/r/styles/default/list-demo.json index 3ddf27cc24..d2433bacda 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 9cc68195c8..ea133b0c38 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-popover.json b/apps/www/public/r/styles/default/media-popover.json index 768d583fd4..f3aa7de4ef 100644 --- a/apps/www/public/r/styles/default/media-popover.json +++ b/apps/www/public/r/styles/default/media-popover.json @@ -17,7 +17,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useEffect } from 'react';\n\nimport {\n type WithRequiredKey,\n isSelectionExpanded,\n} from '@udecode/plate-common';\nimport {\n useEditorSelector,\n useElement,\n useRemoveNodeButton,\n} from '@udecode/plate-common/react';\nimport {\n FloatingMedia as FloatingMediaPrimitive,\n floatingMediaActions,\n useFloatingMediaSelectors,\n} from '@udecode/plate-media/react';\nimport { Delete, Link } from 'lucide-react';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { Button, buttonVariants } from './button';\nimport { CaptionButton } from './caption';\nimport { inputVariants } from './input';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\nimport { Separator } from './separator';\n\nexport interface MediaPopoverProps {\n children: React.ReactNode;\n plugin: WithRequiredKey;\n}\n\nexport function MediaPopover({ children, plugin }: MediaPopoverProps) {\n const readOnly = useReadOnly();\n const selected = useSelected();\n\n const selectionCollapsed = useEditorSelector(\n (editor) => !isSelectionExpanded(editor),\n []\n );\n const isOpen = !readOnly && selected && selectionCollapsed;\n const isEditing = useFloatingMediaSelectors().isEditing();\n\n useEffect(() => {\n if (!isOpen && isEditing) {\n floatingMediaActions.isEditing(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n if (readOnly) return <>{children};\n\n return (\n \n {children}\n\n e.preventDefault()}\n >\n {isEditing ? (\n
\n
\n
\n \n
\n\n \n
\n
\n ) : (\n
\n \n Edit link\n \n\n Caption\n\n \n\n \n
\n )}\n \n
\n );\n}\n", + "content": "'use client';\n\nimport React, { useEffect } from 'react';\n\nimport {\n type WithRequiredKey,\n isSelectionExpanded,\n} from '@udecode/plate-common';\nimport {\n useEditorSelector,\n useElement,\n useRemoveNodeButton,\n} from '@udecode/plate-common/react';\nimport {\n FloatingMedia as FloatingMediaPrimitive,\n floatingMediaActions,\n useFloatingMediaSelectors,\n} from '@udecode/plate-media/react';\nimport { Link, Trash2Icon } from 'lucide-react';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { Button, buttonVariants } from './button';\nimport { CaptionButton } from './caption';\nimport { inputVariants } from './input';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\nimport { Separator } from './separator';\n\nexport interface MediaPopoverProps {\n children: React.ReactNode;\n plugin: WithRequiredKey;\n}\n\nexport function MediaPopover({ children, plugin }: MediaPopoverProps) {\n const readOnly = useReadOnly();\n const selected = useSelected();\n\n const selectionCollapsed = useEditorSelector(\n (editor) => !isSelectionExpanded(editor),\n []\n );\n const isOpen = !readOnly && selected && selectionCollapsed;\n const isEditing = useFloatingMediaSelectors().isEditing();\n\n useEffect(() => {\n if (!isOpen && isEditing) {\n floatingMediaActions.isEditing(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n if (readOnly) return <>{children};\n\n return (\n \n {children}\n\n e.preventDefault()}\n >\n {isEditing ? (\n
\n
\n
\n \n
\n\n \n
\n
\n ) : (\n
\n \n Edit link\n \n\n Caption\n\n \n\n \n
\n )}\n \n
\n );\n}\n", "path": "plate-ui/media-popover.tsx", "target": "components/plate-ui/media-popover.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/mention-demo.json b/apps/www/public/r/styles/default/mention-demo.json index e62db710b7..188937a25e 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-input-element.json b/apps/www/public/r/styles/default/mention-input-element.json index 599d3754ee..95a6857a53 100644 --- a/apps/www/public/r/styles/default/mention-input-element.json +++ b/apps/www/public/r/styles/default/mention-input-element.json @@ -18,7 +18,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useState } from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { getMentionOnSelectItem } from '@udecode/plate-mention';\n\nimport {\n InlineCombobox,\n InlineComboboxContent,\n InlineComboboxEmpty,\n InlineComboboxInput,\n InlineComboboxItem,\n} from './inline-combobox';\nimport { PlateElement } from './plate-element';\n\nconst onSelectItem = getMentionOnSelectItem();\n\nexport const MentionInputElement = withRef(\n ({ className, ...props }, ref) => {\n const { children, editor, element } = props;\n const [search, setSearch] = useState('');\n\n return (\n \n \n \n \n \n\n \n No results found\n\n {MENTIONABLES.map((item) => (\n onSelectItem(editor, item, search)}\n >\n {item.text}\n \n ))}\n \n \n\n {children}\n \n );\n }\n);\n\nexport const MENTIONABLES = [\n { key: '0', text: 'Aayla Secura' },\n { key: '1', text: 'Adi Gallia' },\n {\n key: '2',\n text: 'Admiral Dodd Rancit',\n },\n {\n key: '3',\n text: 'Admiral Firmus Piett',\n },\n {\n key: '4',\n text: 'Admiral Gial Ackbar',\n },\n { key: '5', text: 'Admiral Ozzel' },\n { key: '6', text: 'Admiral Raddus' },\n {\n key: '7',\n text: 'Admiral Terrinald Screed',\n },\n { key: '8', text: 'Admiral Trench' },\n {\n key: '9',\n text: 'Admiral U.O. Statura',\n },\n { key: '10', text: 'Agen Kolar' },\n { key: '11', text: 'Agent Kallus' },\n {\n key: '12',\n text: 'Aiolin and Morit Astarte',\n },\n { key: '13', text: 'Aks Moe' },\n { key: '14', text: 'Almec' },\n { key: '15', text: 'Alton Kastle' },\n { key: '16', text: 'Amee' },\n { key: '17', text: 'AP-5' },\n { key: '18', text: 'Armitage Hux' },\n { key: '19', text: 'Artoo' },\n { key: '20', text: 'Arvel Crynyd' },\n { key: '21', text: 'Asajj Ventress' },\n { key: '22', text: 'Aurra Sing' },\n { key: '23', text: 'AZI-3' },\n { key: '24', text: 'Bala-Tik' },\n { key: '25', text: 'Barada' },\n { key: '26', text: 'Bargwill Tomder' },\n { key: '27', text: 'Baron Papanoida' },\n { key: '28', text: 'Barriss Offee' },\n { key: '29', text: 'Baze Malbus' },\n { key: '30', text: 'Bazine Netal' },\n { key: '31', text: 'BB-8' },\n { key: '32', text: 'BB-9E' },\n { key: '33', text: 'Ben Quadinaros' },\n { key: '34', text: 'Berch Teller' },\n { key: '35', text: 'Beru Lars' },\n { key: '36', text: 'Bib Fortuna' },\n {\n key: '37',\n text: 'Biggs Darklighter',\n },\n { key: '38', text: 'Black Krrsantan' },\n { key: '39', text: 'Bo-Katan Kryze' },\n { key: '40', text: 'Boba Fett' },\n { key: '41', text: 'Bobbajo' },\n { key: '42', text: 'Bodhi Rook' },\n { key: '43', text: 'Borvo the Hutt' },\n { key: '44', text: 'Boss Nass' },\n { key: '45', text: 'Bossk' },\n {\n key: '46',\n text: 'Breha Antilles-Organa',\n },\n { key: '47', text: 'Bren Derlin' },\n { key: '48', text: 'Brendol Hux' },\n { key: '49', text: 'BT-1' },\n];\n", + "content": "'use client';\n\nimport React, { useState } from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { getMentionOnSelectItem } from '@udecode/plate-mention';\n\nimport {\n InlineCombobox,\n InlineComboboxContent,\n InlineComboboxEmpty,\n InlineComboboxGroup,\n InlineComboboxInput,\n InlineComboboxItem,\n} from './inline-combobox';\nimport { PlateElement } from './plate-element';\n\nconst onSelectItem = getMentionOnSelectItem();\n\nexport const MentionInputElement = withRef(\n ({ className, ...props }, ref) => {\n const { children, editor, element } = props;\n const [search, setSearch] = useState('');\n\n return (\n \n \n \n \n \n\n \n No results\n\n \n {MENTIONABLES.map((item) => (\n onSelectItem(editor, item, search)}\n >\n {item.text}\n \n ))}\n \n \n \n\n {children}\n \n );\n }\n);\n\nexport const MENTIONABLES = [\n { key: '0', text: 'Aayla Secura' },\n { key: '1', text: 'Adi Gallia' },\n {\n key: '2',\n text: 'Admiral Dodd Rancit',\n },\n {\n key: '3',\n text: 'Admiral Firmus Piett',\n },\n {\n key: '4',\n text: 'Admiral Gial Ackbar',\n },\n { key: '5', text: 'Admiral Ozzel' },\n { key: '6', text: 'Admiral Raddus' },\n {\n key: '7',\n text: 'Admiral Terrinald Screed',\n },\n { key: '8', text: 'Admiral Trench' },\n {\n key: '9',\n text: 'Admiral U.O. Statura',\n },\n { key: '10', text: 'Agen Kolar' },\n { key: '11', text: 'Agent Kallus' },\n {\n key: '12',\n text: 'Aiolin and Morit Astarte',\n },\n { key: '13', text: 'Aks Moe' },\n { key: '14', text: 'Almec' },\n { key: '15', text: 'Alton Kastle' },\n { key: '16', text: 'Amee' },\n { key: '17', text: 'AP-5' },\n { key: '18', text: 'Armitage Hux' },\n { key: '19', text: 'Artoo' },\n { key: '20', text: 'Arvel Crynyd' },\n { key: '21', text: 'Asajj Ventress' },\n { key: '22', text: 'Aurra Sing' },\n { key: '23', text: 'AZI-3' },\n { key: '24', text: 'Bala-Tik' },\n { key: '25', text: 'Barada' },\n { key: '26', text: 'Bargwill Tomder' },\n { key: '27', text: 'Baron Papanoida' },\n { key: '28', text: 'Barriss Offee' },\n { key: '29', text: 'Baze Malbus' },\n { key: '30', text: 'Bazine Netal' },\n { key: '31', text: 'BB-8' },\n { key: '32', text: 'BB-9E' },\n { key: '33', text: 'Ben Quadinaros' },\n { key: '34', text: 'Berch Teller' },\n { key: '35', text: 'Beru Lars' },\n { key: '36', text: 'Bib Fortuna' },\n {\n key: '37',\n text: 'Biggs Darklighter',\n },\n { key: '38', text: 'Black Krrsantan' },\n { key: '39', text: 'Bo-Katan Kryze' },\n { key: '40', text: 'Boba Fett' },\n { key: '41', text: 'Bobbajo' },\n { key: '42', text: 'Bodhi Rook' },\n { key: '43', text: 'Borvo the Hutt' },\n { key: '44', text: 'Boss Nass' },\n { key: '45', text: 'Bossk' },\n {\n key: '46',\n text: 'Breha Antilles-Organa',\n },\n { key: '47', text: 'Bren Derlin' },\n { key: '48', text: 'Brendol Hux' },\n { key: '49', text: 'BT-1' },\n];\n", "path": "plate-ui/mention-input-element.tsx", "target": "components/plate-ui/mention-input-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/mode-demo.json b/apps/www/public/r/styles/default/mode-demo.json index 26cf62c2c9..5f9eadf114 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-dropdown-menu.json b/apps/www/public/r/styles/default/mode-dropdown-menu.json index 1153b79f75..b214a776b9 100644 --- a/apps/www/public/r/styles/default/mode-dropdown-menu.json +++ b/apps/www/public/r/styles/default/mode-dropdown-menu.json @@ -10,7 +10,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n focusEditor,\n useEditorReadOnly,\n useEditorRef,\n usePlateStore,\n} from '@udecode/plate-common/react';\nimport { Eye, Pen } from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function ModeDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const setReadOnly = usePlateStore().set.readOnly();\n const readOnly = useEditorReadOnly();\n const openState = useOpenState();\n\n let value = 'editing';\n\n if (readOnly) value = 'viewing';\n\n const item: any = {\n editing: (\n <>\n \n Editing\n \n ),\n viewing: (\n <>\n \n Viewing\n \n ),\n };\n\n return (\n \n \n \n {item[value]}\n \n \n\n \n {\n if (newValue !== 'viewing') {\n setReadOnly(false);\n }\n if (newValue === 'viewing') {\n setReadOnly(true);\n\n return;\n }\n if (newValue === 'editing') {\n focusEditor(editor);\n\n return;\n }\n }}\n >\n \n {item.editing}\n \n\n \n {item.viewing}\n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n focusEditor,\n useEditorReadOnly,\n useEditorRef,\n usePlateStore,\n} from '@udecode/plate-common/react';\nimport { Eye, Pen } from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function ModeDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const setReadOnly = usePlateStore().set.readOnly();\n const readOnly = useEditorReadOnly();\n const openState = useOpenState();\n\n let value = 'editing';\n\n if (readOnly) value = 'viewing';\n\n const item: any = {\n editing: (\n <>\n \n Editing\n \n ),\n viewing: (\n <>\n \n Viewing\n \n ),\n };\n\n return (\n \n \n \n {item[value]}\n \n \n\n \n {\n if (newValue !== 'viewing') {\n setReadOnly(false);\n }\n if (newValue === 'viewing') {\n setReadOnly(true);\n\n return;\n }\n if (newValue === 'editing') {\n focusEditor(editor);\n\n return;\n }\n }}\n >\n \n {item.editing}\n \n\n \n {item.viewing}\n \n \n \n \n );\n}\n", "path": "plate-ui/mode-dropdown-menu.tsx", "target": "components/plate-ui/mode-dropdown-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/more-dropdown-menu.json b/apps/www/public/r/styles/default/more-dropdown-menu.json index b52394012b..1f44ffd6b7 100644 --- a/apps/www/public/r/styles/default/more-dropdown-menu.json +++ b/apps/www/public/r/styles/default/more-dropdown-menu.json @@ -1,7 +1,9 @@ { "dependencies": [ + "@radix-ui/react-dropdown-menu", "@udecode/plate-basic-marks", - "@radix-ui/react-dropdown-menu" + "@udecode/plate-highlight", + "@udecode/plate-kbd" ], "doc": { "description": "A menu for additional text formatting options.", @@ -17,7 +19,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n SubscriptPlugin,\n SuperscriptPlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { focusEditor, useEditorRef } from '@udecode/plate-common/react';\nimport { MoreHorizontal, Subscript, Superscript } from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function MoreDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n {\n editor.tf.toggle.mark({\n key: SuperscriptPlugin.key,\n clear: [SubscriptPlugin.key, SuperscriptPlugin.key],\n });\n focusEditor(editor);\n }}\n >\n \n Superscript\n {/* (⌘+,) */}\n \n {\n editor.tf.toggle.mark({\n key: SubscriptPlugin.key,\n clear: [SuperscriptPlugin.key, SubscriptPlugin.key],\n });\n focusEditor(editor);\n }}\n >\n \n Subscript\n {/* (⌘+.) */}\n \n \n \n );\n}\n", + "content": "import React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n SubscriptPlugin,\n SuperscriptPlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { collapseSelection } from '@udecode/plate-common';\nimport { focusEditor, useEditorRef } from '@udecode/plate-common/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport {\n HighlighterIcon,\n KeyboardIcon,\n MoreHorizontalIcon,\n SubscriptIcon,\n SuperscriptIcon,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function MoreDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n \n {\n editor.tf.toggle.mark({ key: HighlightPlugin.key });\n collapseSelection(editor, { edge: 'end' });\n focusEditor(editor);\n }}\n >\n \n Highlight\n \n\n {\n editor.tf.toggle.mark({ key: KbdPlugin.key });\n collapseSelection(editor, { edge: 'end' });\n focusEditor(editor);\n }}\n >\n \n Keyboard input\n \n\n {\n editor.tf.toggle.mark({\n key: SuperscriptPlugin.key,\n clear: [SubscriptPlugin.key, SuperscriptPlugin.key],\n });\n focusEditor(editor);\n }}\n >\n \n Superscript\n {/* (⌘+,) */}\n \n {\n editor.tf.toggle.mark({\n key: SubscriptPlugin.key,\n clear: [SuperscriptPlugin.key, SubscriptPlugin.key],\n });\n focusEditor(editor);\n }}\n >\n \n Subscript\n {/* (⌘+.) */}\n \n \n \n \n );\n}\n", "path": "plate-ui/more-dropdown-menu.tsx", "target": "components/plate-ui/more-dropdown-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/multiple-editors-demo.json b/apps/www/public/r/styles/default/multiple-editors-demo.json index 301ef7048b..e5cb5d8500 100644 --- a/apps/www/public/r/styles/default/multiple-editors-demo.json +++ b/apps/www/public/r/styles/default/multiple-editors-demo.json @@ -1,7 +1,7 @@ { "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { BasicElementsPlugin } from '@udecode/plate-basic-elements/react';\nimport { BasicMarksPlugin } from '@udecode/plate-basic-marks/react';\nimport { Plate, usePlateEditor } from '@udecode/plate-common/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { ImagePlugin } from '@udecode/plate-media/react';\nimport { SelectOnBackspacePlugin } from '@udecode/plate-select';\n\nimport { PlaygroundTurnIntoDropdownMenu } from '@/components/plate-ui/playground-turn-into-dropdown-menu';\nimport { PlateUI } from '@/plate/demo/plate-ui';\nimport { basicElementsValue } from '@/plate/demo/values/basicElementsValue';\nimport { basicMarksValue } from '@/plate/demo/values/basicMarksValue';\nimport { imageValue } from '@/plate/demo/values/mediaValue';\nimport { Editor } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { Separator } from '@/components/plate-ui/separator';\n\nexport default function MultipleEditorsDemo() {\n const editor = usePlateEditor({\n override: { components: PlateUI },\n plugins: [BasicElementsPlugin, BasicMarksPlugin],\n value: basicElementsValue,\n });\n\n const editorMarks = usePlateEditor({\n id: 'marks',\n override: { components: PlateUI },\n plugins: [BasicElementsPlugin, BasicMarksPlugin],\n value: basicMarksValue,\n });\n\n const editorImage = usePlateEditor({\n id: 'marks',\n override: { components: PlateUI },\n plugins: [\n BasicElementsPlugin,\n BasicMarksPlugin,\n ImagePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n ],\n value: imageValue,\n });\n\n return (\n \n \n \n \n \n \n\n
\n \n \n \n \n \n
\n
\n
\n
\n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { BasicElementsPlugin } from '@udecode/plate-basic-elements/react';\nimport { BasicMarksPlugin } from '@udecode/plate-basic-marks/react';\nimport { Plate, usePlateEditor } from '@udecode/plate-common/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { ImagePlugin } from '@udecode/plate-media/react';\nimport { SelectOnBackspacePlugin } from '@udecode/plate-select';\n\nimport { PlateUI } from '@/plate/demo/plate-ui';\nimport { basicElementsValue } from '@/plate/demo/values/basicElementsValue';\nimport { basicMarksValue } from '@/plate/demo/values/basicMarksValue';\nimport { imageValue } from '@/plate/demo/values/mediaValue';\nimport { Editor } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\nimport { Separator } from '@/components/plate-ui/separator';\nimport { TurnIntoDropdownMenu } from '@/components/plate-ui/turn-into-dropdown-menu';\n\nexport default function MultipleEditorsDemo() {\n const editor = usePlateEditor({\n override: { components: PlateUI },\n plugins: [BasicElementsPlugin, BasicMarksPlugin],\n value: basicElementsValue,\n });\n\n const editorMarks = usePlateEditor({\n id: 'marks',\n override: { components: PlateUI },\n plugins: [BasicElementsPlugin, BasicMarksPlugin],\n value: basicMarksValue,\n });\n\n const editorImage = usePlateEditor({\n id: 'marks',\n override: { components: PlateUI },\n plugins: [\n BasicElementsPlugin,\n BasicMarksPlugin,\n ImagePlugin,\n SelectOnBackspacePlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key, HorizontalRulePlugin.key],\n },\n },\n }),\n ],\n value: imageValue,\n });\n\n return (\n \n \n \n \n \n \n\n
\n \n \n \n \n \n
\n
\n
\n
\n );\n}\n", "path": "example/multiple-editors-demo.tsx", "target": "components/multiple-editors-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 ebac25a723..ea2ee80cc1 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 c56019fd66..568f04ef31 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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/popover.json b/apps/www/public/r/styles/default/popover.json index c76f963464..1cd556fb44 100644 --- a/apps/www/public/r/styles/default/popover.json +++ b/apps/www/public/r/styles/default/popover.json @@ -7,7 +7,7 @@ }, "files": [ { - "content": "'use client';\n\nimport * as React from 'react';\n\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { cn, withRef } from '@udecode/cn';\nimport { cva } from 'class-variance-authority';\n\nexport const Popover = PopoverPrimitive.Root;\n\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\n\nexport const PopoverAnchor = PopoverPrimitive.Anchor;\n\nexport const popoverVariants = cva(\n 'w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 print:hidden'\n);\n\nexport const PopoverContent = withRef(\n ({ align = 'center', className, sideOffset = 4, style, ...props }, ref) => (\n \n \n \n )\n);\n", + "content": "'use client';\n\nimport * as React from 'react';\n\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { cn, withRef } from '@udecode/cn';\nimport { cva } from 'class-variance-authority';\n\nexport const Popover = PopoverPrimitive.Root;\n\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\n\nexport const PopoverAnchor = PopoverPrimitive.Anchor;\n\nexport const popoverVariants = cva(\n 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 print:hidden'\n);\n\nexport const PopoverContent = withRef(\n ({ align = 'center', className, sideOffset = 4, style, ...props }, ref) => (\n \n \n \n )\n);\n", "path": "plate-ui/popover.tsx", "target": "components/plate-ui/popover.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/resizable-demo.json b/apps/www/public/r/styles/default/resizable-demo.json index 91615a4fed..5f3ed95469 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 d84249e24e..677ecc348d 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-input-element.json b/apps/www/public/r/styles/default/slash-input-element.json index 52e80c1f39..dcd1ec8370 100644 --- a/apps/www/public/r/styles/default/slash-input-element.json +++ b/apps/www/public/r/styles/default/slash-input-element.json @@ -1,29 +1,17 @@ { "dependencies": [ - "@udecode/plate-heading", "@udecode/plate-ai", + "@udecode/plate-block-quote", + "@udecode/plate-code-block", "@udecode/plate-date", - "@udecode/plate-indent-list" + "@udecode/plate-heading", + "@udecode/plate-indent-list", + "@udecode/plate-table", + "@udecode/plate-toggle" ], "doc": { "description": "A command input component for inserting various elements.", "docs": [ - { - "route": "/docs/ai", - "title": "AI" - }, - { - "route": "/docs/basic-elements", - "title": "Basic Elements" - }, - { - "route": "/docs/date", - "title": "Date" - }, - { - "route": "/docs/indent-list", - "title": "Indent List" - }, { "route": "https://pro.platejs.org/docs/components/slash-input-element" } @@ -36,7 +24,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { type ComponentType, type SVGProps } from 'react';\n\nimport type { PlateEditor } from '@udecode/plate-common/react';\n\nimport { withRef } from '@udecode/cn';\nimport { AIChatPlugin } from '@udecode/plate-ai/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { ListStyleType, toggleIndentList } from '@udecode/plate-indent-list';\nimport {\n CalendarIcon,\n Heading1Icon,\n Heading2Icon,\n Heading3Icon,\n ListIcon,\n ListOrderedIcon,\n SparklesIcon,\n} from 'lucide-react';\n\nimport {\n InlineCombobox,\n InlineComboboxContent,\n InlineComboboxEmpty,\n InlineComboboxInput,\n InlineComboboxItem,\n} from './inline-combobox';\nimport { PlateElement } from './plate-element';\n\ninterface SlashCommandRule {\n icon: ComponentType>;\n onSelect: (editor: PlateEditor) => void;\n value: string;\n className?: string;\n focusEditor?: boolean;\n keywords?: string[];\n}\n\nconst rules: SlashCommandRule[] = [\n {\n focusEditor: false,\n icon: SparklesIcon,\n value: 'AI',\n onSelect: (editor) => {\n editor.getApi(AIChatPlugin).aiChat.show();\n },\n },\n {\n icon: Heading1Icon,\n value: 'Heading 1',\n onSelect: (editor) => {\n editor.tf.toggle.block({ type: HEADING_KEYS.h1 });\n },\n },\n {\n icon: Heading2Icon,\n value: 'Heading 2',\n onSelect: (editor) => {\n editor.tf.toggle.block({ type: HEADING_KEYS.h2 });\n },\n },\n {\n icon: Heading3Icon,\n value: 'Heading 3',\n onSelect: (editor) => {\n editor.tf.toggle.block({ type: HEADING_KEYS.h3 });\n },\n },\n {\n icon: ListIcon,\n keywords: ['ul', 'unordered list'],\n value: 'Bulleted list',\n onSelect: (editor) => {\n toggleIndentList(editor, {\n listStyleType: ListStyleType.Disc,\n });\n },\n },\n {\n icon: ListOrderedIcon,\n keywords: ['ol', 'ordered list'],\n value: 'Numbered list',\n onSelect: (editor) => {\n toggleIndentList(editor, {\n listStyleType: ListStyleType.Decimal,\n });\n },\n },\n {\n icon: CalendarIcon,\n keywords: ['inline', 'date'],\n value: 'Date',\n onSelect: (editor) => {\n editor.getTransforms(DatePlugin).insert.date();\n },\n },\n];\n\nexport const SlashInputElement = withRef(\n ({ className, ...props }, ref) => {\n const { children, editor, element } = props;\n\n return (\n \n \n \n\n \n \n No matching commands found\n \n\n {rules.map(\n ({ focusEditor, icon: Icon, keywords, value, onSelect }) => (\n onSelect(editor)}\n focusEditor={focusEditor}\n keywords={keywords}\n >\n \n {value}\n \n )\n )}\n \n \n\n {children}\n \n );\n }\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { withRef } from '@udecode/cn';\nimport { AIChatPlugin } from '@udecode/plate-ai/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { type PlateEditor, ParagraphPlugin } from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { INDENT_LIST_KEYS, ListStyleType } from '@udecode/plate-indent-list';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport {\n CalendarIcon,\n ChevronRightIcon,\n Code2,\n Columns3Icon,\n Heading1Icon,\n Heading2Icon,\n Heading3Icon,\n ListIcon,\n ListOrdered,\n PilcrowIcon,\n Quote,\n SparklesIcon,\n Square,\n Table,\n TableOfContentsIcon,\n} from 'lucide-react';\n\nimport {\n insertBlock,\n insertInlineElement,\n} from '@/lib/transforms';\n\nimport {\n InlineCombobox,\n InlineComboboxContent,\n InlineComboboxEmpty,\n InlineComboboxGroup,\n InlineComboboxGroupLabel,\n InlineComboboxInput,\n InlineComboboxItem,\n} from './inline-combobox';\nimport { PlateElement } from './plate-element';\n\ntype Group = {\n group: string;\n items: Item[];\n};\n\ninterface Item {\n icon: React.ReactNode;\n\n onSelect: (editor: PlateEditor, value: string) => void;\n\n value: string;\n className?: string;\n focusEditor?: boolean;\n keywords?: string[];\n label?: string;\n}\n\nconst groups: Group[] = [\n {\n group: 'AI',\n items: [\n {\n focusEditor: false,\n icon: ,\n value: 'AI',\n onSelect: (editor) => {\n editor.getApi(AIChatPlugin).aiChat.show();\n },\n },\n ],\n },\n {\n group: 'Basic blocks',\n items: [\n {\n icon: ,\n keywords: ['paragraph'],\n label: 'Text',\n value: ParagraphPlugin.key,\n },\n {\n icon: ,\n keywords: ['title', 'h1'],\n label: 'Heading 1',\n value: HEADING_KEYS.h1,\n },\n {\n icon: ,\n keywords: ['subtitle', 'h2'],\n label: 'Heading 2',\n value: HEADING_KEYS.h2,\n },\n {\n icon: ,\n keywords: ['subtitle', 'h3'],\n label: 'Heading 3',\n value: HEADING_KEYS.h3,\n },\n {\n icon: ,\n keywords: ['unordered', 'ul', '-'],\n label: 'Bulleted list',\n value: ListStyleType.Disc,\n },\n {\n icon: ,\n keywords: ['ordered', 'ol', '1'],\n label: 'Numbered list',\n value: ListStyleType.Decimal,\n },\n {\n icon: ,\n keywords: ['checklist', 'task', 'checkbox', '[]'],\n label: 'To-do list',\n value: INDENT_LIST_KEYS.todo,\n },\n {\n icon: ,\n keywords: ['collapsible', 'expandable'],\n label: 'Toggle',\n value: TogglePlugin.key,\n },\n {\n icon: ,\n keywords: ['```'],\n label: 'Code Block',\n value: CodeBlockPlugin.key,\n },\n {\n icon: ,\n label: 'Table',\n value: TablePlugin.key,\n },\n {\n icon: ,\n keywords: ['citation', 'blockquote', 'quote', '>'],\n label: 'Blockquote',\n value: BlockquotePlugin.key,\n },\n ].map((item) => ({\n ...item,\n onSelect: (editor, value) => {\n insertBlock(editor, value);\n },\n })),\n },\n {\n group: 'Advanced blocks',\n items: [\n {\n icon: ,\n keywords: ['toc'],\n value: 'Table of Contents',\n },\n {\n icon: ,\n label: '3 columns',\n value: 'action_three_columns',\n },\n ].map((item) => ({\n ...item,\n onSelect: (editor, value) => {\n insertBlock(editor, value);\n },\n })),\n },\n {\n group: 'Inline',\n items: [\n {\n focusEditor: true,\n icon: ,\n keywords: ['time'],\n label: 'Date',\n value: DatePlugin.key,\n },\n ].map((item) => ({\n ...item,\n onSelect: (editor, value) => {\n insertInlineElement(editor, value);\n },\n })),\n },\n];\n\nexport const SlashInputElement = withRef(\n ({ className, ...props }, ref) => {\n const { children, editor, element } = props;\n\n return (\n \n \n \n\n \n No results\n\n {groups.map(({ group, items }) => (\n \n {group}\n\n {items.map(\n ({ focusEditor, icon, keywords, label, value, onSelect }) => (\n onSelect(editor, value)}\n label={label}\n focusEditor={focusEditor}\n group={group}\n keywords={keywords}\n >\n
{icon}
\n {label ?? value}\n \n )\n )}\n
\n ))}\n
\n
\n\n {children}\n \n );\n }\n);\n", "path": "plate-ui/slash-input-element.tsx", "target": "components/plate-ui/slash-input-element.tsx", "type": "registry:ui" @@ -45,7 +33,8 @@ "name": "slash-input-element", "registryDependencies": [ "inline-combobox", - "plate-element" + "plate-element", + "transforms" ], "type": "registry:ui" } \ No newline at end of file diff --git a/apps/www/public/r/styles/default/table-demo.json b/apps/www/public/r/styles/default/table-demo.json index 7e22a9a1fc..2a498fbf20 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-dropdown-menu.json b/apps/www/public/r/styles/default/table-dropdown-menu.json index 3158aab966..0cd31f5283 100644 --- a/apps/www/public/r/styles/default/table-dropdown-menu.json +++ b/apps/www/public/r/styles/default/table-dropdown-menu.json @@ -17,7 +17,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport { someNode } from '@udecode/plate-common';\nimport {\n focusEditor,\n useEditorPlugin,\n useEditorSelector,\n} from '@udecode/plate-common/react';\nimport { deleteTable, insertTableRow } from '@udecode/plate-table';\nimport {\n TablePlugin,\n deleteColumn,\n deleteRow,\n insertTable,\n} from '@udecode/plate-table/react';\nimport {\n Minus,\n Plus,\n RectangleHorizontal,\n RectangleVertical,\n Table,\n Trash,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function TableDropdownMenu(props: DropdownMenuProps) {\n const tableSelected = useEditorSelector(\n (editor) => someNode(editor, { match: { type: TablePlugin.key } }),\n []\n );\n\n const { editor, tf } = useEditorPlugin(TablePlugin);\n\n const openState = useOpenState();\n\n return (\n \n \n \n
\n \n \n\n \n \n \n
\n Table\n \n \n {\n insertTable(editor, {}, { select: true });\n focusEditor(editor);\n }}\n >\n \n Insert table\n \n {\n deleteTable(editor);\n focusEditor(editor);\n }}\n >\n \n Delete table\n \n \n \n\n \n \n \n Column\n \n \n {\n tf.insert.tableColumn();\n focusEditor(editor);\n }}\n >\n \n Insert column after\n \n {\n deleteColumn(editor);\n focusEditor(editor);\n }}\n >\n \n Delete column\n \n \n \n\n \n \n \n Row\n \n \n {\n insertTableRow(editor);\n focusEditor(editor);\n }}\n >\n \n Insert row after\n \n {\n deleteRow(editor);\n focusEditor(editor);\n }}\n >\n \n Delete row\n \n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport { someNode } from '@udecode/plate-common';\nimport {\n focusEditor,\n useEditorPlugin,\n useEditorSelector,\n} from '@udecode/plate-common/react';\nimport { deleteTable, insertTableRow } from '@udecode/plate-table';\nimport {\n TablePlugin,\n deleteColumn,\n deleteRow,\n insertTable,\n} from '@udecode/plate-table/react';\nimport {\n Minus,\n Plus,\n RectangleHorizontal,\n RectangleVertical,\n Table,\n Trash,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function TableDropdownMenu(props: DropdownMenuProps) {\n const tableSelected = useEditorSelector(\n (editor) => someNode(editor, { match: { type: TablePlugin.key } }),\n []\n );\n\n const { editor, tf } = useEditorPlugin(TablePlugin);\n\n const openState = useOpenState();\n\n return (\n \n \n \n
\n \n \n\n \n \n \n \n
\n Table\n \n \n {\n insertTable(editor, {}, { select: true });\n focusEditor(editor);\n }}\n >\n \n Insert table\n \n {\n deleteTable(editor);\n focusEditor(editor);\n }}\n >\n \n Delete table\n \n \n \n\n \n \n \n Column\n \n \n {\n tf.insert.tableColumn();\n focusEditor(editor);\n }}\n >\n \n Insert column after\n \n {\n deleteColumn(editor);\n focusEditor(editor);\n }}\n >\n \n Delete column\n \n \n \n\n \n \n \n Row\n \n \n {\n insertTableRow(editor);\n focusEditor(editor);\n }}\n >\n \n Insert row after\n \n {\n deleteRow(editor);\n focusEditor(editor);\n }}\n >\n \n Delete row\n \n \n \n \n \n \n );\n}\n", "path": "plate-ui/table-dropdown-menu.tsx", "target": "components/plate-ui/table-dropdown-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/table-element.json b/apps/www/public/r/styles/default/table-element.json index bec696ff1c..5784d98d4a 100644 --- a/apps/www/public/r/styles/default/table-element.json +++ b/apps/www/public/r/styles/default/table-element.json @@ -20,7 +20,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport type { TTableElement } from '@udecode/plate-table';\n\nimport { PopoverAnchor } from '@radix-ui/react-popover';\nimport { cn, withRef } from '@udecode/cn';\nimport { isSelectionExpanded } from '@udecode/plate-common';\nimport {\n useEditorRef,\n useEditorSelector,\n useElement,\n useRemoveNodeButton,\n withHOC,\n} from '@udecode/plate-common/react';\nimport {\n TableProvider,\n mergeTableCells,\n unmergeTableCells,\n useTableBordersDropdownMenuContentState,\n useTableElement,\n useTableElementState,\n useTableMergeState,\n} from '@udecode/plate-table/react';\nimport { type LucideProps, Combine, Delete, Ungroup } from 'lucide-react';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n} from './dropdown-menu';\nimport { PlateElement } from './plate-element';\nimport { Popover, PopoverContent, popoverVariants } from './popover';\nimport { Separator } from './separator';\n\nexport const TableBordersDropdownMenuContent = withRef<\n typeof DropdownMenuPrimitive.Content\n>((props, ref) => {\n const {\n getOnSelectTableBorder,\n hasBottomBorder,\n hasLeftBorder,\n hasNoBorders,\n hasOuterBorders,\n hasRightBorder,\n hasTopBorder,\n } = useTableBordersDropdownMenuContentState();\n\n return (\n \n \n \n
Bottom Border
\n \n \n \n
Top Border
\n \n \n \n
Left Border
\n \n \n \n
Right Border
\n \n\n \n\n \n \n
No Border
\n \n \n \n
Outside Borders
\n \n \n );\n});\n\nexport const TableFloatingToolbar = withRef(\n ({ children, ...props }, ref) => {\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n const selectionCollapsed = useEditorSelector(\n (editor) => !isSelectionExpanded(editor),\n []\n );\n\n const readOnly = useReadOnly();\n const selected = useSelected();\n const editor = useEditorRef();\n\n const collapsed = !readOnly && selected && selectionCollapsed;\n const open = !readOnly && selected;\n\n const { canMerge, canUnmerge } = useTableMergeState();\n\n const mergeContent = canMerge && (\n mergeTableCells(editor)}\n contentEditable={false}\n isMenu\n >\n \n Merge\n \n );\n\n const unmergeButton = canUnmerge && (\n unmergeTableCells(editor)}\n contentEditable={false}\n isMenu\n >\n \n Unmerge\n \n );\n\n const bordersContent = collapsed && (\n <>\n \n \n \n \n\n \n \n \n \n\n \n \n );\n\n return (\n \n {children}\n {(canMerge || canUnmerge || collapsed) && (\n e.preventDefault()}\n {...props}\n >\n {unmergeButton}\n {mergeContent}\n {bordersContent}\n \n )}\n \n );\n }\n);\n\nexport const TableElement = withHOC(\n TableProvider,\n withRef(({ children, className, ...props }, ref) => {\n const { colSizes, isSelectingCell, marginLeft, minColumnWidth } =\n useTableElementState();\n const { colGroupProps, props: tableProps } = useTableElement();\n\n return (\n \n
\n \n
\n {colSizes.map((width, index) => (\n \n ))}\n \n\n {children}\n \n \n \n );\n })\n);\n\nconst BorderAll = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderBottom = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderLeft = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderNone = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderRight = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderTop = (props: LucideProps) => (\n \n \n \n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport type { TTableElement } from '@udecode/plate-table';\n\nimport { PopoverAnchor } from '@radix-ui/react-popover';\nimport { cn, withRef } from '@udecode/cn';\nimport { isSelectionExpanded } from '@udecode/plate-common';\nimport {\n useEditorRef,\n useEditorSelector,\n useElement,\n useRemoveNodeButton,\n withHOC,\n} from '@udecode/plate-common/react';\nimport {\n TableProvider,\n mergeTableCells,\n unmergeTableCells,\n useTableBordersDropdownMenuContentState,\n useTableElement,\n useTableElementState,\n useTableMergeState,\n} from '@udecode/plate-table/react';\nimport { type LucideProps, Combine, Trash2Icon, Ungroup } from 'lucide-react';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n} from './dropdown-menu';\nimport { PlateElement } from './plate-element';\nimport { Popover, PopoverContent, popoverVariants } from './popover';\n\nexport const TableBordersDropdownMenuContent = withRef<\n typeof DropdownMenuPrimitive.Content\n>((props, ref) => {\n const {\n getOnSelectTableBorder,\n hasBottomBorder,\n hasLeftBorder,\n hasNoBorders,\n hasOuterBorders,\n hasRightBorder,\n hasTopBorder,\n } = useTableBordersDropdownMenuContentState();\n\n return (\n \n \n \n \n
Bottom Border
\n \n \n \n
Top Border
\n \n \n \n
Left Border
\n \n \n \n
Right Border
\n \n
\n\n \n \n \n
No Border
\n \n \n \n
Outside Borders
\n \n
\n \n );\n});\n\nexport const TableFloatingToolbar = withRef(\n ({ children, ...props }, ref) => {\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n const selectionCollapsed = useEditorSelector(\n (editor) => !isSelectionExpanded(editor),\n []\n );\n\n const readOnly = useReadOnly();\n const selected = useSelected();\n const editor = useEditorRef();\n\n const collapsed = !readOnly && selected && selectionCollapsed;\n const open = !readOnly && selected;\n\n const { canMerge, canUnmerge } = useTableMergeState();\n\n const mergeContent = canMerge && (\n mergeTableCells(editor)}\n contentEditable={false}\n isMenu\n >\n \n Merge\n \n );\n\n const unmergeButton = canUnmerge && (\n unmergeTableCells(editor)}\n contentEditable={false}\n isMenu\n >\n \n Unmerge\n \n );\n\n const bordersContent = collapsed && (\n <>\n \n \n \n \n\n \n \n \n \n\n \n \n );\n\n return (\n \n {children}\n {(canMerge || canUnmerge || collapsed) && (\n e.preventDefault()}\n {...props}\n >\n {unmergeButton}\n {mergeContent}\n {bordersContent}\n \n )}\n \n );\n }\n);\n\nexport const TableElement = withHOC(\n TableProvider,\n withRef(({ children, className, ...props }, ref) => {\n const { colSizes, isSelectingCell, marginLeft, minColumnWidth } =\n useTableElementState();\n const { colGroupProps, props: tableProps } = useTableElement();\n\n return (\n \n
\n \n
\n {colSizes.map((width, index) => (\n \n ))}\n \n\n {children}\n \n \n \n );\n })\n);\n\nconst BorderAll = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderBottom = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderLeft = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderNone = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderRight = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderTop = (props: LucideProps) => (\n \n \n \n);\n", "path": "plate-ui/table-element.tsx", "target": "components/plate-ui/table-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/toc-demo.json b/apps/www/public/r/styles/default/toc-demo.json index 9031ed0400..d36786499e 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 a37860a2ab..77cd8dbc16 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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-element.json b/apps/www/public/r/styles/default/toggle-element.json index 5d25ec5f31..eb4aef1c71 100644 --- a/apps/www/public/r/styles/default/toggle-element.json +++ b/apps/www/public/r/styles/default/toggle-element.json @@ -16,7 +16,7 @@ }, "files": [ { - "content": "import { cn, withRef } from '@udecode/cn';\nimport { useElement } from '@udecode/plate-common/react';\nimport {\n useToggleButton,\n useToggleButtonState,\n} from '@udecode/plate-toggle/react';\nimport { ChevronDown, ChevronRight } from 'lucide-react';\n\nimport { PlateElement } from './plate-element';\n\nexport const ToggleElement = withRef(\n ({ children, className, ...props }, ref) => {\n const element = useElement();\n const state = useToggleButtonState(element.id as string);\n const { buttonProps, open } = useToggleButton(state);\n\n return (\n \n \n {open ? : }\n \n {children}\n \n );\n }\n);\n", + "content": "import { cn, withRef } from '@udecode/cn';\nimport { useElement } from '@udecode/plate-common/react';\nimport {\n useToggleButton,\n useToggleButtonState,\n} from '@udecode/plate-toggle/react';\nimport { ChevronDown, ChevronRight } from 'lucide-react';\n\nimport { Button } from './button';\nimport { PlateElement } from './plate-element';\n\nexport const ToggleElement = withRef(\n ({ children, className, ...props }, ref) => {\n const element = useElement();\n const state = useToggleButtonState(element.id as string);\n const { buttonProps, open } = useToggleButton(state);\n\n return (\n \n \n {open ? : }\n \n {children}\n \n );\n }\n);\n", "path": "plate-ui/toggle-element.tsx", "target": "components/plate-ui/toggle-element.tsx", "type": "registry:ui" @@ -24,6 +24,7 @@ ], "name": "toggle-element", "registryDependencies": [ + "button", "plate-element" ], "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/toggle-toolbar-button.json b/apps/www/public/r/styles/default/toggle-toolbar-button.json index 6bbb05c86f..1d2f93f383 100644 --- a/apps/www/public/r/styles/default/toggle-toolbar-button.json +++ b/apps/www/public/r/styles/default/toggle-toolbar-button.json @@ -16,7 +16,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { withRef } from '@udecode/cn';\nimport {\n useToggleToolbarButton,\n useToggleToolbarButtonState,\n} from '@udecode/plate-toggle/react';\nimport { ChevronDown } from 'lucide-react';\n\nimport { ToolbarButton } from './toolbar';\n\nexport const ToggleToolbarButton = withRef(\n (rest, ref) => {\n const state = useToggleToolbarButtonState();\n const { props } = useToggleToolbarButton(state);\n\n return (\n \n \n \n );\n }\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { withRef } from '@udecode/cn';\nimport {\n useToggleToolbarButton,\n useToggleToolbarButtonState,\n} from '@udecode/plate-toggle/react';\nimport { ChevronRightIcon } from 'lucide-react';\n\nimport { ToolbarButton } from './toolbar';\n\nexport const ToggleToolbarButton = withRef(\n (rest, ref) => {\n const state = useToggleToolbarButtonState();\n const { props } = useToggleToolbarButton(state);\n\n return (\n \n \n \n );\n }\n);\n", "path": "plate-ui/toggle-toolbar-button.tsx", "target": "components/plate-ui/toggle-toolbar-button.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/toolbar-demo.json b/apps/www/public/r/styles/default/toolbar-demo.json index 74a52d7d01..376c4d9c30 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 { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons';\nimport { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar';\nimport { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons';\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 } from '@/components/plate-ui/editor';\nimport { FixedToolbar } from '@/components/plate-ui/fixed-toolbar';\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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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 { 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 } 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 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({ options: autoformatOptions }),\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 ColumnPlugin,\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.json b/apps/www/public/r/styles/default/toolbar.json index 4c3064f2fe..d4a2c48de6 100644 --- a/apps/www/public/r/styles/default/toolbar.json +++ b/apps/www/public/r/styles/default/toolbar.json @@ -7,7 +7,7 @@ }, "files": [ { - "content": "'use client';\n\nimport * as React from 'react';\n\nimport * as ToolbarPrimitive from '@radix-ui/react-toolbar';\nimport { cn, withCn, withRef, withVariants } from '@udecode/cn';\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport { ChevronDown } from 'lucide-react';\n\nimport { Separator } from './separator';\nimport { withTooltip } from './tooltip';\n\nexport const Toolbar = withCn(\n ToolbarPrimitive.Root,\n 'relative flex select-none items-center'\n);\n\nexport const ToolbarToggleGroup = withCn(\n ToolbarPrimitive.ToolbarToggleGroup,\n 'flex items-center'\n);\n\nexport const ToolbarLink = withCn(\n ToolbarPrimitive.Link,\n 'font-medium underline underline-offset-4'\n);\n\nexport const ToolbarSeparator = withCn(\n ToolbarPrimitive.Separator,\n 'mx-2 my-1 w-px shrink-0 bg-border'\n);\n\nconst toolbarButtonVariants = cva(\n cn(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium text-foreground ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n '[&_svg:not([data-icon])]:size-4'\n ),\n {\n defaultVariants: {\n size: 'sm',\n variant: 'default',\n },\n variants: {\n size: {\n default: 'h-10 px-3',\n lg: 'h-11 px-5',\n sm: 'h-7 px-2',\n },\n variant: {\n default:\n 'bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground',\n outline:\n 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',\n },\n },\n }\n);\n\nconst ToolbarButton = withTooltip(\n // eslint-disable-next-line react/display-name\n React.forwardRef<\n React.ElementRef,\n {\n isDropdown?: boolean;\n pressed?: boolean;\n } & Omit<\n React.ComponentPropsWithoutRef,\n 'asChild' | 'value'\n > &\n VariantProps\n >(\n (\n { children, className, isDropdown, pressed, size, variant, ...props },\n ref\n ) => {\n return typeof pressed === 'boolean' ? (\n \n \n {isDropdown ? (\n <>\n
\n {children}\n
\n
\n \n
\n \n ) : (\n children\n )}\n \n \n ) : (\n \n {children}\n \n );\n }\n )\n);\nToolbarButton.displayName = 'ToolbarButton';\n\nexport { ToolbarButton };\n\nexport const ToolbarToggleItem = withVariants(\n ToolbarPrimitive.ToggleItem,\n toolbarButtonVariants,\n ['variant', 'size']\n);\n\nexport const ToolbarGroup = withRef<'div'>(({ children, className }, ref) => {\n const childArr = React.Children.map(children, (c) => c);\n\n if (!childArr || childArr.length === 0) return null;\n\n return (\n \n
{children}
\n\n \n \n );\n});\n", + "content": "'use client';\n\nimport * as React from 'react';\n\nimport * as ToolbarPrimitive from '@radix-ui/react-toolbar';\nimport { cn, withCn, withRef, withVariants } from '@udecode/cn';\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport { ChevronDown } from 'lucide-react';\n\nimport { Separator } from './separator';\nimport { withTooltip } from './tooltip';\n\nexport const Toolbar = withCn(\n ToolbarPrimitive.Root,\n 'relative flex select-none items-center'\n);\n\nexport const ToolbarToggleGroup = withCn(\n ToolbarPrimitive.ToolbarToggleGroup,\n 'flex items-center'\n);\n\nexport const ToolbarLink = withCn(\n ToolbarPrimitive.Link,\n 'font-medium underline underline-offset-4'\n);\n\nexport const ToolbarSeparator = withCn(\n ToolbarPrimitive.Separator,\n 'mx-2 my-1 w-px shrink-0 bg-border'\n);\n\nconst toolbarButtonVariants = cva(\n cn(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium text-foreground ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg:not([data-icon])]:size-4'\n ),\n {\n defaultVariants: {\n size: 'sm',\n variant: 'default',\n },\n variants: {\n size: {\n default: 'h-10 px-3',\n lg: 'h-11 px-5',\n sm: 'h-7 px-2',\n },\n variant: {\n default:\n 'bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground',\n outline:\n 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',\n },\n },\n }\n);\n\nconst ToolbarButton = withTooltip(\n // eslint-disable-next-line react/display-name\n React.forwardRef<\n React.ElementRef,\n {\n isDropdown?: boolean;\n pressed?: boolean;\n } & Omit<\n React.ComponentPropsWithoutRef,\n 'asChild' | 'value'\n > &\n VariantProps\n >(\n (\n { children, className, isDropdown, pressed, size, variant, ...props },\n ref\n ) => {\n return typeof pressed === 'boolean' ? (\n \n \n {isDropdown ? (\n <>\n
\n {children}\n
\n
\n \n
\n \n ) : (\n children\n )}\n \n \n ) : (\n \n {children}\n \n );\n }\n )\n);\nToolbarButton.displayName = 'ToolbarButton';\n\nexport { ToolbarButton };\n\nexport const ToolbarToggleItem = withVariants(\n ToolbarPrimitive.ToggleItem,\n toolbarButtonVariants,\n ['variant', 'size']\n);\n\nexport const ToolbarGroup = withRef<'div'>(({ children, className }, ref) => {\n return (\n
+
); @@ -168,7 +174,7 @@ export const TR = ({ className, ...props }: React.HTMLAttributes) => ( - + ); export const TH = ({ @@ -177,7 +183,7 @@ export const TH = ({ }: React.HTMLAttributes) => (
) => ( - + - + diff --git a/apps/www/src/registry/default/example/multiple-editors-demo.tsx b/apps/www/src/registry/default/example/multiple-editors-demo.tsx index 7cec59b1e5..1fbc589632 100644 --- a/apps/www/src/registry/default/example/multiple-editors-demo.tsx +++ b/apps/www/src/registry/default/example/multiple-editors-demo.tsx @@ -9,7 +9,6 @@ import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react'; import { ImagePlugin } from '@udecode/plate-media/react'; import { SelectOnBackspacePlugin } from '@udecode/plate-select'; -import { PlaygroundTurnIntoDropdownMenu } from '@/components/plate-ui/playground-turn-into-dropdown-menu'; import { PlateUI } from '@/plate/demo/plate-ui'; import { basicElementsValue } from '@/plate/demo/values/basicElementsValue'; import { basicMarksValue } from '@/plate/demo/values/basicMarksValue'; @@ -17,6 +16,7 @@ import { imageValue } from '@/plate/demo/values/mediaValue'; import { Editor } from '@/registry/default/plate-ui/editor'; import { FixedToolbar } from '@/registry/default/plate-ui/fixed-toolbar'; import { Separator } from '@/registry/default/plate-ui/separator'; +import { TurnIntoDropdownMenu } from '@/registry/default/plate-ui/turn-into-dropdown-menu'; export default function MultipleEditorsDemo() { const editor = usePlateEditor({ @@ -55,7 +55,7 @@ export default function MultipleEditorsDemo() { - +
diff --git a/apps/www/src/registry/default/example/playground-demo.tsx b/apps/www/src/registry/default/example/playground-demo.tsx index 0f3f668dea..14f9fe7abd 100644 --- a/apps/www/src/registry/default/example/playground-demo.tsx +++ b/apps/www/src/registry/default/example/playground-demo.tsx @@ -68,9 +68,6 @@ import Prism from 'prismjs'; import { CheckPlugin } from '@/components/context/check-plugin'; import { settingsStore } from '@/components/context/settings-store'; -import { PlaygroundFixedToolbarButtons } from '@/components/plate-ui/playground-fixed-toolbar-buttons'; -import { PlaygroundFloatingToolbar } from '@/components/plate-ui/playground-floating-toolbar'; -import { PlaygroundFloatingToolbarButtons } from '@/components/plate-ui/playground-floating-toolbar-buttons'; import { aiPlugins } from '@/lib/plate/demo/plugins/ai-plugins'; import { getAutoformatOptions } from '@/lib/plate/demo/plugins/autoformatOptions'; import { copilotPlugins } from '@/lib/plate/demo/plugins/copilot-plugins'; @@ -92,6 +89,9 @@ import { } from '@/registry/default/plate-ui/cursor-overlay'; import { Editor } from '@/registry/default/plate-ui/editor'; import { FixedToolbar } from '@/registry/default/plate-ui/fixed-toolbar'; +import { FixedToolbarButtons } from '@/registry/default/plate-ui/fixed-toolbar-buttons'; +import { FloatingToolbar } from '@/registry/default/plate-ui/floating-toolbar'; +import { FloatingToolbarButtons } from '@/registry/default/plate-ui/floating-toolbar-buttons'; import { ImagePreview } from '@/registry/default/plate-ui/image-preview'; import { FireLiComponent, @@ -366,7 +366,7 @@ export default function PlaygroundDemo({ - + @@ -398,7 +398,7 @@ export default function PlaygroundDemo({ /> - - + - + diff --git a/apps/www/src/registry/default/lib/transforms.ts b/apps/www/src/registry/default/lib/transforms.ts new file mode 100644 index 0000000000..92e9d29edb --- /dev/null +++ b/apps/www/src/registry/default/lib/transforms.ts @@ -0,0 +1,223 @@ +import type { PlateEditor } from '@udecode/plate-common/react'; + +import { insertCallout } from '@udecode/plate-callout'; +import { CalloutPlugin } from '@udecode/plate-callout/react'; +import { insertCodeBlock } from '@udecode/plate-code-block'; +import { CodeBlockPlugin } from '@udecode/plate-code-block/react'; +import { + type TElement, + type TNodeEntry, + getBlockAbove, + getBlocks, + getNodeEntry, + insertNodes, + removeEmptyPreviousBlock, + setNodes, + unsetNodes, + withoutNormalizing, +} from '@udecode/plate-common'; +import { insertDate } from '@udecode/plate-date'; +import { DatePlugin } from '@udecode/plate-date/react'; +import { insertToc } from '@udecode/plate-heading'; +import { TocPlugin } from '@udecode/plate-heading/react'; +import { INDENT_LIST_KEYS, ListStyleType } from '@udecode/plate-indent-list'; +import { IndentListPlugin } from '@udecode/plate-indent-list/react'; +import { toggleColumns } from '@udecode/plate-layout'; +import { LinkPlugin, triggerFloatingLink } from '@udecode/plate-link/react'; +import { insertEquation, insertInlineEquation } from '@udecode/plate-math'; +import { + EquationPlugin, + InlineEquationPlugin, +} from '@udecode/plate-math/react'; +import { + insertAudioPlaceholder, + insertFilePlaceholder, + insertMedia, + insertVideoPlaceholder, +} from '@udecode/plate-media'; +import { + AudioPlugin, + FilePlugin, + ImagePlugin, + MediaEmbedPlugin, + VideoPlugin, +} from '@udecode/plate-media/react'; +import { TablePlugin, insertTable } from '@udecode/plate-table/react'; +import { Path } from 'slate'; + +const ACTION_THREE_COLUMNS = 'action_three_columns'; + +const insertList = (editor: PlateEditor, type: string) => { + insertNodes( + editor, + editor.api.create.block({ + indent: 1, + listStyleType: type, + }), + { select: true } + ); +}; + +const insertColumns = (editor: PlateEditor, _: string) => { + insertNodes(editor, editor.api.create.block(), { + select: true, + }); + + const entry = getBlockAbove(editor); + + if (!entry) return; + + toggleColumns(editor, entry); +}; + +const insertBlockMap: Record< + string, + (editor: PlateEditor, type: string) => void +> = { + [ACTION_THREE_COLUMNS]: insertColumns, + [AudioPlugin.key]: (editor) => + insertAudioPlaceholder(editor, { select: true }), + [CalloutPlugin.key]: (editor) => insertCallout(editor, { select: true }), + [CodeBlockPlugin.key]: (editor) => insertCodeBlock(editor, { select: true }), + [EquationPlugin.key]: (editor) => insertEquation(editor, { select: true }), + [FilePlugin.key]: (editor) => insertFilePlaceholder(editor, { select: true }), + [INDENT_LIST_KEYS.todo]: insertList, + [ImagePlugin.key]: (editor) => + insertMedia(editor, { + select: true, + type: ImagePlugin.key, + }), + [ListStyleType.Decimal]: insertList, + [ListStyleType.Disc]: insertList, + [MediaEmbedPlugin.key]: (editor) => + insertMedia(editor, { + select: true, + type: MediaEmbedPlugin.key, + }), + [TablePlugin.key]: (editor) => insertTable(editor, {}, { select: true }), + [TocPlugin.key]: (editor) => insertToc(editor, { select: true }), + [VideoPlugin.key]: (editor) => + insertVideoPlaceholder(editor, { select: true }), +}; + +const insertInlineMap: Record< + string, + (editor: PlateEditor, type: string) => void +> = { + [DatePlugin.key]: (editor) => insertDate(editor, { select: true }), + [InlineEquationPlugin.key]: (editor) => + insertInlineEquation(editor, '', { select: true }), + [LinkPlugin.key]: (editor) => triggerFloatingLink(editor, { focused: true }), +}; + +export const insertBlock = (editor: PlateEditor, type: string) => { + withoutNormalizing(editor, () => { + if (type in insertBlockMap) { + insertBlockMap[type](editor, type); + } else { + const path = getBlockAbove(editor)?.[1]; + + if (!path) return; + + const at = Path.next(path); + + insertNodes(editor, editor.api.create.block({ type }), { + at, + select: true, + }); + } + + removeEmptyPreviousBlock(editor); + }); +}; + +export const insertInlineElement = (editor: PlateEditor, type: string) => { + if (insertInlineMap[type]) { + insertInlineMap[type](editor, type); + } +}; + +const setList = ( + editor: PlateEditor, + type: string, + entry: TNodeEntry +) => { + setNodes( + editor, + editor.api.create.block({ + indent: 1, + listStyleType: type, + }), + { + at: entry[1], + } + ); +}; + +const setColumns = ( + editor: PlateEditor, + _: string, + entry: TNodeEntry +) => { + toggleColumns(editor, entry); +}; + +const setBlockMap: Record< + string, + (editor: PlateEditor, type: string, entry: TNodeEntry) => void +> = { + [ACTION_THREE_COLUMNS]: setColumns, + [INDENT_LIST_KEYS.todo]: setList, + [ListStyleType.Decimal]: setList, + [ListStyleType.Disc]: setList, +}; + +export const setBlockType = ( + editor: PlateEditor, + type: string, + { at }: { at?: Path } = {} +) => { + withoutNormalizing(editor, () => { + const setEntry = (entry: TNodeEntry) => { + const [node, path] = entry; + + if (node[IndentListPlugin.key]) { + unsetNodes(editor, [IndentListPlugin.key, 'indent'], { at: path }); + } + if (type in setBlockMap) { + return setBlockMap[type](editor, type, entry); + } + if (node.type !== type) { + editor.setNodes({ type }, { at: path }); + } + }; + + if (at) { + const entry = getNodeEntry(editor, at); + + if (entry) { + setEntry(entry); + + return; + } + } + + const entries = getBlocks(editor); + + entries.forEach((entry) => setEntry(entry)); + }); +}; + +export const getBlockType = (block: TElement) => { + if (block[IndentListPlugin.key]) { + if (block[IndentListPlugin.key] === ListStyleType.Decimal) { + return ListStyleType.Decimal; + } else if (block[IndentListPlugin.key] === INDENT_LIST_KEYS.todo) { + return INDENT_LIST_KEYS.todo; + } else { + return ListStyleType.Disc; + } + } + + return block.type; +}; diff --git a/apps/www/src/registry/default/plate-ui/ai-menu-items.tsx b/apps/www/src/registry/default/plate-ui/ai-menu-items.tsx index ef4f36e3b2..1afaa90ccc 100644 --- a/apps/www/src/registry/default/plate-ui/ai-menu-items.tsx +++ b/apps/www/src/registry/default/plate-ui/ai-menu-items.tsx @@ -76,7 +76,7 @@ Start writing a new paragraph AFTER ONLY ONE SENTENCE` }, }, explain: { - icon: , + icon: , label: 'Explain', value: 'explain', onSelect: ({ editor }) => { @@ -155,7 +155,7 @@ Start writing a new paragraph AFTER ONLY ONE SENTENCE` }, }, summarize: { - icon: , + icon: , label: 'Add a summary', value: 'summarize', onSelect: ({ editor }) => { @@ -278,7 +278,7 @@ export const AIMenuItems = ({ {group.items.map((menuItem) => ( { menuItem.onSelect?.({ diff --git a/apps/www/src/registry/default/plate-ui/align-dropdown-menu.tsx b/apps/www/src/registry/default/plate-ui/align-dropdown-menu.tsx index 7d6857f98f..e07646909c 100644 --- a/apps/www/src/registry/default/plate-ui/align-dropdown-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/align-dropdown-menu.tsx @@ -62,13 +62,10 @@ export function AlignDropdownMenu({ children, ...props }: DropdownMenuProps) { - + {items.map(({ icon: Icon, value: itemValue }) => ( - + ))} diff --git a/apps/www/src/registry/default/plate-ui/block-context-menu.tsx b/apps/www/src/registry/default/plate-ui/block-context-menu.tsx index e3e494c5f7..c92412c640 100644 --- a/apps/www/src/registry/default/plate-ui/block-context-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/block-context-menu.tsx @@ -21,9 +21,8 @@ import { import { ContextMenu, ContextMenuContent, + ContextMenuGroup, ContextMenuItem, - ContextMenuSeparator, - ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, @@ -91,93 +90,97 @@ export function BlockContextMenu({ children }: { children: React.ReactNode }) { setValue(null); }} > - { - setValue('askAI'); - }} - > - Ask AI - - { - editor - .getTransforms(BlockSelectionPlugin) - .blockSelection.removeNodes(); - focusEditor(editor); - }} - > - Delete - - { - editor - .getTransforms(BlockSelectionPlugin) - .blockSelection.duplicate( - editor.getApi(BlockSelectionPlugin).blockSelection.getNodes() - ); - }} - > - Duplicate - ⌘ + D - - - Turn into - - handleTurnInto(ParagraphPlugin.key)} - > - Paragraph - - - handleTurnInto(HEADING_KEYS.h1)}> - Heading 1 - - handleTurnInto(HEADING_KEYS.h2)}> - Heading 2 - - handleTurnInto(HEADING_KEYS.h3)}> - Heading 3 - - handleTurnInto(BlockquotePlugin.key)} - > - Blockquote - - - - - - editor - .getTransforms(BlockSelectionPlugin) - .blockSelection.setIndent(1) - } - > - Indent - - - editor - .getTransforms(BlockSelectionPlugin) - .blockSelection.setIndent(-1) - } - > - Outdent - - - Align - - handleAlign('left')}> - Left - - handleAlign('center')}> - Center - - handleAlign('right')}> - Right - - - + + { + setValue('askAI'); + }} + > + Ask AI + + { + editor + .getTransforms(BlockSelectionPlugin) + .blockSelection.removeNodes(); + focusEditor(editor); + }} + > + Delete + + { + editor + .getTransforms(BlockSelectionPlugin) + .blockSelection.duplicate( + editor.getApi(BlockSelectionPlugin).blockSelection.getNodes() + ); + }} + > + Duplicate + {/* ⌘ + D */} + + + Turn into + + handleTurnInto(ParagraphPlugin.key)} + > + Paragraph + + + handleTurnInto(HEADING_KEYS.h1)}> + Heading 1 + + handleTurnInto(HEADING_KEYS.h2)}> + Heading 2 + + handleTurnInto(HEADING_KEYS.h3)}> + Heading 3 + + handleTurnInto(BlockquotePlugin.key)} + > + Blockquote + + + + + + + + editor + .getTransforms(BlockSelectionPlugin) + .blockSelection.setIndent(1) + } + > + Indent + + + editor + .getTransforms(BlockSelectionPlugin) + .blockSelection.setIndent(-1) + } + > + Outdent + + + Align + + handleAlign('left')}> + Left + + handleAlign('center')}> + Center + + handleAlign('right')}> + Right + + + + ); diff --git a/apps/www/src/registry/default/plate-ui/button.tsx b/apps/www/src/registry/default/plate-ui/button.tsx index 85aba8ce9a..d017db41fe 100644 --- a/apps/www/src/registry/default/plate-ui/button.tsx +++ b/apps/www/src/registry/default/plate-ui/button.tsx @@ -8,20 +8,19 @@ export const buttonVariants = cva( 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', { defaultVariants: { - size: 'default', + size: 'sm', variant: 'default', }, variants: { isMenu: { - true: 'h-auto w-full cursor-pointer justify-start', + true: 'w-full cursor-pointer justify-start', }, size: { - default: 'h-10 px-4 py-2', - icon: 'size-10', - lg: 'h-11 rounded-md px-8', + icon: 'size-[28px] rounded-md px-1.5', + lg: 'h-10 rounded-md px-4', + md: 'h-8 px-3 text-sm', none: '', - sm: 'h-9 rounded-md px-3', - sms: 'size-9 rounded-md px-0', + sm: 'h-[28px] rounded-md px-2.5', xs: 'h-8 rounded-md px-3 text-xs', }, variant: { diff --git a/apps/www/src/registry/default/plate-ui/code-block-combobox.tsx b/apps/www/src/registry/default/plate-ui/code-block-combobox.tsx index b691137410..535f20d68a 100644 --- a/apps/www/src/registry/default/plate-ui/code-block-combobox.tsx +++ b/apps/www/src/registry/default/plate-ui/code-block-combobox.tsx @@ -189,7 +189,6 @@ export function CodeBlockCombobox() { > diff --git a/apps/www/src/registry/default/plate-ui/color-dropdown-menu-items.tsx b/apps/www/src/registry/default/plate-ui/color-dropdown-menu-items.tsx index 13c14b07a8..fb8b107bf1 100644 --- a/apps/www/src/registry/default/plate-ui/color-dropdown-menu-items.tsx +++ b/apps/www/src/registry/default/plate-ui/color-dropdown-menu-items.tsx @@ -57,7 +57,7 @@ export function ColorDropdownMenuItem({ }} {...props} > - {isSelected ? : null} + {isSelected ? : null} ); diff --git a/apps/www/src/registry/default/plate-ui/color-picker.tsx b/apps/www/src/registry/default/plate-ui/color-picker.tsx index 1aef4f160f..901990e681 100644 --- a/apps/www/src/registry/default/plate-ui/color-picker.tsx +++ b/apps/www/src/registry/default/plate-ui/color-picker.tsx @@ -3,8 +3,7 @@ import React from 'react'; import { cn, withRef } from '@udecode/cn'; - -import { Icons } from '@/components/icons'; +import { EraserIcon } from 'lucide-react'; import { buttonVariants } from './button'; import { @@ -12,12 +11,7 @@ import { ColorDropdownMenuItems, } from './color-dropdown-menu-items'; import { ColorCustom } from './colors-custom'; -import { - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, -} from './dropdown-menu'; +import { DropdownMenuGroup, DropdownMenuItem } from './dropdown-menu'; export const ColorPickerContent = withRef< 'div', @@ -45,8 +39,7 @@ export const ColorPickerContent = withRef< ) => { return (
- Color Picker - + - {color && ( - - - - - - Clear - - - + + + + Clear + + )}
); diff --git a/apps/www/src/registry/default/plate-ui/colors-custom.tsx b/apps/www/src/registry/default/plate-ui/colors-custom.tsx index 4ca1f7307b..e5568e72f2 100644 --- a/apps/www/src/registry/default/plate-ui/colors-custom.tsx +++ b/apps/www/src/registry/default/plate-ui/colors-custom.tsx @@ -7,8 +7,7 @@ import { useColorsCustom, useColorsCustomState, } from '@udecode/plate-font/react'; - -import { Icons } from '@/components/icons'; +import { PlusIcon } from 'lucide-react'; import { buttonVariants } from './button'; import { @@ -65,7 +64,7 @@ export function ColorCustom({ {...menuItemProps} > Custom - + diff --git a/apps/www/src/registry/default/plate-ui/column-group-element.tsx b/apps/www/src/registry/default/plate-ui/column-group-element.tsx index 3970d1a920..10d903bd74 100644 --- a/apps/www/src/registry/default/plate-ui/column-group-element.tsx +++ b/apps/www/src/registry/default/plate-ui/column-group-element.tsx @@ -11,7 +11,7 @@ import { useColumnState, useDebouncePopoverOpen, } from '@udecode/plate-layout/react'; -import { type LucideProps, Delete } from 'lucide-react'; +import { type LucideProps, Trash2Icon } from 'lucide-react'; import { useReadOnly } from 'slate-react'; import { Button } from './button'; @@ -60,30 +60,34 @@ export function ColumnFloatingToolbar({ children }: React.PropsWithChildren) { side="top" sideOffset={10} > -
- - - - - -
diff --git a/apps/www/src/registry/default/plate-ui/command.tsx b/apps/www/src/registry/default/plate-ui/command.tsx index 0c391c8bec..0a4b9dc120 100644 --- a/apps/www/src/registry/default/plate-ui/command.tsx +++ b/apps/www/src/registry/default/plate-ui/command.tsx @@ -79,7 +79,7 @@ export const CommandSeparator = withCn( export const CommandItem = withCn( CommandPrimitive.Item, - 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50' + 'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0' ); export const CommandShortcut = withCn( diff --git a/apps/www/src/registry/default/plate-ui/comment-more-dropdown.tsx b/apps/www/src/registry/default/plate-ui/comment-more-dropdown.tsx index 930d7ef1f9..2a5316e59a 100644 --- a/apps/www/src/registry/default/plate-ui/comment-more-dropdown.tsx +++ b/apps/www/src/registry/default/plate-ui/comment-more-dropdown.tsx @@ -15,6 +15,7 @@ import { Button } from './button'; import { DropdownMenu, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuItem, DropdownMenuTrigger, } from './dropdown-menu'; @@ -33,8 +34,10 @@ export function CommentMoreDropdown() { - Edit comment - Delete comment + + Edit comment + Delete comment + ); diff --git a/apps/www/src/registry/default/plate-ui/context-menu.tsx b/apps/www/src/registry/default/plate-ui/context-menu.tsx index ed1a4cc136..baf1d1f166 100644 --- a/apps/www/src/registry/default/plate-ui/context-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/context-menu.tsx @@ -10,7 +10,36 @@ const ContextMenu = ContextMenuPrimitive.Root; const ContextMenuTrigger = ContextMenuPrimitive.Trigger; -const ContextMenuGroup = ContextMenuPrimitive.Group; +const ContextMenuGroup = React.forwardRef< + HTMLDivElement, + { label?: React.ReactNode } & React.ComponentPropsWithoutRef< + typeof ContextMenuPrimitive.Group + > +>(({ label, ...props }, ref) => { + return ( + <> + + + + {label && {label}} + {props.children} + + + ); +}); const ContextMenuPortal = ContextMenuPrimitive.Portal; @@ -27,7 +56,7 @@ const ContextMenuSubTrigger = React.forwardRef< +>(({ label, ...props }, ref) => { + return ( + <> + + + + {label && {label}} + {props.children} + + + ); +}); export const DropdownMenuPortal = DropdownMenuPrimitive.Portal; export const DropdownMenuSub = DropdownMenuPrimitive.Sub; -export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup; +export const DropdownMenuRadioGroup = React.forwardRef< + HTMLDivElement, + { label?: React.ReactNode } & React.ComponentPropsWithoutRef< + typeof DropdownMenuPrimitive.RadioGroup + > +>(({ label, ...props }, ref) => { + return ( + <> + + + + {label && {label}} + {props.children} + + + ); +}); export const DropdownMenuSubTrigger = withRef< typeof DropdownMenuPrimitive.SubTrigger, @@ -36,26 +94,25 @@ export const DropdownMenuSubTrigger = withRef< {children} - + )); export const DropdownMenuSubContent = withCn( DropdownMenuPrimitive.SubContent, - 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2' + 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover py-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2' ); const DropdownMenuContentVariants = withProps(DropdownMenuPrimitive.Content, { className: cn( - 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2' + 'z-50 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2' ), sideOffset: 4, }); @@ -75,11 +132,7 @@ export const DropdownMenuContent = withRef< )); const menuItemVariants = cva( - cn( - 'relative flex h-9 cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors', - '[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', - 'focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50' - ), + 'relative mx-1 flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', { variants: { inset: { @@ -101,7 +154,7 @@ export const DropdownMenuCheckboxItem = withRef< - + )} @@ -143,7 +195,9 @@ export const DropdownMenuRadioItem = withRef< )); const dropdownMenuLabelVariants = cva( - cn('select-none px-2 py-1.5 text-sm font-semibold'), + cn( + 'mx-1 select-none px-2 pb-2 pt-1.5 text-xs font-semibold text-muted-foreground' + ), { variants: { inset: { diff --git a/apps/www/src/registry/default/plate-ui/emoji-dropdown-menu.tsx b/apps/www/src/registry/default/plate-ui/emoji-dropdown-menu.tsx index 855e193c42..aa2397a5c4 100644 --- a/apps/www/src/registry/default/plate-ui/emoji-dropdown-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/emoji-dropdown-menu.tsx @@ -28,7 +28,7 @@ export function EmojiDropdownMenu({ - + } isOpen={isOpen} diff --git a/apps/www/src/registry/default/plate-ui/emoji-input-element.tsx b/apps/www/src/registry/default/plate-ui/emoji-input-element.tsx index f3485fd6e4..4731522745 100644 --- a/apps/www/src/registry/default/plate-ui/emoji-input-element.tsx +++ b/apps/www/src/registry/default/plate-ui/emoji-input-element.tsx @@ -11,6 +11,7 @@ import { InlineCombobox, InlineComboboxContent, InlineComboboxEmpty, + InlineComboboxGroup, InlineComboboxInput, InlineComboboxItem, } from './inline-combobox'; @@ -50,18 +51,20 @@ export const EmojiInputElement = withRef( {!isPending && ( - No matching emoji found + No results )} - {filteredEmojis.map((emoji) => ( - insertEmoji(editor, emoji)} - > - {emoji.skins[0].native} {emoji.name} - - ))} + + {filteredEmojis.map((emoji) => ( + insertEmoji(editor, emoji)} + > + {emoji.skins[0].native} {emoji.name} + + ))} + diff --git a/apps/www/src/registry/default/plate-ui/fixed-toolbar-buttons.tsx b/apps/www/src/registry/default/plate-ui/fixed-toolbar-buttons.tsx index 02f3714902..3c9e6075c4 100644 --- a/apps/www/src/registry/default/plate-ui/fixed-toolbar-buttons.tsx +++ b/apps/www/src/registry/default/plate-ui/fixed-toolbar-buttons.tsx @@ -1,5 +1,3 @@ -'use client'; - import React from 'react'; import { @@ -10,11 +8,46 @@ import { UnderlinePlugin, } from '@udecode/plate-basic-marks/react'; import { useEditorReadOnly } from '@udecode/plate-common/react'; -import { Bold, Code, Italic, Strikethrough, Underline } from 'lucide-react'; +import { + FontBackgroundColorPlugin, + FontColorPlugin, +} from '@udecode/plate-font/react'; +import { ListStyleType } from '@udecode/plate-indent-list'; +import { + BulletedListPlugin, + NumberedListPlugin, +} from '@udecode/plate-list/react'; +import { ImagePlugin } from '@udecode/plate-media/react'; +import { + BaselineIcon, + BoldIcon, + Code2Icon, + ItalicIcon, + PaintBucketIcon, + SparklesIcon, + StrikethroughIcon, + UnderlineIcon, +} from 'lucide-react'; +import { AIToolbarButton } from './ai-toolbar-button'; +import { AlignDropdownMenu } from './align-dropdown-menu'; +import { ColorDropdownMenu } from './color-dropdown-menu'; +import { CommentToolbarButton } from './comment-toolbar-button'; +import { EmojiDropdownMenu } from './emoji-dropdown-menu'; +import { IndentListToolbarButton } from './indent-list-toolbar-button'; +import { IndentTodoToolbarButton } from './indent-todo-toolbar-button'; +import { IndentToolbarButton } from './indent-toolbar-button'; import { InsertDropdownMenu } from './insert-dropdown-menu'; +import { LineHeightDropdownMenu } from './line-height-dropdown-menu'; +import { LinkToolbarButton } from './link-toolbar-button'; +import { ListToolbarButton } from './list-toolbar-button'; import { MarkToolbarButton } from './mark-toolbar-button'; +import { MediaToolbarButton } from './media-toolbar-button'; import { ModeDropdownMenu } from './mode-dropdown-menu'; +import { MoreDropdownMenu } from './more-dropdown-menu'; +import { OutdentToolbarButton } from './outdent-toolbar-button'; +import { TableDropdownMenu } from './table-dropdown-menu'; +import { ToggleToolbarButton } from './toggle-toolbar-button'; import { ToolbarGroup } from './toolbar'; import { TurnIntoDropdownMenu } from './turn-into-dropdown-menu'; @@ -22,56 +55,101 @@ export function FixedToolbarButtons() { const readOnly = useEditorReadOnly(); return ( -
-
- {!readOnly && ( - <> - - - - - - - - - - - - - - - - - - - - - - - - - )} - -
- - - - -
+
+ {!readOnly && ( + <> + + + + Ask AI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + +
+ + + + +
); } diff --git a/apps/www/src/registry/default/plate-ui/floating-toolbar-buttons.tsx b/apps/www/src/registry/default/plate-ui/floating-toolbar-buttons.tsx index f71626387a..76c83ce326 100644 --- a/apps/www/src/registry/default/plate-ui/floating-toolbar-buttons.tsx +++ b/apps/www/src/registry/default/plate-ui/floating-toolbar-buttons.tsx @@ -1,5 +1,3 @@ -'use client'; - import React from 'react'; import { @@ -10,12 +8,21 @@ import { UnderlinePlugin, } from '@udecode/plate-basic-marks/react'; import { useEditorReadOnly } from '@udecode/plate-common/react'; -import { Bold, Code, Italic, Strikethrough, Underline } from 'lucide-react'; - -import { ToolbarGroup } from './toolbar'; +import { + BoldIcon, + Code2Icon, + ItalicIcon, + SparklesIcon, + StrikethroughIcon, + UnderlineIcon, +} from 'lucide-react'; -// import { AIToolbarButton } from './ai-toolbar-button'; +import { AIToolbarButton } from './ai-toolbar-button'; +import { CommentToolbarButton } from './comment-toolbar-button'; +import { LinkToolbarButton } from './link-toolbar-button'; import { MarkToolbarButton } from './mark-toolbar-button'; +import { MoreDropdownMenu } from './more-dropdown-menu'; +import { ToolbarGroup } from './toolbar'; import { TurnIntoDropdownMenu } from './turn-into-dropdown-menu'; export function FloatingToolbarButtons() { @@ -25,46 +32,58 @@ export function FloatingToolbarButtons() { <> {!readOnly && ( <> - {/* + - + Ask AI - */} + - + + - + + - + + - + + - + + + )} + + + + + {!readOnly && } + ); } diff --git a/apps/www/src/registry/default/plate-ui/image-preview.tsx b/apps/www/src/registry/default/plate-ui/image-preview.tsx index eab41ed842..c9f3191b02 100644 --- a/apps/www/src/registry/default/plate-ui/image-preview.tsx +++ b/apps/www/src/registry/default/plate-ui/image-preview.tsx @@ -71,7 +71,7 @@ export const ImagePreview = () => { className="absolute bottom-0 left-1/2 z-40 flex w-fit -translate-x-1/2 justify-center gap-4 p-2 text-center text-white" onClick={(e) => e.stopPropagation()} > -
+
{(currentUrlIndex ?? 0) + 1}
diff --git a/apps/www/src/registry/default/plate-ui/inline-combobox.tsx b/apps/www/src/registry/default/plate-ui/inline-combobox.tsx index bf6ab4fed5..601ec14e7d 100644 --- a/apps/www/src/registry/default/plate-ui/inline-combobox.tsx +++ b/apps/www/src/registry/default/plate-ui/inline-combobox.tsx @@ -19,14 +19,17 @@ import type { PointRef } from 'slate'; import { type ComboboxItemProps, Combobox, + ComboboxGroup, + ComboboxGroupLabel, ComboboxItem, ComboboxPopover, ComboboxProvider, + ComboboxRow, Portal, useComboboxContext, useComboboxStore, } from '@ariakit/react'; -import { cn } from '@udecode/cn'; +import { cn, withCn } from '@udecode/cn'; import { filterWords } from '@udecode/plate-combobox'; import { type UseComboboxInputResult, @@ -48,7 +51,7 @@ import { import { cva } from 'class-variance-authority'; type FilterFn = ( - item: { value: string; keywords?: string[] }, + item: { value: string; group?: string; keywords?: string[]; label?: string }, search: string ) => boolean; @@ -66,8 +69,18 @@ const InlineComboboxContext = createContext( null as any ); -export const defaultFilter: FilterFn = ({ keywords = [], value }, search) => - [value, ...keywords].some((keyword) => filterWords(keyword, search)); +export const defaultFilter: FilterFn = ( + { group, keywords = [], label, value }, + search +) => { + const uniqueTerms = new Set( + [value, ...keywords, group, label].filter(Boolean) + ); + + return Array.from(uniqueTerms).some((keyword) => + filterWords(keyword!, search) + ); +}; interface InlineComboboxProps { children: ReactNode; @@ -281,7 +294,7 @@ const InlineComboboxContent: typeof ComboboxPopover = ({ }; const comboboxItemVariants = cva( - 'relative flex h-9 select-none items-center rounded-sm px-2 py-1.5 text-sm text-foreground outline-none', + 'relative mx-1 flex h-[28px] select-none items-center rounded-sm px-2 text-sm text-foreground outline-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', { defaultVariants: { interactive: true, @@ -297,14 +310,18 @@ const comboboxItemVariants = cva( export type InlineComboboxItemProps = { focusEditor?: boolean; + group?: string; keywords?: string[]; + label?: string; } & ComboboxItemProps & Required>; const InlineComboboxItem = ({ className, focusEditor = true, + group, keywords, + label, onClick, ...props }: InlineComboboxItemProps) => { @@ -318,8 +335,9 @@ const InlineComboboxItem = ({ const search = filter && store.useState('value'); const visible = useMemo( - () => !filter || filter({ keywords, value }, search as string), - [filter, value, keywords, search] + () => + !filter || filter({ group, keywords, label, value }, search as string), + [filter, group, keywords, label, value, search] ); if (!visible) return null; @@ -363,10 +381,25 @@ const InlineComboboxEmpty = ({ ); }; +const InlineComboboxRow = ComboboxRow; + +const InlineComboboxGroup = withCn( + ComboboxGroup, + 'hidden py-1.5 [&:has([role=option])]:block [&:not(:last-child)]:border-b' +); + +const InlineComboboxGroupLabel = withCn( + ComboboxGroupLabel, + 'mb-2 mt-1.5 px-3 text-xs font-medium text-muted-foreground' +); + export { InlineCombobox, InlineComboboxContent, InlineComboboxEmpty, + InlineComboboxGroup, + InlineComboboxGroupLabel, InlineComboboxInput, InlineComboboxItem, + InlineComboboxRow, }; diff --git a/apps/www/src/registry/default/plate-ui/input.tsx b/apps/www/src/registry/default/plate-ui/input.tsx index b8aac8a16e..42119f710f 100644 --- a/apps/www/src/registry/default/plate-ui/input.tsx +++ b/apps/www/src/registry/default/plate-ui/input.tsx @@ -11,7 +11,7 @@ export const inputVariants = cva( variants: { h: { md: 'h-10 px-3 py-2', - sm: 'h-9 px-3 py-2', + sm: 'h-[28px] px-1.5 py-1', }, variant: { default: diff --git a/apps/www/src/registry/default/plate-ui/insert-dropdown-menu.tsx b/apps/www/src/registry/default/plate-ui/insert-dropdown-menu.tsx index 781d2a5538..101d8f04f6 100644 --- a/apps/www/src/registry/default/plate-ui/insert-dropdown-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/insert-dropdown-menu.tsx @@ -5,133 +5,221 @@ import React from 'react'; import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu'; import { BlockquotePlugin } from '@udecode/plate-block-quote/react'; -import { insertEmptyElement } from '@udecode/plate-common'; +import { CodeBlockPlugin } from '@udecode/plate-code-block/react'; import { + type PlateEditor, ParagraphPlugin, focusEditor, useEditorRef, } from '@udecode/plate-common/react'; +import { DatePlugin } from '@udecode/plate-date/react'; +import { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react'; import { HEADING_KEYS } from '@udecode/plate-heading'; +import { TocPlugin } from '@udecode/plate-heading/react'; +import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react'; +import { INDENT_LIST_KEYS, ListStyleType } from '@udecode/plate-indent-list'; +import { LinkPlugin } from '@udecode/plate-link/react'; +import { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react'; +import { TablePlugin } from '@udecode/plate-table/react'; +import { TogglePlugin } from '@udecode/plate-toggle/react'; import { + CalendarIcon, + ChevronRightIcon, + Columns3Icon, + FileCodeIcon, + FilmIcon, Heading1Icon, Heading2Icon, Heading3Icon, + ImageIcon, + Link2Icon, + ListIcon, + ListOrderedIcon, + MinusIcon, + PenToolIcon, PilcrowIcon, - Plus, + PlusIcon, QuoteIcon, + SquareIcon, + TableIcon, + TableOfContentsIcon, } from 'lucide-react'; +import { + insertBlock, + insertInlineElement, +} from '@/registry/default/lib/transforms'; + import { DropdownMenu, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, DropdownMenuTrigger, useOpenState, } from './dropdown-menu'; import { ToolbarButton } from './toolbar'; -const items = [ +type Group = { + group: string; + items: Item[]; +}; + +interface Item { + icon: React.ReactNode; + onSelect: (editor: PlateEditor, value: string) => void; + value: string; + focusEditor?: boolean; + label?: string; +} + +const groups: Group[] = [ { + group: 'Basic blocks', items: [ { - description: 'Paragraph', - icon: PilcrowIcon, + icon: , label: 'Paragraph', value: ParagraphPlugin.key, }, { - description: 'Heading 1', - icon: Heading1Icon, + icon: , label: 'Heading 1', value: HEADING_KEYS.h1, }, { - description: 'Heading 2', - icon: Heading2Icon, + icon: , label: 'Heading 2', value: HEADING_KEYS.h2, }, { - description: 'Heading 3', - icon: Heading3Icon, + icon: , label: 'Heading 3', value: HEADING_KEYS.h3, }, { - description: 'Quote (⌘+⇧+.)', - icon: QuoteIcon, + icon: , + label: 'Table', + value: TablePlugin.key, + }, + { + icon: , + label: 'Code', + value: CodeBlockPlugin.key, + }, + { + icon: , label: 'Quote', value: BlockquotePlugin.key, }, - // { - // value: TablePlugin.key, - // label: 'Table', - // description: 'Table', - // icon: Icons.table, - // }, - // { - // value: 'ul', - // label: 'Bulleted list', - // description: 'Bulleted list', - // icon: Icons.ul, - // }, - // { - // value: 'ol', - // label: 'Numbered list', - // description: 'Numbered list', - // icon: Icons.ol, - // }, - // { - // value: HorizontalRulePlugin.key, - // label: 'Divider', - // description: 'Divider (---)', - // icon: Icons.hr, - // }, - ], - label: 'Basic blocks', + { + icon: , + label: 'Divider', + value: HorizontalRulePlugin.key, + }, + ].map((item) => ({ + ...item, + onSelect: (editor, value) => { + insertBlock(editor, value); + }, + })), + }, + { + group: 'Lists', + items: [ + { + icon: , + label: 'Bulleted list', + value: ListStyleType.Disc, + }, + { + icon: , + label: 'Numbered list', + value: ListStyleType.Decimal, + }, + { + icon: , + label: 'To-do list', + value: INDENT_LIST_KEYS.todo, + }, + { + icon: , + label: 'Toggle list', + value: TogglePlugin.key, + }, + ].map((item) => ({ + ...item, + onSelect: (editor, value) => { + insertBlock(editor, value); + }, + })), + }, + { + group: 'Media', + items: [ + { + icon: , + label: 'Image', + value: ImagePlugin.key, + }, + { + icon: , + label: 'Embed', + value: MediaEmbedPlugin.key, + }, + { + icon: , + label: 'Excalidraw', + value: ExcalidrawPlugin.key, + }, + ].map((item) => ({ + ...item, + onSelect: (editor, value) => { + insertBlock(editor, value); + }, + })), + }, + { + group: 'Advanced blocks', + items: [ + { + icon: , + label: 'Table of contents', + value: TocPlugin.key, + }, + { + icon: , + label: '3 columns', + value: 'action_three_columns', + }, + ].map((item) => ({ + ...item, + onSelect: (editor, value) => { + insertBlock(editor, value); + }, + })), + }, + { + group: 'Inline', + items: [ + { + icon: , + label: 'Link', + value: LinkPlugin.key, + }, + { + focusEditor: true, + icon: , + label: 'Date', + value: DatePlugin.key, + }, + ].map((item) => ({ + ...item, + onSelect: (editor, value) => { + insertInlineElement(editor, value); + }, + })), }, - // { - // label: 'Media', - // items: [ - // { - // value: CodeBlockPlugin.key, - // label: 'Code', - // description: 'Code (```)', - // icon: Icons.codeblock, - // }, - // { - // value: ImagePlugin.key, - // label: 'Image', - // description: 'Image', - // icon: Icons.image, - // }, - // { - // value: MediaEmbedPlugin.key, - // label: 'Embed', - // description: 'Embed', - // icon: Icons.embed, - // }, - // { - // value: ExcalidrawPlugin.key, - // label: 'Excalidraw', - // description: 'Excalidraw', - // icon: Icons.excalidraw, - // }, - // ], - // }, - // { - // label: 'Inline', - // items: [ - // { - // value: LinkPlugin.key, - // label: 'Link', - // description: 'Link', - // icon: Icons.link, - // }, - // ], - // }, ]; export function InsertDropdownMenu(props: DropdownMenuProps) { @@ -142,87 +230,30 @@ export function InsertDropdownMenu(props: DropdownMenuProps) { - + - {items.map(({ items: nestedItems, label }, index) => ( - - {index !== 0 && } - - {label} - {nestedItems.map( - ({ icon: Icon, label: itemLabel, value: type }) => ( - { - switch (type) { - // case CodeBlockPlugin.key: { - // insertEmptyCodeBlock(editor); - // - // break; - // } - // case ImagePlugin.key: { - // await insertMedia(editor, { type: ImagePlugin.key }); - // - // break; - // } - // case MediaEmbedPlugin.key: { - // await insertMedia(editor, { - // type: MediaEmbedPlugin.key, - // }); - // - // break; - // } - // case 'ul': - // case 'ol': { - // insertEmptyElement(editor, ParagraphPlugin.key, { - // select: true, - // nextBlock: true, - // }); - // - // if (settingsStore.get.checkedId(IndentListPlugin.key)) { - // toggleIndentList(editor, { - // listStyleType: type === 'ul' ? 'disc' : 'decimal', - // }); - // } else if (settingsStore.get.checkedId('list')) { - // toggleList(editor, { type }); - // } - // - // break; - // } - // case TablePlugin.key: { - // insertTable(editor); - // - // break; - // } - // case LinkPlugin.key: { - // triggerFloatingLink(editor, { focused: true }); - // - // break; - // } - default: { - insertEmptyElement(editor, type, { - nextBlock: true, - select: true, - }); - } - } - - focusEditor(editor); - }} - > - - {itemLabel} - - ) - )} - + {groups.map(({ group, items: nestedItems }) => ( + + {nestedItems.map(({ icon, label, value, onSelect }) => ( + { + onSelect(editor, value); + focusEditor(editor); + }} + > + {icon} + {label} + + ))} + ))} diff --git a/apps/www/src/registry/default/plate-ui/line-height-dropdown-menu.tsx b/apps/www/src/registry/default/plate-ui/line-height-dropdown-menu.tsx index 3bf6e25805..0472c08857 100644 --- a/apps/www/src/registry/default/plate-ui/line-height-dropdown-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/line-height-dropdown-menu.tsx @@ -38,10 +38,7 @@ export function LineHeightDropdownMenu({ ...props }: DropdownMenuProps) { - + {state.values.map((_value) => (
-
+
@@ -86,9 +86,9 @@ export function LinkFloatingToolbar({ state }: LinkFloatingToolbarProps) { placeholder="Paste link" />
- +
-
+
+
)} diff --git a/apps/www/src/registry/default/plate-ui/mention-input-element.tsx b/apps/www/src/registry/default/plate-ui/mention-input-element.tsx index a5966489fa..e9bb671d8a 100644 --- a/apps/www/src/registry/default/plate-ui/mention-input-element.tsx +++ b/apps/www/src/registry/default/plate-ui/mention-input-element.tsx @@ -9,6 +9,7 @@ import { InlineCombobox, InlineComboboxContent, InlineComboboxEmpty, + InlineComboboxGroup, InlineComboboxInput, InlineComboboxItem, } from './inline-combobox'; @@ -45,17 +46,19 @@ export const MentionInputElement = withRef( - No results found + No results - {MENTIONABLES.map((item) => ( - onSelectItem(editor, item, search)} - > - {item.text} - - ))} + + {MENTIONABLES.map((item) => ( + onSelectItem(editor, item, search)} + > + {item.text} + + ))} + diff --git a/apps/www/src/registry/default/plate-ui/mode-dropdown-menu.tsx b/apps/www/src/registry/default/plate-ui/mode-dropdown-menu.tsx index df477e9330..dcac579d20 100644 --- a/apps/www/src/registry/default/plate-ui/mode-dropdown-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/mode-dropdown-menu.tsx @@ -35,13 +35,13 @@ export function ModeDropdownMenu(props: DropdownMenuProps) { const item: any = { editing: ( <> - + Editing ), viewing: ( <> - + Viewing ), @@ -61,7 +61,6 @@ export function ModeDropdownMenu(props: DropdownMenuProps) { { if (newValue !== 'viewing') { diff --git a/apps/www/src/registry/default/plate-ui/more-dropdown-menu.tsx b/apps/www/src/registry/default/plate-ui/more-dropdown-menu.tsx index 5cd94cf88b..223d13f28d 100644 --- a/apps/www/src/registry/default/plate-ui/more-dropdown-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/more-dropdown-menu.tsx @@ -1,5 +1,3 @@ -'use client'; - import React from 'react'; import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu'; @@ -8,12 +6,22 @@ import { SubscriptPlugin, SuperscriptPlugin, } from '@udecode/plate-basic-marks/react'; +import { collapseSelection } from '@udecode/plate-common'; import { focusEditor, useEditorRef } from '@udecode/plate-common/react'; -import { MoreHorizontal, Subscript, Superscript } from 'lucide-react'; +import { HighlightPlugin } from '@udecode/plate-highlight/react'; +import { KbdPlugin } from '@udecode/plate-kbd/react'; +import { + HighlighterIcon, + KeyboardIcon, + MoreHorizontalIcon, + SubscriptIcon, + SuperscriptIcon, +} from 'lucide-react'; import { DropdownMenu, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuItem, DropdownMenuTrigger, useOpenState, @@ -28,40 +36,64 @@ export function MoreDropdownMenu(props: DropdownMenuProps) { - + - { - editor.tf.toggle.mark({ - key: SuperscriptPlugin.key, - clear: [SubscriptPlugin.key, SuperscriptPlugin.key], - }); - focusEditor(editor); - }} - > - - Superscript - {/* (⌘+,) */} - - { - editor.tf.toggle.mark({ - key: SubscriptPlugin.key, - clear: [SuperscriptPlugin.key, SubscriptPlugin.key], - }); - focusEditor(editor); - }} - > - - Subscript - {/* (⌘+.) */} - + + { + editor.tf.toggle.mark({ key: HighlightPlugin.key }); + collapseSelection(editor, { edge: 'end' }); + focusEditor(editor); + }} + > + + Highlight + + + { + editor.tf.toggle.mark({ key: KbdPlugin.key }); + collapseSelection(editor, { edge: 'end' }); + focusEditor(editor); + }} + > + + Keyboard input + + + { + editor.tf.toggle.mark({ + key: SuperscriptPlugin.key, + clear: [SubscriptPlugin.key, SuperscriptPlugin.key], + }); + focusEditor(editor); + }} + > + + Superscript + {/* (⌘+,) */} + + { + editor.tf.toggle.mark({ + key: SubscriptPlugin.key, + clear: [SuperscriptPlugin.key, SubscriptPlugin.key], + }); + focusEditor(editor); + }} + > + + Subscript + {/* (⌘+.) */} + + ); diff --git a/apps/www/src/registry/default/plate-ui/popover.tsx b/apps/www/src/registry/default/plate-ui/popover.tsx index 3ea03f21dd..5f02ac5291 100644 --- a/apps/www/src/registry/default/plate-ui/popover.tsx +++ b/apps/www/src/registry/default/plate-ui/popover.tsx @@ -13,7 +13,7 @@ export const PopoverTrigger = PopoverPrimitive.Trigger; export const PopoverAnchor = PopoverPrimitive.Anchor; export const popoverVariants = cva( - 'w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 print:hidden' + 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 print:hidden' ); export const PopoverContent = withRef( @@ -22,7 +22,6 @@ export const PopoverContent = withRef( >; - onSelect: (editor: PlateEditor) => void; +type Group = { + group: string; + items: Item[]; +}; + +interface Item { + icon: React.ReactNode; + + onSelect: (editor: PlateEditor, value: string) => void; + value: string; className?: string; focusEditor?: boolean; keywords?: string[]; + label?: string; } -const rules: SlashCommandRule[] = [ +const groups: Group[] = [ { - focusEditor: false, - icon: SparklesIcon, - value: 'AI', - onSelect: (editor) => { - editor.getApi(AIChatPlugin).aiChat.show(); - }, + group: 'AI', + items: [ + { + focusEditor: false, + icon: , + value: 'AI', + onSelect: (editor) => { + editor.getApi(AIChatPlugin).aiChat.show(); + }, + }, + ], }, { - icon: Heading1Icon, - value: 'Heading 1', - onSelect: (editor) => { - editor.tf.toggle.block({ type: HEADING_KEYS.h1 }); - }, + group: 'Basic blocks', + items: [ + { + icon: , + keywords: ['paragraph'], + label: 'Text', + value: ParagraphPlugin.key, + }, + { + icon: , + keywords: ['title', 'h1'], + label: 'Heading 1', + value: HEADING_KEYS.h1, + }, + { + icon: , + keywords: ['subtitle', 'h2'], + label: 'Heading 2', + value: HEADING_KEYS.h2, + }, + { + icon: , + keywords: ['subtitle', 'h3'], + label: 'Heading 3', + value: HEADING_KEYS.h3, + }, + { + icon: , + keywords: ['unordered', 'ul', '-'], + label: 'Bulleted list', + value: ListStyleType.Disc, + }, + { + icon: , + keywords: ['ordered', 'ol', '1'], + label: 'Numbered list', + value: ListStyleType.Decimal, + }, + { + icon: , + keywords: ['checklist', 'task', 'checkbox', '[]'], + label: 'To-do list', + value: INDENT_LIST_KEYS.todo, + }, + { + icon: , + keywords: ['collapsible', 'expandable'], + label: 'Toggle', + value: TogglePlugin.key, + }, + { + icon: , + keywords: ['```'], + label: 'Code Block', + value: CodeBlockPlugin.key, + }, + { + icon: , + label: 'Table', + value: TablePlugin.key, + }, + { + icon: , + keywords: ['citation', 'blockquote', 'quote', '>'], + label: 'Blockquote', + value: BlockquotePlugin.key, + }, + ].map((item) => ({ + ...item, + onSelect: (editor, value) => { + insertBlock(editor, value); + }, + })), }, { - icon: Heading2Icon, - value: 'Heading 2', - onSelect: (editor) => { - editor.tf.toggle.block({ type: HEADING_KEYS.h2 }); - }, + group: 'Advanced blocks', + items: [ + { + icon: , + keywords: ['toc'], + value: 'Table of Contents', + }, + { + icon: , + label: '3 columns', + value: 'action_three_columns', + }, + ].map((item) => ({ + ...item, + onSelect: (editor, value) => { + insertBlock(editor, value); + }, + })), }, { - icon: Heading3Icon, - value: 'Heading 3', - onSelect: (editor) => { - editor.tf.toggle.block({ type: HEADING_KEYS.h3 }); - }, - }, - { - icon: ListIcon, - keywords: ['ul', 'unordered list'], - value: 'Bulleted list', - onSelect: (editor) => { - toggleIndentList(editor, { - listStyleType: ListStyleType.Disc, - }); - }, - }, - { - icon: ListOrderedIcon, - keywords: ['ol', 'ordered list'], - value: 'Numbered list', - onSelect: (editor) => { - toggleIndentList(editor, { - listStyleType: ListStyleType.Decimal, - }); - }, - }, - { - icon: CalendarIcon, - keywords: ['inline', 'date'], - value: 'Date', - onSelect: (editor) => { - editor.getTransforms(DatePlugin).insert.date(); - }, + group: 'Inline', + items: [ + { + focusEditor: true, + icon: , + keywords: ['time'], + label: 'Date', + value: DatePlugin.key, + }, + ].map((item) => ({ + ...item, + onSelect: (editor, value) => { + insertInlineElement(editor, value); + }, + })), }, ]; @@ -112,24 +206,30 @@ export const SlashInputElement = withRef( - - No matching commands found - + No results + + {groups.map(({ group, items }) => ( + + {group} - {rules.map( - ({ focusEditor, icon: Icon, keywords, value, onSelect }) => ( - onSelect(editor)} - focusEditor={focusEditor} - keywords={keywords} - > - - {value} - - ) - )} + {items.map( + ({ focusEditor, icon, keywords, label, value, onSelect }) => ( + onSelect(editor, value)} + label={label} + focusEditor={focusEditor} + group={group} + keywords={keywords} + > +
{icon}
+ {label ?? value} +
+ ) + )} +
+ ))}
diff --git a/apps/www/src/registry/default/plate-ui/table-dropdown-menu.tsx b/apps/www/src/registry/default/plate-ui/table-dropdown-menu.tsx index b937959ca2..5f28689b4c 100644 --- a/apps/www/src/registry/default/plate-ui/table-dropdown-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/table-dropdown-menu.tsx @@ -29,6 +29,7 @@ import { import { DropdownMenu, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuItem, DropdownMenuSub, DropdownMenuSubContent, @@ -57,100 +58,102 @@ export function TableDropdownMenu(props: DropdownMenuProps) { - - -
- Table - - - { - insertTable(editor, {}, { select: true }); - focusEditor(editor); - }} - > - - Insert table - - { - deleteTable(editor); - focusEditor(editor); - }} - > - - Delete table - - - + + + +
+ Table + + + { + insertTable(editor, {}, { select: true }); + focusEditor(editor); + }} + > + + Insert table + + { + deleteTable(editor); + focusEditor(editor); + }} + > + + Delete table + + + - - - - Column - - - { - tf.insert.tableColumn(); - focusEditor(editor); - }} - > - - Insert column after - - { - deleteColumn(editor); - focusEditor(editor); - }} - > - - Delete column - - - + + + + Column + + + { + tf.insert.tableColumn(); + focusEditor(editor); + }} + > + + Insert column after + + { + deleteColumn(editor); + focusEditor(editor); + }} + > + + Delete column + + + - - - - Row - - - { - insertTableRow(editor); - focusEditor(editor); - }} - > - - Insert row after - - { - deleteRow(editor); - focusEditor(editor); - }} - > - - Delete row - - - + + + + Row + + + { + insertTableRow(editor); + focusEditor(editor); + }} + > + + Insert row after + + { + deleteRow(editor); + focusEditor(editor); + }} + > + + Delete row + + + + ); diff --git a/apps/www/src/registry/default/plate-ui/table-element.tsx b/apps/www/src/registry/default/plate-ui/table-element.tsx index 11b1552e9b..39b572455c 100644 --- a/apps/www/src/registry/default/plate-ui/table-element.tsx +++ b/apps/www/src/registry/default/plate-ui/table-element.tsx @@ -24,7 +24,7 @@ import { useTableElementState, useTableMergeState, } from '@udecode/plate-table/react'; -import { type LucideProps, Combine, Delete, Ungroup } from 'lucide-react'; +import { type LucideProps, Combine, Trash2Icon, Ungroup } from 'lucide-react'; import { useReadOnly, useSelected } from 'slate-react'; import { Button } from './button'; @@ -32,12 +32,12 @@ import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuPortal, DropdownMenuTrigger, } from './dropdown-menu'; import { PlateElement } from './plate-element'; import { Popover, PopoverContent, popoverVariants } from './popover'; -import { Separator } from './separator'; export const TableBordersDropdownMenuContent = withRef< typeof DropdownMenuPrimitive.Content @@ -61,51 +61,53 @@ export const TableBordersDropdownMenuContent = withRef< sideOffset={0} {...props} > - - -
Bottom Border
-
- - -
Top Border
-
- - -
Left Border
-
- - -
Right Border
-
- - + + + +
Bottom Border
+
+ + +
Top Border
+
+ + +
Left Border
+
+ + +
Right Border
+
+
- - -
No Border
-
- - -
Outside Borders
-
+ + + +
No Border
+
+ + +
Outside Borders
+
+
); }); @@ -136,7 +138,7 @@ export const TableFloatingToolbar = withRef( contentEditable={false} isMenu > - + Merge ); @@ -148,7 +150,7 @@ export const TableFloatingToolbar = withRef( contentEditable={false} isMenu > - + Unmerge ); @@ -158,7 +160,7 @@ export const TableFloatingToolbar = withRef( @@ -169,7 +171,7 @@ export const TableFloatingToolbar = withRef( @@ -181,10 +183,7 @@ export const TableFloatingToolbar = withRef( {(canMerge || canUnmerge || collapsed) && ( e.preventDefault()} {...props} > diff --git a/apps/www/src/registry/default/plate-ui/toggle-element.tsx b/apps/www/src/registry/default/plate-ui/toggle-element.tsx index 89cb68dcd9..e13e7fa0fc 100644 --- a/apps/www/src/registry/default/plate-ui/toggle-element.tsx +++ b/apps/www/src/registry/default/plate-ui/toggle-element.tsx @@ -6,6 +6,7 @@ import { } from '@udecode/plate-toggle/react'; import { ChevronDown, ChevronRight } from 'lucide-react'; +import { Button } from './button'; import { PlateElement } from './plate-element'; export const ToggleElement = withRef( @@ -20,13 +21,15 @@ export const ToggleElement = withRef( className={cn('relative pl-6', className)} {...props} > - {open ? : } - + {children} ); diff --git a/apps/www/src/registry/default/plate-ui/toggle-toolbar-button.tsx b/apps/www/src/registry/default/plate-ui/toggle-toolbar-button.tsx index 3e7b1f875f..985a05f637 100644 --- a/apps/www/src/registry/default/plate-ui/toggle-toolbar-button.tsx +++ b/apps/www/src/registry/default/plate-ui/toggle-toolbar-button.tsx @@ -7,7 +7,7 @@ import { useToggleToolbarButton, useToggleToolbarButtonState, } from '@udecode/plate-toggle/react'; -import { ChevronDown } from 'lucide-react'; +import { ChevronRightIcon } from 'lucide-react'; import { ToolbarButton } from './toolbar'; @@ -18,7 +18,7 @@ export const ToggleToolbarButton = withRef( return ( - + ); } diff --git a/apps/www/src/registry/default/plate-ui/toolbar.tsx b/apps/www/src/registry/default/plate-ui/toolbar.tsx index 31c6754358..9720c3624f 100644 --- a/apps/www/src/registry/default/plate-ui/toolbar.tsx +++ b/apps/www/src/registry/default/plate-ui/toolbar.tsx @@ -32,8 +32,7 @@ export const ToolbarSeparator = withCn( const toolbarButtonVariants = cva( cn( - 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium text-foreground ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', - '[&_svg:not([data-icon])]:size-4' + 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium text-foreground ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg:not([data-icon])]:size-4' ), { defaultVariants: { @@ -86,7 +85,7 @@ const ToolbarButton = withTooltip( size, variant, }), - isDropdown && 'justify-between pr-1', + isDropdown && 'justify-between gap-1 pr-1', className )} value={pressed ? 'single' : ''} @@ -94,12 +93,12 @@ const ToolbarButton = withTooltip( > {isDropdown ? ( <> -
+
{children}
@@ -139,18 +138,18 @@ export const ToolbarToggleItem = withVariants( ); export const ToolbarGroup = withRef<'div'>(({ children, className }, ref) => { - const childArr = React.Children.map(children, (c) => c); - - if (!childArr || childArr.length === 0) return null; - return (