Skip to content
File

Blob: src/client/components/editor/extensions/table/overlay-extension.ts

typescript62 lines
1import { Extension } from "@tiptap/core";
2import { Plugin } from "@tiptap/pm/state";
3import { isInTable } from "@tiptap/pm/tables";
4import { TableOverlayView } from "./overlay-view";
5import {
6 applyTableHandlesState,
7 createTableHandlesPluginState,
8 isPrintableKey,
9 tableHandlesKey,
10 type TableHandlesMeta,
11 type TableHandlesPluginState,
12} from "./state";
13 
14export const TableHandles = Extension.create({
15 name: "tableHandles",
16 
17 addProseMirrorPlugins() {
18 return [
19 new Plugin<TableHandlesPluginState>({
20 key: tableHandlesKey,
21 state: {
22 init: createTableHandlesPluginState,
23 apply: applyTableHandlesState,
24 },
25 props: {
26 handleKeyDown(view, event) {
27 if (!isInTable(view.state)) return false;
28 
29 if (event.key === "Escape") {
30 const current = tableHandlesKey.getState(view.state);
31 if (current?.openMenu || current?.isTyping) {
32 const meta: TableHandlesMeta = {};
33 if (current.openMenu) meta.openMenu = "close";
34 if (current.isTyping) meta.isTyping = false;
35 view.dispatch(view.state.tr.setMeta(tableHandlesKey, meta));
36 }
37 return false;
38 }
39 
40 if (isPrintableKey(event) && !tableHandlesKey.getState(view.state)?.isTyping) {
41 view.dispatch(view.state.tr.setMeta(tableHandlesKey, { isTyping: true }));
42 }
43 return false;
44 },
45 handleDOMEvents: {
46 mousedown(view, event) {
47 if (!tableHandlesKey.getState(view.state)?.isTyping) return false;
48 const target = event.target as HTMLElement | null;
49 if (!target?.closest("td, th, .tableWrapper")) return false;
50 view.dispatch(view.state.tr.setMeta(tableHandlesKey, { isTyping: false }));
51 return false;
52 },
53 },
54 },
55 view(editorView) {
56 return new TableOverlayView(editorView);
57 },
58 }),
59 ];
60 },
61});