diff --git a/apps/www/src/registry/default/components/editor/plugins/ai-plugins.tsx b/apps/www/src/registry/default/components/editor/plugins/ai-plugins.tsx index cde23f15a1..f374b5ad51 100644 --- a/apps/www/src/registry/default/components/editor/plugins/ai-plugins.tsx +++ b/apps/www/src/registry/default/components/editor/plugins/ai-plugins.tsx @@ -2,77 +2,71 @@ import React from 'react'; -import { withProps } from '@udecode/cn'; import { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react'; import { - BoldPlugin, - CodePlugin, - ItalicPlugin, - StrikethroughPlugin, - UnderlinePlugin, -} from '@udecode/plate-basic-marks/react'; -import { BlockquotePlugin } from '@udecode/plate-block-quote/react'; + BaseBoldPlugin, + BaseCodePlugin, + BaseItalicPlugin, + BaseStrikethroughPlugin, + BaseUnderlinePlugin, +} from '@udecode/plate-basic-marks'; +import { BaseBlockquotePlugin } from '@udecode/plate-block-quote'; import { - CodeBlockPlugin, - CodeLinePlugin, - CodeSyntaxPlugin, -} from '@udecode/plate-code-block/react'; -import { - ParagraphPlugin, - PlateLeaf, - createPlateEditor, -} from '@udecode/plate-common/react'; -import { HEADING_KEYS } from '@udecode/plate-heading'; -import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react'; -import { LinkPlugin } from '@udecode/plate-link/react'; + BaseCodeBlockPlugin, + BaseCodeLinePlugin, + BaseCodeSyntaxPlugin, +} from '@udecode/plate-code-block'; +import { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate-common'; +import { BaseHeadingPlugin, HEADING_LEVELS } from '@udecode/plate-heading'; +import { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule'; +import { BaseIndentListPlugin } from '@udecode/plate-indent-list'; +import { BaseLinkPlugin } from '@udecode/plate-link'; import { MarkdownPlugin } from '@udecode/plate-markdown'; -import { cursorOverlayPlugin } from '@/registry/default/components/editor/plugins/cursor-overlay-plugin'; import { AIMenu } from '@/registry/default/plate-ui/ai-menu'; -import { BlockquoteElement } from '@/registry/default/plate-ui/blockquote-element'; -import { CodeBlockElement } from '@/registry/default/plate-ui/code-block-element'; -import { CodeLeaf } from '@/registry/default/plate-ui/code-leaf'; -import { CodeLineElement } from '@/registry/default/plate-ui/code-line-element'; -import { CodeSyntaxLeaf } from '@/registry/default/plate-ui/code-syntax-leaf'; -import { HeadingElement } from '@/registry/default/plate-ui/heading-element'; -import { HrElement } from '@/registry/default/plate-ui/hr-element'; -import { LinkElement } from '@/registry/default/plate-ui/link-element'; -import { ParagraphElement } from '@/registry/default/plate-ui/paragraph-element'; - -import { basicNodesPlugins } from './basic-nodes-plugins'; -import { blockSelectionReadOnlyPlugin } from './block-selection-plugins'; -import { indentListPlugins } from './indent-list-plugins'; -import { linkPlugin } from './link-plugin'; +import { + TodoLiStatic, + TodoMarkerStatic, +} from '@/registry/default/plate-ui/indent-todo-marker-static'; +import { cursorOverlayPlugin } from './cursor-overlay-plugin'; const createAIEditor = () => { - const editor = createPlateEditor({ + const editor = createSlateEditor({ id: 'ai', - override: { - components: { - [BlockquotePlugin.key]: BlockquoteElement, - [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }), - [CodeBlockPlugin.key]: CodeBlockElement, - [CodeLinePlugin.key]: CodeLineElement, - [CodePlugin.key]: CodeLeaf, - [CodeSyntaxPlugin.key]: CodeSyntaxLeaf, - [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }), - [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }), - [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }), - [HorizontalRulePlugin.key]: HrElement, - [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }), - [LinkPlugin.key]: LinkElement, - [ParagraphPlugin.key]: ParagraphElement, - [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }), - [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }), - }, - }, plugins: [ - ...basicNodesPlugins, - ...indentListPlugins, - HorizontalRulePlugin, - linkPlugin, + BaseBlockquotePlugin, + BaseBoldPlugin, + BaseCodeBlockPlugin, + BaseCodeLinePlugin, + BaseCodePlugin, + BaseCodeSyntaxPlugin, + BaseItalicPlugin, + BaseStrikethroughPlugin, + BaseUnderlinePlugin, + BaseHeadingPlugin, + BaseHorizontalRulePlugin, + BaseLinkPlugin, + BaseParagraphPlugin, + BaseIndentListPlugin.extend({ + inject: { + targetPlugins: [ + BaseParagraphPlugin.key, + ...HEADING_LEVELS, + BaseBlockquotePlugin.key, + BaseCodeBlockPlugin.key, + ], + }, + options: { + listStyleTypes: { + todo: { + liComponent: TodoLiStatic, + markerComponent: TodoMarkerStatic, + type: 'todo', + }, + }, + }, + }), MarkdownPlugin.configure({ options: { indentList: true } }), - blockSelectionReadOnlyPlugin, ], }); diff --git a/apps/www/src/registry/default/plate-ui/ai-chat-editor.tsx b/apps/www/src/registry/default/plate-ui/ai-chat-editor.tsx index a34755a07d..d0729695d0 100644 --- a/apps/www/src/registry/default/plate-ui/ai-chat-editor.tsx +++ b/apps/www/src/registry/default/plate-ui/ai-chat-editor.tsx @@ -2,21 +2,66 @@ import React, { memo } from 'react'; +import { withProps } from '@udecode/cn'; import { AIChatPlugin, useLastAssistantMessage } from '@udecode/plate-ai/react'; import { - type PlateEditor, - Plate, - useEditorPlugin, -} from '@udecode/plate-common/react'; + BaseBoldPlugin, + BaseCodePlugin, + BaseItalicPlugin, + BaseStrikethroughPlugin, + BaseUnderlinePlugin, +} from '@udecode/plate-basic-marks'; +import { BaseBlockquotePlugin } from '@udecode/plate-block-quote'; +import { + BaseCodeBlockPlugin, + BaseCodeLinePlugin, + BaseCodeSyntaxPlugin, +} from '@udecode/plate-code-block'; +import { useEditorPlugin } from '@udecode/plate-common/react'; +import { + type SlateEditor, + BaseParagraphPlugin, + SlateLeaf, +} from '@udecode/plate-core'; +import { HEADING_KEYS } from '@udecode/plate-heading'; +import { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule'; +import { BaseLinkPlugin } from '@udecode/plate-link'; import { deserializeMd } from '@udecode/plate-markdown'; -import { Editor } from './editor'; +import { BlockquoteElementStatic } from './blockquote-element-static'; +import { CodeBlockElementStatic } from './code-block-element-static'; +import { CodeLeafStatic } from './code-leaf-static'; +import { CodeLineElementStatic } from './code-line-element-static'; +import { CodeSyntaxLeafStatic } from './code-syntax-leaf-static'; +import { EditorStatic } from './editor-static'; +import { HeadingElementStatic } from './heading-element-static'; +import { HrElementStatic } from './hr-element-static'; +import { LinkElementStatic } from './link-element-static'; +import { ParagraphElementStatic } from './paragraph-element-static'; + +const staticComponents = { + [BaseBlockquotePlugin.key]: BlockquoteElementStatic, + [BaseBoldPlugin.key]: withProps(SlateLeaf, { as: 'strong' }), + [BaseCodeBlockPlugin.key]: CodeBlockElementStatic, + [BaseCodeLinePlugin.key]: CodeLineElementStatic, + [BaseCodePlugin.key]: CodeLeafStatic, + [BaseCodeSyntaxPlugin.key]: CodeSyntaxLeafStatic, + [BaseHorizontalRulePlugin.key]: HrElementStatic, + [BaseItalicPlugin.key]: withProps(SlateLeaf, { as: 'em' }), + [BaseLinkPlugin.key]: LinkElementStatic, + [BaseParagraphPlugin.key]: ParagraphElementStatic, + [BaseStrikethroughPlugin.key]: withProps(SlateLeaf, { as: 's' }), + [BaseUnderlinePlugin.key]: withProps(SlateLeaf, { as: 'u' }), + [HEADING_KEYS.h1]: withProps(HeadingElementStatic, { variant: 'h1' }), + [HEADING_KEYS.h2]: withProps(HeadingElementStatic, { variant: 'h2' }), + [HEADING_KEYS.h3]: withProps(HeadingElementStatic, { variant: 'h3' }), +}; export const AIChatEditor = memo( ({ aiEditorRef, }: { - aiEditorRef: React.MutableRefObject; + aiEditorRef: React.MutableRefObject; }) => { const { getOptions } = useEditorPlugin(AIChatPlugin); const lastAssistantMessage = useLastAssistantMessage(); @@ -46,9 +91,11 @@ export const AIChatEditor = memo( if (!content) return null; return ( - - - + ); } ); 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 a00f8f54d6..e483b10a4e 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 @@ -4,6 +4,7 @@ import { useEffect, useMemo } from 'react'; import { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react'; import { + type SlateEditor, getAncestorNode, getEndPoint, getNodeString, @@ -193,7 +194,7 @@ Start writing a new paragraph AFTER ONLY ONE SENTENCE` aiEditor, editor, }: { - aiEditor: PlateEditor; + aiEditor: SlateEditor; editor: PlateEditor; }) => void; } @@ -247,7 +248,7 @@ export const AIMenuItems = ({ aiEditorRef, setValue, }: { - aiEditorRef: React.MutableRefObject; + aiEditorRef: React.MutableRefObject; setValue: (value: string) => void; }) => { const { editor, useOption } = useEditorPlugin(AIChatPlugin); diff --git a/apps/www/src/registry/default/plate-ui/ai-menu.tsx b/apps/www/src/registry/default/plate-ui/ai-menu.tsx index 558eac3adc..7d4f05dfae 100644 --- a/apps/www/src/registry/default/plate-ui/ai-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/ai-menu.tsx @@ -4,6 +4,7 @@ import * as React from 'react'; import { AIChatPlugin, useEditorChat } from '@udecode/plate-ai/react'; import { + type SlateEditor, type TElement, type TNodeEntry, getAncestorNode, @@ -13,7 +14,6 @@ import { isSelectionAtBlockEnd, } from '@udecode/plate-common'; import { - type PlateEditor, toDOMNode, useEditorPlugin, useHotkeys, @@ -37,7 +37,7 @@ export function AIMenu() { const mode = useOption('mode'); const isSelecting = useIsSelecting(); - const aiEditorRef = React.useRef(null); + const aiEditorRef = React.useRef(null); const [value, setValue] = React.useState(''); const chat = useChat(); diff --git a/apps/www/src/registry/default/plate-ui/editor-static.tsx b/apps/www/src/registry/default/plate-ui/editor-static.tsx index f383031c41..d6e1276419 100644 --- a/apps/www/src/registry/default/plate-ui/editor-static.tsx +++ b/apps/www/src/registry/default/plate-ui/editor-static.tsx @@ -28,7 +28,7 @@ export const editorVariants = cva( variant: { ai: 'w-full px-0 text-base md:text-sm', aiChat: - 'max-h-[min(70vh,320px)] w-full max-w-[700px] overflow-y-auto px-3 py-2 text-base md:text-sm', + 'max-h-[min(70vh,320px)] w-full max-w-[700px] overflow-y-auto px-10 py-2 text-base md:text-sm', default: 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]', demo: 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]', diff --git a/packages/ai/src/react/ai-chat/AIChatPlugin.ts b/packages/ai/src/react/ai-chat/AIChatPlugin.ts index 87ef38b2b5..fbee2e44fe 100644 --- a/packages/ai/src/react/ai-chat/AIChatPlugin.ts +++ b/packages/ai/src/react/ai-chat/AIChatPlugin.ts @@ -4,14 +4,11 @@ import type { UseChatHelpers } from 'ai/react'; import { type OmitFirst, type PluginConfig, + type SlateEditor, bindFirst, + createSlateEditor, } from '@udecode/plate-common'; -import { - type PlateEditor, - createPlateEditor, - createTPlatePlugin, - focusEditor, -} from '@udecode/plate-common/react'; +import { createTPlatePlugin, focusEditor } from '@udecode/plate-common/react'; import { BlockSelectionPlugin } from '@udecode/plate-selection/react'; import type { AIBatch } from '../../lib'; @@ -31,7 +28,7 @@ import { withAIChat } from './withAIChat'; export type AIChatOptions = { chat: Partial; - createAIEditor: () => PlateEditor; + createAIEditor: () => SlateEditor; /** * Specifies how the assistant message is handled: * @@ -88,7 +85,7 @@ export const AIChatPlugin = createTPlatePlugin({ options: { chat: { messages: [] } as any, createAIEditor: () => - createPlateEditor({ + createSlateEditor({ id: 'ai', }), mode: 'chat', diff --git a/packages/ai/src/react/ai-chat/transforms/insertBelowAIChat.ts b/packages/ai/src/react/ai-chat/transforms/insertBelowAIChat.ts index 188bdce40f..7ee96a7e47 100644 --- a/packages/ai/src/react/ai-chat/transforms/insertBelowAIChat.ts +++ b/packages/ai/src/react/ai-chat/transforms/insertBelowAIChat.ts @@ -1,6 +1,6 @@ import type { PlateEditor } from '@udecode/plate-common/react'; -import { isEditorEmpty } from '@udecode/plate-common'; +import { type SlateEditor, isEditorEmpty } from '@udecode/plate-common'; import { BlockSelectionPlugin } from '@udecode/plate-selection/react'; import cloneDeep from 'lodash/cloneDeep.js'; import { Path, Range } from 'slate'; @@ -9,7 +9,7 @@ import type { AIChatPluginConfig } from '../AIChatPlugin'; export const insertBelowAIChat = ( editor: PlateEditor, - sourceEditor: PlateEditor + sourceEditor: SlateEditor ) => { if (!sourceEditor || isEditorEmpty(sourceEditor)) return; diff --git a/packages/ai/src/react/ai-chat/transforms/replaceSelectionAIChat.ts b/packages/ai/src/react/ai-chat/transforms/replaceSelectionAIChat.ts index eb438a3015..f0be843f79 100644 --- a/packages/ai/src/react/ai-chat/transforms/replaceSelectionAIChat.ts +++ b/packages/ai/src/react/ai-chat/transforms/replaceSelectionAIChat.ts @@ -1,4 +1,5 @@ import { + type SlateEditor, type TElement, getFirstNodeText, getNodeProps, @@ -17,7 +18,7 @@ import type { AIChatPluginConfig } from '../AIChatPlugin'; export const replaceSelectionAIChat = ( editor: PlateEditor, - sourceEditor: PlateEditor, + sourceEditor: SlateEditor, { format = 'single' }: { format?: 'all' | 'none' | 'single' } = {} ) => { if (!sourceEditor || isEditorEmpty(sourceEditor)) return;