From c8b169da8cb7eae0957e0ab5e7370b071093a224 Mon Sep 17 00:00:00 2001 From: soryu Date: Tue, 28 Apr 2026 00:18:40 +0100 Subject: feat: Document UI for directive orchestration with Lexical editor (#93) * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Save previous goal on update and include history in re-planning prompt * feat: soryu-co/soryu - makima: Install Lexical and create base document editor component * feat: soryu-co/soryu - makima: Create directive file system sidebar and document layout * feat: soryu-co/soryu - makima: Create custom Lexical step diagram block * feat: soryu-co/soryu - makima: Add context menu and goal auto-update integration * WIP: heartbeat checkpoint --- .../components/document/nodes/StepsDiagramNode.tsx | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 frontend/src/components/document/nodes/StepsDiagramNode.tsx (limited to 'frontend/src/components/document/nodes/StepsDiagramNode.tsx') diff --git a/frontend/src/components/document/nodes/StepsDiagramNode.tsx b/frontend/src/components/document/nodes/StepsDiagramNode.tsx new file mode 100644 index 0000000..8b37f52 --- /dev/null +++ b/frontend/src/components/document/nodes/StepsDiagramNode.tsx @@ -0,0 +1,91 @@ +import { + DecoratorNode, + DOMExportOutput, + LexicalNode, + NodeKey, + SerializedLexicalNode, + Spread, +} from 'lexical'; +import React from 'react'; +import { StepsDiagramComponent } from './StepsDiagramComponent'; + +export type SerializedStepsDiagramNode = Spread< + { + directiveId: string; + }, + SerializedLexicalNode +>; + +export class StepsDiagramNode extends DecoratorNode { + __directiveId: string; + + static getType(): string { + return 'steps-diagram'; + } + + static clone(node: StepsDiagramNode): StepsDiagramNode { + return new StepsDiagramNode(node.__directiveId, node.__key); + } + + constructor(directiveId: string, key?: NodeKey) { + super(key); + this.__directiveId = directiveId; + } + + createDOM(): HTMLElement { + const div = document.createElement('div'); + div.className = 'steps-diagram-block'; + return div; + } + + updateDOM(): boolean { + return false; + } + + decorate(): JSX.Element { + return ; + } + + exportJSON(): SerializedStepsDiagramNode { + return { + ...super.exportJSON(), + type: 'steps-diagram', + directiveId: this.__directiveId, + version: 1, + }; + } + + static importJSON(serializedNode: SerializedStepsDiagramNode): StepsDiagramNode { + return $createStepsDiagramNode(serializedNode.directiveId); + } + + isInline(): boolean { + return false; + } + + canInsertTextBefore(): boolean { + return false; + } + + canInsertTextAfter(): boolean { + return false; + } + + exportDOM(): DOMExportOutput { + const element = document.createElement('div'); + element.className = 'steps-diagram-block'; + element.setAttribute('data-directive-id', this.__directiveId); + element.textContent = '[Steps Diagram]'; + return { element }; + } +} + +export function $createStepsDiagramNode(directiveId: string): StepsDiagramNode { + return new StepsDiagramNode(directiveId); +} + +export function $isStepsDiagramNode( + node: LexicalNode | null | undefined, +): node is StepsDiagramNode { + return node instanceof StepsDiagramNode; +} -- cgit v1.2.3