File size: 2,362 Bytes
561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 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>
);
}
|