From c13d65c8429372e9dc2d5b9dc5be3b8c939826dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Tue, 19 Jan 2021 10:09:32 +0100 Subject: [PATCH] refactoring --- packages/core/src/commands/replace.ts | 7 +--- packages/core/src/types.ts | 5 +++ packages/extension-mention/src/mention.ts | 2 +- .../suggestion/src/findSuggestionMatch.ts | 6 +-- packages/suggestion/src/getVirtualNode.ts | 8 +++- packages/suggestion/src/index.ts | 2 + packages/suggestion/src/suggestion.ts | 38 ++++++++++++++----- 7 files changed, 46 insertions(+), 22 deletions(-) diff --git a/packages/core/src/commands/replace.ts b/packages/core/src/commands/replace.ts index 3ce34450a..92c693a86 100644 --- a/packages/core/src/commands/replace.ts +++ b/packages/core/src/commands/replace.ts @@ -1,11 +1,6 @@ import { NodeType } from 'prosemirror-model' import getNodeType from '../helpers/getNodeType' -import { Command } from '../types' - -export type Range = { - from: number, - to: number, -} +import { Command, Range } from '../types' /** * Replaces text with a node within a range. diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index b9ff3aafd..4f4fc4eb0 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -130,3 +130,8 @@ export type ChainedCommands = { export type CanCommands = SingleCommands & { chain: () => ChainedCommands } export type FocusPosition = 'start' | 'end' | number | boolean | null + +export type Range = { + from: number, + to: number, +} diff --git a/packages/extension-mention/src/mention.ts b/packages/extension-mention/src/mention.ts index ff8edb968..d4b7f6692 100644 --- a/packages/extension-mention/src/mention.ts +++ b/packages/extension-mention/src/mention.ts @@ -8,7 +8,6 @@ export const Mention = Node.create({ defaultOptions: { char: '@', - render: () => ({}), }, group: 'inline', @@ -50,6 +49,7 @@ export const Mention = Node.create({ command: ({ range }) => { this.editor .chain() + .focus() .replace(range, 'mention') .insertText(' ') .run() diff --git a/packages/suggestion/src/findSuggestionMatch.ts b/packages/suggestion/src/findSuggestionMatch.ts index 23a1c0886..35dac99f4 100644 --- a/packages/suggestion/src/findSuggestionMatch.ts +++ b/packages/suggestion/src/findSuggestionMatch.ts @@ -1,3 +1,4 @@ +import { Range } from '@tiptap/core' import { ResolvedPos } from 'prosemirror-model' export interface Trigger { @@ -8,10 +9,7 @@ export interface Trigger { } export type SuggestionMatch = { - range: { - from: number, - to: number, - }, + range: Range, query: string, text: string, } | null diff --git a/packages/suggestion/src/getVirtualNode.ts b/packages/suggestion/src/getVirtualNode.ts index 7f2ca9ab3..1b6a5c735 100644 --- a/packages/suggestion/src/getVirtualNode.ts +++ b/packages/suggestion/src/getVirtualNode.ts @@ -1,4 +1,10 @@ -export function getVirtualNode(node: Element) { +export interface VirtualNode { + getBoundingClientRect: () => DOMRect, + clientWidth: number, + clientHeight: number, +} + +export function getVirtualNode(node: Element): VirtualNode { return { getBoundingClientRect() { return node.getBoundingClientRect() diff --git a/packages/suggestion/src/index.ts b/packages/suggestion/src/index.ts index 43cdefd63..6a8d7a35d 100644 --- a/packages/suggestion/src/index.ts +++ b/packages/suggestion/src/index.ts @@ -1,5 +1,7 @@ import { Suggestion } from './suggestion' +export * from './findSuggestionMatch' +export * from './getVirtualNode' export * from './suggestion' export default Suggestion diff --git a/packages/suggestion/src/suggestion.ts b/packages/suggestion/src/suggestion.ts index 7cc86058e..37fbf43e7 100644 --- a/packages/suggestion/src/suggestion.ts +++ b/packages/suggestion/src/suggestion.ts @@ -1,8 +1,8 @@ -import { Editor } from '@tiptap/core' +import { Editor, Range } from '@tiptap/core' import { Plugin, PluginKey } from 'prosemirror-state' -import { Decoration, DecorationSet } from 'prosemirror-view' +import { Decoration, DecorationSet, EditorView } from 'prosemirror-view' import { findSuggestionMatch } from './findSuggestionMatch' -import { getVirtualNode } from './getVirtualNode' +import { getVirtualNode, VirtualNode } from './getVirtualNode' export interface SuggestionOptions { editor: Editor, @@ -10,17 +10,35 @@ export interface SuggestionOptions { allowSpaces?: boolean, startOfLine?: boolean, suggestionClass?: string, - command?: (props: any) => any, + command?: (props: { range: Range }) => void, items?: (query: string) => any[], render?: () => { - onStart?: (props: any) => void, - onUpdate?: (props: any) => void, - onExit?: (props: any) => void, - onKeyDown?: (props: any) => boolean, + onStart?: (props: SuggestionProps) => void, + onUpdate?: (props: SuggestionProps) => void, + onExit?: (props: SuggestionProps) => void, + onKeyDown?: (props: SuggestionKeyDownProps) => boolean, }, } +export interface SuggestionProps { + editor: Editor, + range: Range, + query: string, + text: string, + items: any[], + command: () => void, + decorationNode: Element | null, + virtualNode: VirtualNode | null, +} + +export interface SuggestionKeyDownProps { + view: EditorView, + event: KeyboardEvent, + range: Range, +} + export function Suggestion({ + editor, char = '@', allowSpaces = false, startOfLine = false, @@ -57,8 +75,8 @@ export function Suggestion({ const state = handleExit ? prev : next const decorationNode = document.querySelector(`[data-decoration-id="${state.decorationId}"]`) - const props = { - view, + const props: SuggestionProps = { + editor, range: state.range, query: state.query, text: state.text,