diff --git a/apps/www/content/docs/en/ai.mdx b/apps/www/content/docs/en/ai.mdx index 8d40d2589..a223a5165 100644 --- a/apps/www/content/docs/en/ai.mdx +++ b/apps/www/content/docs/en/ai.mdx @@ -442,3 +442,52 @@ Special undo operation for AI changes: - Undoes the last operation if it was AI-generated - Removes the redo stack entry to prevent redoing AI operations + +### useAIChatEditor + +A hook that creates an editor for AI chat responses, registers it in the AI chat plugin, and deserializes markdown content with block-level memoization. + + + +The markdown content to deserialize into the editor. + + + + +Enable block-level memoization with `_memo` property. Defaults to true. + + +Options for the markdown token parser. Can filter out specific token types. + + +Function to customize the markdown processor. + + +Additional options passed to `usePlateEditor`. + + + + + + +The configured editor instance with deserialized content. + + + +```tsx +const AIChatEditor = ({ content }: { content: string }) => { + const aiEditor = useAIChatEditor(content, { + plugins: [ + // Your editor plugins + MarkdownPlugin, + // etc... + ], + // Optional markdown parser options + parser: { + exclude: ['space'], + }, + }); + + return ; +}; +``` diff --git a/apps/www/content/docs/en/block-selection.mdx b/apps/www/content/docs/en/block-selection.mdx index e1d92245c..eff3f888c 100644 --- a/apps/www/content/docs/en/block-selection.mdx +++ b/apps/www/content/docs/en/block-selection.mdx @@ -222,6 +222,18 @@ A set of IDs for the currently selected blocks. - **Default:** `new Set()` + + +(Internal) The ID of the anchor block in the current selection. Used for shift-based selection. + +- **Default:** `null` + + + +Function to determine if a block element is selectable. + +- **Default:** `() => true` + ### BlockMenuPlugin @@ -371,3 +383,64 @@ Returns fragment prop for the currently selected blocks. ### useSelectionArea A hook that initializes and manages the selection area functionality. + +### editor.api.blockSelection.isSelectable + +Checks if a block element is selectable. + + + +The block element to check. + + +The path to the block element. + + + + + +Returns true if the block is selectable. + + + +### editor.api.blockSelection.moveSelection + +Moves the selection up or down to the next selectable block. + + + +The direction to move the selection. + + + +When moving up: +- Gets the previous selectable block from the top-most selected block +- Sets it as the new anchor +- Clears previous selection and selects only this block + +When moving down: +- Gets the next selectable block from the bottom-most selected block +- Sets it as the new anchor +- Clears previous selection and selects only this block + +### editor.api.blockSelection.shiftSelection + +Expands or shrinks the selection based on the anchor block. + + + +The direction to expand/shrink the selection. + + + +For SHIFT + DOWN: +- If anchor is top-most: Expands down by adding block below bottom-most +- Otherwise: Shrinks from top-most (unless top-most is the anchor) + +For SHIFT + UP: +- If anchor is bottom-most: Expands up by adding block above top-most +- Otherwise: Shrinks from bottom-most (unless bottom-most is the anchor) + +The anchor block always remains selected. If no anchor is set, it defaults to: +- Bottom-most block for SHIFT + UP +- Top-most block for SHIFT + DOWN diff --git a/apps/www/src/registry/default/components/editor/use-chat.ts b/apps/www/src/registry/default/components/editor/use-chat.ts index 98bebcdf9..e6ac3d653 100644 --- a/apps/www/src/registry/default/components/editor/use-chat.ts +++ b/apps/www/src/registry/default/components/editor/use-chat.ts @@ -49,15 +49,15 @@ const fakeStreamText = ({ // Create 3 blocks with different lengths const blocks = [ Array.from({ length: chunkCount }, () => ({ - delay: faker.number.int({ max: 150, min: 50 }), + delay: faker.number.int({ max: 100, min: 30 }), texts: faker.lorem.words({ max: 3, min: 1 }) + ' ', })), Array.from({ length: chunkCount + 2 }, () => ({ - delay: faker.number.int({ max: 150, min: 50 }), + delay: faker.number.int({ max: 100, min: 30 }), texts: faker.lorem.words({ max: 3, min: 1 }) + ' ', })), Array.from({ length: chunkCount + 4 }, () => ({ - delay: faker.number.int({ max: 150, min: 50 }), + delay: faker.number.int({ max: 100, min: 30 }), texts: faker.lorem.words({ max: 3, min: 1 }) + ' ', })), ];