payload-richtext-tiptap 0.0.143 → 0.0.145
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 +48 -38
- package/dist/src/fields/TiptapEditor/extensions/AICommand/AICommand.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/LinkPreview/LinkPreview.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/LinkPreview/LinkPreview.js +11 -7
- package/dist/src/fields/TiptapEditor/extensions/LinkPreview/LinkPreview.js.map +1 -1
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.js +4 -4
- package/dist/src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.js.map +1 -1
- package/dist/src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.js +4 -6
- package/dist/src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.js.map +1 -1
- package/dist/src/mobile.css +1 -1
- package/dist/src/styles.css +1 -1
- 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,CAAA;AAchD,eAAO,MAAM,SAAS,
|
|
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,CAAA;AAchD,eAAO,MAAM,SAAS,qBAwSpB,CAAA;AAEF,eAAe,SAAS,CAAA"}
|
|
@@ -12,36 +12,7 @@ let popupSelection;
|
|
|
12
12
|
export const AICommand = Extension.create({
|
|
13
13
|
name: extensionName,
|
|
14
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
|
-
onHidden: (instance)=>{
|
|
37
|
-
const selection = this.editor.state.selection;
|
|
38
|
-
this.editor?.chain()?.focus()?.insertContentAt({
|
|
39
|
-
from: popupSelection.from - 1,
|
|
40
|
-
to: popupSelection.to
|
|
41
|
-
}, ' ')?.insertContentAt(selection.to, this?.editor?.storage?.aiCommand?.completion?.content ?? [])?.run();
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
},
|
|
15
|
+
onCreate () {},
|
|
45
16
|
addProseMirrorPlugins () {
|
|
46
17
|
return [
|
|
47
18
|
Suggestion({
|
|
@@ -111,6 +82,46 @@ export const AICommand = Extension.create({
|
|
|
111
82
|
let scrollHandler = null;
|
|
112
83
|
return {
|
|
113
84
|
onStart: (props)=>{
|
|
85
|
+
const editor = props.editor;
|
|
86
|
+
const t = tippy;
|
|
87
|
+
popup = t('body', {
|
|
88
|
+
interactive: true,
|
|
89
|
+
trigger: 'manual',
|
|
90
|
+
placement: 'bottom-start',
|
|
91
|
+
theme: 'slash-command',
|
|
92
|
+
// maxWidth: "16rem",
|
|
93
|
+
offset: [
|
|
94
|
+
0,
|
|
95
|
+
-16
|
|
96
|
+
],
|
|
97
|
+
popperOptions: {
|
|
98
|
+
strategy: 'fixed',
|
|
99
|
+
modifiers: [
|
|
100
|
+
{
|
|
101
|
+
name: 'flip',
|
|
102
|
+
enabled: false
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
editor: editor,
|
|
107
|
+
onHide (instance) {
|
|
108
|
+
try {
|
|
109
|
+
const editorRef = instance.props.editor;
|
|
110
|
+
const completion = editorRef?.storage?.aiCommand?.completion ?? [];
|
|
111
|
+
const selection = editorRef?.state?.selection;
|
|
112
|
+
if (!completion || completion === '') {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
editorRef?.chain().focus().insertContentAt({
|
|
116
|
+
from: popupSelection.from - 1,
|
|
117
|
+
to: popupSelection.to
|
|
118
|
+
}, ' ').insertContentAt(popupSelection.to, completion).run();
|
|
119
|
+
props.editor.storage.aiCommand.completion = '';
|
|
120
|
+
} catch (e) {
|
|
121
|
+
console.log('Error', e);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
114
125
|
component = new ReactRenderer(AIMenuList, {
|
|
115
126
|
props,
|
|
116
127
|
editor: props.editor
|
|
@@ -145,7 +156,7 @@ export const AICommand = Extension.create({
|
|
|
145
156
|
popup?.[0].setProps({
|
|
146
157
|
getReferenceClientRect,
|
|
147
158
|
appendTo: ()=>document.body,
|
|
148
|
-
content: component
|
|
159
|
+
content: component?.element
|
|
149
160
|
});
|
|
150
161
|
const selection = this?.editor?.state?.selection;
|
|
151
162
|
popupSelection = {
|
|
@@ -154,8 +165,8 @@ export const AICommand = Extension.create({
|
|
|
154
165
|
};
|
|
155
166
|
popup?.[0].show();
|
|
156
167
|
},
|
|
157
|
-
onUpdate (props)
|
|
158
|
-
component
|
|
168
|
+
onUpdate: (props)=>{
|
|
169
|
+
component?.updateProps(props);
|
|
159
170
|
const { view } = props.editor;
|
|
160
171
|
const editorNode = view.dom;
|
|
161
172
|
const getReferenceClientRect = ()=>{
|
|
@@ -188,7 +199,7 @@ export const AICommand = Extension.create({
|
|
|
188
199
|
getReferenceClientRect
|
|
189
200
|
});
|
|
190
201
|
},
|
|
191
|
-
onKeyDown (props)
|
|
202
|
+
onKeyDown: (props)=>{
|
|
192
203
|
if (props.event.key === 'Escape') {
|
|
193
204
|
popup?.[0].hide();
|
|
194
205
|
return true;
|
|
@@ -196,10 +207,9 @@ export const AICommand = Extension.create({
|
|
|
196
207
|
if (!popup?.[0].state.isShown) {
|
|
197
208
|
popup?.[0].show();
|
|
198
209
|
}
|
|
199
|
-
return component
|
|
210
|
+
return component?.ref?.onKeyDown(props);
|
|
200
211
|
},
|
|
201
|
-
onExit (props)
|
|
202
|
-
popup?.[0].hide();
|
|
212
|
+
onExit: (props)=>{
|
|
203
213
|
if (scrollHandler) {
|
|
204
214
|
const { view } = props.editor;
|
|
205
215
|
view.dom.parentElement?.removeEventListener('scroll', scrollHandler);
|
|
@@ -207,7 +217,7 @@ export const AICommand = Extension.create({
|
|
|
207
217
|
props.editor.storage.aiCommand.active = false;
|
|
208
218
|
props.editor.storage.aiCommand.userPrompt = '';
|
|
209
219
|
props.editor.storage.aiCommand.completion = '';
|
|
210
|
-
component
|
|
220
|
+
component?.destroy();
|
|
211
221
|
}
|
|
212
222
|
};
|
|
213
223
|
}
|
|
@@ -1 +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, { SuggestionKeyDownProps, SuggestionProps } from '@tiptap/suggestion'\nimport tippy from 'tippy.js'\n\nimport AIMenuList from './AIMenuList.js'\n// import { AICommandPanel } from \"../../features/panels/AICommandPanel/AICommandPanel.js\";\n\nconst extensionName = 'aiCommand'\n\nlet popup: any\nlet popupSelection: { from: number; to: number }\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({ from: popupSelection.from - 1, to: popupSelection.to }, ' ')\n ?.insertContentAt(\n selection.to,\n this?.editor?.storage?.aiCommand?.completion?.content ?? [],\n )\n ?.run()\n },\n })\n },\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n char: ' ',\n allowSpaces: false,\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 const textLength = $from.parent.textContent?.length\n\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 return (\n ((isRootDepth && isParagraph && isStartOfNode) ||\n (isInColumn && isParagraph && isStartOfNode)) &&\n isValidAfterContent &&\n textLength === 1\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: async ({ query }: { query: string }) => {\n const GROUPS = (await import('./groups.js')).default\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) => alias.toLowerCase().trim())\n\n return (\n labelNormalized.includes(queryNormalized) || aliases.includes(queryNormalized)\n )\n }\n\n return labelNormalized.includes(queryNormalized)\n })\n .filter((command) =>\n command.shouldBeHidden ? !command.shouldBeHidden(this.editor) : 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 (rect.top + component.element.offsetHeight + 40 > window.innerHeight) {\n const diff = rect.top + component.element.offsetHeight - window.innerHeight + 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(rect.x, yPos, boundigClient.width, rect.height)\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 const selection = this?.editor?.state?.selection\n popupSelection = { from: selection?.from, to: selection?.to }\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('scroll', scrollHandler)\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 title: '',\n active: false,\n }\n },\n})\n\nexport default AICommand\n"],"names":["Extension","PluginKey","ReactRenderer","Suggestion","tippy","AIMenuList","extensionName","popup","popupSelection","AICommand","create","name","priority","onCreate","t","interactive","trigger","placement","theme","offset","popperOptions","strategy","modifiers","enabled","onHidden","instance","selection","editor","state","chain","focus","insertContentAt","from","to","storage","aiCommand","completion","content","run","addProseMirrorPlugins","char","allowSpaces","startOfLine","pluginKey","allow","range","$from","doc","resolve","isRootDepth","depth","isParagraph","parent","type","isStartOfNode","textContent","charAt","textLength","length","isInColumn","isActive","afterContent","substring","indexOf","isValidAfterContent","endsWith","command","props","action","items","query","GROUPS","default","withFilteredCommands","map","group","commands","filter","item","labelNormalized","label","toLowerCase","trim","queryNormalized","aliases","alias","includes","shouldBeHidden","withoutEmptyGroups","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","show","onUpdate","updateProps","left","right","bottom","onKeyDown","event","key","hide","isShown","ref","onExit","removeEventListener","userPrompt","destroy","addStorage","title"],"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, { SuggestionKeyDownProps, SuggestionProps } from '@tiptap/suggestion'\nimport tippy from 'tippy.js'\n\nimport AIMenuList from './AIMenuList.js'\n// import { AICommandPanel } from \"../../features/panels/AICommandPanel/AICommandPanel.js\";\n\nconst extensionName = 'aiCommand'\n\nlet popup: any\nlet popupSelection: { from: number; to: number }\n\nexport const AICommand = Extension.create({\n name: extensionName,\n\n priority: 200,\n\n onCreate() {},\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n char: ' ',\n allowSpaces: false,\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 const textLength = $from.parent.textContent?.length\n\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 return (\n ((isRootDepth && isParagraph && isStartOfNode) ||\n (isInColumn && isParagraph && isStartOfNode)) &&\n isValidAfterContent &&\n textLength === 1\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: async ({ query }: { query: string }) => {\n const GROUPS = (await import('./groups.js')).default\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) => alias.toLowerCase().trim())\n\n return (\n labelNormalized.includes(queryNormalized) || aliases.includes(queryNormalized)\n )\n }\n\n return labelNormalized.includes(queryNormalized)\n })\n .filter((command) =>\n command.shouldBeHidden ? !command.shouldBeHidden(this.editor) : 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 const editor = props.editor\n\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 editor: editor,\n onHide(instance) {\n try {\n const editorRef = instance.props.editor\n const completion = editorRef?.storage?.aiCommand?.completion ?? []\n const selection = editorRef?.state?.selection\n\n if (!completion || completion === '') {\n return\n }\n editorRef\n ?.chain()\n .focus()\n .insertContentAt(\n { from: popupSelection.from - 1, to: popupSelection.to },\n ' ',\n )\n .insertContentAt(popupSelection.to, completion)\n .run()\n\n props.editor.storage.aiCommand.completion = ''\n } catch (e) {\n console.log('Error', e)\n }\n },\n })\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 (rect.top + component.element.offsetHeight + 40 > window.innerHeight) {\n const diff = rect.top + component.element.offsetHeight - window.innerHeight + 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(rect.x, yPos, boundigClient.width, rect.height)\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 const selection = this?.editor?.state?.selection\n popupSelection = { from: selection?.from, to: selection?.to }\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 if (scrollHandler) {\n const { view } = props.editor\n view.dom.parentElement?.removeEventListener('scroll', scrollHandler)\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 title: '',\n active: false,\n }\n },\n})\n\nexport default AICommand\n"],"names":["Extension","PluginKey","ReactRenderer","Suggestion","tippy","AIMenuList","extensionName","popup","popupSelection","AICommand","create","name","priority","onCreate","addProseMirrorPlugins","editor","char","allowSpaces","startOfLine","pluginKey","allow","state","range","$from","doc","resolve","from","isRootDepth","depth","isParagraph","parent","type","isStartOfNode","textContent","charAt","textLength","length","isInColumn","isActive","afterContent","substring","indexOf","isValidAfterContent","endsWith","command","props","action","items","query","GROUPS","default","withFilteredCommands","map","group","commands","filter","item","labelNormalized","label","toLowerCase","trim","queryNormalized","aliases","alias","includes","shouldBeHidden","withoutEmptyGroups","withEnabledSettings","isEnabled","render","component","scrollHandler","onStart","t","interactive","trigger","placement","theme","offset","popperOptions","strategy","modifiers","enabled","onHide","instance","editorRef","completion","storage","aiCommand","selection","chain","focus","insertContentAt","to","run","e","console","log","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","title"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkPreview.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/LinkPreview/LinkPreview.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAGpE,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,WAAW,EAAE;YACX,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,KAAK,UAAU,CAAC;SACvE,CAAC;KACH;CACF;AAED,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"LinkPreview.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/LinkPreview/LinkPreview.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAGpE,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,WAAW,EAAE;YACX,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,KAAK,UAAU,CAAC;SACvE,CAAC;KACH;CACF;AAED,eAAO,MAAM,WAAW,gBA6GtB,CAAC"}
|
|
@@ -28,6 +28,8 @@ export const LinkPreview = Node.create({
|
|
|
28
28
|
];
|
|
29
29
|
},
|
|
30
30
|
renderHTML ({ node }) {
|
|
31
|
+
const hasValidImage = node.attrs.image && node.attrs.image !== '/png/placeholder.png';
|
|
32
|
+
const padding = hasValidImage ? 'px-4' : 'pl-6 pr-4';
|
|
31
33
|
return [
|
|
32
34
|
'a',
|
|
33
35
|
mergeAttributes({
|
|
@@ -36,17 +38,17 @@ export const LinkPreview = Node.create({
|
|
|
36
38
|
target: '_blank',
|
|
37
39
|
rel: 'noopener noreferrer',
|
|
38
40
|
dir: i18next.dir(),
|
|
39
|
-
class:
|
|
41
|
+
class: `relative flex w-full ${padding} py-3 flex-col items-start gap-6 rounded bg-[#F1F1F1] border-l-0 transition-all duration-200 ease-in-out box-border mb-4 hover:bg-[#F9F9F9] hover:shadow-[0_4px_6px_-1px_rgba(0,0,0,0.1),0_-4px_6px_-1px_rgba(0,0,0,0.06),4px_0_6px_-1px_rgba(0,0,0,0.06)] focus:bg-[#F9F9F9] focus:shadow-[0_4px_6px_-1px_rgba(0,0,0,0.1),0_-4px_6px_-1px_rgba(0,0,0,0.06),4px_0_6px_-1px_rgba(0,0,0,0.06)] before:content-[""] before:absolute before:left-0 before:top-0 before:bottom-0 before:w-[3px] before:rounded-l-md before:bg-[#01ABD9]`
|
|
40
42
|
}),
|
|
41
43
|
[
|
|
42
44
|
'div',
|
|
43
45
|
{
|
|
44
|
-
class: 'flex items-start w-full gap-3'
|
|
46
|
+
class: hasValidImage ? 'flex items-start w-full gap-3' : 'flex items-start w-full'
|
|
45
47
|
},
|
|
46
|
-
|
|
48
|
+
hasValidImage ? [
|
|
47
49
|
'img',
|
|
48
50
|
{
|
|
49
|
-
class: 'flex justify-center items-center rounded
|
|
51
|
+
class: 'flex justify-center items-center rounded-md !w-20 !h-20 aspect-square flex-shrink-0 sm:rounded md:rounded-md lg:!w-[84px] lg:!h-[84px] lg:rounded xl:rounded-md',
|
|
50
52
|
src: node.attrs.image
|
|
51
53
|
}
|
|
52
54
|
] : '',
|
|
@@ -58,7 +60,7 @@ export const LinkPreview = Node.create({
|
|
|
58
60
|
[
|
|
59
61
|
'span',
|
|
60
62
|
{
|
|
61
|
-
class: 'overflow-hidden text-[#1F2121] text-ellipsis font-[var(--font-notosans),Arial,sans-serif] text-xs md:text-base font-medium leading-[15px]
|
|
63
|
+
class: 'line-clamp-1 overflow-hidden text-[#1F2121] text-ellipsis font-[var(--font-notosans),Arial,sans-serif] text-xs font-bold leading-normal uppercase sm:text-xs sm:font-bold md:text-base md:font-medium md:leading-[15px] lg:text-base xl:text-base',
|
|
62
64
|
'data-link-preview-related': '',
|
|
63
65
|
'data-testid': 'link-preview-related'
|
|
64
66
|
},
|
|
@@ -67,7 +69,7 @@ export const LinkPreview = Node.create({
|
|
|
67
69
|
[
|
|
68
70
|
'strong',
|
|
69
71
|
{
|
|
70
|
-
class: 'text-[#1F2121] font-[var(--font-playfair),Georgia,serif] text-base
|
|
72
|
+
class: 'text-[#1F2121] font-[var(--font-playfair),Georgia,serif] text-base font-extrabold leading-[26px] underline decoration-solid line-clamp-2 overflow-hidden text-ellipsis sm:text-lg sm:leading-[31px] md:text-lg md:leading-[28px] lg:text-xl lg:leading-[31px] xl:text-xl'
|
|
71
73
|
},
|
|
72
74
|
node.attrs.title
|
|
73
75
|
]
|
|
@@ -78,13 +80,15 @@ export const LinkPreview = Node.create({
|
|
|
78
80
|
addCommands () {
|
|
79
81
|
return {
|
|
80
82
|
setLinkPreview: (src, metadata)=>({ commands, state })=>{
|
|
83
|
+
// Don't use placeholder image
|
|
84
|
+
const imageUrl = metadata?.images?.[0] || '';
|
|
81
85
|
return commands.insertContent({
|
|
82
86
|
type: 'linkPreview',
|
|
83
87
|
attrs: {
|
|
84
88
|
href: src,
|
|
85
89
|
title: metadata?.title,
|
|
86
90
|
description: metadata?.description,
|
|
87
|
-
image:
|
|
91
|
+
image: imageUrl
|
|
88
92
|
}
|
|
89
93
|
});
|
|
90
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/LinkPreview/LinkPreview.tsx"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core';\nimport { SiteMetaData } from '../../features/BlockEditor/types.jsx';\nimport i18next from 'i18next';\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n linkPreview: {\n setLinkPreview: (src?: string, metadata?: SiteMetaData) => ReturnType;\n };\n }\n}\n\nexport const LinkPreview = Node.create({\n name: 'linkPreview',\n group: 'block',\n atom: true,\n\n addAttributes() {\n return {\n href: {\n default: ''\n },\n title: { default: '' },\n description: {\n default: ''\n },\n image: {\n default: ''\n }\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'a[data-link-preview]'\n }\n ];\n },\n\n renderHTML({ node }) {\n return [\n 'a',\n mergeAttributes({\n 'data-link-preview': '',\n href: node.attrs.href,\n target: '_blank',\n rel: 'noopener noreferrer',\n dir: i18next.dir(),\n class
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/LinkPreview/LinkPreview.tsx"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core';\nimport { SiteMetaData } from '../../features/BlockEditor/types.jsx';\nimport i18next from 'i18next';\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n linkPreview: {\n setLinkPreview: (src?: string, metadata?: SiteMetaData) => ReturnType;\n };\n }\n}\n\nexport const LinkPreview = Node.create({\n name: 'linkPreview',\n group: 'block',\n atom: true,\n\n addAttributes() {\n return {\n href: {\n default: ''\n },\n title: { default: '' },\n description: {\n default: ''\n },\n image: {\n default: ''\n }\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'a[data-link-preview]'\n }\n ];\n },\n\n renderHTML({ node }) {\n const hasValidImage =\n node.attrs.image && node.attrs.image !== '/png/placeholder.png';\n\n const padding = hasValidImage ? 'px-4' : 'pl-6 pr-4';\n\n return [\n 'a',\n mergeAttributes({\n 'data-link-preview': '',\n href: node.attrs.href,\n target: '_blank',\n rel: 'noopener noreferrer',\n dir: i18next.dir(),\n class: `relative flex w-full ${padding} py-3 flex-col items-start gap-6 rounded bg-[#F1F1F1] border-l-0 transition-all duration-200 ease-in-out box-border mb-4 hover:bg-[#F9F9F9] hover:shadow-[0_4px_6px_-1px_rgba(0,0,0,0.1),0_-4px_6px_-1px_rgba(0,0,0,0.06),4px_0_6px_-1px_rgba(0,0,0,0.06)] focus:bg-[#F9F9F9] focus:shadow-[0_4px_6px_-1px_rgba(0,0,0,0.1),0_-4px_6px_-1px_rgba(0,0,0,0.06),4px_0_6px_-1px_rgba(0,0,0,0.06)] before:content-[\"\"] before:absolute before:left-0 before:top-0 before:bottom-0 before:w-[3px] before:rounded-l-md before:bg-[#01ABD9]`\n }),\n [\n 'div',\n {\n class: hasValidImage\n ? 'flex items-start w-full gap-3'\n : 'flex items-start w-full'\n },\n hasValidImage\n ? [\n 'img',\n {\n class:\n 'flex justify-center items-center rounded-md !w-20 !h-20 aspect-square flex-shrink-0 sm:rounded md:rounded-md lg:!w-[84px] lg:!h-[84px] lg:rounded xl:rounded-md',\n src: node.attrs.image\n }\n ]\n : '',\n [\n 'div',\n {\n class: 'flex flex-col items-start'\n },\n [\n 'span',\n {\n class:\n 'line-clamp-1 overflow-hidden text-[#1F2121] text-ellipsis font-[var(--font-notosans),Arial,sans-serif] text-xs font-bold leading-normal uppercase sm:text-xs sm:font-bold md:text-base md:font-medium md:leading-[15px] lg:text-base xl:text-base',\n 'data-link-preview-related': '',\n 'data-testid': 'link-preview-related'\n },\n i18next.t('related', 'RELATED')\n ],\n [\n 'strong',\n {\n class:\n 'text-[#1F2121] font-[var(--font-playfair),Georgia,serif] text-base font-extrabold leading-[26px] underline decoration-solid line-clamp-2 overflow-hidden text-ellipsis sm:text-lg sm:leading-[31px] md:text-lg md:leading-[28px] lg:text-xl lg:leading-[31px] xl:text-xl'\n },\n node.attrs.title\n ]\n ]\n ]\n ];\n },\n\n addCommands() {\n return {\n setLinkPreview:\n (src, metadata) =>\n ({ commands, state }) => {\n // Don't use placeholder image\n const imageUrl = metadata?.images?.[0] || '';\n\n return commands.insertContent({\n type: 'linkPreview',\n attrs: {\n href: src,\n title: metadata?.title,\n description: metadata?.description,\n image: imageUrl\n }\n });\n }\n };\n }\n});\n"],"names":["Node","mergeAttributes","i18next","LinkPreview","create","name","group","atom","addAttributes","href","default","title","description","image","parseHTML","tag","renderHTML","node","hasValidImage","attrs","padding","target","rel","dir","class","src","t","addCommands","setLinkPreview","metadata","commands","state","imageUrl","images","insertContent","type"],"mappings":"AAAA,SAASA,IAAI,EAAEC,eAAe,QAAQ,eAAe;AAErD,OAAOC,aAAa,UAAU;AAU9B,OAAO,MAAMC,cAAcH,KAAKI,MAAM,CAAC;IACrCC,MAAM;IACNC,OAAO;IACPC,MAAM;IAENC;QACE,OAAO;YACLC,MAAM;gBACJC,SAAS;YACX;YACAC,OAAO;gBAAED,SAAS;YAAG;YACrBE,aAAa;gBACXF,SAAS;YACX;YACAG,OAAO;gBACLH,SAAS;YACX;QACF;IACF;IAEAI;QACE,OAAO;YACL;gBACEC,KAAK;YACP;SACD;IACH;IAEAC,YAAW,EAAEC,IAAI,EAAE;QACjB,MAAMC,gBACJD,KAAKE,KAAK,CAACN,KAAK,IAAII,KAAKE,KAAK,CAACN,KAAK,KAAK;QAE3C,MAAMO,UAAUF,gBAAgB,SAAS;QAEzC,OAAO;YACL;YACAjB,gBAAgB;gBACd,qBAAqB;gBACrBQ,MAAMQ,KAAKE,KAAK,CAACV,IAAI;gBACrBY,QAAQ;gBACRC,KAAK;gBACLC,KAAKrB,QAAQqB,GAAG;gBAChBC,OAAO,CAAC,qBAAqB,EAAEJ,QAAQ,kgBAAkgB,CAAC;YAC5iB;YACA;gBACE;gBACA;oBACEI,OAAON,gBACH,kCACA;gBACN;gBACAA,gBACI;oBACE;oBACA;wBACEM,OACE;wBACFC,KAAKR,KAAKE,KAAK,CAACN,KAAK;oBACvB;iBACD,GACD;gBACJ;oBACE;oBACA;wBACEW,OAAO;oBACT;oBACA;wBACE;wBACA;4BACEA,OACE;4BACF,6BAA6B;4BAC7B,eAAe;wBACjB;wBACAtB,QAAQwB,CAAC,CAAC,WAAW;qBACtB;oBACD;wBACE;wBACA;4BACEF,OACE;wBACJ;wBACAP,KAAKE,KAAK,CAACR,KAAK;qBACjB;iBACF;aACF;SACF;IACH;IAEAgB;QACE,OAAO;YACLC,gBACE,CAACH,KAAKI,WACN,CAAC,EAAEC,QAAQ,EAAEC,KAAK,EAAE;oBAClB,8BAA8B;oBAC9B,MAAMC,WAAWH,UAAUI,QAAQ,CAAC,EAAE,IAAI;oBAE1C,OAAOH,SAASI,aAAa,CAAC;wBAC5BC,MAAM;wBACNhB,OAAO;4BACLV,MAAMgB;4BACNd,OAAOkB,UAAUlB;4BACjBC,aAAaiB,UAAUjB;4BACvBC,OAAOmB;wBACT;oBACF;gBACF;QACJ;IACF;AACF,GAAG"}
|
|
@@ -66,11 +66,11 @@ export const AICommandPanel = /*#__PURE__*/ forwardRef(({ editor, onOpenChange,
|
|
|
66
66
|
userPrompt
|
|
67
67
|
]);
|
|
68
68
|
useEffect(()=>{
|
|
69
|
-
if (hasCompletion) {
|
|
70
|
-
editor.storage.aiCommand.completion = object;
|
|
69
|
+
if (!!hasCompletion) {
|
|
70
|
+
editor.storage.aiCommand.completion = object?.content ?? [];
|
|
71
71
|
}
|
|
72
72
|
}, [
|
|
73
|
-
|
|
73
|
+
markdown,
|
|
74
74
|
isLoading
|
|
75
75
|
]);
|
|
76
76
|
useEffect(()=>{
|
|
@@ -163,7 +163,7 @@ export const AICommandPanel = /*#__PURE__*/ forwardRef(({ editor, onOpenChange,
|
|
|
163
163
|
markdown && /*#__PURE__*/ _jsx("div", {
|
|
164
164
|
className: "flex w-full",
|
|
165
165
|
children: /*#__PURE__*/ _jsx(ScrollArea, {
|
|
166
|
-
className: "prose p-2 px-4 prose-sm",
|
|
166
|
+
className: "prose p-2 px-4 prose-sm max-h-96",
|
|
167
167
|
dir: i18next.dir(),
|
|
168
168
|
children: /*#__PURE__*/ _jsx(Markdown, {
|
|
169
169
|
children: markdown
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.tsx"],"sourcesContent":["'use client'\nimport { ArrowUpCircle, Sparkles } from 'lucide-react'\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react'\nimport Markdown from 'react-markdown'\nimport TextareaAutosize from 'react-textarea-autosize'\n\nimport { Editor } from '@tiptap/react'\n\nimport { experimental_useObject as useObject } from '@ai-sdk/react'\nimport i18next from 'i18next'\nimport { Command, Group } from '../../../extensions/AICommand/types.js'\nimport { TiptapSchema } from '../../../lib/tiptapSchema.js'\nimport { getPrevText } from '../../../lib/utils/index.js'\nimport AISelectorCommands from '../../menus/TextMenu/components/ai-selector-commands.js'\nimport CrazySpinner from '../../ui/crazy-spinner.js'\nimport { DropdownButton } from '../../ui/Dropdown/Dropdown.js'\nimport { Icon } from '../../ui/Icon.js'\nimport { ScrollArea } from '../../ui/scroll-area.js'\nimport { Surface } from '../../ui/Surface.js'\nimport { Toolbar } from '../../ui/Toolbar.js'\nimport { useExtractMarkdown } from '../AIEditorPanel/markdown.hook.js'\n\nexport type AICommandPanelProps = {\n editor: Editor\n userPrompt?: string\n onOpenChange: (value: boolean) => void\n items: Group[]\n}\n\nexport const AICommandPanel = forwardRef(\n ({ editor, onOpenChange, userPrompt, items, ...restProps }: AICommandPanelProps, ref) => {\n const [inputValue, setInputValue] = useState(userPrompt ?? '')\n const { view } = editor\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\n const editorNode = view.dom as HTMLElement\n const boundigClient = editorNode.getBoundingClientRect()\n const inputRef = useRef<HTMLTextAreaElement>(null)\n\n const { object, submit, isLoading } = useObject({\n api: '/api/generate',\n schema: TiptapSchema,\n })\n\n const { markdown } = useExtractMarkdown(object)\n\n const hasCompletion = Boolean(object)\n\n const handleClick = useCallback(() => {\n if (object) {\n submit({\n prompt: '',\n body: {\n option: 'zap',\n command: inputValue,\n language: editor?.storage?.aiCommand?.language,\n selection: object,\n },\n })\n setInputValue('')\n return\n }\n\n submit({\n prompt: '',\n body: {\n option: 'zap',\n command: inputValue,\n language: editor?.storage?.aiCommand?.language,\n },\n })\n setInputValue('')\n }, [editor?.storage?.aiCommand?.language, inputValue, object, submit])\n\n useEffect(() => {\n if (userPrompt) setInputValue(userPrompt)\n }, [userPrompt])\n useEffect(() => {\n if (hasCompletion) {\n editor.storage.aiCommand.completion = object\n }\n }, [object, isLoading])\n\n useEffect(() => {\n setSelectedGroupIndex(0)\n setSelectedCommandIndex(0)\n }, [items])\n\n const selectItem = useCallback(\n (groupIndex: number, commandIndex: number) => {\n const command = items[groupIndex].commands[commandIndex]\n setInputValue(command.action(editor))\n },\n [items, editor],\n )\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: React.KeyboardEvent }) => {\n if (event.key === 'ArrowDown') {\n if (!items.length) {\n return false\n }\n\n const commands = 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 (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 (!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 = items[newGroupIndex]?.commands.length - 1 || 0\n }\n\n if (newGroupIndex < 0) {\n newGroupIndex = items.length - 1\n newCommandIndex = 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 (!items.length || selectedGroupIndex === -1 || selectedCommandIndex === -1) {\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 return (\n <>\n <Surface\n className={`p-2 min-w-[20rem] flex flex-col gap-2 w-full ${\n hasCompletion ? '-mt-72' : ''\n }`}\n style={{\n width: boundigClient?.width,\n }}\n >\n <>\n {markdown && (\n <div className='flex w-full'>\n <ScrollArea className='prose p-2 px-4 prose-sm' dir={i18next.dir()}>\n <Markdown>{markdown}</Markdown>\n </ScrollArea>\n </div>\n )}\n\n {isLoading && (\n <div\n className='flex h-12 w-full items-center px-4 text-sm font-medium text-muted-foreground text-blue-500'\n style={{\n width: boundigClient?.width,\n }}\n >\n <Sparkles className='mr-2 h-4 w-4 shrink-0 ' />\n AI (Beta) is thinking\n <div className='ml-2 mt-1'>\n <CrazySpinner />\n </div>\n </div>\n )}\n\n {!isLoading && (\n <>\n <div className='flex justify-between items-center '>\n <Sparkles className='mr-2 h-4 w-4 shrink-0 text-blue-500 ' />\n <TextareaAutosize\n ref={inputRef}\n style={{ resize: 'none' }}\n className='w-full p-2 text-black bg-white rounded dark:bg-black dark:text-white focus:outline-none outline-none border-0 '\n value={inputValue}\n onChange={(e) => {\n editor.storage.aiCommand.userPrompt = e.target.value\n setInputValue(e.target.value)\n }}\n placeholder={\n hasCompletion\n ? i18next.t('tellAiPlaceholder') || 'Tell AI (Beta) what to do next'\n : i18next.t('askAiPlaceholder') || 'Ask AI (Beta) to edit or generate...'\n }\n autoFocus\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleClick()\n }}\n />\n <Toolbar.Button onClick={handleClick}>\n <ArrowUpCircle />\n </Toolbar.Button>\n </div>\n </>\n )}\n </>\n </Surface>\n {!isLoading && (\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 {hasCompletion ? (\n <AISelectorCommands\n editor={editor}\n messages={object}\n onSelect={(value, options) => {\n if (options?.option === 'translate') {\n submit({ prompt: value, body: options })\n } else {\n submit({\n prompt: value,\n body: { ...options, source: editor?.storage?.aiCommand?.language },\n })\n }\n }}\n />\n ) : (\n 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 && 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 )}\n </div>\n </Surface>\n )}\n </>\n )\n },\n)\n"],"names":["ArrowUpCircle","Sparkles","React","forwardRef","useCallback","useEffect","useImperativeHandle","useRef","useState","Markdown","TextareaAutosize","experimental_useObject","useObject","i18next","TiptapSchema","AISelectorCommands","CrazySpinner","DropdownButton","Icon","ScrollArea","Surface","Toolbar","useExtractMarkdown","AICommandPanel","editor","onOpenChange","userPrompt","items","restProps","ref","inputValue","setInputValue","view","scrollContainer","activeItem","selectedGroupIndex","setSelectedGroupIndex","selectedCommandIndex","setSelectedCommandIndex","editorNode","dom","boundigClient","getBoundingClientRect","inputRef","object","submit","isLoading","api","schema","markdown","hasCompletion","Boolean","handleClick","prompt","body","option","command","language","storage","aiCommand","selection","completion","selectItem","groupIndex","commandIndex","commands","action","onKeyDown","event","key","length","newCommandIndex","newGroupIndex","current","offsetTop","offsetHeight","scrollTop","createCommandClickHandler","className","style","width","div","dir","resize","value","onChange","e","target","placeholder","t","autoFocus","Button","onClick","messages","onSelect","options","source","map","group","Fragment","title","isActive","icon","label"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/features/panels/AICommandPanel/AICommandPanel.tsx"],"sourcesContent":["'use client'\nimport { ArrowUpCircle, Sparkles } from 'lucide-react'\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react'\nimport Markdown from 'react-markdown'\nimport TextareaAutosize from 'react-textarea-autosize'\n\nimport { Editor } from '@tiptap/react'\n\nimport { experimental_useObject as useObject } from '@ai-sdk/react'\nimport i18next from 'i18next'\nimport { Command, Group } from '../../../extensions/AICommand/types.js'\nimport { TiptapSchema } from '../../../lib/tiptapSchema.js'\nimport { getPrevText } from '../../../lib/utils/index.js'\nimport AISelectorCommands from '../../menus/TextMenu/components/ai-selector-commands.js'\nimport CrazySpinner from '../../ui/crazy-spinner.js'\nimport { DropdownButton } from '../../ui/Dropdown/Dropdown.js'\nimport { Icon } from '../../ui/Icon.js'\nimport { ScrollArea } from '../../ui/scroll-area.js'\nimport { Surface } from '../../ui/Surface.js'\nimport { Toolbar } from '../../ui/Toolbar.js'\nimport { useExtractMarkdown } from '../AIEditorPanel/markdown.hook.js'\n\nexport type AICommandPanelProps = {\n editor: Editor\n userPrompt?: string\n onOpenChange: (value: boolean) => void\n items: Group[]\n}\n\nexport const AICommandPanel = forwardRef(\n ({ editor, onOpenChange, userPrompt, items, ...restProps }: AICommandPanelProps, ref) => {\n const [inputValue, setInputValue] = useState(userPrompt ?? '')\n const { view } = editor\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\n const editorNode = view.dom as HTMLElement\n const boundigClient = editorNode.getBoundingClientRect()\n const inputRef = useRef<HTMLTextAreaElement>(null)\n\n const { object, submit, isLoading } = useObject({\n api: '/api/generate',\n schema: TiptapSchema,\n })\n\n const { markdown } = useExtractMarkdown(object)\n\n const hasCompletion = Boolean(object)\n\n const handleClick = useCallback(() => {\n if (object) {\n submit({\n prompt: '',\n body: {\n option: 'zap',\n command: inputValue,\n language: editor?.storage?.aiCommand?.language,\n selection: object,\n },\n })\n setInputValue('')\n return\n }\n\n submit({\n prompt: '',\n body: {\n option: 'zap',\n command: inputValue,\n language: editor?.storage?.aiCommand?.language,\n },\n })\n setInputValue('')\n }, [editor?.storage?.aiCommand?.language, inputValue, object, submit])\n\n useEffect(() => {\n if (userPrompt) setInputValue(userPrompt)\n }, [userPrompt])\n useEffect(() => {\n if (!!hasCompletion) {\n editor.storage.aiCommand.completion = object?.content ?? []\n }\n }, [markdown, isLoading])\n\n useEffect(() => {\n setSelectedGroupIndex(0)\n setSelectedCommandIndex(0)\n }, [items])\n\n const selectItem = useCallback(\n (groupIndex: number, commandIndex: number) => {\n const command = items[groupIndex].commands[commandIndex]\n setInputValue(command.action(editor))\n },\n [items, editor],\n )\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: React.KeyboardEvent }) => {\n if (event.key === 'ArrowDown') {\n if (!items.length) {\n return false\n }\n\n const commands = 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 (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 (!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 = items[newGroupIndex]?.commands.length - 1 || 0\n }\n\n if (newGroupIndex < 0) {\n newGroupIndex = items.length - 1\n newCommandIndex = 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 (!items.length || selectedGroupIndex === -1 || selectedCommandIndex === -1) {\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 return (\n <>\n <Surface\n className={`p-2 min-w-[20rem] flex flex-col gap-2 w-full ${\n hasCompletion ? '-mt-72' : ''\n }`}\n style={{\n width: boundigClient?.width,\n }}\n >\n <>\n {markdown && (\n <div className='flex w-full'>\n <ScrollArea className='prose p-2 px-4 prose-sm max-h-96' dir={i18next.dir()}>\n <Markdown>{markdown}</Markdown>\n </ScrollArea>\n </div>\n )}\n\n {isLoading && (\n <div\n className='flex h-12 w-full items-center px-4 text-sm font-medium text-muted-foreground text-blue-500'\n style={{\n width: boundigClient?.width,\n }}\n >\n <Sparkles className='mr-2 h-4 w-4 shrink-0 ' />\n AI (Beta) is thinking\n <div className='ml-2 mt-1'>\n <CrazySpinner />\n </div>\n </div>\n )}\n\n {!isLoading && (\n <>\n <div className='flex justify-between items-center '>\n <Sparkles className='mr-2 h-4 w-4 shrink-0 text-blue-500 ' />\n <TextareaAutosize\n ref={inputRef}\n style={{ resize: 'none' }}\n className='w-full p-2 text-black bg-white rounded dark:bg-black dark:text-white focus:outline-none outline-none border-0 '\n value={inputValue}\n onChange={(e) => {\n editor.storage.aiCommand.userPrompt = e.target.value\n setInputValue(e.target.value)\n }}\n placeholder={\n hasCompletion\n ? i18next.t('tellAiPlaceholder') || 'Tell AI (Beta) what to do next'\n : i18next.t('askAiPlaceholder') || 'Ask AI (Beta) to edit or generate...'\n }\n autoFocus\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleClick()\n }}\n />\n <Toolbar.Button onClick={handleClick}>\n <ArrowUpCircle />\n </Toolbar.Button>\n </div>\n </>\n )}\n </>\n </Surface>\n {!isLoading && (\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 {hasCompletion ? (\n <AISelectorCommands\n editor={editor}\n messages={object}\n onSelect={(value, options) => {\n if (options?.option === 'translate') {\n submit({ prompt: value, body: options })\n } else {\n submit({\n prompt: value,\n body: { ...options, source: editor?.storage?.aiCommand?.language },\n })\n }\n }}\n />\n ) : (\n 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 && 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 )}\n </div>\n </Surface>\n )}\n </>\n )\n },\n)\n"],"names":["ArrowUpCircle","Sparkles","React","forwardRef","useCallback","useEffect","useImperativeHandle","useRef","useState","Markdown","TextareaAutosize","experimental_useObject","useObject","i18next","TiptapSchema","AISelectorCommands","CrazySpinner","DropdownButton","Icon","ScrollArea","Surface","Toolbar","useExtractMarkdown","AICommandPanel","editor","onOpenChange","userPrompt","items","restProps","ref","inputValue","setInputValue","view","scrollContainer","activeItem","selectedGroupIndex","setSelectedGroupIndex","selectedCommandIndex","setSelectedCommandIndex","editorNode","dom","boundigClient","getBoundingClientRect","inputRef","object","submit","isLoading","api","schema","markdown","hasCompletion","Boolean","handleClick","prompt","body","option","command","language","storage","aiCommand","selection","completion","content","selectItem","groupIndex","commandIndex","commands","action","onKeyDown","event","key","length","newCommandIndex","newGroupIndex","current","offsetTop","offsetHeight","scrollTop","createCommandClickHandler","className","style","width","div","dir","resize","value","onChange","e","target","placeholder","t","autoFocus","Button","onClick","messages","onSelect","options","source","map","group","Fragment","title","isActive","icon","label"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AIEditorPanel.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAmBtC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC,CAAA;AAED,eAAO,MAAM,aAAa,6BAA8B,kBAAkB,
|
|
1
|
+
{"version":3,"file":"AIEditorPanel.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAmBtC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC,CAAA;AAED,eAAO,MAAM,aAAa,6BAA8B,kBAAkB,gCAmHzE,CAAA"}
|
|
@@ -68,12 +68,10 @@ export const AIEditorPanel = ({ editor, onOpenChange })=>{
|
|
|
68
68
|
markdown && /*#__PURE__*/ _jsx("div", {
|
|
69
69
|
className: "flex w-full",
|
|
70
70
|
children: /*#__PURE__*/ _jsx(ScrollArea, {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
children:
|
|
75
|
-
children: markdown
|
|
76
|
-
})
|
|
71
|
+
className: "prose p-2 px-4 prose-sm max-h-96",
|
|
72
|
+
dir: i18next.dir(),
|
|
73
|
+
children: /*#__PURE__*/ _jsx(Markdown, {
|
|
74
|
+
children: markdown
|
|
77
75
|
})
|
|
78
76
|
})
|
|
79
77
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.tsx"],"sourcesContent":["'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { ArrowRight, Sparkles } from 'lucide-react'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport TextareaAutosize from 'react-textarea-autosize'\n\nimport { experimental_useObject as useObject } from '@ai-sdk/react'\nimport i18next from 'i18next'\nimport Markdown from 'react-markdown'\nimport { extractMarkdown } from '../../../lib/extract.js'\nimport { TiptapSchema } from '../../../lib/tiptapSchema.js'\nimport { getPrevText } from '../../../lib/utils/index.js'\nimport AICompletionCommands from '../../menus/TextMenu/components/ai-completion-command.js'\nimport AISelectorCommands from '../../menus/TextMenu/components/ai-selector-commands.js'\nimport { Surface } from '../../ui/Surface.js'\nimport { Toolbar } from '../../ui/Toolbar.js'\nimport CrazySpinner from '../../ui/crazy-spinner.js'\nimport { ScrollArea } from '../../ui/scroll-area.js'\nimport { useExtractMarkdown } from './markdown.hook.js'\n\nexport type AIEditorPanelProps = {\n editor: Editor\n onOpenChange: (value: boolean) => void\n}\n\nexport const AIEditorPanel = ({ editor, onOpenChange }: AIEditorPanelProps) => {\n const [inputValue, setInputValue] = useState('')\n const { view } = editor\n\n const editorNode = view.dom as HTMLElement\n const boundigClient = editorNode.getBoundingClientRect()\n const inputRef = useRef<HTMLTextAreaElement>(null)\n\n const { object, submit, isLoading } = useObject({\n api: '/api/generate',\n schema: TiptapSchema,\n })\n const hasCompletion = Boolean(object)\n\n const handleClick = useCallback(() => {\n if (object) {\n submit({\n prompt: object,\n body: {\n option: 'zap',\n command: inputValue,\n language: editor?.storage?.aiCommand?.language,\n },\n })\n setInputValue('')\n return\n }\n const text = getPrevText(editor, { chars: 5000 })\n\n submit({\n prompt: text,\n body: {\n option: 'zap',\n command: inputValue,\n language: editor?.storage?.aiCommand?.language,\n },\n })\n setInputValue('')\n }, [editor?.storage?.aiCommand?.language, inputValue, object, submit])\n\n const { markdown } = useExtractMarkdown(object)\n return (\n <Surface\n className={`p-2 min-w-[20rem] `}\n style={{\n width: boundigClient?.width,\n }}\n >\n <>\n {markdown && (\n <div className='flex w-full'>\n <ScrollArea
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/features/panels/AIEditorPanel/AIEditorPanel.tsx"],"sourcesContent":["'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { ArrowRight, Sparkles } from 'lucide-react'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport TextareaAutosize from 'react-textarea-autosize'\n\nimport { experimental_useObject as useObject } from '@ai-sdk/react'\nimport i18next from 'i18next'\nimport Markdown from 'react-markdown'\nimport { extractMarkdown } from '../../../lib/extract.js'\nimport { TiptapSchema } from '../../../lib/tiptapSchema.js'\nimport { getPrevText } from '../../../lib/utils/index.js'\nimport AICompletionCommands from '../../menus/TextMenu/components/ai-completion-command.js'\nimport AISelectorCommands from '../../menus/TextMenu/components/ai-selector-commands.js'\nimport { Surface } from '../../ui/Surface.js'\nimport { Toolbar } from '../../ui/Toolbar.js'\nimport CrazySpinner from '../../ui/crazy-spinner.js'\nimport { ScrollArea } from '../../ui/scroll-area.js'\nimport { useExtractMarkdown } from './markdown.hook.js'\n\nexport type AIEditorPanelProps = {\n editor: Editor\n onOpenChange: (value: boolean) => void\n}\n\nexport const AIEditorPanel = ({ editor, onOpenChange }: AIEditorPanelProps) => {\n const [inputValue, setInputValue] = useState('')\n const { view } = editor\n\n const editorNode = view.dom as HTMLElement\n const boundigClient = editorNode.getBoundingClientRect()\n const inputRef = useRef<HTMLTextAreaElement>(null)\n\n const { object, submit, isLoading } = useObject({\n api: '/api/generate',\n schema: TiptapSchema,\n })\n const hasCompletion = Boolean(object)\n\n const handleClick = useCallback(() => {\n if (object) {\n submit({\n prompt: object,\n body: {\n option: 'zap',\n command: inputValue,\n language: editor?.storage?.aiCommand?.language,\n },\n })\n setInputValue('')\n return\n }\n const text = getPrevText(editor, { chars: 5000 })\n\n submit({\n prompt: text,\n body: {\n option: 'zap',\n command: inputValue,\n language: editor?.storage?.aiCommand?.language,\n },\n })\n setInputValue('')\n }, [editor?.storage?.aiCommand?.language, inputValue, object, submit])\n\n const { markdown } = useExtractMarkdown(object)\n return (\n <Surface\n className={`p-2 min-w-[20rem] `}\n style={{\n width: boundigClient?.width,\n }}\n >\n <>\n {markdown && (\n <div className='flex w-full'>\n <ScrollArea className='prose p-2 px-4 prose-sm max-h-96' dir={i18next.dir()}>\n <Markdown>{markdown}</Markdown>\n </ScrollArea>\n </div>\n )}\n\n {isLoading && (\n <div className='flex h-12 w-full items-center px-4 text-sm font-medium text-muted-foreground text-blue-500'>\n <Sparkles className='mr-2 h-4 w-4 shrink-0 ' />\n AI (Beta) is thinking\n <div className='ml-2 mt-1'>\n <CrazySpinner />\n </div>\n </div>\n )}\n\n {!isLoading && (\n <>\n <div className='flex justify-between items-center'>\n <Sparkles className='mr-2 h-4 w-4 shrink-0 text-blue-500 ' />\n <TextareaAutosize\n ref={inputRef}\n className='w-full p-2 text-black bg-white rounded dark:bg-black dark:text-white focus:outline-none'\n value={inputValue}\n onChange={(e) => {\n setInputValue(e.target.value)\n }}\n placeholder={\n hasCompletion\n ? i18next.t('tellAiPlaceholder') || 'Tell AI (Beta) what to do next'\n : i18next.t('askAiPlaceholder') || 'Ask AI (Beta) to edit or generate...'\n }\n autoFocus\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleClick()\n }}\n />\n <Toolbar.Button onClick={handleClick}>\n <ArrowRight />\n </Toolbar.Button>\n </div>\n {hasCompletion ? (\n <AICompletionCommands\n editor={editor}\n onDiscard={() => {\n editor?.chain()?.focus()?.run()\n onOpenChange(false)\n }}\n completion={object}\n />\n ) : (\n <AISelectorCommands\n messages={object}\n editor={editor}\n onSelect={(value, options) => {\n submit({ prompt: value, body: options as any })\n }}\n />\n )}\n </>\n )}\n </>\n </Surface>\n )\n}\n"],"names":["ArrowRight","Sparkles","useCallback","useRef","useState","TextareaAutosize","experimental_useObject","useObject","i18next","Markdown","TiptapSchema","getPrevText","AICompletionCommands","AISelectorCommands","Surface","Toolbar","CrazySpinner","ScrollArea","useExtractMarkdown","AIEditorPanel","editor","onOpenChange","inputValue","setInputValue","view","editorNode","dom","boundigClient","getBoundingClientRect","inputRef","object","submit","isLoading","api","schema","hasCompletion","Boolean","handleClick","prompt","body","option","command","language","storage","aiCommand","text","chars","markdown","className","style","width","div","dir","ref","value","onChange","e","target","placeholder","t","autoFocus","onKeyDown","key","Button","onClick","onDiscard","chain","focus","run","completion","messages","onSelect","options"],"mappings":"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"}
|