move suggestion list code to separate file
This commit is contained in:
parent
c04e36e3fe
commit
3a61ddaee7
|
@ -7,7 +7,6 @@ import {
|
||||||
JSONContent,
|
JSONContent,
|
||||||
Content,
|
Content,
|
||||||
Editor,
|
Editor,
|
||||||
ReactRenderer,
|
|
||||||
} from '@tiptap/react'
|
} from '@tiptap/react'
|
||||||
import StarterKit from '@tiptap/starter-kit'
|
import StarterKit from '@tiptap/starter-kit'
|
||||||
import { Image } from '@tiptap/extension-image'
|
import { Image } from '@tiptap/extension-image'
|
||||||
|
@ -18,12 +17,11 @@ import { useEffect } from 'react'
|
||||||
import { Linkify } from './linkify'
|
import { Linkify } from './linkify'
|
||||||
import { uploadImage } from 'web/lib/firebase/storage'
|
import { uploadImage } from 'web/lib/firebase/storage'
|
||||||
import { useMutation } from 'react-query'
|
import { useMutation } from 'react-query'
|
||||||
import { exhibitExts, searchInAny } from 'common/util/parse'
|
import { exhibitExts } from 'common/util/parse'
|
||||||
import { FileUploadButton } from './file-upload-button'
|
import { FileUploadButton } from './file-upload-button'
|
||||||
import { linkClass } from './site-link'
|
import { linkClass } from './site-link'
|
||||||
import { useUsers } from 'web/hooks/use-users'
|
import { useUsers } from 'web/hooks/use-users'
|
||||||
import { MentionList } from './editor/mention-list'
|
import { mentionSuggestion } from './editor/mention-suggestion'
|
||||||
import tippy from 'tippy.js'
|
|
||||||
|
|
||||||
const proseClass = clsx(
|
const proseClass = clsx(
|
||||||
'prose prose-p:my-0 prose-li:my-0 prose-blockquote:not-italic max-w-none prose-quoteless leading-relaxed',
|
'prose prose-p:my-0 prose-li:my-0 prose-blockquote:not-italic max-w-none prose-quoteless leading-relaxed',
|
||||||
|
@ -75,59 +73,7 @@ export function useTextEditor(props: {
|
||||||
{ href: node.attrs.label },
|
{ href: node.attrs.label },
|
||||||
`${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`,
|
`${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`,
|
||||||
] as any,
|
] as any,
|
||||||
suggestion: {
|
suggestion: mentionSuggestion(users),
|
||||||
items: ({ query }) =>
|
|
||||||
users
|
|
||||||
.filter((u) => searchInAny(query, u.username, u.name))
|
|
||||||
.slice(0, 5),
|
|
||||||
render: () => {
|
|
||||||
let component: any
|
|
||||||
let popup: any
|
|
||||||
return {
|
|
||||||
onStart: (props) => {
|
|
||||||
component = new ReactRenderer(MentionList, {
|
|
||||||
props,
|
|
||||||
editor: props.editor,
|
|
||||||
})
|
|
||||||
if (!props.clientRect) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
popup = tippy('body', {
|
|
||||||
getReferenceClientRect: props.clientRect as any,
|
|
||||||
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()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
content: defaultValue,
|
content: defaultValue,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { User } from 'common/user'
|
||||||
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'
|
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'
|
||||||
import { Avatar } from '../avatar'
|
import { Avatar } from '../avatar'
|
||||||
|
|
||||||
// copied from https://tiptap.dev/api/nodes/mention
|
// copied from https://tiptap.dev/api/nodes/mention#usage
|
||||||
export const MentionList = forwardRef((props: SuggestionProps<User>, ref) => {
|
export const MentionList = forwardRef((props: SuggestionProps<User>, ref) => {
|
||||||
const { items: users, command } = props
|
const { items: users, command } = props
|
||||||
|
|
||||||
|
|
61
web/components/editor/mention-suggestion.ts
Normal file
61
web/components/editor/mention-suggestion.ts
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
import type { MentionOptions } from '@tiptap/extension-mention'
|
||||||
|
import { ReactRenderer } from '@tiptap/react'
|
||||||
|
import { User } from 'common/lib/user'
|
||||||
|
import { searchInAny } from 'common/util/parse'
|
||||||
|
import tippy from 'tippy.js'
|
||||||
|
import { MentionList } from './mention-list'
|
||||||
|
|
||||||
|
type Suggestion = MentionOptions['suggestion']
|
||||||
|
|
||||||
|
// copied from https://tiptap.dev/api/nodes/mention#usage
|
||||||
|
export const mentionSuggestion = (users: User[]): Suggestion => ({
|
||||||
|
items: ({ query }) =>
|
||||||
|
users.filter((u) => searchInAny(query, u.username, u.name)).slice(0, 5),
|
||||||
|
render: () => {
|
||||||
|
let component: any
|
||||||
|
let popup: any
|
||||||
|
return {
|
||||||
|
onStart: (props) => {
|
||||||
|
component = new ReactRenderer(MentionList, {
|
||||||
|
props,
|
||||||
|
editor: props.editor,
|
||||||
|
})
|
||||||
|
if (!props.clientRect) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
popup = tippy('body', {
|
||||||
|
getReferenceClientRect: props.clientRect as any,
|
||||||
|
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()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user