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:
Philip Okugbe
2026-02-27 01:34:03 +00:00
committed by GitHub
parent 59e945562d
commit ea44468fad
11 changed files with 365 additions and 7 deletions
+1
View File
@@ -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";
+108
View File
@@ -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',
},
});
},
};
},
});