payload-richtext-tiptap 0.0.41 → 0.0.43
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/Components.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/Components.js +3 -3
- package/dist/src/fields/TiptapEditor/Components.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AICommand.d.ts +4 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AICommand.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AICommand.js +223 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AICommand.js.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AIMenuList.d.ts +5 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AIMenuList.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AIMenuList.js +135 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AIMenuList.js.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/CommandButton.d.ts +10 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/CommandButton.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/CommandButton.js +29 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/CommandButton.js.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/MenuList.d.ts +5 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/MenuList.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/MenuList.js +123 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/MenuList.js.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/groups.d.ts +4 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/groups.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/groups.js +85 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/groups.js.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/index.d.ts +2 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/index.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/index.js +3 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/index.js.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/types.d.ts +22 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/types.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/types.js +3 -0
- package/dist/src/fields/TiptapEditor/extensions/AICommand/types.js.map +1 -0
- package/dist/src/fields/TiptapEditor/extensions/ImageUpload/ImageUpload.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/ImageUpload/ImageUpload.js +3 -2
- package/dist/src/fields/TiptapEditor/extensions/ImageUpload/ImageUpload.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/ImageUpload/view/ImageUpload.d.ts +2 -2
- package/dist/src/fields/TiptapEditor/extensions/ImageUpload/view/ImageUpload.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/ImageUpload/view/ImageUpload.js +38 -21
- package/dist/src/fields/TiptapEditor/extensions/ImageUpload/view/ImageUpload.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 +3 -1
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.js +23 -16
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/index.d.ts +1 -0
- package/dist/src/fields/TiptapEditor/extensions/index.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/index.js +1 -0
- package/dist/src/fields/TiptapEditor/extensions/index.js.map +1 -1
- package/dist/src/fields/TiptapEditor/features/BlockEditor/BlockEditor.d.ts +4 -1
- package/dist/src/fields/TiptapEditor/features/BlockEditor/BlockEditor.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/features/BlockEditor/BlockEditor.js +3 -2
- package/dist/src/fields/TiptapEditor/features/BlockEditor/BlockEditor.js.map +1 -1
- package/dist/src/fields/TiptapEditor/features/menus/TextMenu/components/ai-draft-selector-commands.d.ts +14 -0
- package/dist/src/fields/TiptapEditor/features/menus/TextMenu/components/ai-draft-selector-commands.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/menus/TextMenu/components/ai-draft-selector-commands.js +94 -0
- package/dist/src/fields/TiptapEditor/features/menus/TextMenu/components/ai-draft-selector-commands.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.d.ts +8 -0
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.js +168 -0
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/index.d.ts +2 -0
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/index.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/index.js +3 -0
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/index.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.js +29 -17
- package/dist/src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.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/fields/TiptapEditor/hooks/useBlockEditor.d.ts +3 -1
- package/dist/src/fields/TiptapEditor/hooks/useBlockEditor.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/hooks/useBlockEditor.js +4 -3
- package/dist/src/fields/TiptapEditor/hooks/useBlockEditor.js.map +1 -1
- package/dist/src/fields/TiptapEditor/lib/extract.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/lib/extract.js +6 -5
- package/dist/src/fields/TiptapEditor/lib/extract.js.map +1 -1
- package/dist/src/fields/TiptapEditor/types.d.js +3 -0
- package/dist/src/fields/TiptapEditor/types.d.js.map +1 -0
- package/dist/src/styles.css +4 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Components.d.ts","sourceRoot":"","sources":["../../../../src/fields/TiptapEditor/Components.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Components.d.ts","sourceRoot":"","sources":["../../../../src/fields/TiptapEditor/Components.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAE,eAAe,EAA0B,MAAM,SAAS,CAAC;AAqClE,eAAO,MAAM,eAAe,EAAE,eA4B7B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import
|
|
3
|
+
import { useCallback, useEffect, useState } from "react";
|
|
4
4
|
// import 'cal-sans'
|
|
5
5
|
// import '@fontsource/inter/100.css'
|
|
6
6
|
// import '@fontsource/inter/200.css'
|
|
@@ -10,8 +10,7 @@ import React, { useCallback, useEffect, useState } from "react";
|
|
|
10
10
|
// import '@fontsource/inter/600.css'
|
|
11
11
|
// import '@fontsource/inter/700.css'
|
|
12
12
|
// import { BlockEditor } from './features/BlockEditor'
|
|
13
|
-
import { useField } from "@payloadcms/ui";
|
|
14
|
-
import { useLocale } from "@payloadcms/ui";
|
|
13
|
+
import { useField, useLocale } from "@payloadcms/ui";
|
|
15
14
|
import { BlockEditor } from "./features/BlockEditor/BlockEditor.js";
|
|
16
15
|
const useDarkmode = ()=>{
|
|
17
16
|
const [isDarkMode, setIsDarkMode] = useState(typeof window !== "undefined" ? document.documentElement.getAttribute("data-theme") === "dark" : false);
|
|
@@ -55,6 +54,7 @@ export const EditorComponent = (props)=>{
|
|
|
55
54
|
children: /*#__PURE__*/ _jsx(BlockEditor, {
|
|
56
55
|
hasCollab: hasCollab,
|
|
57
56
|
content: value,
|
|
57
|
+
openAssetHQHandler: (listener)=>{},
|
|
58
58
|
handleChange: (value)=>{
|
|
59
59
|
setValue(value);
|
|
60
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/fields/TiptapEditor/Components.tsx"],"sourcesContent":["\"use client\";\nimport
|
|
1
|
+
{"version":3,"sources":["../../../../src/fields/TiptapEditor/Components.tsx"],"sourcesContent":["\"use client\";\nimport { useCallback, useEffect, useState } from \"react\";\n\n// import 'cal-sans'\n\n// import '@fontsource/inter/100.css'\n// import '@fontsource/inter/200.css'\n// import '@fontsource/inter/300.css'\n// import '@fontsource/inter/400.css'\n// import '@fontsource/inter/500.css'\n// import '@fontsource/inter/600.css'\n// import '@fontsource/inter/700.css'\n// import { BlockEditor } from './features/BlockEditor'\nimport { useField, useLocale } from \"@payloadcms/ui\";\nimport { BlockEditor } from \"./features/BlockEditor/BlockEditor.js\";\n\n// import \"../../styles.css\";\nimport { CustomComponent, JSONField, ServerProps } from \"payload\";\n\ntype Props = JSONField & ServerProps;\n\nconst useDarkmode = () => {\n const [isDarkMode, setIsDarkMode] = useState<boolean>(\n typeof window !== \"undefined\"\n ? document.documentElement.getAttribute(\"data-theme\") === \"dark\"\n : false\n );\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const handleChange = () => setIsDarkMode(mediaQuery.matches);\n mediaQuery.addEventListener(\"change\", handleChange);\n return () => mediaQuery.removeEventListener(\"change\", handleChange);\n }, []);\n\n useEffect(() => {\n document.documentElement.classList.toggle(\"dark\", isDarkMode);\n }, [isDarkMode]);\n\n const toggleDarkMode = useCallback(\n () => setIsDarkMode((isDark) => !isDark),\n []\n );\n const lightMode = useCallback(() => setIsDarkMode(false), []);\n const darkMode = useCallback(() => setIsDarkMode(true), []);\n\n return {\n isDarkMode,\n toggleDarkMode,\n lightMode,\n darkMode,\n };\n};\n\nexport const EditorComponent: CustomComponent = (props) => {\n const { value, setValue } = useField<any>({\n path: props.name,\n });\n\n useDarkmode();\n const hasCollab = false;\n // const { i18n } = useTranslation()\n\n const { code } = useLocale();\n return (\n <div\n lang={code}\n className=\"editor-tiptap content-field content-field-disabled\"\n style={{ width: \"100%\", height: \"100%\", overflow: \"visible\" }}\n >\n {/* {DarkModeSwitcher} */}\n {/* <FieldLabel label={props?.label ?? capitalize(props?.name) ?? ''} /> */}\n <BlockEditor\n hasCollab={hasCollab}\n content={value}\n openAssetHQHandler={(listener) => {}}\n handleChange={(value) => {\n setValue(value);\n }}\n />\n </div>\n );\n};\n"],"names":["useCallback","useEffect","useState","useField","useLocale","BlockEditor","useDarkmode","isDarkMode","setIsDarkMode","window","document","documentElement","getAttribute","mediaQuery","matchMedia","handleChange","matches","addEventListener","removeEventListener","classList","toggle","toggleDarkMode","isDark","lightMode","darkMode","EditorComponent","props","value","setValue","path","name","hasCollab","code","div","lang","className","style","width","height","overflow","content","openAssetHQHandler","listener"],"mappings":"AAAA;;AACA,SAASA,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAEzD,oBAAoB;AAEpB,qCAAqC;AACrC,qCAAqC;AACrC,qCAAqC;AACrC,qCAAqC;AACrC,qCAAqC;AACrC,qCAAqC;AACrC,qCAAqC;AACrC,uDAAuD;AACvD,SAASC,QAAQ,EAAEC,SAAS,QAAQ,iBAAiB;AACrD,SAASC,WAAW,QAAQ,wCAAwC;AAOpE,MAAMC,cAAc;IAClB,MAAM,CAACC,YAAYC,cAAc,GAAGN,SAClC,OAAOO,WAAW,cACdC,SAASC,eAAe,CAACC,YAAY,CAAC,kBAAkB,SACxD;IAGNX,UAAU;QACR,MAAMY,aAAaJ,OAAOK,UAAU,CAAC;QACrC,MAAMC,eAAe,IAAMP,cAAcK,WAAWG,OAAO;QAC3DH,WAAWI,gBAAgB,CAAC,UAAUF;QACtC,OAAO,IAAMF,WAAWK,mBAAmB,CAAC,UAAUH;IACxD,GAAG,EAAE;IAELd,UAAU;QACRS,SAASC,eAAe,CAACQ,SAAS,CAACC,MAAM,CAAC,QAAQb;IACpD,GAAG;QAACA;KAAW;IAEf,MAAMc,iBAAiBrB,YACrB,IAAMQ,cAAc,CAACc,SAAW,CAACA,SACjC,EAAE;IAEJ,MAAMC,YAAYvB,YAAY,IAAMQ,cAAc,QAAQ,EAAE;IAC5D,MAAMgB,WAAWxB,YAAY,IAAMQ,cAAc,OAAO,EAAE;IAE1D,OAAO;QACLD;QACAc;QACAE;QACAC;IACF;AACF;AAEA,OAAO,MAAMC,kBAAmC,CAACC;IAC/C,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGzB,SAAc;QACxC0B,MAAMH,MAAMI,IAAI;IAClB;IAEAxB;IACA,MAAMyB,YAAY;IAClB,oCAAoC;IAEpC,MAAM,EAAEC,IAAI,EAAE,GAAG5B;IACjB,qBACE,KAAC6B;QACCC,MAAMF;QACNG,WAAU;QACVC,OAAO;YAAEC,OAAO;YAAQC,QAAQ;YAAQC,UAAU;QAAU;kBAI5D,cAAA,KAAClC;YACC0B,WAAWA;YACXS,SAASb;YACTc,oBAAoB,CAACC,YAAc;YACnC3B,cAAc,CAACY;gBACbC,SAASD;YACX;;;AAIR,EAAE"}
|
|
@@ -0,0 +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;AAiBjD,eAAO,MAAM,SAAS,qBAsSpB,CAAC;AAEH,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Extension } from "@tiptap/core";
|
|
3
|
+
import { PluginKey } from "@tiptap/pm/state";
|
|
4
|
+
import { ReactRenderer } from "@tiptap/react";
|
|
5
|
+
import Suggestion from "@tiptap/suggestion";
|
|
6
|
+
import tippy from "tippy.js";
|
|
7
|
+
import { GROUPS } from "./groups.js";
|
|
8
|
+
import AIMenuList from "./AIMenuList.js";
|
|
9
|
+
// import { AICommandPanel } from "../../features/panels/AICommandPanel/AICommandPanel.js";
|
|
10
|
+
const extensionName = "aiCommand";
|
|
11
|
+
let popup;
|
|
12
|
+
export const AICommand = Extension.create({
|
|
13
|
+
name: extensionName,
|
|
14
|
+
priority: 200,
|
|
15
|
+
onCreate () {
|
|
16
|
+
const t = tippy;
|
|
17
|
+
popup = t("body", {
|
|
18
|
+
interactive: true,
|
|
19
|
+
trigger: "manual",
|
|
20
|
+
placement: "bottom-start",
|
|
21
|
+
theme: "slash-command",
|
|
22
|
+
// maxWidth: "16rem",
|
|
23
|
+
offset: [
|
|
24
|
+
0,
|
|
25
|
+
-16
|
|
26
|
+
],
|
|
27
|
+
popperOptions: {
|
|
28
|
+
strategy: "fixed",
|
|
29
|
+
modifiers: [
|
|
30
|
+
{
|
|
31
|
+
name: "flip",
|
|
32
|
+
enabled: false
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
addProseMirrorPlugins () {
|
|
39
|
+
return [
|
|
40
|
+
Suggestion({
|
|
41
|
+
editor: this.editor,
|
|
42
|
+
char: " ",
|
|
43
|
+
allowSpaces: true,
|
|
44
|
+
startOfLine: true,
|
|
45
|
+
pluginKey: new PluginKey(extensionName),
|
|
46
|
+
allow: ({ state, range })=>{
|
|
47
|
+
const $from = state.doc.resolve(range.from);
|
|
48
|
+
const isRootDepth = $from.depth === 1;
|
|
49
|
+
const isParagraph = $from.parent.type.name === "paragraph";
|
|
50
|
+
const isStartOfNode = $from.parent.textContent?.charAt(0) === " ";
|
|
51
|
+
// TODO
|
|
52
|
+
const isInColumn = this.editor.isActive("column");
|
|
53
|
+
const afterContent = $from.parent.textContent?.substring($from.parent.textContent?.indexOf(" "));
|
|
54
|
+
const isValidAfterContent = !afterContent?.endsWith(" ");
|
|
55
|
+
return (isRootDepth && isParagraph && isStartOfNode || isInColumn && isParagraph && isStartOfNode) && isValidAfterContent;
|
|
56
|
+
},
|
|
57
|
+
command: ({ editor, props })=>{
|
|
58
|
+
// const { view, state } = editor;
|
|
59
|
+
// const { $head, $from } = view.state.selection;
|
|
60
|
+
// const end = $from.pos;
|
|
61
|
+
// const from = $head?.nodeBefore
|
|
62
|
+
// ? end -
|
|
63
|
+
// ($head.nodeBefore.text?.substring(
|
|
64
|
+
// $head.nodeBefore.text?.indexOf(" ")
|
|
65
|
+
// ).length ?? 0)
|
|
66
|
+
// : $from.start();
|
|
67
|
+
// const tr = state.tr.deleteRange(from, end);
|
|
68
|
+
// view.dispatch(tr);
|
|
69
|
+
props.action(editor);
|
|
70
|
+
// view.focus();
|
|
71
|
+
},
|
|
72
|
+
items: ({ query })=>{
|
|
73
|
+
const withFilteredCommands = GROUPS.map((group)=>({
|
|
74
|
+
...group,
|
|
75
|
+
commands: group.commands.filter((item)=>{
|
|
76
|
+
const labelNormalized = item.label.toLowerCase().trim();
|
|
77
|
+
const queryNormalized = query.toLowerCase().trim();
|
|
78
|
+
if (item.aliases) {
|
|
79
|
+
const aliases = item.aliases.map((alias)=>alias.toLowerCase().trim());
|
|
80
|
+
return labelNormalized.includes(queryNormalized) || aliases.includes(queryNormalized);
|
|
81
|
+
}
|
|
82
|
+
return labelNormalized.includes(queryNormalized);
|
|
83
|
+
}).filter((command)=>command.shouldBeHidden ? !command.shouldBeHidden(this.editor) : true)
|
|
84
|
+
}));
|
|
85
|
+
const withoutEmptyGroups = withFilteredCommands.filter((group)=>{
|
|
86
|
+
if (group.commands.length > 0) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
});
|
|
91
|
+
const withEnabledSettings = withoutEmptyGroups.map((group)=>({
|
|
92
|
+
...group,
|
|
93
|
+
commands: group.commands.map((command)=>({
|
|
94
|
+
...command,
|
|
95
|
+
isEnabled: true
|
|
96
|
+
}))
|
|
97
|
+
}));
|
|
98
|
+
return withEnabledSettings;
|
|
99
|
+
},
|
|
100
|
+
render: ()=>{
|
|
101
|
+
let component;
|
|
102
|
+
let scrollHandler = null;
|
|
103
|
+
return {
|
|
104
|
+
onStart: (props)=>{
|
|
105
|
+
component = new ReactRenderer(AIMenuList, {
|
|
106
|
+
props,
|
|
107
|
+
editor: props.editor
|
|
108
|
+
});
|
|
109
|
+
props.editor.storage.aiCommand.active = true;
|
|
110
|
+
const { view } = props.editor;
|
|
111
|
+
const editorNode = view.dom;
|
|
112
|
+
const getReferenceClientRect = ()=>{
|
|
113
|
+
if (!props.clientRect) {
|
|
114
|
+
return props.editor.storage[extensionName].rect;
|
|
115
|
+
}
|
|
116
|
+
const rect = props.clientRect();
|
|
117
|
+
if (!rect) {
|
|
118
|
+
return props.editor.storage[extensionName].rect;
|
|
119
|
+
}
|
|
120
|
+
let yPos = rect.y;
|
|
121
|
+
if (rect.top + component.element.offsetHeight + 40 > window.innerHeight) {
|
|
122
|
+
const diff = rect.top + component.element.offsetHeight - window.innerHeight + 40;
|
|
123
|
+
yPos = rect.y - diff;
|
|
124
|
+
}
|
|
125
|
+
// Account for when the editor is bound inside a container that doesn't go all the way to the edge of the screen
|
|
126
|
+
const editorXOffset = editorNode.getBoundingClientRect().x;
|
|
127
|
+
const boundigClient = editorNode.getBoundingClientRect();
|
|
128
|
+
return new DOMRect(rect.x, yPos, boundigClient.width, rect.height);
|
|
129
|
+
};
|
|
130
|
+
scrollHandler = ()=>{
|
|
131
|
+
popup?.[0].setProps({
|
|
132
|
+
getReferenceClientRect
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
view.dom.parentElement?.addEventListener("scroll", scrollHandler);
|
|
136
|
+
popup?.[0].setProps({
|
|
137
|
+
getReferenceClientRect,
|
|
138
|
+
appendTo: ()=>document.body,
|
|
139
|
+
content: component.element
|
|
140
|
+
});
|
|
141
|
+
popup?.[0].show();
|
|
142
|
+
},
|
|
143
|
+
onUpdate (props) {
|
|
144
|
+
component.updateProps(props);
|
|
145
|
+
const { view } = props.editor;
|
|
146
|
+
const editorNode = view.dom;
|
|
147
|
+
const getReferenceClientRect = ()=>{
|
|
148
|
+
if (!props.clientRect) {
|
|
149
|
+
return props.editor.storage[extensionName].rect;
|
|
150
|
+
}
|
|
151
|
+
const rect = props.clientRect();
|
|
152
|
+
if (!rect) {
|
|
153
|
+
return props.editor.storage[extensionName].rect;
|
|
154
|
+
}
|
|
155
|
+
// Account for when the editor is bound inside a container that doesn't go all the way to the edge of the screen
|
|
156
|
+
return new DOMRect(rect.x, rect.y, rect.width, rect.height);
|
|
157
|
+
};
|
|
158
|
+
let scrollHandler = ()=>{
|
|
159
|
+
popup?.[0].setProps({
|
|
160
|
+
getReferenceClientRect
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
view.dom.parentElement?.addEventListener("scroll", scrollHandler);
|
|
164
|
+
// eslint-disable-next-line no-param-reassign
|
|
165
|
+
props.editor.storage[extensionName].rect = props.clientRect ? getReferenceClientRect() : {
|
|
166
|
+
width: 0,
|
|
167
|
+
height: 0,
|
|
168
|
+
left: 0,
|
|
169
|
+
top: 0,
|
|
170
|
+
right: 0,
|
|
171
|
+
bottom: 0
|
|
172
|
+
};
|
|
173
|
+
popup?.[0].setProps({
|
|
174
|
+
getReferenceClientRect
|
|
175
|
+
});
|
|
176
|
+
},
|
|
177
|
+
onKeyDown (props) {
|
|
178
|
+
if (props.event.key === "Escape") {
|
|
179
|
+
popup?.[0].hide();
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
if (!popup?.[0].state.isShown) {
|
|
183
|
+
popup?.[0].show();
|
|
184
|
+
}
|
|
185
|
+
return component.ref?.onKeyDown(props);
|
|
186
|
+
},
|
|
187
|
+
onExit (props) {
|
|
188
|
+
popup?.[0].hide();
|
|
189
|
+
if (scrollHandler) {
|
|
190
|
+
const { view } = props.editor;
|
|
191
|
+
view.dom.parentElement?.removeEventListener("scroll", scrollHandler);
|
|
192
|
+
}
|
|
193
|
+
const selection = props.editor.state.selection;
|
|
194
|
+
props.editor.chain().focus().insertContentAt(selection.to - 1, props.editor.storage.aiCommand.completion).insertContentAt(selection.to, " ").run();
|
|
195
|
+
props.editor.storage.aiCommand.active = false;
|
|
196
|
+
props.editor.storage.aiCommand.userPrompt = "";
|
|
197
|
+
props.editor.storage.aiCommand.completion = "";
|
|
198
|
+
component.destroy();
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
];
|
|
204
|
+
},
|
|
205
|
+
addStorage () {
|
|
206
|
+
return {
|
|
207
|
+
rect: {
|
|
208
|
+
width: 0,
|
|
209
|
+
height: 0,
|
|
210
|
+
left: 0,
|
|
211
|
+
top: 0,
|
|
212
|
+
right: 0,
|
|
213
|
+
bottom: 0
|
|
214
|
+
},
|
|
215
|
+
userPrompt: "",
|
|
216
|
+
completion: "",
|
|
217
|
+
active: false
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
export default AICommand;
|
|
222
|
+
|
|
223
|
+
//# sourceMappingURL=AICommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 });\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 const selection = props.editor.state.selection;\n props.editor\n .chain()\n .focus()\n .insertContentAt(\n selection.to - 1,\n props.editor.storage.aiCommand.completion\n )\n .insertContentAt(selection.to, \" \")\n .run();\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","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","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","storage","aiCommand","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","selection","chain","focus","insertContentAt","to","completion","run","userPrompt","destroy","addStorage"],"mappings":"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"}
|
|
@@ -0,0 +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,EAAE,eAAe,EAAW,MAAM,YAAY,CAAC;AAKtD,eAAO,MAAM,UAAU,iFA2JrB,CAAC;AAIH,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { DropdownButton } from "../../features/ui/Dropdown/Dropdown.js";
|
|
4
|
+
import { Surface } from "../../features/ui/Surface.js";
|
|
5
|
+
import { AICommandPanel } from "../../features/panels/AICommandPanel/AICommandPanel.js";
|
|
6
|
+
import { Icon } from "../../features/ui/Icon.js";
|
|
7
|
+
export const AIMenuList = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
8
|
+
const scrollContainer = useRef(null);
|
|
9
|
+
const activeItem = useRef(null);
|
|
10
|
+
const [selectedGroupIndex, setSelectedGroupIndex] = useState(0);
|
|
11
|
+
const [selectedCommandIndex, setSelectedCommandIndex] = useState(0);
|
|
12
|
+
const [userPrompt, setUserPrompt] = useState("");
|
|
13
|
+
// Anytime the groups change, i.e. the user types to narrow it down, we want to
|
|
14
|
+
// reset the current selection to the first menu item
|
|
15
|
+
useEffect(()=>{
|
|
16
|
+
setSelectedGroupIndex(0);
|
|
17
|
+
setSelectedCommandIndex(0);
|
|
18
|
+
}, [
|
|
19
|
+
props.items
|
|
20
|
+
]);
|
|
21
|
+
const selectItem = useCallback((groupIndex, commandIndex)=>{
|
|
22
|
+
const command = props.items[groupIndex].commands[commandIndex];
|
|
23
|
+
setUserPrompt(command.action(props.editor));
|
|
24
|
+
// props.command(command);
|
|
25
|
+
}, [
|
|
26
|
+
props
|
|
27
|
+
]);
|
|
28
|
+
React.useImperativeHandle(ref, ()=>({
|
|
29
|
+
onKeyDown: ({ event })=>{
|
|
30
|
+
if (event.key === "ArrowDown") {
|
|
31
|
+
if (!props.items.length) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const commands = props.items[selectedGroupIndex].commands;
|
|
35
|
+
let newCommandIndex = selectedCommandIndex + 1;
|
|
36
|
+
let newGroupIndex = selectedGroupIndex;
|
|
37
|
+
if (commands.length - 1 < newCommandIndex) {
|
|
38
|
+
newCommandIndex = 0;
|
|
39
|
+
newGroupIndex = selectedGroupIndex + 1;
|
|
40
|
+
}
|
|
41
|
+
if (props.items.length - 1 < newGroupIndex) {
|
|
42
|
+
newGroupIndex = 0;
|
|
43
|
+
}
|
|
44
|
+
setSelectedCommandIndex(newCommandIndex);
|
|
45
|
+
setSelectedGroupIndex(newGroupIndex);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (event.key === "ArrowUp") {
|
|
49
|
+
if (!props.items.length) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
let newCommandIndex = selectedCommandIndex - 1;
|
|
53
|
+
let newGroupIndex = selectedGroupIndex;
|
|
54
|
+
if (newCommandIndex < 0) {
|
|
55
|
+
newGroupIndex = selectedGroupIndex - 1;
|
|
56
|
+
newCommandIndex = props.items[newGroupIndex]?.commands.length - 1 || 0;
|
|
57
|
+
}
|
|
58
|
+
if (newGroupIndex < 0) {
|
|
59
|
+
newGroupIndex = props.items.length - 1;
|
|
60
|
+
newCommandIndex = props.items[newGroupIndex].commands.length - 1;
|
|
61
|
+
}
|
|
62
|
+
setSelectedCommandIndex(newCommandIndex);
|
|
63
|
+
setSelectedGroupIndex(newGroupIndex);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
if (event.key === "Enter") {
|
|
67
|
+
if (!props.items.length || selectedGroupIndex === -1 || selectedCommandIndex === -1) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
selectItem(selectedGroupIndex, selectedCommandIndex);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}));
|
|
76
|
+
useEffect(()=>{
|
|
77
|
+
if (activeItem.current && scrollContainer.current) {
|
|
78
|
+
const offsetTop = activeItem.current.offsetTop;
|
|
79
|
+
const offsetHeight = activeItem.current.offsetHeight;
|
|
80
|
+
scrollContainer.current.scrollTop = offsetTop - offsetHeight;
|
|
81
|
+
}
|
|
82
|
+
}, [
|
|
83
|
+
selectedCommandIndex,
|
|
84
|
+
selectedGroupIndex
|
|
85
|
+
]);
|
|
86
|
+
const createCommandClickHandler = useCallback((groupIndex, commandIndex)=>{
|
|
87
|
+
return ()=>{
|
|
88
|
+
selectItem(groupIndex, commandIndex);
|
|
89
|
+
};
|
|
90
|
+
}, [
|
|
91
|
+
selectItem
|
|
92
|
+
]);
|
|
93
|
+
if (!props.items.length) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
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
|
+
]
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
AIMenuList.displayName = "AIMenuList";
|
|
133
|
+
export default AIMenuList;
|
|
134
|
+
|
|
135
|
+
//# sourceMappingURL=AIMenuList.js.map
|
|
@@ -0,0 +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 { 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":";AAAA,OAAOA,SAASC,WAAW,EAAEC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAExE,SAASC,cAAc,QAAQ,yCAAyC;AACxE,SAASC,OAAO,QAAQ,+BAA+B;AAGvD,SAASC,cAAc,QAAQ,yDAAyD;AACxF,SAASC,IAAI,QAAQ,4BAA4B;AAEjD,OAAO,MAAMC,2BAAaT,MAAMU,UAAU,CAAC,CAACC,OAAwBC;IAClE,MAAMC,kBAAkBV,OAAuB;IAC/C,MAAMW,aAAaX,OAA0B;IAC7C,MAAM,CAACY,oBAAoBC,sBAAsB,GAAGZ,SAAS;IAC7D,MAAM,CAACa,sBAAsBC,wBAAwB,GAAGd,SAAS;IACjE,MAAM,CAACe,YAAYC,cAAc,GAAGhB,SAAS;IAE7C,+EAA+E;IAC/E,qDAAqD;IACrDF,UAAU;QACRc,sBAAsB;QACtBE,wBAAwB;IAC1B,GAAG;QAACP,MAAMU,KAAK;KAAC;IAEhB,MAAMC,aAAarB,YACjB,CAACsB,YAAoBC;QACnB,MAAMC,UAAUd,MAAMU,KAAK,CAACE,WAAW,CAACG,QAAQ,CAACF,aAAa;QAE9DJ,cAAcK,QAAQE,MAAM,CAAChB,MAAMiB,MAAM;IACzC,0BAA0B;IAC5B,GACA;QAACjB;KAAM;IAGTX,MAAM6B,mBAAmB,CAACjB,KAAK,IAAO,CAAA;YACpCkB,WAAW,CAAC,EAAEC,KAAK,EAAkC;gBACnD,IAAIA,MAAMC,GAAG,KAAK,aAAa;oBAC7B,IAAI,CAACrB,MAAMU,KAAK,CAACY,MAAM,EAAE;wBACvB,OAAO;oBACT;oBAEA,MAAMP,WAAWf,MAAMU,KAAK,CAACN,mBAAmB,CAACW,QAAQ;oBAEzD,IAAIQ,kBAAkBjB,uBAAuB;oBAC7C,IAAIkB,gBAAgBpB;oBAEpB,IAAIW,SAASO,MAAM,GAAG,IAAIC,iBAAiB;wBACzCA,kBAAkB;wBAClBC,gBAAgBpB,qBAAqB;oBACvC;oBAEA,IAAIJ,MAAMU,KAAK,CAACY,MAAM,GAAG,IAAIE,eAAe;wBAC1CA,gBAAgB;oBAClB;oBAEAjB,wBAAwBgB;oBACxBlB,sBAAsBmB;oBAEtB,OAAO;gBACT;gBAEA,IAAIJ,MAAMC,GAAG,KAAK,WAAW;oBAC3B,IAAI,CAACrB,MAAMU,KAAK,CAACY,MAAM,EAAE;wBACvB,OAAO;oBACT;oBAEA,IAAIC,kBAAkBjB,uBAAuB;oBAC7C,IAAIkB,gBAAgBpB;oBAEpB,IAAImB,kBAAkB,GAAG;wBACvBC,gBAAgBpB,qBAAqB;wBACrCmB,kBACEvB,MAAMU,KAAK,CAACc,cAAc,EAAET,SAASO,SAAS,KAAK;oBACvD;oBAEA,IAAIE,gBAAgB,GAAG;wBACrBA,gBAAgBxB,MAAMU,KAAK,CAACY,MAAM,GAAG;wBACrCC,kBAAkBvB,MAAMU,KAAK,CAACc,cAAc,CAACT,QAAQ,CAACO,MAAM,GAAG;oBACjE;oBAEAf,wBAAwBgB;oBACxBlB,sBAAsBmB;oBAEtB,OAAO;gBACT;gBAEA,IAAIJ,MAAMC,GAAG,KAAK,SAAS;oBACzB,IACE,CAACrB,MAAMU,KAAK,CAACY,MAAM,IACnBlB,uBAAuB,CAAC,KACxBE,yBAAyB,CAAC,GAC1B;wBACA,OAAO;oBACT;oBAEAK,WAAWP,oBAAoBE;oBAE/B,OAAO;gBACT;gBAEA,OAAO;YACT;QACF,CAAA;IAEAf,UAAU;QACR,IAAIY,WAAWsB,OAAO,IAAIvB,gBAAgBuB,OAAO,EAAE;YACjD,MAAMC,YAAYvB,WAAWsB,OAAO,CAACC,SAAS;YAC9C,MAAMC,eAAexB,WAAWsB,OAAO,CAACE,YAAY;YAEpDzB,gBAAgBuB,OAAO,CAACG,SAAS,GAAGF,YAAYC;QAClD;IACF,GAAG;QAACrB;QAAsBF;KAAmB;IAE7C,MAAMyB,4BAA4BvC,YAChC,CAACsB,YAAoBC;QACnB,OAAO;YACLF,WAAWC,YAAYC;QACzB;IACF,GACA;QAACF;KAAW;IAGd,IAAI,CAACX,MAAMU,KAAK,CAACY,MAAM,EAAE;QACvB,OAAO;IACT;IAEA,qBACE;;0BACE,KAAC1B;gBACCqB,QAAQjB,OAAOiB;gBACfa,cAAc,KAAO;gBACrBtB,YAAYA;;0BAEd,KAACb;gBACCM,KAAKC;gBACL6B,WAAU;0BAEV,cAAA,KAACC;oBAAID,WAAU;8BACZ/B,MAAMU,KAAK,CAACuB,GAAG,CAAC,CAACC,OAAOtB,2BACvB,MAACvB,MAAM8C,QAAQ;;8CACb,KAACH;oCACCD,WAAU;8CAGTG,MAAME,KAAK;mCAFP,CAAC,EAAEF,MAAME,KAAK,CAAC,CAAC;gCAItBF,MAAMnB,QAAQ,CAACkB,GAAG,CAAC,CAACnB,SAAkBD,6BACrC,MAACnB;wCAEC2C,UACEjC,uBAAuBQ,cACvBN,yBAAyBO;wCAE3ByB,SAAST,0BAA0BjB,YAAYC;;0DAE/C,KAAChB;gDAAK0C,MAAMzB,QAAQyB,IAAI;gDAAER,WAAU;;4CACnCjB,QAAQ0B,KAAK;;uCART,CAAC,EAAE1B,QAAQ0B,KAAK,CAAC,CAAC;;2BATR,CAAC,EAAEN,MAAME,KAAK,CAAC,QAAQ,CAAC;;;;;AA0BzD,GAAG;AAEHtC,WAAW2C,WAAW,GAAG;AAEzB,eAAe3C,WAAW"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LucideIcon } from "lucide-react";
|
|
2
|
+
export type CommandButtonProps = {
|
|
3
|
+
active?: boolean;
|
|
4
|
+
description: string;
|
|
5
|
+
icon: LucideIcon;
|
|
6
|
+
onClick: () => void;
|
|
7
|
+
title: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const CommandButton: import("react").ForwardRefExoticComponent<CommandButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
10
|
+
//# sourceMappingURL=CommandButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandButton.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/CommandButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK1C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,aAAa,kHAsBzB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { Icon } from "../../features/ui/Icon.js";
|
|
4
|
+
import { cn } from "../../lib/utils/index.js";
|
|
5
|
+
export const CommandButton = /*#__PURE__*/ forwardRef(({ active, icon, onClick, title }, ref)=>{
|
|
6
|
+
const wrapperClass = cn("flex text-neutral-500 items-center text-xs font-semibold justify-start p-1.5 gap-2 rounded", !active && "bg-transparent hover:bg-neutral-50 hover:text-black", active && "bg-neutral-100 text-black hover:bg-neutral-100");
|
|
7
|
+
return /*#__PURE__*/ _jsxs("button", {
|
|
8
|
+
type: "button",
|
|
9
|
+
ref: ref,
|
|
10
|
+
onClick: onClick,
|
|
11
|
+
className: wrapperClass,
|
|
12
|
+
children: [
|
|
13
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
14
|
+
icon: icon,
|
|
15
|
+
className: "w-3 h-3"
|
|
16
|
+
}),
|
|
17
|
+
/*#__PURE__*/ _jsx("div", {
|
|
18
|
+
className: "flex flex-col items-start justify-start",
|
|
19
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
20
|
+
className: "text-sm font-medium",
|
|
21
|
+
children: title
|
|
22
|
+
})
|
|
23
|
+
})
|
|
24
|
+
]
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
CommandButton.displayName = "CommandButton";
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=CommandButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/CommandButton.tsx"],"sourcesContent":["import { LucideIcon } from \"lucide-react\";\nimport { forwardRef } from \"react\";\nimport { Icon } from \"../../features/ui/Icon.js\";\nimport { cn } from \"../../lib/utils/index.js\";\n\nexport type CommandButtonProps = {\n active?: boolean;\n description: string;\n icon: LucideIcon;\n onClick: () => void;\n title: string;\n};\n\nexport const CommandButton = forwardRef<HTMLButtonElement, CommandButtonProps>(\n ({ active, icon, onClick, title }, ref) => {\n const wrapperClass = cn(\n \"flex text-neutral-500 items-center text-xs font-semibold justify-start p-1.5 gap-2 rounded\",\n !active && \"bg-transparent hover:bg-neutral-50 hover:text-black\",\n active && \"bg-neutral-100 text-black hover:bg-neutral-100\"\n );\n\n return (\n <button\n type=\"button\"\n ref={ref}\n onClick={onClick}\n className={wrapperClass}\n >\n <Icon icon={icon} className=\"w-3 h-3\" />\n <div className=\"flex flex-col items-start justify-start\">\n <div className=\"text-sm font-medium\">{title}</div>\n </div>\n </button>\n );\n }\n);\n\nCommandButton.displayName = \"CommandButton\";\n"],"names":["forwardRef","Icon","cn","CommandButton","active","icon","onClick","title","ref","wrapperClass","button","type","className","div","displayName"],"mappings":";AACA,SAASA,UAAU,QAAQ,QAAQ;AACnC,SAASC,IAAI,QAAQ,4BAA4B;AACjD,SAASC,EAAE,QAAQ,2BAA2B;AAU9C,OAAO,MAAMC,8BAAgBH,WAC3B,CAAC,EAAEI,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAEC,KAAK,EAAE,EAAEC;IACjC,MAAMC,eAAeP,GACnB,8FACA,CAACE,UAAU,uDACXA,UAAU;IAGZ,qBACE,MAACM;QACCC,MAAK;QACLH,KAAKA;QACLF,SAASA;QACTM,WAAWH;;0BAEX,KAACR;gBAAKI,MAAMA;gBAAMO,WAAU;;0BAC5B,KAACC;gBAAID,WAAU;0BACb,cAAA,KAACC;oBAAID,WAAU;8BAAuBL;;;;;AAI9C,GACA;AAEFJ,cAAcW,WAAW,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MenuList.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/AICommand/MenuList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAIxE,OAAO,EAAW,aAAa,EAAE,MAAM,YAAY,CAAC;AAIpD,eAAO,MAAM,QAAQ,+EAiJnB,CAAC;AAIH,eAAe,QAAQ,CAAC"}
|