Skip to content

Commit

Permalink
feat: init slash comamnd
Browse files Browse the repository at this point in the history
  • Loading branch information
phodal committed Nov 21, 2023
1 parent 9e74bc3 commit 3010d70
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 5 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ Todos
- [ ] Online Runtime
- [ ] Unit Runtime

## Refs:

### Tiptap Editor extensions

[https://github.com/fantasticit/magic-editor](https://github.com/fantasticit/magic-editor)
[Think Editor'S Tiptap Plugins](https://github.com/fantasticit/think/tree/main/packages/client/src/tiptap/core/extensions)

## License

This code is distributed under the MIT license. See `LICENSE` in this directory.
3 changes: 3 additions & 0 deletions components/editor/auto-complete.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// AutoComplete will use semantic search to search in Local


16 changes: 11 additions & 5 deletions components/editor/live-editor.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Color } from '@tiptap/extension-color'
import ListItem from '@tiptap/extension-list-item'
import TextStyle from '@tiptap/extension-text-style'
import { BubbleMenu, EditorContent, Extension, useEditor } from '@tiptap/react'
import { EditorContent, Extension, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import React from 'react'
import { MenuBar } from './menu-bar'

import MarkdownIt from 'markdown-it'
import { AiBubbleMenu } from './ai-bubble-menu'
import { CommandsList, SlashCommands } from './slash-commands'

const md = new MarkdownIt()
const CustomCommands = Extension.create({
Expand All @@ -28,10 +29,6 @@ const CustomCommands = Extension.create({

const extensions = [
CustomCommands,
// or try SlashCommands: https://github.com/ueberdosis/tiptap/issues/1508
Color.configure({ types: [TextStyle.name, ListItem.name] }),
// @ts-ignore
TextStyle.configure({ types: [ListItem.name] }),
StarterKit.configure({
bulletList: {
keepMarks: true,
Expand All @@ -42,6 +39,15 @@ const extensions = [
keepAttributes: false, // TODO : Making this as `false` becase marks are not preserved when I try to preserve attrs, awaiting a bit of help
},
}),
SlashCommands.configure({
commands: [
{ title: "续写内容", options: { command: "continue-writing" } }
],
component: CommandsList
}),
Color.configure({ types: [TextStyle.name, ListItem.name] }),
// @ts-ignore
TextStyle.configure({ types: [ListItem.name] }),
]

const content = `
Expand Down
120 changes: 120 additions & 0 deletions components/editor/slash-commands.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { Extension, ReactRenderer } from '@tiptap/react'
import React from 'react'
import { Suggestion } from '@tiptap/suggestion'
import tippy from 'tippy.js'

// or try SlashCommands: https://github.com/ueberdosis/tiptap/issues/1508
export const SlashCommands = Extension.create({
name: 'slash-command',
addOptions () {
return {
char: '/',
pluginKey: 'slash-/',
}
},
addProseMirrorPlugins () {
return [
Suggestion({
editor: this.editor,
char: this.options.char,
command: ({ editor, props }) => {
console.log('ss')
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 }) => {
return [
{
title: 'H1',
command: ({ editor, range }) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', { level: 1 })
.run()
},
},
].filter(item => item.title)
},
render: () => {
let component
let popup

return {
onStart: props => {
component = new ReactRenderer(CommandsList, {
props,
editor: props.editor,
})

popup = tippy('body', {
getReferenceClientRect: props.clientRect,
appendTo: () => document.body,
content: component.element,
showOnCreate: true,
interactive: true,
trigger: 'manual',
placement: 'bottom-start',
})
},

onUpdate (props) {
component.updateProps(props)

if (!props.clientRect) {
return
}

popup[0].setProps({
getReferenceClientRect: props.clientRect,
})
},

onKeyDown (props) {
if (props.event.key === 'Escape') {
popup[0].hide()

return true
}

return component.ref?.onKeyDown(props)
},

onExit () {
popup[0].destroy()
component.destroy()
},
}
},
}),
]
},
})

export function CommandsList (props) {
const { items, selectedIndex, selectItem } = props

return (
<ul>
{items.map(({ title }, idx) => (
<li key={idx} onClick={() => selectItem(idx)}>
{title}
</li>
))}
</ul>
)
}

0 comments on commit 3010d70

Please sign in to comment.