Spaces:
Sleeping
Sleeping
| import { NodeViewWrapper, NodeViewContent } from "@tiptap/react"; | |
| import { useCallback } from "react"; | |
| import type { NodeViewProps } from "@tiptap/react"; | |
| const GAP_MAP: Record<string, string> = { | |
| small: "8px", | |
| medium: "16px", | |
| large: "24px", | |
| }; | |
| const LAYOUT_OPTIONS = ["2-column", "3-column", "4-column"]; | |
| const GAP_OPTIONS = ["small", "medium", "large"]; | |
| export function StackView({ node, updateAttributes, editor, getPos }: NodeViewProps) { | |
| const layout = (node.attrs.layout as string) || "2-column"; | |
| const gap = (node.attrs.gap as string) || "medium"; | |
| const colCount = parseInt(layout) || 2; | |
| const handleLayoutChange = useCallback( | |
| (e: React.ChangeEvent<HTMLSelectElement>) => { | |
| const newLayout = e.target.value; | |
| const newColCount = parseInt(newLayout) || 2; | |
| const pos = getPos(); | |
| if (typeof pos === "number") { | |
| editor.commands.setStackColumns(pos, newColCount); | |
| } | |
| }, | |
| [editor, getPos], | |
| ); | |
| const handleGapChange = useCallback( | |
| (e: React.ChangeEvent<HTMLSelectElement>) => updateAttributes({ gap: e.target.value }), | |
| [updateAttributes], | |
| ); | |
| return ( | |
| <NodeViewWrapper data-component="stack" className="stack-wrapper"> | |
| <div className="stack-container"> | |
| <div contentEditable={false} className="stack-header"> | |
| <span className="stack-header-icon">▥</span> | |
| <span className="stack-header-label">Stack</span> | |
| <select | |
| value={layout} | |
| onChange={handleLayoutChange} | |
| className="stack-header-select" | |
| > | |
| {LAYOUT_OPTIONS.map((opt) => ( | |
| <option key={opt} value={opt}>{opt}</option> | |
| ))} | |
| </select> | |
| <select | |
| value={gap} | |
| onChange={handleGapChange} | |
| className="stack-header-select" | |
| > | |
| {GAP_OPTIONS.map((opt) => ( | |
| <option key={opt} value={opt}>{opt}</option> | |
| ))} | |
| </select> | |
| </div> | |
| <div | |
| className="stack-grid" | |
| style={{ | |
| display: "grid", | |
| gridTemplateColumns: `repeat(${colCount}, 1fr)`, | |
| gap: GAP_MAP[gap] || "16px", | |
| padding: "10px 12px", | |
| }} | |
| > | |
| <NodeViewContent className="stack-columns" /> | |
| </div> | |
| </div> | |
| </NodeViewWrapper> | |
| ); | |
| } | |