diff --git a/components/editor/intelli/quick-extension.js b/components/editor/intelli/quick-extension.js index c57a1c5..5df01dd 100644 --- a/components/editor/intelli/quick-extension.js +++ b/components/editor/intelli/quick-extension.js @@ -1,24 +1,58 @@ -import { Extension, ReactRenderer } from '@tiptap/react' +import { Node, ReactRenderer } from '@tiptap/react' import tippy from 'tippy.js' import { Plugin, PluginKey } from '@tiptap/pm/state' import { QuickView } from './quick-view' +import { Suggestion } from '@tiptap/suggestion' + +const extensionName = 'quick-command' -const extensionName = 'ai-quick-command' export const createQuickExtension = () => { - return Extension.create({ + return Node.create({ name: extensionName, addOptions () { return { char: 'Mod-/', - pluginKey: extensionName, + pluginKey: 'quick-extension', } }, + // addKeyboardShortcuts () { + // return { + // 'Mod-/': () => { + // this.editor.commands.command(({ tr, state, dispatch }) => { + // dispatch(tr.setMeta(pluginKey, false)) + // return true + // }) + // }, + // } + // }, addProseMirrorPlugins () { - let plugin = new Plugin({ + let plugin = Suggestion({ editor: this.editor, - char: 'Mod-/', - ...this.options, + char: this.options.char, + pluginKey: new PluginKey(extensionName), + + command: ({ editor, props }) => { + const { state, dispatch } = editor.view + const { $head, $from } = state.selection + + const end = $from.pos + const from = $head?.nodeBefore?.text + ? end - + $head.nodeBefore.text.substring( + $head.nodeBefore.text.indexOf('/') + ).length + : $from.start() + + const tr = state.tr.deleteRange(from, end) + dispatch(tr) + props?.action?.(editor, props.user) + editor?.view?.focus() + }, + items: ({ query }) => { + // todo: match fo query + return [{}] + }, render: () => { let component @@ -27,6 +61,7 @@ export const createQuickExtension = () => { return { onStart: (props) => { + console.log(props) isEditable = props.editor.isEditable if (!isEditable) return diff --git a/components/editor/intelli/slash-extension.js b/components/editor/intelli/slash-extension.js index 90497b3..13b4a1e 100644 --- a/components/editor/intelli/slash-extension.js +++ b/components/editor/intelli/slash-extension.js @@ -3,6 +3,7 @@ import { Node } from '@tiptap/core' import { Suggestion } from '@tiptap/suggestion' import tippy from 'tippy.js' import SlashView from './slash-view' +import { PluginKey } from '@tiptap/pm/state' export const createSlashExtension = (name, options) => { const extensionName = `ai-insert` @@ -12,7 +13,7 @@ export const createSlashExtension = (name, options) => { addOptions () { return { char: '/', - pluginKey: 'slash-/', + pluginKey: 'slash', } }, addProseMirrorPlugins () { @@ -20,6 +21,7 @@ export const createSlashExtension = (name, options) => { Suggestion({ editor: this.editor, char: this.options.char, + pluginKey: new PluginKey(this.options.pluginKey), command: ({ editor, props }) => { const { state, dispatch } = editor.view diff --git a/components/editor/intelli/slash-view.jsx b/components/editor/intelli/slash-view.jsx index b981684..97db004 100644 --- a/components/editor/intelli/slash-view.jsx +++ b/components/editor/intelli/slash-view.jsx @@ -84,17 +84,17 @@ class SlashView extends React.Component { const { selectedIndex } = this.state return ( - + ) } } diff --git a/styles/global.css b/styles/global.css index ccbdce8..390ef7c 100644 --- a/styles/global.css +++ b/styles/global.css @@ -51,27 +51,31 @@ input { .DropdownMenuContent, .DropdownMenuSubContent { - min-width: 220px; + min-width: 160px; background-color: white; border-radius: 6px; - padding: 5px; + padding: 12px; box-shadow: 0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2); animation-duration: 400ms; animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); will-change: transform, opacity; } + .DropdownMenuContent[data-side='top'], .DropdownMenuSubContent[data-side='top'] { animation-name: slideDownAndFade; } + .DropdownMenuContent[data-side='right'], .DropdownMenuSubContent[data-side='right'] { animation-name: slideLeftAndFade; } + .DropdownMenuContent[data-side='bottom'], .DropdownMenuSubContent[data-side='bottom'] { animation-name: slideUpAndFade; } + .DropdownMenuContent[data-side='left'], .DropdownMenuSubContent[data-side='left'] { animation-name: slideRightAndFade; @@ -94,10 +98,12 @@ input { user-select: none; outline: none; } + .DropdownMenuSubTrigger[data-state='open'] { background-color: var(--violet-4); color: var(--violet-11); } + .DropdownMenuItem[data-disabled], .DropdownMenuCheckboxItem[data-disabled], .DropdownMenuRadioItem[data-disabled], @@ -105,6 +111,7 @@ input { color: var(--mauve-8); pointer-events: none; } + .DropdownMenuItem[data-highlighted], .DropdownMenuCheckboxItem[data-highlighted], .DropdownMenuRadioItem[data-highlighted], @@ -151,9 +158,11 @@ input { background-color: white; box-shadow: 0 2px 10px var(--black-a7); } + .IconButton:hover { background-color: var(--violet-3); } + .IconButton:focus { box-shadow: 0 0 0 2px black; } @@ -163,9 +172,11 @@ input { padding-left: 20px; color: var(--mauve-11); } + [data-highlighted] > .RightSlot { color: white; } + [data-disabled] .RightSlot { color: var(--mauve-8); }