payload-richtext-tiptap 0.0.42 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AICommand.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AICommand.js +31 -14
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AICommand.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AIMenuList.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AIMenuList.js +39 -27
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AIMenuList.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/groups.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/groups.js +52 -227
- package/dist/src/fields/TiptapEditor/extensions/AICommand/groups.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/types.d.ts +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/types.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/types.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/Paragraph/AIEditorParagraph.d.ts +3 -0
- package/dist/src/fields/TiptapEditor/extensions/Paragraph/AIEditorParagraph.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/Paragraph/AIEditorParagraph.js +35 -0
- package/dist/src/fields/TiptapEditor/extensions/Paragraph/AIEditorParagraph.js.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/SlashCommand/MenuList.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/SlashCommand/MenuList.js +35 -26
- package/dist/src/fields/TiptapEditor/extensions/SlashCommand/MenuList.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.js +2 -2
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.js.map +1 -1
- package/dist/src/fields/TiptapEditor/features/menus/TextMenu/components/ai-draft-selector-commands.d.ts +6 -0
- package/dist/src/fields/TiptapEditor/features/menus/TextMenu/components/ai-draft-selector-commands.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/features/menus/TextMenu/components/ai-draft-selector-commands.js +1 -1
- package/dist/src/fields/TiptapEditor/features/menus/TextMenu/components/ai-draft-selector-commands.js.map +1 -1
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.d.ts +2 -1
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.js +60 -85
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.js.map +1 -1
- package/dist/src/fields/TiptapEditor/features/ui/Dropdown/Dropdown.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/features/ui/Dropdown/Dropdown.js +5 -1
- package/dist/src/fields/TiptapEditor/features/ui/Dropdown/Dropdown.js.map +1 -1
- package/dist/src/styles.css +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AICommand.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/AICommand.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"AICommand.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/AICommand.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,SAAS,EAAE,MAAM,cAAc,CAAC;AAiBjD,eAAO,MAAM,SAAS,qBAySpB,CAAC;AAEH,eAAe,SAAS,CAAC"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Extension } from "@tiptap/core";
|
|
3
|
+
import { PluginKey } from "@tiptap/pm/state";
|
|
3
4
|
import { ReactRenderer } from "@tiptap/react";
|
|
4
5
|
import Suggestion from "@tiptap/suggestion";
|
|
5
|
-
import { PluginKey } from "@tiptap/pm/state";
|
|
6
6
|
import tippy from "tippy.js";
|
|
7
7
|
import { GROUPS } from "./groups.js";
|
|
8
|
-
import
|
|
8
|
+
import AIMenuList from "./AIMenuList.js";
|
|
9
|
+
// import { AICommandPanel } from "../../features/panels/AICommandPanel/AICommandPanel.js";
|
|
9
10
|
const extensionName = "aiCommand";
|
|
10
11
|
let popup;
|
|
11
12
|
export const AICommand = Extension.create({
|
|
@@ -20,8 +21,8 @@ export const AICommand = Extension.create({
|
|
|
20
21
|
theme: "slash-command",
|
|
21
22
|
// maxWidth: "16rem",
|
|
22
23
|
offset: [
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
0,
|
|
25
|
+
-16
|
|
25
26
|
],
|
|
26
27
|
popperOptions: {
|
|
27
28
|
strategy: "fixed",
|
|
@@ -31,6 +32,10 @@ export const AICommand = Extension.create({
|
|
|
31
32
|
enabled: false
|
|
32
33
|
}
|
|
33
34
|
]
|
|
35
|
+
},
|
|
36
|
+
onHidden: (instance)=>{
|
|
37
|
+
const selection = this?.editor?.state?.selection;
|
|
38
|
+
this.editor?.chain()?.focus()?.insertContentAt(selection.to - 1, this?.editor?.storage?.aiCommand?.completion ?? "")?.insertContentAt(selection.to, " ")?.run();
|
|
34
39
|
}
|
|
35
40
|
});
|
|
36
41
|
},
|
|
@@ -49,19 +54,24 @@ export const AICommand = Extension.create({
|
|
|
49
54
|
const isStartOfNode = $from.parent.textContent?.charAt(0) === " ";
|
|
50
55
|
// TODO
|
|
51
56
|
const isInColumn = this.editor.isActive("column");
|
|
52
|
-
const afterContent = $from.parent.textContent?.substring($from.parent.textContent?.indexOf("
|
|
57
|
+
const afterContent = $from.parent.textContent?.substring($from.parent.textContent?.indexOf(" "));
|
|
53
58
|
const isValidAfterContent = !afterContent?.endsWith(" ");
|
|
54
59
|
return (isRootDepth && isParagraph && isStartOfNode || isInColumn && isParagraph && isStartOfNode) && isValidAfterContent;
|
|
55
60
|
},
|
|
56
61
|
command: ({ editor, props })=>{
|
|
57
|
-
const { view, state } = editor;
|
|
58
|
-
const { $head, $from } = view.state.selection;
|
|
59
|
-
const end = $from.pos;
|
|
60
|
-
const from = $head?.nodeBefore
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
// const { view, state } = editor;
|
|
63
|
+
// const { $head, $from } = view.state.selection;
|
|
64
|
+
// const end = $from.pos;
|
|
65
|
+
// const from = $head?.nodeBefore
|
|
66
|
+
// ? end -
|
|
67
|
+
// ($head.nodeBefore.text?.substring(
|
|
68
|
+
// $head.nodeBefore.text?.indexOf(" ")
|
|
69
|
+
// ).length ?? 0)
|
|
70
|
+
// : $from.start();
|
|
71
|
+
// const tr = state.tr.deleteRange(from, end);
|
|
72
|
+
// view.dispatch(tr);
|
|
63
73
|
props.action(editor);
|
|
64
|
-
|
|
74
|
+
// view.focus();
|
|
65
75
|
},
|
|
66
76
|
items: ({ query })=>{
|
|
67
77
|
const withFilteredCommands = GROUPS.map((group)=>({
|
|
@@ -96,10 +106,11 @@ export const AICommand = Extension.create({
|
|
|
96
106
|
let scrollHandler = null;
|
|
97
107
|
return {
|
|
98
108
|
onStart: (props)=>{
|
|
99
|
-
component = new ReactRenderer(
|
|
109
|
+
component = new ReactRenderer(AIMenuList, {
|
|
100
110
|
props,
|
|
101
111
|
editor: props.editor
|
|
102
112
|
});
|
|
113
|
+
props.editor.storage.aiCommand.active = true;
|
|
103
114
|
const { view } = props.editor;
|
|
104
115
|
const editorNode = view.dom;
|
|
105
116
|
const getReferenceClientRect = ()=>{
|
|
@@ -183,6 +194,9 @@ export const AICommand = Extension.create({
|
|
|
183
194
|
const { view } = props.editor;
|
|
184
195
|
view.dom.parentElement?.removeEventListener("scroll", scrollHandler);
|
|
185
196
|
}
|
|
197
|
+
props.editor.storage.aiCommand.active = false;
|
|
198
|
+
props.editor.storage.aiCommand.userPrompt = "";
|
|
199
|
+
props.editor.storage.aiCommand.completion = "";
|
|
186
200
|
component.destroy();
|
|
187
201
|
}
|
|
188
202
|
};
|
|
@@ -199,7 +213,10 @@ export const AICommand = Extension.create({
|
|
|
199
213
|
top: 0,
|
|
200
214
|
right: 0,
|
|
201
215
|
bottom: 0
|
|
202
|
-
}
|
|
216
|
+
},
|
|
217
|
+
userPrompt: "",
|
|
218
|
+
completion: "",
|
|
219
|
+
active: false
|
|
203
220
|
};
|
|
204
221
|
}
|
|
205
222
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/AICommand.ts"],"sourcesContent":["\"use client\";\nimport { Editor, Extension } from \"@tiptap/core\";\nimport { ReactRenderer } from \"@tiptap/react\";\nimport Suggestion, {\n SuggestionProps,\n SuggestionKeyDownProps,\n} from \"@tiptap/suggestion\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport tippy from \"tippy.js\";\n\nimport { GROUPS } from \"./groups.js\";\nimport { AIMenuList } from \"./AIMenuList.js\";\nimport { AIEditorPanel } from \"../../features/panels/AIEditorPanel/AIEditorPanel.js\";\nimport { AICommandPanel } from \"../../features/panels/AICommandPanel/AICommandPanel.js\";\n\nconst extensionName = \"aiCommand\";\n\nlet popup: any;\n\nexport const AICommand = Extension.create({\n name: extensionName,\n\n priority: 200,\n\n onCreate() {\n const t = tippy as any;\n popup = t(\"body\", {\n interactive: true,\n trigger: \"manual\",\n placement: \"bottom-start\",\n theme: \"slash-command\",\n // maxWidth: \"16rem\",\n offset: [16, 8],\n popperOptions: {\n strategy: \"fixed\",\n modifiers: [\n {\n name: \"flip\",\n enabled: false,\n },\n ],\n },\n });\n },\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n char: \" \",\n allowSpaces: true,\n startOfLine: true,\n pluginKey: new PluginKey(extensionName),\n allow: ({ state, range }) => {\n const $from = state.doc.resolve(range.from);\n const isRootDepth = $from.depth === 1;\n const isParagraph = $from.parent.type.name === \"paragraph\";\n const isStartOfNode = $from.parent.textContent?.charAt(0) === \" \";\n // TODO\n const isInColumn = this.editor.isActive(\"column\");\n\n const afterContent = $from.parent.textContent?.substring(\n $from.parent.textContent?.indexOf(\"/\")\n );\n const isValidAfterContent = !afterContent?.endsWith(\" \");\n\n return (\n ((isRootDepth && isParagraph && isStartOfNode) ||\n (isInColumn && isParagraph && isStartOfNode)) &&\n isValidAfterContent\n );\n },\n command: ({ editor, props }: { editor: Editor; props: any }) => {\n const { view, state } = editor;\n const { $head, $from } = view.state.selection;\n\n const end = $from.pos;\n const from = $head?.nodeBefore\n ? end -\n ($head.nodeBefore.text?.substring(\n $head.nodeBefore.text?.indexOf(\" \")\n ).length ?? 0)\n : $from.start();\n\n const tr = state.tr.deleteRange(from, end);\n view.dispatch(tr);\n\n props.action(editor);\n view.focus();\n },\n items: ({ query }: { query: string }) => {\n const withFilteredCommands = GROUPS.map((group) => ({\n ...group,\n commands: group.commands\n .filter((item) => {\n const labelNormalized = item.label.toLowerCase().trim();\n const queryNormalized = query.toLowerCase().trim();\n\n if (item.aliases) {\n const aliases = item.aliases.map((alias) =>\n alias.toLowerCase().trim()\n );\n\n return (\n labelNormalized.includes(queryNormalized) ||\n aliases.includes(queryNormalized)\n );\n }\n\n return labelNormalized.includes(queryNormalized);\n })\n .filter((command) =>\n command.shouldBeHidden\n ? !command.shouldBeHidden(this.editor)\n : true\n ),\n }));\n\n const withoutEmptyGroups = withFilteredCommands.filter((group) => {\n if (group.commands.length > 0) {\n return true;\n }\n\n return false;\n });\n\n const withEnabledSettings = withoutEmptyGroups.map((group) => ({\n ...group,\n commands: group.commands.map((command) => ({\n ...command,\n isEnabled: true,\n })),\n }));\n\n return withEnabledSettings;\n },\n render: () => {\n let component: any;\n\n let scrollHandler: (() => void) | null = null;\n\n return {\n onStart: (props: SuggestionProps) => {\n component = new ReactRenderer(AICommandPanel, {\n props,\n editor: props.editor,\n });\n\n const { view } = props.editor;\n\n const editorNode = view.dom as HTMLElement;\n\n const getReferenceClientRect = () => {\n if (!props.clientRect) {\n return props.editor.storage[extensionName].rect;\n }\n\n const rect = props.clientRect();\n\n if (!rect) {\n return props.editor.storage[extensionName].rect;\n }\n\n let yPos = rect.y;\n\n if (\n rect.top + component.element.offsetHeight + 40 >\n window.innerHeight\n ) {\n const diff =\n rect.top +\n component.element.offsetHeight -\n window.innerHeight +\n 40;\n yPos = rect.y - diff;\n }\n\n // Account for when the editor is bound inside a container that doesn't go all the way to the edge of the screen\n const editorXOffset = editorNode.getBoundingClientRect().x;\n const boundigClient = editorNode.getBoundingClientRect();\n\n return new DOMRect(\n rect.x,\n yPos,\n boundigClient.width,\n rect.height\n );\n };\n\n scrollHandler = () => {\n popup?.[0].setProps({\n getReferenceClientRect,\n });\n };\n\n view.dom.parentElement?.addEventListener(\"scroll\", scrollHandler);\n\n popup?.[0].setProps({\n getReferenceClientRect,\n appendTo: () => document.body,\n content: component.element,\n });\n\n popup?.[0].show();\n },\n\n onUpdate(props: SuggestionProps) {\n component.updateProps(props);\n\n const { view } = props.editor;\n\n const editorNode = view.dom as HTMLElement;\n\n const getReferenceClientRect = () => {\n if (!props.clientRect) {\n return props.editor.storage[extensionName].rect;\n }\n\n const rect = props.clientRect();\n\n if (!rect) {\n return props.editor.storage[extensionName].rect;\n }\n\n // Account for when the editor is bound inside a container that doesn't go all the way to the edge of the screen\n return new DOMRect(rect.x, rect.y, rect.width, rect.height);\n };\n\n let scrollHandler = () => {\n popup?.[0].setProps({\n getReferenceClientRect,\n });\n };\n\n view.dom.parentElement?.addEventListener(\"scroll\", scrollHandler);\n\n // eslint-disable-next-line no-param-reassign\n props.editor.storage[extensionName].rect = props.clientRect\n ? getReferenceClientRect()\n : {\n width: 0,\n height: 0,\n left: 0,\n top: 0,\n right: 0,\n bottom: 0,\n };\n popup?.[0].setProps({\n getReferenceClientRect,\n });\n },\n\n onKeyDown(props: SuggestionKeyDownProps) {\n if (props.event.key === \"Escape\") {\n popup?.[0].hide();\n\n return true;\n }\n\n if (!popup?.[0].state.isShown) {\n popup?.[0].show();\n }\n\n return component.ref?.onKeyDown(props);\n },\n\n onExit(props) {\n popup?.[0].hide();\n if (scrollHandler) {\n const { view } = props.editor;\n view.dom.parentElement?.removeEventListener(\n \"scroll\",\n scrollHandler\n );\n }\n component.destroy();\n },\n };\n },\n }),\n ];\n },\n\n addStorage() {\n return {\n rect: {\n width: 0,\n height: 0,\n left: 0,\n top: 0,\n right: 0,\n bottom: 0,\n },\n };\n },\n});\n\nexport default AICommand;\n"],"names":["Extension","ReactRenderer","Suggestion","PluginKey","tippy","GROUPS","AICommandPanel","extensionName","popup","AICommand","create","name","priority","onCreate","t","interactive","trigger","placement","theme","offset","popperOptions","strategy","modifiers","enabled","addProseMirrorPlugins","editor","char","allowSpaces","startOfLine","pluginKey","allow","state","range","$from","doc","resolve","from","isRootDepth","depth","isParagraph","parent","type","isStartOfNode","textContent","charAt","isInColumn","isActive","afterContent","substring","indexOf","isValidAfterContent","endsWith","command","props","view","$head","selection","end","pos","nodeBefore","text","length","start","tr","deleteRange","dispatch","action","focus","items","query","withFilteredCommands","map","group","commands","filter","item","labelNormalized","label","toLowerCase","trim","queryNormalized","aliases","alias","includes","shouldBeHidden","withoutEmptyGroups","withEnabledSettings","isEnabled","render","component","scrollHandler","onStart","editorNode","dom","getReferenceClientRect","clientRect","storage","rect","yPos","y","top","element","offsetHeight","window","innerHeight","diff","editorXOffset","getBoundingClientRect","x","boundigClient","DOMRect","width","height","setProps","parentElement","addEventListener","appendTo","document","body","content","show","onUpdate","updateProps","left","right","bottom","onKeyDown","event","key","hide","isShown","ref","onExit","removeEventListener","destroy","addStorage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/AICommand.ts"],"sourcesContent":["\"use client\";\nimport { Editor, Extension } from \"@tiptap/core\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport { ReactRenderer } from \"@tiptap/react\";\nimport Suggestion, {\n SuggestionKeyDownProps,\n SuggestionProps,\n} from \"@tiptap/suggestion\";\nimport tippy from \"tippy.js\";\n\nimport { GROUPS } from \"./groups.js\";\nimport AIMenuList from \"./AIMenuList.js\";\n// import { AICommandPanel } from \"../../features/panels/AICommandPanel/AICommandPanel.js\";\n\nconst extensionName = \"aiCommand\";\n\nlet popup: any;\n\nexport const AICommand = Extension.create({\n name: extensionName,\n\n priority: 200,\n\n onCreate() {\n const t = tippy as any;\n popup = t(\"body\", {\n interactive: true,\n trigger: \"manual\",\n placement: \"bottom-start\",\n theme: \"slash-command\",\n // maxWidth: \"16rem\",\n offset: [0, -16],\n popperOptions: {\n strategy: \"fixed\",\n modifiers: [\n {\n name: \"flip\",\n enabled: false,\n },\n ],\n },\n onHidden: (instance) => {\n const selection = this?.editor?.state?.selection;\n\n this.editor\n ?.chain()\n ?.focus()\n ?.insertContentAt(\n selection.to - 1,\n this?.editor?.storage?.aiCommand?.completion ?? \"\"\n )\n ?.insertContentAt(selection.to, \" \")\n ?.run();\n },\n });\n },\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n char: \" \",\n allowSpaces: true,\n startOfLine: true,\n pluginKey: new PluginKey(extensionName),\n allow: ({ state, range }) => {\n const $from = state.doc.resolve(range.from);\n const isRootDepth = $from.depth === 1;\n const isParagraph = $from.parent.type.name === \"paragraph\";\n const isStartOfNode = $from.parent.textContent?.charAt(0) === \" \";\n // TODO\n const isInColumn = this.editor.isActive(\"column\");\n\n const afterContent = $from.parent.textContent?.substring(\n $from.parent.textContent?.indexOf(\" \")\n );\n const isValidAfterContent = !afterContent?.endsWith(\" \");\n\n return (\n ((isRootDepth && isParagraph && isStartOfNode) ||\n (isInColumn && isParagraph && isStartOfNode)) &&\n isValidAfterContent\n );\n },\n command: ({ editor, props }: { editor: Editor; props: any }) => {\n // const { view, state } = editor;\n // const { $head, $from } = view.state.selection;\n\n // const end = $from.pos;\n // const from = $head?.nodeBefore\n // ? end -\n // ($head.nodeBefore.text?.substring(\n // $head.nodeBefore.text?.indexOf(\" \")\n // ).length ?? 0)\n // : $from.start();\n\n // const tr = state.tr.deleteRange(from, end);\n // view.dispatch(tr);\n\n props.action(editor);\n // view.focus();\n },\n items: ({ query }: { query: string }) => {\n const withFilteredCommands = GROUPS.map((group) => ({\n ...group,\n commands: group.commands\n .filter((item) => {\n const labelNormalized = item.label.toLowerCase().trim();\n const queryNormalized = query.toLowerCase().trim();\n\n if (item.aliases) {\n const aliases = item.aliases.map((alias) =>\n alias.toLowerCase().trim()\n );\n\n return (\n labelNormalized.includes(queryNormalized) ||\n aliases.includes(queryNormalized)\n );\n }\n\n return labelNormalized.includes(queryNormalized);\n })\n .filter((command) =>\n command.shouldBeHidden\n ? !command.shouldBeHidden(this.editor)\n : true\n ),\n }));\n\n const withoutEmptyGroups = withFilteredCommands.filter((group) => {\n if (group.commands.length > 0) {\n return true;\n }\n\n return false;\n });\n\n const withEnabledSettings = withoutEmptyGroups.map((group) => ({\n ...group,\n commands: group.commands.map((command) => ({\n ...command,\n isEnabled: true,\n })),\n }));\n\n return withEnabledSettings;\n },\n render: () => {\n let component: any;\n\n let scrollHandler: (() => void) | null = null;\n\n return {\n onStart: (props: SuggestionProps) => {\n component = new ReactRenderer(AIMenuList, {\n props,\n editor: props.editor,\n });\n props.editor.storage.aiCommand.active = true;\n const { view } = props.editor;\n\n const editorNode = view.dom as HTMLElement;\n\n const getReferenceClientRect = () => {\n if (!props.clientRect) {\n return props.editor.storage[extensionName].rect;\n }\n\n const rect = props.clientRect();\n\n if (!rect) {\n return props.editor.storage[extensionName].rect;\n }\n\n let yPos = rect.y;\n\n if (\n rect.top + component.element.offsetHeight + 40 >\n window.innerHeight\n ) {\n const diff =\n rect.top +\n component.element.offsetHeight -\n window.innerHeight +\n 40;\n yPos = rect.y - diff;\n }\n\n // Account for when the editor is bound inside a container that doesn't go all the way to the edge of the screen\n const editorXOffset = editorNode.getBoundingClientRect().x;\n const boundigClient = editorNode.getBoundingClientRect();\n\n return new DOMRect(\n rect.x,\n yPos,\n boundigClient.width,\n rect.height\n );\n };\n\n scrollHandler = () => {\n popup?.[0].setProps({\n getReferenceClientRect,\n });\n };\n\n view.dom.parentElement?.addEventListener(\"scroll\", scrollHandler);\n\n popup?.[0].setProps({\n getReferenceClientRect,\n appendTo: () => document.body,\n content: component.element,\n });\n\n popup?.[0].show();\n },\n\n onUpdate(props: SuggestionProps) {\n component.updateProps(props);\n\n const { view } = props.editor;\n\n const editorNode = view.dom as HTMLElement;\n\n const getReferenceClientRect = () => {\n if (!props.clientRect) {\n return props.editor.storage[extensionName].rect;\n }\n\n const rect = props.clientRect();\n\n if (!rect) {\n return props.editor.storage[extensionName].rect;\n }\n\n // Account for when the editor is bound inside a container that doesn't go all the way to the edge of the screen\n return new DOMRect(rect.x, rect.y, rect.width, rect.height);\n };\n\n let scrollHandler = () => {\n popup?.[0].setProps({\n getReferenceClientRect,\n });\n };\n\n view.dom.parentElement?.addEventListener(\"scroll\", scrollHandler);\n\n // eslint-disable-next-line no-param-reassign\n props.editor.storage[extensionName].rect = props.clientRect\n ? getReferenceClientRect()\n : {\n width: 0,\n height: 0,\n left: 0,\n top: 0,\n right: 0,\n bottom: 0,\n };\n popup?.[0].setProps({\n getReferenceClientRect,\n });\n },\n\n onKeyDown(props: SuggestionKeyDownProps) {\n if (props.event.key === \"Escape\") {\n popup?.[0].hide();\n\n return true;\n }\n\n if (!popup?.[0].state.isShown) {\n popup?.[0].show();\n }\n\n return component.ref?.onKeyDown(props);\n },\n\n onExit(props) {\n popup?.[0].hide();\n if (scrollHandler) {\n const { view } = props.editor;\n view.dom.parentElement?.removeEventListener(\n \"scroll\",\n scrollHandler\n );\n }\n\n props.editor.storage.aiCommand.active = false;\n props.editor.storage.aiCommand.userPrompt = \"\";\n props.editor.storage.aiCommand.completion = \"\";\n\n component.destroy();\n },\n };\n },\n }),\n ];\n },\n\n addStorage() {\n return {\n rect: {\n width: 0,\n height: 0,\n left: 0,\n top: 0,\n right: 0,\n bottom: 0,\n },\n userPrompt: \"\",\n completion: \"\",\n active: false,\n };\n },\n});\n\nexport default AICommand;\n"],"names":["Extension","PluginKey","ReactRenderer","Suggestion","tippy","GROUPS","AIMenuList","extensionName","popup","AICommand","create","name","priority","onCreate","t","interactive","trigger","placement","theme","offset","popperOptions","strategy","modifiers","enabled","onHidden","instance","selection","editor","state","chain","focus","insertContentAt","to","storage","aiCommand","completion","run","addProseMirrorPlugins","char","allowSpaces","startOfLine","pluginKey","allow","range","$from","doc","resolve","from","isRootDepth","depth","isParagraph","parent","type","isStartOfNode","textContent","charAt","isInColumn","isActive","afterContent","substring","indexOf","isValidAfterContent","endsWith","command","props","action","items","query","withFilteredCommands","map","group","commands","filter","item","labelNormalized","label","toLowerCase","trim","queryNormalized","aliases","alias","includes","shouldBeHidden","withoutEmptyGroups","length","withEnabledSettings","isEnabled","render","component","scrollHandler","onStart","active","view","editorNode","dom","getReferenceClientRect","clientRect","rect","yPos","y","top","element","offsetHeight","window","innerHeight","diff","editorXOffset","getBoundingClientRect","x","boundigClient","DOMRect","width","height","setProps","parentElement","addEventListener","appendTo","document","body","content","show","onUpdate","updateProps","left","right","bottom","onKeyDown","event","key","hide","isShown","ref","onExit","removeEventListener","userPrompt","destroy","addStorage"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AIMenuList.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/AIMenuList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAIxE,OAAO,
|
|
1
|
+
{"version":3,"file":"AIMenuList.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/AIMenuList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAIxE,OAAO,EAAE,eAAe,EAAW,MAAM,YAAY,CAAC;AAKtD,eAAO,MAAM,UAAU,iFA2JrB,CAAC;AAIH,eAAe,UAAU,CAAC"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { DropdownButton } from "../../features/ui/Dropdown/Dropdown.js";
|
|
4
4
|
import { Surface } from "../../features/ui/Surface.js";
|
|
5
|
+
import { AICommandPanel } from "../../features/panels/AICommandPanel/AICommandPanel.js";
|
|
5
6
|
import { Icon } from "../../features/ui/Icon.js";
|
|
6
7
|
export const AIMenuList = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
7
8
|
const scrollContainer = useRef(null);
|
|
8
9
|
const activeItem = useRef(null);
|
|
9
10
|
const [selectedGroupIndex, setSelectedGroupIndex] = useState(0);
|
|
10
11
|
const [selectedCommandIndex, setSelectedCommandIndex] = useState(0);
|
|
12
|
+
const [userPrompt, setUserPrompt] = useState("");
|
|
11
13
|
// Anytime the groups change, i.e. the user types to narrow it down, we want to
|
|
12
14
|
// reset the current selection to the first menu item
|
|
13
15
|
useEffect(()=>{
|
|
@@ -18,7 +20,8 @@ export const AIMenuList = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
18
20
|
]);
|
|
19
21
|
const selectItem = useCallback((groupIndex, commandIndex)=>{
|
|
20
22
|
const command = props.items[groupIndex].commands[commandIndex];
|
|
21
|
-
props.
|
|
23
|
+
setUserPrompt(command.action(props.editor));
|
|
24
|
+
// props.command(command);
|
|
22
25
|
}, [
|
|
23
26
|
props
|
|
24
27
|
]);
|
|
@@ -90,31 +93,40 @@ export const AIMenuList = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
90
93
|
if (!props.items.length) {
|
|
91
94
|
return null;
|
|
92
95
|
}
|
|
93
|
-
return /*#__PURE__*/
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
96
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
97
|
+
children: [
|
|
98
|
+
/*#__PURE__*/ _jsx(AICommandPanel, {
|
|
99
|
+
editor: props?.editor,
|
|
100
|
+
onOpenChange: ()=>{},
|
|
101
|
+
userPrompt: userPrompt
|
|
102
|
+
}),
|
|
103
|
+
/*#__PURE__*/ _jsx(Surface, {
|
|
104
|
+
ref: scrollContainer,
|
|
105
|
+
className: "text-black max-h-[min(80vh,24rem)] overflow-auto flex-wrap mb-8 p-2",
|
|
106
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
107
|
+
className: "grid grid-cols-1 gap-0.5",
|
|
108
|
+
children: props.items.map((group, groupIndex)=>/*#__PURE__*/ _jsxs(React.Fragment, {
|
|
109
|
+
children: [
|
|
110
|
+
/*#__PURE__*/ _jsx("div", {
|
|
111
|
+
className: "text-neutral-500 text-[0.65rem] col-[1/-1] mx-2 mt-4 font-semibold tracking-wider select-none uppercase first:mt-0.5",
|
|
112
|
+
children: group.title
|
|
113
|
+
}, `${group.title}`),
|
|
114
|
+
group.commands.map((command, commandIndex)=>/*#__PURE__*/ _jsxs(DropdownButton, {
|
|
115
|
+
isActive: selectedGroupIndex === groupIndex && selectedCommandIndex === commandIndex,
|
|
116
|
+
onClick: createCommandClickHandler(groupIndex, commandIndex),
|
|
117
|
+
children: [
|
|
118
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
119
|
+
icon: command.icon,
|
|
120
|
+
className: "mr-1"
|
|
121
|
+
}),
|
|
122
|
+
command.label
|
|
123
|
+
]
|
|
124
|
+
}, `${command.label}`))
|
|
125
|
+
]
|
|
126
|
+
}, `${group.title}-wrapper`))
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
]
|
|
118
130
|
});
|
|
119
131
|
});
|
|
120
132
|
AIMenuList.displayName = "AIMenuList";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/AIMenuList.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { DropdownButton } from \"../../features/ui/Dropdown/Dropdown.js\";\nimport { Surface } from \"../../features/ui/Surface.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/AIMenuList.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { DropdownButton } from \"../../features/ui/Dropdown/Dropdown.js\";\nimport { Surface } from \"../../features/ui/Surface.js\";\nimport { AIMenuListProps, Command } from \"./types.js\";\n\nimport { AICommandPanel } from \"../../features/panels/AICommandPanel/AICommandPanel.js\";\nimport { Icon } from \"../../features/ui/Icon.js\";\n\nexport const AIMenuList = React.forwardRef((props: AIMenuListProps, ref) => {\n const scrollContainer = useRef<HTMLDivElement>(null);\n const activeItem = useRef<HTMLButtonElement>(null);\n const [selectedGroupIndex, setSelectedGroupIndex] = useState(0);\n const [selectedCommandIndex, setSelectedCommandIndex] = useState(0);\n const [userPrompt, setUserPrompt] = useState(\"\");\n\n // Anytime the groups change, i.e. the user types to narrow it down, we want to\n // reset the current selection to the first menu item\n useEffect(() => {\n setSelectedGroupIndex(0);\n setSelectedCommandIndex(0);\n }, [props.items]);\n\n const selectItem = useCallback(\n (groupIndex: number, commandIndex: number) => {\n const command = props.items[groupIndex].commands[commandIndex];\n\n setUserPrompt(command.action(props.editor));\n // props.command(command);\n },\n [props]\n );\n\n React.useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: React.KeyboardEvent }) => {\n if (event.key === \"ArrowDown\") {\n if (!props.items.length) {\n return false;\n }\n\n const commands = props.items[selectedGroupIndex].commands;\n\n let newCommandIndex = selectedCommandIndex + 1;\n let newGroupIndex = selectedGroupIndex;\n\n if (commands.length - 1 < newCommandIndex) {\n newCommandIndex = 0;\n newGroupIndex = selectedGroupIndex + 1;\n }\n\n if (props.items.length - 1 < newGroupIndex) {\n newGroupIndex = 0;\n }\n\n setSelectedCommandIndex(newCommandIndex);\n setSelectedGroupIndex(newGroupIndex);\n\n return true;\n }\n\n if (event.key === \"ArrowUp\") {\n if (!props.items.length) {\n return false;\n }\n\n let newCommandIndex = selectedCommandIndex - 1;\n let newGroupIndex = selectedGroupIndex;\n\n if (newCommandIndex < 0) {\n newGroupIndex = selectedGroupIndex - 1;\n newCommandIndex =\n props.items[newGroupIndex]?.commands.length - 1 || 0;\n }\n\n if (newGroupIndex < 0) {\n newGroupIndex = props.items.length - 1;\n newCommandIndex = props.items[newGroupIndex].commands.length - 1;\n }\n\n setSelectedCommandIndex(newCommandIndex);\n setSelectedGroupIndex(newGroupIndex);\n\n return true;\n }\n\n if (event.key === \"Enter\") {\n if (\n !props.items.length ||\n selectedGroupIndex === -1 ||\n selectedCommandIndex === -1\n ) {\n return false;\n }\n\n selectItem(selectedGroupIndex, selectedCommandIndex);\n\n return true;\n }\n\n return false;\n },\n }));\n\n useEffect(() => {\n if (activeItem.current && scrollContainer.current) {\n const offsetTop = activeItem.current.offsetTop;\n const offsetHeight = activeItem.current.offsetHeight;\n\n scrollContainer.current.scrollTop = offsetTop - offsetHeight;\n }\n }, [selectedCommandIndex, selectedGroupIndex]);\n\n const createCommandClickHandler = useCallback(\n (groupIndex: number, commandIndex: number) => {\n return () => {\n selectItem(groupIndex, commandIndex);\n };\n },\n [selectItem]\n );\n\n if (!props.items.length) {\n return null;\n }\n\n return (\n <>\n <AICommandPanel\n editor={props?.editor as any}\n onOpenChange={() => {}}\n userPrompt={userPrompt}\n />\n <Surface\n ref={scrollContainer}\n className=\"text-black max-h-[min(80vh,24rem)] overflow-auto flex-wrap mb-8 p-2\"\n >\n <div className=\"grid grid-cols-1 gap-0.5\">\n {props.items.map((group, groupIndex: number) => (\n <React.Fragment key={`${group.title}-wrapper`}>\n <div\n className=\"text-neutral-500 text-[0.65rem] col-[1/-1] mx-2 mt-4 font-semibold tracking-wider select-none uppercase first:mt-0.5\"\n key={`${group.title}`}\n >\n {group.title}\n </div>\n {group.commands.map((command: Command, commandIndex: number) => (\n <DropdownButton\n key={`${command.label}`}\n isActive={\n selectedGroupIndex === groupIndex &&\n selectedCommandIndex === commandIndex\n }\n onClick={createCommandClickHandler(groupIndex, commandIndex)}\n >\n <Icon icon={command.icon} className=\"mr-1\" />\n {command.label}\n </DropdownButton>\n ))}\n </React.Fragment>\n ))}\n </div>\n </Surface>\n </>\n );\n});\n\nAIMenuList.displayName = \"AIMenuList\";\n\nexport default AIMenuList;\n"],"names":["React","useCallback","useEffect","useRef","useState","DropdownButton","Surface","AICommandPanel","Icon","AIMenuList","forwardRef","props","ref","scrollContainer","activeItem","selectedGroupIndex","setSelectedGroupIndex","selectedCommandIndex","setSelectedCommandIndex","userPrompt","setUserPrompt","items","selectItem","groupIndex","commandIndex","command","commands","action","editor","useImperativeHandle","onKeyDown","event","key","length","newCommandIndex","newGroupIndex","current","offsetTop","offsetHeight","scrollTop","createCommandClickHandler","onOpenChange","className","div","map","group","Fragment","title","isActive","onClick","icon","label","displayName"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groups.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/groups.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"groups.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/groups.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,eAAO,MAAM,MAAM,EAAE,KAAK,EAqFzB,CAAC;AAEF,eAAe,MAAM,CAAC"}
|