@hex-core/components 1.7.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/_tsup-dts-rollup.d.ts +1566 -5
  2. package/dist/arc.d.ts +4 -0
  3. package/dist/arc.js +147 -0
  4. package/dist/arc.js.map +1 -0
  5. package/dist/audio-player.d.ts +2 -0
  6. package/dist/audio-player.js +119 -0
  7. package/dist/audio-player.js.map +1 -0
  8. package/dist/audio-waveform.d.ts +2 -0
  9. package/dist/audio-waveform.js +72 -0
  10. package/dist/audio-waveform.js.map +1 -0
  11. package/dist/canvas.d.ts +2 -0
  12. package/dist/canvas.js +73 -0
  13. package/dist/canvas.js.map +1 -0
  14. package/dist/chord.d.ts +4 -0
  15. package/dist/chord.js +230 -0
  16. package/dist/chord.js.map +1 -0
  17. package/dist/cloze.d.ts +3 -0
  18. package/dist/cloze.js +98 -0
  19. package/dist/cloze.js.map +1 -0
  20. package/dist/color-picker.js.map +1 -1
  21. package/dist/compare-table.d.ts +4 -0
  22. package/dist/compare-table.js +109 -0
  23. package/dist/compare-table.js.map +1 -0
  24. package/dist/data-table.js.map +1 -1
  25. package/dist/deck.d.ts +3 -0
  26. package/dist/deck.js +231 -0
  27. package/dist/deck.js.map +1 -0
  28. package/dist/dendrogram.d.ts +3 -0
  29. package/dist/dendrogram.js +162 -0
  30. package/dist/dendrogram.js.map +1 -0
  31. package/dist/diagram.d.ts +2 -0
  32. package/dist/diagram.js +70 -0
  33. package/dist/diagram.js.map +1 -0
  34. package/dist/flashcard.d.ts +2 -0
  35. package/dist/flashcard.js +107 -0
  36. package/dist/flashcard.js.map +1 -0
  37. package/dist/flowchart.d.ts +4 -0
  38. package/dist/flowchart.js +275 -0
  39. package/dist/flowchart.js.map +1 -0
  40. package/dist/funnel.d.ts +3 -0
  41. package/dist/funnel.js +157 -0
  42. package/dist/funnel.js.map +1 -0
  43. package/dist/gantt.d.ts +3 -0
  44. package/dist/gantt.js +279 -0
  45. package/dist/gantt.js.map +1 -0
  46. package/dist/image-occlusion.d.ts +3 -0
  47. package/dist/image-occlusion.js +106 -0
  48. package/dist/image-occlusion.js.map +1 -0
  49. package/dist/index.d.ts +84 -0
  50. package/dist/index.js +3946 -2
  51. package/dist/index.js.map +1 -1
  52. package/dist/matrix.d.ts +3 -0
  53. package/dist/matrix.js +155 -0
  54. package/dist/matrix.js.map +1 -0
  55. package/dist/mind-map.d.ts +3 -0
  56. package/dist/mind-map.js +167 -0
  57. package/dist/mind-map.js.map +1 -0
  58. package/dist/org-chart.d.ts +3 -0
  59. package/dist/org-chart.js +215 -0
  60. package/dist/org-chart.js.map +1 -0
  61. package/dist/pyramid.d.ts +3 -0
  62. package/dist/pyramid.js +150 -0
  63. package/dist/pyramid.js.map +1 -0
  64. package/dist/quiz.d.ts +3 -0
  65. package/dist/quiz.js +128 -0
  66. package/dist/quiz.js.map +1 -0
  67. package/dist/sankey.d.ts +4 -0
  68. package/dist/sankey.js +190 -0
  69. package/dist/sankey.js.map +1 -0
  70. package/dist/schemas.d.ts +23 -0
  71. package/dist/schemas.js +2210 -3
  72. package/dist/schemas.js.map +1 -1
  73. package/dist/sequence.d.ts +4 -0
  74. package/dist/sequence.js +229 -0
  75. package/dist/sequence.js.map +1 -0
  76. package/dist/sonner.js.map +1 -1
  77. package/dist/spaced-repetition.d.ts +3 -0
  78. package/dist/spaced-repetition.js +73 -0
  79. package/dist/spaced-repetition.js.map +1 -0
  80. package/dist/sunburst.d.ts +3 -0
  81. package/dist/sunburst.js +205 -0
  82. package/dist/sunburst.js.map +1 -0
  83. package/dist/terminal.d.ts +2 -0
  84. package/dist/terminal.js +153 -0
  85. package/dist/terminal.js.map +1 -0
  86. package/dist/textarea.js.map +1 -1
  87. package/dist/time-axis.d.ts +3 -0
  88. package/dist/time-axis.js +233 -0
  89. package/dist/time-axis.js.map +1 -0
  90. package/dist/tool-call.js +6 -1
  91. package/dist/tool-call.js.map +1 -1
  92. package/dist/tree-map.d.ts +3 -0
  93. package/dist/tree-map.js +171 -0
  94. package/dist/tree-map.js.map +1 -0
  95. package/dist/venn.d.ts +3 -0
  96. package/dist/venn.js +196 -0
  97. package/dist/venn.js.map +1 -0
  98. package/package.json +49 -5
@@ -0,0 +1,3 @@
1
+ export { MatrixNode_alias_1 as MatrixNode } from './_tsup-dts-rollup.js';
2
+ export { MatrixProps_alias_1 as MatrixProps } from './_tsup-dts-rollup.js';
3
+ export { Matrix_alias_1 as Matrix } from './_tsup-dts-rollup.js';
package/dist/matrix.js ADDED
@@ -0,0 +1,155 @@
1
+ "use client";
2
+ import * as React from 'react';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ function cn(...inputs) {
8
+ return twMerge(clsx(inputs));
9
+ }
10
+ var MIN_CELL_SIZE_FOR_VALUE = 28;
11
+ function Matrix({
12
+ nodes,
13
+ matrix,
14
+ size = 480,
15
+ labelMargin = 80,
16
+ showValues = true,
17
+ onCellHover,
18
+ onCellClick,
19
+ className,
20
+ ...rest
21
+ }) {
22
+ const cells = React.useMemo(() => layout(nodes, matrix, size, labelMargin), [nodes, matrix, size, labelMargin]);
23
+ const desc = `Matrix with ${nodes.length} node${nodes.length === 1 ? "" : "s"} (${nodes.length}\xD7${nodes.length} cells)`;
24
+ const cellSize = nodes.length > 0 ? (size - labelMargin) / nodes.length : 0;
25
+ return /* @__PURE__ */ jsxs(
26
+ "svg",
27
+ {
28
+ ...rest,
29
+ "data-hex-matrix": true,
30
+ role: "img",
31
+ width: size,
32
+ height: size,
33
+ viewBox: `0 0 ${size} ${size}`,
34
+ className: cn("block", className),
35
+ children: [
36
+ /* @__PURE__ */ jsx("title", { children: "Adjacency matrix" }),
37
+ /* @__PURE__ */ jsx("desc", { children: desc }),
38
+ /* @__PURE__ */ jsx("g", { "data-hex-matrix-rows": true, children: nodes.map((n, i) => /* @__PURE__ */ jsx(
39
+ "text",
40
+ {
41
+ x: labelMargin - 4,
42
+ y: labelMargin + cellSize * i + cellSize / 2,
43
+ dy: "0.35em",
44
+ textAnchor: "end",
45
+ fontSize: 10,
46
+ fill: "hsl(var(--foreground))",
47
+ children: n.label
48
+ },
49
+ `row-${n.id}`
50
+ )) }),
51
+ /* @__PURE__ */ jsx("g", { "data-hex-matrix-cols": true, children: nodes.map((n, i) => /* @__PURE__ */ jsx(
52
+ "text",
53
+ {
54
+ x: labelMargin + cellSize * i + cellSize / 2,
55
+ y: labelMargin - 4,
56
+ textAnchor: "end",
57
+ fontSize: 10,
58
+ fill: "hsl(var(--foreground))",
59
+ transform: `rotate(-45 ${labelMargin + cellSize * i + cellSize / 2} ${labelMargin - 4})`,
60
+ children: n.label
61
+ },
62
+ `col-${n.id}`
63
+ )) }),
64
+ /* @__PURE__ */ jsx("g", { "data-hex-matrix-cells": true, children: cells.map((c) => {
65
+ const interactive = Boolean(onCellHover || onCellClick);
66
+ const cellPayload = { row: c.row, col: c.col, value: c.value };
67
+ const fireHover = (cell) => onCellHover?.(cell);
68
+ const handleActivate = () => onCellClick?.(cellPayload);
69
+ return /* @__PURE__ */ jsxs(
70
+ "g",
71
+ {
72
+ "data-hex-matrix-cell": true,
73
+ "data-row": c.rowIndex,
74
+ "data-col": c.colIndex,
75
+ role: interactive ? "button" : void 0,
76
+ tabIndex: interactive ? 0 : void 0,
77
+ "aria-label": interactive ? `${c.row.label} \u2192 ${c.col.label}: ${c.value}` : void 0,
78
+ style: interactive ? { cursor: "pointer" } : void 0,
79
+ onMouseEnter: onCellHover ? () => fireHover(cellPayload) : void 0,
80
+ onMouseLeave: onCellHover ? () => fireHover(null) : void 0,
81
+ onFocus: onCellHover ? () => fireHover(cellPayload) : void 0,
82
+ onBlur: onCellHover ? () => fireHover(null) : void 0,
83
+ onClick: onCellClick ? handleActivate : void 0,
84
+ onKeyDown: onCellClick ? (e) => activateOnKey(e, handleActivate) : void 0,
85
+ children: [
86
+ /* @__PURE__ */ jsx(
87
+ "rect",
88
+ {
89
+ x: c.x,
90
+ y: c.y,
91
+ width: cellSize,
92
+ height: cellSize,
93
+ fill: "hsl(var(--chart-1, var(--primary)))",
94
+ fillOpacity: 0.08 + 0.87 * c.intensity,
95
+ stroke: "hsl(var(--background))",
96
+ strokeWidth: 0.5
97
+ }
98
+ ),
99
+ showValues && cellSize > MIN_CELL_SIZE_FOR_VALUE && c.value !== 0 ? /* @__PURE__ */ jsx(
100
+ "text",
101
+ {
102
+ x: c.x + cellSize / 2,
103
+ y: c.y + cellSize / 2,
104
+ dy: "0.35em",
105
+ textAnchor: "middle",
106
+ fontSize: 9,
107
+ fill: c.intensity > 0.55 ? "hsl(var(--background))" : "hsl(var(--foreground))",
108
+ style: { pointerEvents: "none" },
109
+ children: c.value
110
+ }
111
+ ) : null
112
+ ]
113
+ },
114
+ `${c.rowIndex}-${c.colIndex}`
115
+ );
116
+ }) })
117
+ ]
118
+ }
119
+ );
120
+ }
121
+ function layout(nodes, matrix, size, labelMargin) {
122
+ if (nodes.length === 0) return [];
123
+ const cellSize = (size - labelMargin) / nodes.length;
124
+ let maxValue = 0;
125
+ for (const row of matrix) {
126
+ for (const v of row) if (v > maxValue) maxValue = v;
127
+ }
128
+ const cells = [];
129
+ for (let i = 0; i < nodes.length; i++) {
130
+ for (let j = 0; j < nodes.length; j++) {
131
+ const value = matrix[i]?.[j] ?? 0;
132
+ cells.push({
133
+ row: nodes[i],
134
+ col: nodes[j],
135
+ rowIndex: i,
136
+ colIndex: j,
137
+ value,
138
+ x: labelMargin + cellSize * j,
139
+ y: labelMargin + cellSize * i,
140
+ intensity: maxValue > 0 ? value / maxValue : 0
141
+ });
142
+ }
143
+ }
144
+ return cells;
145
+ }
146
+ function activateOnKey(e, fn) {
147
+ if (e.key === "Enter" || e.key === " ") {
148
+ e.preventDefault();
149
+ fn();
150
+ }
151
+ }
152
+
153
+ export { Matrix };
154
+ //# sourceMappingURL=matrix.js.map
155
+ //# sourceMappingURL=matrix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts","../src/artifacts/matrix/matrix.tsx"],"names":[],"mappings":"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","file":"matrix.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Adjacency-matrix diagram. Square grid where cell (row i, col j)\n * encodes the relationship from node i to node j by color intensity.\n * Pure SVG; no heavy peer dependency. Best for dense graphs where\n * node-link diagrams turn into \"hairballs\" — Matrix scales gracefully\n * to hundreds of nodes if the SVG is sized to match.\n *\n * @example\n * <Matrix\n * nodes={[\"A\", \"B\", \"C\", \"D\"].map((id) => ({ id, label: id }))}\n * matrix={[\n * [0, 5, 8, 1],\n * [3, 0, 2, 4],\n * [6, 0, 0, 7],\n * [2, 1, 9, 0],\n * ]}\n * />\n */\nexport type MatrixNode = {\n\tid: string;\n\tlabel: string;\n};\n\nexport interface MatrixProps extends Omit<React.SVGAttributes<SVGSVGElement>, \"children\"> {\n\t/** Nodes — rows AND columns. Order matches `matrix` rows/columns. */\n\tnodes: MatrixNode[];\n\t/** Square N×N matrix of values. matrix[i][j] = relationship from node i to node j. */\n\tmatrix: number[][];\n\t/** Pixel size of the rendered SVG (it's square). Default 480. */\n\tsize?: number;\n\t/** Pixel reserved for row/column labels along the edges. Default 80. */\n\tlabelMargin?: number;\n\t/** Show numeric values inside cells when the cell is large enough. Default true. */\n\tshowValues?: boolean;\n\t/** Fired when a cell is hovered (or hover ends, with `null`). */\n\tonCellHover?: (cell: { row: MatrixNode; col: MatrixNode; value: number } | null) => void;\n\t/** Fired when a cell is clicked. */\n\tonCellClick?: (cell: { row: MatrixNode; col: MatrixNode; value: number }) => void;\n}\n\ninterface LaidOutCell {\n\trow: MatrixNode;\n\tcol: MatrixNode;\n\trowIndex: number;\n\tcolIndex: number;\n\tvalue: number;\n\tx: number;\n\ty: number;\n\tintensity: number;\n}\n\n/** Below this px size, in-cell numeric labels become unreadable and are hidden. */\nconst MIN_CELL_SIZE_FOR_VALUE = 28;\n\nfunction Matrix({\n\tnodes,\n\tmatrix,\n\tsize = 480,\n\tlabelMargin = 80,\n\tshowValues = true,\n\tonCellHover,\n\tonCellClick,\n\tclassName,\n\t...rest\n}: MatrixProps) {\n\tconst cells = React.useMemo(() => layout(nodes, matrix, size, labelMargin), [nodes, matrix, size, labelMargin]);\n\tconst desc = `Matrix with ${nodes.length} node${nodes.length === 1 ? \"\" : \"s\"} (${nodes.length}×${nodes.length} cells)`;\n\tconst cellSize = nodes.length > 0 ? (size - labelMargin) / nodes.length : 0;\n\n\treturn (\n\t\t<svg\n\t\t\t{...rest}\n\t\t\tdata-hex-matrix\n\t\t\trole=\"img\"\n\t\t\twidth={size}\n\t\t\theight={size}\n\t\t\tviewBox={`0 0 ${size} ${size}`}\n\t\t\tclassName={cn(\"block\", className)}\n\t\t>\n\t\t\t<title>Adjacency matrix</title>\n\t\t\t<desc>{desc}</desc>\n\t\t\t<g data-hex-matrix-rows>\n\t\t\t\t{nodes.map((n, i) => (\n\t\t\t\t\t<text\n\t\t\t\t\t\tkey={`row-${n.id}`}\n\t\t\t\t\t\tx={labelMargin - 4}\n\t\t\t\t\t\ty={labelMargin + cellSize * i + cellSize / 2}\n\t\t\t\t\t\tdy=\"0.35em\"\n\t\t\t\t\t\ttextAnchor=\"end\"\n\t\t\t\t\t\tfontSize={10}\n\t\t\t\t\t\tfill=\"hsl(var(--foreground))\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{n.label}\n\t\t\t\t\t</text>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t\t<g data-hex-matrix-cols>\n\t\t\t\t{nodes.map((n, i) => (\n\t\t\t\t\t<text\n\t\t\t\t\t\tkey={`col-${n.id}`}\n\t\t\t\t\t\tx={labelMargin + cellSize * i + cellSize / 2}\n\t\t\t\t\t\ty={labelMargin - 4}\n\t\t\t\t\t\ttextAnchor=\"end\"\n\t\t\t\t\t\tfontSize={10}\n\t\t\t\t\t\tfill=\"hsl(var(--foreground))\"\n\t\t\t\t\t\ttransform={`rotate(-45 ${labelMargin + cellSize * i + cellSize / 2} ${labelMargin - 4})`}\n\t\t\t\t\t>\n\t\t\t\t\t\t{n.label}\n\t\t\t\t\t</text>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t\t<g data-hex-matrix-cells>\n\t\t\t\t{cells.map((c) => {\n\t\t\t\t\tconst interactive = Boolean(onCellHover || onCellClick);\n\t\t\t\t\tconst cellPayload = { row: c.row, col: c.col, value: c.value };\n\t\t\t\t\tconst fireHover = (cell: typeof cellPayload | null) => onCellHover?.(cell);\n\t\t\t\t\tconst handleActivate = () => onCellClick?.(cellPayload);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<g\n\t\t\t\t\t\t\tkey={`${c.rowIndex}-${c.colIndex}`}\n\t\t\t\t\t\t\tdata-hex-matrix-cell\n\t\t\t\t\t\t\tdata-row={c.rowIndex}\n\t\t\t\t\t\t\tdata-col={c.colIndex}\n\t\t\t\t\t\t\trole={interactive ? \"button\" : undefined}\n\t\t\t\t\t\t\ttabIndex={interactive ? 0 : undefined}\n\t\t\t\t\t\t\taria-label={interactive ? `${c.row.label} → ${c.col.label}: ${c.value}` : undefined}\n\t\t\t\t\t\t\tstyle={interactive ? { cursor: \"pointer\" } : undefined}\n\t\t\t\t\t\t\tonMouseEnter={onCellHover ? () => fireHover(cellPayload) : undefined}\n\t\t\t\t\t\t\tonMouseLeave={onCellHover ? () => fireHover(null) : undefined}\n\t\t\t\t\t\t\tonFocus={onCellHover ? () => fireHover(cellPayload) : undefined}\n\t\t\t\t\t\t\tonBlur={onCellHover ? () => fireHover(null) : undefined}\n\t\t\t\t\t\t\tonClick={onCellClick ? handleActivate : undefined}\n\t\t\t\t\t\t\tonKeyDown={onCellClick ? (e) => activateOnKey(e, handleActivate) : undefined}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\t\tx={c.x}\n\t\t\t\t\t\t\t\ty={c.y}\n\t\t\t\t\t\t\t\twidth={cellSize}\n\t\t\t\t\t\t\t\theight={cellSize}\n\t\t\t\t\t\t\t\t// Floor at 0.08 so empty cells are visible as grid lines;\n\t\t\t\t\t\t\t\t// ramp up to 0.95 for max-value cells. `--chart-1` carries\n\t\t\t\t\t\t\t\t// the hue, opacity carries the magnitude. Falls back to\n\t\t\t\t\t\t\t\t// `--primary` for consumers whose theme presets predate\n\t\t\t\t\t\t\t\t// the chart token family.\n\t\t\t\t\t\t\t\tfill=\"hsl(var(--chart-1, var(--primary)))\"\n\t\t\t\t\t\t\t\tfillOpacity={0.08 + 0.87 * c.intensity}\n\t\t\t\t\t\t\t\tstroke=\"hsl(var(--background))\"\n\t\t\t\t\t\t\t\tstrokeWidth={0.5}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{showValues && cellSize > MIN_CELL_SIZE_FOR_VALUE && c.value !== 0 ? (\n\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\tx={c.x + cellSize / 2}\n\t\t\t\t\t\t\t\t\ty={c.y + cellSize / 2}\n\t\t\t\t\t\t\t\t\tdy=\"0.35em\"\n\t\t\t\t\t\t\t\t\ttextAnchor=\"middle\"\n\t\t\t\t\t\t\t\t\tfontSize={9}\n\t\t\t\t\t\t\t\t\t// Above ~0.55 intensity the cell is dark enough that\n\t\t\t\t\t\t\t\t\t// background-tone foreground reads better.\n\t\t\t\t\t\t\t\t\tfill={c.intensity > 0.55 ? \"hsl(var(--background))\" : \"hsl(var(--foreground))\"}\n\t\t\t\t\t\t\t\t\tstyle={{ pointerEvents: \"none\" }}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{c.value}\n\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</g>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</g>\n\t\t</svg>\n\t);\n}\n\nfunction layout(\n\tnodes: MatrixNode[],\n\tmatrix: number[][],\n\tsize: number,\n\tlabelMargin: number,\n): LaidOutCell[] {\n\tif (nodes.length === 0) return [];\n\tconst cellSize = (size - labelMargin) / nodes.length;\n\tlet maxValue = 0;\n\tfor (const row of matrix) {\n\t\tfor (const v of row) if (v > maxValue) maxValue = v;\n\t}\n\tconst cells: LaidOutCell[] = [];\n\tfor (let i = 0; i < nodes.length; i++) {\n\t\tfor (let j = 0; j < nodes.length; j++) {\n\t\t\tconst value = matrix[i]?.[j] ?? 0;\n\t\t\tcells.push({\n\t\t\t\trow: nodes[i],\n\t\t\t\tcol: nodes[j],\n\t\t\t\trowIndex: i,\n\t\t\t\tcolIndex: j,\n\t\t\t\tvalue,\n\t\t\t\tx: labelMargin + cellSize * j,\n\t\t\t\ty: labelMargin + cellSize * i,\n\t\t\t\tintensity: maxValue > 0 ? value / maxValue : 0,\n\t\t\t});\n\t\t}\n\t}\n\treturn cells;\n}\n\nfunction activateOnKey(e: React.KeyboardEvent, fn: () => void): void {\n\tif (e.key === \"Enter\" || e.key === \" \") {\n\t\te.preventDefault();\n\t\tfn();\n\t}\n}\n\nexport { Matrix };\n"]}
@@ -0,0 +1,3 @@
1
+ export { MindMapNode_alias_1 as MindMapNode } from './_tsup-dts-rollup.js';
2
+ export { MindMapProps_alias_1 as MindMapProps } from './_tsup-dts-rollup.js';
3
+ export { MindMap_alias_1 as MindMap } from './_tsup-dts-rollup.js';
@@ -0,0 +1,167 @@
1
+ "use client";
2
+ import * as React from 'react';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ function cn(...inputs) {
8
+ return twMerge(clsx(inputs));
9
+ }
10
+ function MindMap({
11
+ root,
12
+ orientation = "radial",
13
+ width = 600,
14
+ height = 400,
15
+ onNodeClick,
16
+ className,
17
+ ...rest
18
+ }) {
19
+ const [d3h, setD3h] = React.useState(null);
20
+ React.useEffect(() => {
21
+ let cancelled = false;
22
+ void import('d3-hierarchy').then((mod) => {
23
+ if (!cancelled) setD3h(mod);
24
+ });
25
+ return () => {
26
+ cancelled = true;
27
+ };
28
+ }, []);
29
+ if (!d3h) {
30
+ return /* @__PURE__ */ jsx(
31
+ "div",
32
+ {
33
+ "data-hex-mind-map-loading": true,
34
+ "aria-busy": "true",
35
+ className: cn("inline-block bg-muted/20", className),
36
+ style: { width, height }
37
+ }
38
+ );
39
+ }
40
+ const { nodes, links, viewBox } = layout(d3h, root, orientation, width, height);
41
+ const nodeCount = nodes.length;
42
+ const desc = `Mind map with ${nodeCount} node${nodeCount === 1 ? "" : "s"}, rooted at "${root.label}"`;
43
+ return /* @__PURE__ */ jsxs(
44
+ "svg",
45
+ {
46
+ ...rest,
47
+ "data-hex-mind-map": true,
48
+ "data-orientation": orientation,
49
+ role: "img",
50
+ viewBox,
51
+ width,
52
+ height,
53
+ className: cn("block", className),
54
+ children: [
55
+ /* @__PURE__ */ jsx("title", { children: "Mind map" }),
56
+ /* @__PURE__ */ jsx("desc", { children: desc }),
57
+ /* @__PURE__ */ jsx("g", { "data-hex-mind-map-links": true, children: links.map((l) => /* @__PURE__ */ jsx(
58
+ "path",
59
+ {
60
+ d: linkPath(l, orientation),
61
+ fill: "none",
62
+ stroke: "hsl(var(--muted-foreground))",
63
+ strokeOpacity: 0.7,
64
+ strokeWidth: 1.5
65
+ },
66
+ l.id
67
+ )) }),
68
+ /* @__PURE__ */ jsx("g", { "data-hex-mind-map-nodes": true, children: nodes.map((n) => /* @__PURE__ */ jsxs(
69
+ "g",
70
+ {
71
+ "data-hex-mind-map-node": true,
72
+ "data-depth": n.depth,
73
+ transform: `translate(${n.x},${n.y})`,
74
+ style: onNodeClick ? { cursor: "pointer" } : void 0,
75
+ onClick: onNodeClick ? () => onNodeClick(n.node) : void 0,
76
+ children: [
77
+ /* @__PURE__ */ jsx(
78
+ "circle",
79
+ {
80
+ r: 4,
81
+ fill: "hsl(var(--primary))",
82
+ stroke: "hsl(var(--background))",
83
+ strokeWidth: 2
84
+ }
85
+ ),
86
+ /* @__PURE__ */ jsx(
87
+ "text",
88
+ {
89
+ x: 8,
90
+ y: 4,
91
+ fontSize: 12,
92
+ fill: "hsl(var(--foreground))",
93
+ style: { paintOrder: "stroke" },
94
+ stroke: "hsl(var(--background))",
95
+ strokeWidth: 3,
96
+ strokeLinejoin: "round",
97
+ children: n.node.label
98
+ }
99
+ )
100
+ ]
101
+ },
102
+ n.node.id
103
+ )) })
104
+ ]
105
+ }
106
+ );
107
+ }
108
+ function layout(d3h, root, orientation, width, height) {
109
+ const hierarchy = d3h.hierarchy(root);
110
+ if (orientation === "radial") {
111
+ const radius = Math.min(width, height) / 2 - 16;
112
+ const layoutRoot2 = d3h.tree().size([2 * Math.PI, radius])(hierarchy);
113
+ const nodes2 = [];
114
+ const links2 = [];
115
+ layoutRoot2.each((d) => {
116
+ const point = polarToCartesian(d.x, d.y);
117
+ nodes2.push({ node: d.data, x: point.x, y: point.y, depth: d.depth });
118
+ });
119
+ layoutRoot2.links().forEach((link, i) => {
120
+ const sPt = polarToCartesian(link.source.x, link.source.y);
121
+ const tPt = polarToCartesian(link.target.x, link.target.y);
122
+ links2.push({ source: sPt, target: tPt, id: `l-${i}` });
123
+ });
124
+ const half = Math.min(width, height) / 2;
125
+ return {
126
+ nodes: nodes2,
127
+ links: links2,
128
+ viewBox: `${-half} ${-half} ${2 * half} ${2 * half}`
129
+ };
130
+ }
131
+ const layoutRoot = d3h.tree().size([height - 32, width - 200])(hierarchy);
132
+ const nodes = [];
133
+ const links = [];
134
+ layoutRoot.each((d) => {
135
+ nodes.push({ node: d.data, x: d.y, y: d.x, depth: d.depth });
136
+ });
137
+ layoutRoot.links().forEach((link, i) => {
138
+ links.push({
139
+ source: { x: link.source.y, y: link.source.x },
140
+ target: { x: link.target.y, y: link.target.x },
141
+ id: `l-${i}`
142
+ });
143
+ });
144
+ return {
145
+ nodes,
146
+ links,
147
+ viewBox: `0 0 ${width} ${height}`
148
+ };
149
+ }
150
+ function polarToCartesian(angle, radius) {
151
+ return {
152
+ x: radius * Math.cos(angle - Math.PI / 2),
153
+ y: radius * Math.sin(angle - Math.PI / 2)
154
+ };
155
+ }
156
+ function linkPath(link, orientation) {
157
+ const { source: s, target: t } = link;
158
+ if (orientation === "horizontal") {
159
+ const mx = (s.x + t.x) / 2;
160
+ return `M${s.x},${s.y} C${mx},${s.y} ${mx},${t.y} ${t.x},${t.y}`;
161
+ }
162
+ return `M${s.x},${s.y} C${s.x},${(s.y + t.y) / 2} ${t.x},${(s.y + t.y) / 2} ${t.x},${t.y}`;
163
+ }
164
+
165
+ export { MindMap };
166
+ //# sourceMappingURL=mind-map.js.map
167
+ //# sourceMappingURL=mind-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts","../src/artifacts/mind-map/mind-map.tsx"],"names":["layoutRoot","nodes","links"],"mappings":"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","file":"mind-map.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Typed React MindMap. Pass a hierarchical `root` node and the component lays\n * the children out radially (or horizontally) using d3-hierarchy's tree\n * layout. No Mermaid string parsing — the data shape IS the API, so consumers\n * can build mind maps from typed application state instead of templating a\n * DSL.\n *\n * Heavy peer: requires `d3-hierarchy` (~3 KB gzip). The hex-core CLI's `add`\n * flow prompts before installing.\n *\n * @example\n * <MindMap\n * root={{\n * id: \"root\",\n * label: \"Project\",\n * children: [\n * { id: \"ui\", label: \"UI\", children: [{ id: \"btn\", label: \"Button\" }] },\n * { id: \"api\", label: \"API\" },\n * ],\n * }}\n * />\n */\nexport type MindMapNode = {\n\tid: string;\n\tlabel: string;\n\tchildren?: MindMapNode[];\n\tdata?: unknown;\n};\n\nexport interface MindMapProps extends Omit<React.SVGAttributes<SVGSVGElement>, \"children\"> {\n\t/** Root of the hierarchy. */\n\troot: MindMapNode;\n\t/** \"radial\" lays children around the root; \"horizontal\" runs left→right. Default \"radial\". */\n\torientation?: \"radial\" | \"horizontal\";\n\t/** Pixel width of the rendered SVG. Default 600. */\n\twidth?: number;\n\t/** Pixel height of the rendered SVG. Default 400. */\n\theight?: number;\n\t/** Fired when a node is clicked. */\n\tonNodeClick?: (node: MindMapNode) => void;\n}\n\ninterface LaidOutNode {\n\tnode: MindMapNode;\n\tx: number;\n\ty: number;\n\tdepth: number;\n}\n\ninterface LaidOutLink {\n\tsource: { x: number; y: number };\n\ttarget: { x: number; y: number };\n\tid: string;\n}\n\ntype D3HierarchyMod = typeof import(\"d3-hierarchy\");\n\nfunction MindMap({\n\troot,\n\torientation = \"radial\",\n\twidth = 600,\n\theight = 400,\n\tonNodeClick,\n\tclassName,\n\t...rest\n}: MindMapProps) {\n\tconst [d3h, setD3h] = React.useState<D3HierarchyMod | null>(null);\n\n\tReact.useEffect(() => {\n\t\tlet cancelled = false;\n\t\tvoid import(\"d3-hierarchy\").then((mod) => {\n\t\t\tif (!cancelled) setD3h(mod);\n\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, []);\n\n\tif (!d3h) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tdata-hex-mind-map-loading\n\t\t\t\taria-busy=\"true\"\n\t\t\t\tclassName={cn(\"inline-block bg-muted/20\", className)}\n\t\t\t\tstyle={{ width, height }}\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst { nodes, links, viewBox } = layout(d3h, root, orientation, width, height);\n\tconst nodeCount = nodes.length;\n\tconst desc = `Mind map with ${nodeCount} node${nodeCount === 1 ? \"\" : \"s\"}, rooted at \"${root.label}\"`;\n\n\treturn (\n\t\t<svg\n\t\t\t{...rest}\n\t\t\tdata-hex-mind-map\n\t\t\tdata-orientation={orientation}\n\t\t\trole=\"img\"\n\t\t\tviewBox={viewBox}\n\t\t\twidth={width}\n\t\t\theight={height}\n\t\t\tclassName={cn(\"block\", className)}\n\t\t>\n\t\t\t<title>Mind map</title>\n\t\t\t<desc>{desc}</desc>\n\t\t\t<g data-hex-mind-map-links>\n\t\t\t\t{links.map((l) => (\n\t\t\t\t\t<path\n\t\t\t\t\t\tkey={l.id}\n\t\t\t\t\t\td={linkPath(l, orientation)}\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"hsl(var(--muted-foreground))\"\n\t\t\t\t\t\tstrokeOpacity={0.7}\n\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t\t<g data-hex-mind-map-nodes>\n\t\t\t\t{nodes.map((n) => (\n\t\t\t\t\t<g\n\t\t\t\t\t\tkey={n.node.id}\n\t\t\t\t\t\tdata-hex-mind-map-node\n\t\t\t\t\t\tdata-depth={n.depth}\n\t\t\t\t\t\ttransform={`translate(${n.x},${n.y})`}\n\t\t\t\t\t\tstyle={onNodeClick ? { cursor: \"pointer\" } : undefined}\n\t\t\t\t\t\tonClick={onNodeClick ? () => onNodeClick(n.node) : undefined}\n\t\t\t\t\t>\n\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\tr={4}\n\t\t\t\t\t\t\tfill=\"hsl(var(--primary))\"\n\t\t\t\t\t\t\tstroke=\"hsl(var(--background))\"\n\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<text\n\t\t\t\t\t\t\tx={8}\n\t\t\t\t\t\t\ty={4}\n\t\t\t\t\t\t\tfontSize={12}\n\t\t\t\t\t\t\tfill=\"hsl(var(--foreground))\"\n\t\t\t\t\t\t\tstyle={{ paintOrder: \"stroke\" }}\n\t\t\t\t\t\t\tstroke=\"hsl(var(--background))\"\n\t\t\t\t\t\t\tstrokeWidth={3}\n\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{n.node.label}\n\t\t\t\t\t\t</text>\n\t\t\t\t\t</g>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t</svg>\n\t);\n}\n\nfunction layout(\n\td3h: D3HierarchyMod,\n\troot: MindMapNode,\n\torientation: \"radial\" | \"horizontal\",\n\twidth: number,\n\theight: number,\n): { nodes: LaidOutNode[]; links: LaidOutLink[]; viewBox: string } {\n\tconst hierarchy = d3h.hierarchy<MindMapNode>(root);\n\n\tif (orientation === \"radial\") {\n\t\tconst radius = Math.min(width, height) / 2 - 16;\n\t\t// d3.tree(hierarchy) returns the layout-mutated root typed as\n\t\t// HierarchyPointNode<T> — its `x`/`y` are populated by the call.\n\t\tconst layoutRoot = d3h.tree<MindMapNode>().size([2 * Math.PI, radius])(hierarchy);\n\t\tconst nodes: LaidOutNode[] = [];\n\t\tconst links: LaidOutLink[] = [];\n\t\tlayoutRoot.each((d) => {\n\t\t\tconst point = polarToCartesian(d.x, d.y);\n\t\t\tnodes.push({ node: d.data, x: point.x, y: point.y, depth: d.depth });\n\t\t});\n\t\tlayoutRoot.links().forEach((link, i) => {\n\t\t\tconst sPt = polarToCartesian(link.source.x, link.source.y);\n\t\t\tconst tPt = polarToCartesian(link.target.x, link.target.y);\n\t\t\tlinks.push({ source: sPt, target: tPt, id: `l-${i}` });\n\t\t});\n\t\tconst half = Math.min(width, height) / 2;\n\t\treturn {\n\t\t\tnodes,\n\t\t\tlinks,\n\t\t\tviewBox: `${-half} ${-half} ${2 * half} ${2 * half}`,\n\t\t};\n\t}\n\n\tconst layoutRoot = d3h.tree<MindMapNode>().size([height - 32, width - 200])(hierarchy);\n\tconst nodes: LaidOutNode[] = [];\n\tconst links: LaidOutLink[] = [];\n\tlayoutRoot.each((d) => {\n\t\t// Horizontal: swap d3's (x, y) so depth runs along the SVG x-axis.\n\t\tnodes.push({ node: d.data, x: d.y, y: d.x, depth: d.depth });\n\t});\n\tlayoutRoot.links().forEach((link, i) => {\n\t\tlinks.push({\n\t\t\tsource: { x: link.source.y, y: link.source.x },\n\t\t\ttarget: { x: link.target.y, y: link.target.x },\n\t\t\tid: `l-${i}`,\n\t\t});\n\t});\n\treturn {\n\t\tnodes,\n\t\tlinks,\n\t\tviewBox: `0 0 ${width} ${height}`,\n\t};\n}\n\nfunction polarToCartesian(angle: number, radius: number): { x: number; y: number } {\n\treturn {\n\t\tx: radius * Math.cos(angle - Math.PI / 2),\n\t\ty: radius * Math.sin(angle - Math.PI / 2),\n\t};\n}\n\nfunction linkPath(link: LaidOutLink, orientation: \"radial\" | \"horizontal\"): string {\n\tconst { source: s, target: t } = link;\n\tif (orientation === \"horizontal\") {\n\t\tconst mx = (s.x + t.x) / 2;\n\t\treturn `M${s.x},${s.y} C${mx},${s.y} ${mx},${t.y} ${t.x},${t.y}`;\n\t}\n\treturn `M${s.x},${s.y} C${s.x},${(s.y + t.y) / 2} ${t.x},${(s.y + t.y) / 2} ${t.x},${t.y}`;\n}\n\nexport { MindMap };\n"]}
@@ -0,0 +1,3 @@
1
+ export { OrgNode_alias_1 as OrgNode } from './_tsup-dts-rollup.js';
2
+ export { OrgChartProps_alias_1 as OrgChartProps } from './_tsup-dts-rollup.js';
3
+ export { OrgChart_alias_1 as OrgChart } from './_tsup-dts-rollup.js';
@@ -0,0 +1,215 @@
1
+ "use client";
2
+ import * as React from 'react';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ function cn(...inputs) {
8
+ return twMerge(clsx(inputs));
9
+ }
10
+ function OrgChart({
11
+ root,
12
+ collapsible = true,
13
+ defaultExpandedDepth = Number.POSITIVE_INFINITY,
14
+ nodeWidth = 180,
15
+ nodeHeight = 64,
16
+ width = 800,
17
+ height = 480,
18
+ onNodeClick,
19
+ className,
20
+ ...rest
21
+ }) {
22
+ const [d3h, setD3h] = React.useState(null);
23
+ const [collapsed, setCollapsed] = React.useState(() => seedCollapsed(root, defaultExpandedDepth));
24
+ React.useEffect(() => {
25
+ let cancelled = false;
26
+ void import('d3-hierarchy').then((mod) => {
27
+ if (!cancelled) setD3h(mod);
28
+ });
29
+ return () => {
30
+ cancelled = true;
31
+ };
32
+ }, []);
33
+ React.useEffect(() => {
34
+ setCollapsed(seedCollapsed(root, defaultExpandedDepth));
35
+ }, [root, defaultExpandedDepth]);
36
+ if (!d3h) {
37
+ return /* @__PURE__ */ jsx(
38
+ "div",
39
+ {
40
+ "data-hex-org-chart-loading": true,
41
+ "aria-busy": "true",
42
+ className: cn("inline-block bg-muted/20", className),
43
+ style: { width, height }
44
+ }
45
+ );
46
+ }
47
+ const { nodes, links } = layout(d3h, root, collapsed, width, height, nodeHeight);
48
+ const desc = `Organizational chart with ${nodes.length} visible node${nodes.length === 1 ? "" : "s"}, rooted at "${root.label}"`;
49
+ const handleClick = (node) => {
50
+ onNodeClick?.(node);
51
+ if (!collapsible) return;
52
+ const hasChildren = node.children && node.children.length > 0;
53
+ if (!hasChildren) return;
54
+ setCollapsed((prev) => {
55
+ const next = new Set(prev);
56
+ if (next.has(node.id)) next.delete(node.id);
57
+ else next.add(node.id);
58
+ return next;
59
+ });
60
+ };
61
+ return /* @__PURE__ */ jsxs(
62
+ "svg",
63
+ {
64
+ ...rest,
65
+ "data-hex-org-chart": true,
66
+ role: "img",
67
+ width,
68
+ height,
69
+ viewBox: `0 0 ${width} ${height}`,
70
+ className: cn("block", className),
71
+ children: [
72
+ /* @__PURE__ */ jsx("title", { children: "Org chart" }),
73
+ /* @__PURE__ */ jsx("desc", { children: desc }),
74
+ /* @__PURE__ */ jsx("g", { "data-hex-org-chart-links": true, children: links.map((l) => /* @__PURE__ */ jsx(
75
+ "path",
76
+ {
77
+ d: `M${l.source.x},${l.source.y} C${l.source.x},${(l.source.y + l.target.y) / 2} ${l.target.x},${(l.source.y + l.target.y) / 2} ${l.target.x},${l.target.y}`,
78
+ fill: "none",
79
+ stroke: "hsl(var(--muted-foreground))",
80
+ strokeOpacity: 0.5,
81
+ strokeWidth: 1
82
+ },
83
+ l.id
84
+ )) }),
85
+ /* @__PURE__ */ jsx("g", { "data-hex-org-chart-nodes": true, children: nodes.map((n) => /* @__PURE__ */ jsxs(
86
+ "g",
87
+ {
88
+ "data-hex-org-chart-node": true,
89
+ "data-depth": n.depth,
90
+ transform: `translate(${n.x - nodeWidth / 2},${n.y - nodeHeight / 2})`,
91
+ style: collapsible || onNodeClick ? { cursor: "pointer" } : void 0,
92
+ onClick: collapsible || onNodeClick ? () => handleClick(n.node) : void 0,
93
+ children: [
94
+ /* @__PURE__ */ jsx(
95
+ "rect",
96
+ {
97
+ width: nodeWidth,
98
+ height: nodeHeight,
99
+ rx: 8,
100
+ ry: 8,
101
+ fill: "hsl(var(--card))",
102
+ stroke: "hsl(var(--border))",
103
+ strokeWidth: 1
104
+ }
105
+ ),
106
+ /* @__PURE__ */ jsx(
107
+ "text",
108
+ {
109
+ x: 12,
110
+ y: 24,
111
+ fontSize: 13,
112
+ fontWeight: 600,
113
+ fill: "hsl(var(--foreground))",
114
+ children: truncate(n.node.label, Math.floor((nodeWidth - 24) / 7))
115
+ }
116
+ ),
117
+ n.node.subtitle ? /* @__PURE__ */ jsx(
118
+ "text",
119
+ {
120
+ x: 12,
121
+ y: 42,
122
+ fontSize: 11,
123
+ fill: "hsl(var(--muted-foreground))",
124
+ children: truncate(n.node.subtitle, Math.floor((nodeWidth - 24) / 6))
125
+ }
126
+ ) : null,
127
+ n.collapsedCount > 0 ? /* @__PURE__ */ jsxs("g", { transform: `translate(${nodeWidth - 28},${nodeHeight - 18})`, children: [
128
+ /* @__PURE__ */ jsx(
129
+ "rect",
130
+ {
131
+ width: 20,
132
+ height: 14,
133
+ rx: 7,
134
+ ry: 7,
135
+ fill: "hsl(var(--primary))",
136
+ opacity: 0.85
137
+ }
138
+ ),
139
+ /* @__PURE__ */ jsx(
140
+ "text",
141
+ {
142
+ x: 10,
143
+ y: 10,
144
+ fontSize: 9,
145
+ fontWeight: 600,
146
+ fill: "hsl(var(--primary-foreground))",
147
+ textAnchor: "middle",
148
+ children: `+${n.collapsedCount}`
149
+ }
150
+ )
151
+ ] }) : null
152
+ ]
153
+ },
154
+ n.node.id
155
+ )) })
156
+ ]
157
+ }
158
+ );
159
+ }
160
+ function seedCollapsed(root, maxDepth) {
161
+ if (!Number.isFinite(maxDepth)) return /* @__PURE__ */ new Set();
162
+ const collapsed = /* @__PURE__ */ new Set();
163
+ const walk = (n, depth) => {
164
+ if (depth >= maxDepth && n.children && n.children.length > 0) {
165
+ collapsed.add(n.id);
166
+ return;
167
+ }
168
+ n.children?.forEach((c) => walk(c, depth + 1));
169
+ };
170
+ walk(root, 0);
171
+ return collapsed;
172
+ }
173
+ function layout(d3h, root, collapsed, width, height, nodeHeight) {
174
+ const indexById = /* @__PURE__ */ new Map();
175
+ indexNodes(root, indexById);
176
+ const visible = pruneCollapsed(root, collapsed);
177
+ const hierarchy = d3h.hierarchy(visible);
178
+ const layoutRoot = d3h.tree().size([width - 32, height - nodeHeight])(hierarchy);
179
+ const nodes = [];
180
+ layoutRoot.each((d) => {
181
+ const original = indexById.get(d.data.id);
182
+ const collapsedCount = collapsed.has(d.data.id) && original ? countDescendants(original) : 0;
183
+ nodes.push({ node: d.data, x: d.x + 16, y: d.y + nodeHeight / 2, depth: d.depth, collapsedCount });
184
+ });
185
+ const links = layoutRoot.links().map((link, i) => ({
186
+ source: { x: link.source.x + 16, y: link.source.y + nodeHeight / 2 },
187
+ target: { x: link.target.x + 16, y: link.target.y + nodeHeight / 2 },
188
+ id: `l-${i}`
189
+ }));
190
+ return { nodes, links };
191
+ }
192
+ function pruneCollapsed(node, collapsed) {
193
+ if (collapsed.has(node.id)) {
194
+ return { ...node, children: void 0 };
195
+ }
196
+ if (!node.children || node.children.length === 0) return node;
197
+ return { ...node, children: node.children.map((c) => pruneCollapsed(c, collapsed)) };
198
+ }
199
+ function indexNodes(node, out) {
200
+ out.set(node.id, node);
201
+ if (!node.children) return;
202
+ for (const c of node.children) indexNodes(c, out);
203
+ }
204
+ function countDescendants(node) {
205
+ if (!node.children || node.children.length === 0) return 0;
206
+ return node.children.reduce((sum, c) => sum + 1 + countDescendants(c), 0);
207
+ }
208
+ function truncate(s, max) {
209
+ if (s.length <= max) return s;
210
+ return `${s.slice(0, Math.max(1, max - 1))}\u2026`;
211
+ }
212
+
213
+ export { OrgChart };
214
+ //# sourceMappingURL=org-chart.js.map
215
+ //# sourceMappingURL=org-chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts","../src/artifacts/org-chart/org-chart.tsx"],"names":[],"mappings":"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","file":"org-chart.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Top-down organizational chart. Pass a hierarchy of people / teams / units\n * and the component lays them out vertically using d3-hierarchy's tree\n * layout. Nodes can be collapsed by clicking; collapsed branches contribute\n * a \"+N\" badge but no further layout.\n *\n * Heavy peer: requires `d3-hierarchy` (~3 KB gzip).\n *\n * @example\n * <OrgChart\n * root={{\n * id: \"ceo\",\n * label: \"Jane Doe\",\n * subtitle: \"CEO\",\n * children: [\n * { id: \"cto\", label: \"Bob Smith\", subtitle: \"CTO\" },\n * ],\n * }}\n * />\n */\nexport type OrgNode = {\n\tid: string;\n\tlabel: string;\n\tsubtitle?: string;\n\tavatarUrl?: string;\n\tchildren?: OrgNode[];\n};\n\nexport interface OrgChartProps extends Omit<React.SVGAttributes<SVGSVGElement>, \"children\"> {\n\t/** Root of the org hierarchy. */\n\troot: OrgNode;\n\t/** Allow nodes to be clicked to collapse their subtree. Default true. */\n\tcollapsible?: boolean;\n\t/** All nodes deeper than this depth render collapsed by default. Default Infinity (all expanded). */\n\tdefaultExpandedDepth?: number;\n\t/** Pixel width of each node card. Default 180. */\n\tnodeWidth?: number;\n\t/** Pixel height of each node card. Default 64. */\n\tnodeHeight?: number;\n\t/** Pixel width of the rendered SVG. Default 800. */\n\twidth?: number;\n\t/** Pixel height of the rendered SVG. Default 480. */\n\theight?: number;\n\t/** Fired when a node is clicked. Fires before any internal collapse toggle. */\n\tonNodeClick?: (node: OrgNode) => void;\n}\n\ninterface LaidOut {\n\tnode: OrgNode;\n\tx: number;\n\ty: number;\n\tdepth: number;\n\tcollapsedCount: number;\n}\n\ninterface LaidOutLink {\n\tsource: { x: number; y: number };\n\ttarget: { x: number; y: number };\n\tid: string;\n}\n\ntype D3HierarchyMod = typeof import(\"d3-hierarchy\");\n\nfunction OrgChart({\n\troot,\n\tcollapsible = true,\n\tdefaultExpandedDepth = Number.POSITIVE_INFINITY,\n\tnodeWidth = 180,\n\tnodeHeight = 64,\n\twidth = 800,\n\theight = 480,\n\tonNodeClick,\n\tclassName,\n\t...rest\n}: OrgChartProps) {\n\tconst [d3h, setD3h] = React.useState<D3HierarchyMod | null>(null);\n\tconst [collapsed, setCollapsed] = React.useState<Set<string>>(() => seedCollapsed(root, defaultExpandedDepth));\n\n\tReact.useEffect(() => {\n\t\tlet cancelled = false;\n\t\tvoid import(\"d3-hierarchy\").then((mod) => {\n\t\t\tif (!cancelled) setD3h(mod);\n\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, []);\n\n\t// Reset collapsed state when the root reference changes — otherwise stale\n\t// ids accumulate across data swaps (memory leak + phantom collapses if ids\n\t// happen to be reused). Mirrors Sunburst's focusId reset.\n\tReact.useEffect(() => {\n\t\tsetCollapsed(seedCollapsed(root, defaultExpandedDepth));\n\t}, [root, defaultExpandedDepth]);\n\n\tif (!d3h) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tdata-hex-org-chart-loading\n\t\t\t\taria-busy=\"true\"\n\t\t\t\tclassName={cn(\"inline-block bg-muted/20\", className)}\n\t\t\t\tstyle={{ width, height }}\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst { nodes, links } = layout(d3h, root, collapsed, width, height, nodeHeight);\n\tconst desc = `Organizational chart with ${nodes.length} visible node${nodes.length === 1 ? \"\" : \"s\"}, rooted at \"${root.label}\"`;\n\n\tconst handleClick = (node: OrgNode) => {\n\t\tonNodeClick?.(node);\n\t\tif (!collapsible) return;\n\t\tconst hasChildren = node.children && node.children.length > 0;\n\t\tif (!hasChildren) return;\n\t\tsetCollapsed((prev) => {\n\t\t\tconst next = new Set(prev);\n\t\t\tif (next.has(node.id)) next.delete(node.id);\n\t\t\telse next.add(node.id);\n\t\t\treturn next;\n\t\t});\n\t};\n\n\treturn (\n\t\t<svg\n\t\t\t{...rest}\n\t\t\tdata-hex-org-chart\n\t\t\trole=\"img\"\n\t\t\twidth={width}\n\t\t\theight={height}\n\t\t\tviewBox={`0 0 ${width} ${height}`}\n\t\t\tclassName={cn(\"block\", className)}\n\t\t>\n\t\t\t<title>Org chart</title>\n\t\t\t<desc>{desc}</desc>\n\t\t\t<g data-hex-org-chart-links>\n\t\t\t\t{links.map((l) => (\n\t\t\t\t\t<path\n\t\t\t\t\t\tkey={l.id}\n\t\t\t\t\t\td={`M${l.source.x},${l.source.y} C${l.source.x},${(l.source.y + l.target.y) / 2} ${l.target.x},${(l.source.y + l.target.y) / 2} ${l.target.x},${l.target.y}`}\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"hsl(var(--muted-foreground))\"\n\t\t\t\t\t\tstrokeOpacity={0.5}\n\t\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t\t<g data-hex-org-chart-nodes>\n\t\t\t\t{nodes.map((n) => (\n\t\t\t\t\t<g\n\t\t\t\t\t\tkey={n.node.id}\n\t\t\t\t\t\tdata-hex-org-chart-node\n\t\t\t\t\t\tdata-depth={n.depth}\n\t\t\t\t\t\ttransform={`translate(${n.x - nodeWidth / 2},${n.y - nodeHeight / 2})`}\n\t\t\t\t\t\tstyle={collapsible || onNodeClick ? { cursor: \"pointer\" } : undefined}\n\t\t\t\t\t\tonClick={collapsible || onNodeClick ? () => handleClick(n.node) : undefined}\n\t\t\t\t\t>\n\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\twidth={nodeWidth}\n\t\t\t\t\t\t\theight={nodeHeight}\n\t\t\t\t\t\t\trx={8}\n\t\t\t\t\t\t\try={8}\n\t\t\t\t\t\t\tfill=\"hsl(var(--card))\"\n\t\t\t\t\t\t\tstroke=\"hsl(var(--border))\"\n\t\t\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<text\n\t\t\t\t\t\t\tx={12}\n\t\t\t\t\t\t\ty={24}\n\t\t\t\t\t\t\tfontSize={13}\n\t\t\t\t\t\t\tfontWeight={600}\n\t\t\t\t\t\t\tfill=\"hsl(var(--foreground))\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{truncate(n.node.label, Math.floor((nodeWidth - 24) / 7))}\n\t\t\t\t\t\t</text>\n\t\t\t\t\t\t{n.node.subtitle ? (\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\tx={12}\n\t\t\t\t\t\t\t\ty={42}\n\t\t\t\t\t\t\t\tfontSize={11}\n\t\t\t\t\t\t\t\tfill=\"hsl(var(--muted-foreground))\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{truncate(n.node.subtitle, Math.floor((nodeWidth - 24) / 6))}\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{n.collapsedCount > 0 ? (\n\t\t\t\t\t\t\t<g transform={`translate(${nodeWidth - 28},${nodeHeight - 18})`}>\n\t\t\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\trx={7}\n\t\t\t\t\t\t\t\t\try={7}\n\t\t\t\t\t\t\t\t\tfill=\"hsl(var(--primary))\"\n\t\t\t\t\t\t\t\t\topacity={0.85}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\tx={10}\n\t\t\t\t\t\t\t\t\ty={10}\n\t\t\t\t\t\t\t\t\tfontSize={9}\n\t\t\t\t\t\t\t\t\tfontWeight={600}\n\t\t\t\t\t\t\t\t\tfill=\"hsl(var(--primary-foreground))\"\n\t\t\t\t\t\t\t\t\ttextAnchor=\"middle\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{`+${n.collapsedCount}`}\n\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</g>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t</svg>\n\t);\n}\n\nfunction seedCollapsed(root: OrgNode, maxDepth: number): Set<string> {\n\tif (!Number.isFinite(maxDepth)) return new Set();\n\tconst collapsed = new Set<string>();\n\tconst walk = (n: OrgNode, depth: number) => {\n\t\tif (depth >= maxDepth && n.children && n.children.length > 0) {\n\t\t\tcollapsed.add(n.id);\n\t\t\treturn;\n\t\t}\n\t\tn.children?.forEach((c) => walk(c, depth + 1));\n\t};\n\twalk(root, 0);\n\treturn collapsed;\n}\n\nfunction layout(\n\td3h: D3HierarchyMod,\n\troot: OrgNode,\n\tcollapsed: Set<string>,\n\twidth: number,\n\theight: number,\n\tnodeHeight: number,\n): { nodes: LaidOut[]; links: LaidOutLink[] } {\n\t// Pre-build an id → original-node map so collapsed-count lookup is O(1) per\n\t// node (vs O(N) DFS), keeping the whole layout pass O(N) for trees up to a\n\t// few thousand nodes.\n\tconst indexById = new Map<string, OrgNode>();\n\tindexNodes(root, indexById);\n\n\tconst visible = pruneCollapsed(root, collapsed);\n\tconst hierarchy = d3h.hierarchy<OrgNode>(visible);\n\tconst layoutRoot = d3h.tree<OrgNode>().size([width - 32, height - nodeHeight])(hierarchy);\n\tconst nodes: LaidOut[] = [];\n\tlayoutRoot.each((d) => {\n\t\tconst original = indexById.get(d.data.id);\n\t\tconst collapsedCount = collapsed.has(d.data.id) && original ? countDescendants(original) : 0;\n\t\tnodes.push({ node: d.data, x: d.x + 16, y: d.y + nodeHeight / 2, depth: d.depth, collapsedCount });\n\t});\n\tconst links: LaidOutLink[] = layoutRoot.links().map((link, i) => ({\n\t\tsource: { x: link.source.x + 16, y: link.source.y + nodeHeight / 2 },\n\t\ttarget: { x: link.target.x + 16, y: link.target.y + nodeHeight / 2 },\n\t\tid: `l-${i}`,\n\t}));\n\treturn { nodes, links };\n}\n\nfunction pruneCollapsed(node: OrgNode, collapsed: Set<string>): OrgNode {\n\tif (collapsed.has(node.id)) {\n\t\treturn { ...node, children: undefined };\n\t}\n\tif (!node.children || node.children.length === 0) return node;\n\treturn { ...node, children: node.children.map((c) => pruneCollapsed(c, collapsed)) };\n}\n\nfunction indexNodes(node: OrgNode, out: Map<string, OrgNode>): void {\n\tout.set(node.id, node);\n\tif (!node.children) return;\n\tfor (const c of node.children) indexNodes(c, out);\n}\n\nfunction countDescendants(node: OrgNode): number {\n\tif (!node.children || node.children.length === 0) return 0;\n\treturn node.children.reduce((sum, c) => sum + 1 + countDescendants(c), 0);\n}\n\nfunction truncate(s: string, max: number): string {\n\tif (s.length <= max) return s;\n\treturn `${s.slice(0, Math.max(1, max - 1))}…`;\n}\n\nexport { OrgChart };\n"]}
@@ -0,0 +1,3 @@
1
+ export { PyramidTier_alias_1 as PyramidTier } from './_tsup-dts-rollup.js';
2
+ export { PyramidProps_alias_1 as PyramidProps } from './_tsup-dts-rollup.js';
3
+ export { Pyramid_alias_1 as Pyramid } from './_tsup-dts-rollup.js';