mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
feat: editor inline status node (#1973)
* inline status node * fix alignment * fix * typed storage * fix math block popup on select all
This commit is contained in:
@@ -26,3 +26,4 @@ export * from "./lib/unique-id";
|
||||
export * from "./lib/shared-storage";
|
||||
export * from "./lib/recreate-transform";
|
||||
export * from "./lib/columns";
|
||||
export * from "./lib/status";
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
import { Node } from '@tiptap/core';
|
||||
import { ReactNodeViewRenderer } from '@tiptap/react';
|
||||
|
||||
export type StatusStorage = {
|
||||
autoOpen: boolean;
|
||||
};
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
status: {
|
||||
setStatus: (attributes?: { text?: string; color?: string }) => ReturnType;
|
||||
};
|
||||
}
|
||||
|
||||
interface Storage {
|
||||
status: StatusStorage;
|
||||
}
|
||||
}
|
||||
|
||||
export type StatusColor =
|
||||
| 'gray'
|
||||
| 'blue'
|
||||
| 'green'
|
||||
| 'yellow'
|
||||
| 'red'
|
||||
| 'purple';
|
||||
|
||||
export interface StatusOption {
|
||||
HTMLAttributes: Record<string, any>;
|
||||
view: any;
|
||||
}
|
||||
|
||||
export const Status = Node.create<StatusOption, StatusStorage>({
|
||||
name: 'status',
|
||||
group: 'inline',
|
||||
inline: true,
|
||||
atom: true,
|
||||
selectable: true,
|
||||
draggable: true,
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
HTMLAttributes: {},
|
||||
view: null,
|
||||
};
|
||||
},
|
||||
|
||||
addStorage() {
|
||||
return {
|
||||
autoOpen: false,
|
||||
};
|
||||
},
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
text: {
|
||||
default: '',
|
||||
parseHTML: (element: HTMLElement) => element.textContent || '',
|
||||
},
|
||||
color: {
|
||||
default: 'gray',
|
||||
parseHTML: (element: HTMLElement) =>
|
||||
element.getAttribute('data-color') || 'gray',
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: `span[data-type="${this.name}"]`,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return [
|
||||
'span',
|
||||
{
|
||||
'data-type': this.name,
|
||||
'data-color': HTMLAttributes.color,
|
||||
},
|
||||
HTMLAttributes.text,
|
||||
];
|
||||
},
|
||||
|
||||
addNodeView() {
|
||||
this.editor.isInitialized = true;
|
||||
return ReactNodeViewRenderer(this.options.view);
|
||||
},
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
setStatus:
|
||||
(attributes) =>
|
||||
({ commands }) => {
|
||||
this.storage.autoOpen = true;
|
||||
return commands.insertContent({
|
||||
type: this.name,
|
||||
attrs: {
|
||||
text: attributes?.text ?? '',
|
||||
color: attributes?.color || 'gray',
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user