@ii_elif_ii/ui-node-tree 1.0.1 → 1.0.4
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.
- package/dist/index.cjs +32 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +10 -10
- package/dist/index.css.map +1 -1
- package/dist/index.js +32 -8
- package/dist/index.js.map +1 -1
- package/dist/node-tree.css +10 -10
- package/dist/node-tree.css.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -60,6 +60,9 @@ function TreeConnections({
|
|
|
60
60
|
"svg",
|
|
61
61
|
{
|
|
62
62
|
className: cn("unt-tree-connections", className),
|
|
63
|
+
"aria-hidden": "true",
|
|
64
|
+
focusable: "false",
|
|
65
|
+
role: "presentation",
|
|
63
66
|
width: layoutState.svgBounds.width,
|
|
64
67
|
height: layoutState.svgBounds.height,
|
|
65
68
|
viewBox: `0 0 ${layoutState.svgBounds.width} ${layoutState.svgBounds.height}`,
|
|
@@ -85,7 +88,7 @@ function TreeConnections({
|
|
|
85
88
|
y1: segment.y1 - layoutState.svgBounds.offsetY,
|
|
86
89
|
x2: segment.x2 - layoutState.svgBounds.offsetX,
|
|
87
90
|
y2: segment.y2 - layoutState.svgBounds.offsetY,
|
|
88
|
-
className: "node-line",
|
|
91
|
+
className: "unt-node-line",
|
|
89
92
|
style: {
|
|
90
93
|
strokeDasharray: segment.length,
|
|
91
94
|
strokeDashoffset: segment.length,
|
|
@@ -123,7 +126,13 @@ function axisToFlexJustify(axis) {
|
|
|
123
126
|
}
|
|
124
127
|
return "center";
|
|
125
128
|
}
|
|
126
|
-
function NodeFrame({
|
|
129
|
+
function NodeFrame({
|
|
130
|
+
node,
|
|
131
|
+
className,
|
|
132
|
+
onRef,
|
|
133
|
+
children,
|
|
134
|
+
...props
|
|
135
|
+
}) {
|
|
127
136
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
128
137
|
"div",
|
|
129
138
|
{
|
|
@@ -143,6 +152,7 @@ function renderTreeNode({
|
|
|
143
152
|
index,
|
|
144
153
|
parentId,
|
|
145
154
|
depth,
|
|
155
|
+
siblingCount,
|
|
146
156
|
path,
|
|
147
157
|
flowDown,
|
|
148
158
|
alignX,
|
|
@@ -161,29 +171,34 @@ function renderTreeNode({
|
|
|
161
171
|
}
|
|
162
172
|
path.add(node.id);
|
|
163
173
|
const childrenLayoutIsStack = node.children?.layout === "stack" || !flowDown;
|
|
174
|
+
const childNodes = node.children?.nodes ?? [];
|
|
164
175
|
const childCount = node.children?.nodes.length ?? 0;
|
|
165
176
|
const isLeaf = childCount === 0;
|
|
166
177
|
const pathIds = [...path];
|
|
167
|
-
const childrenContent =
|
|
178
|
+
const childrenContent = childNodes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
168
179
|
"div",
|
|
169
180
|
{
|
|
181
|
+
role: "group",
|
|
170
182
|
className: "unt-tree-children",
|
|
171
183
|
style: {
|
|
172
184
|
display: "flex",
|
|
173
185
|
flexShrink: 0,
|
|
174
186
|
flexDirection: childrenLayoutIsStack ? "column" : "row",
|
|
175
187
|
alignItems: axisToFlexAlign(childrenLayoutIsStack ? alignX : alignY),
|
|
176
|
-
justifyContent: axisToFlexJustify(
|
|
188
|
+
justifyContent: axisToFlexJustify(
|
|
189
|
+
childrenLayoutIsStack ? alignY : alignX
|
|
190
|
+
),
|
|
177
191
|
gap,
|
|
178
192
|
marginTop: flowDown || stackUnder ? gap : 0,
|
|
179
193
|
marginLeft: flowDown ? node.children?.layout === "stack" ? gap : 0 : stackUnder ? gap / 2 : gap
|
|
180
194
|
},
|
|
181
|
-
children:
|
|
195
|
+
children: childNodes.map(
|
|
182
196
|
(child, childIndex) => renderTreeNode({
|
|
183
197
|
node: child,
|
|
184
198
|
index: childIndex,
|
|
185
199
|
parentId: node.id,
|
|
186
200
|
depth: depth + 1,
|
|
201
|
+
siblingCount: childNodes.length,
|
|
187
202
|
path,
|
|
188
203
|
flowDown,
|
|
189
204
|
alignX,
|
|
@@ -203,6 +218,11 @@ function renderTreeNode({
|
|
|
203
218
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
204
219
|
"div",
|
|
205
220
|
{
|
|
221
|
+
role: "treeitem",
|
|
222
|
+
"aria-level": depth + 1,
|
|
223
|
+
"aria-posinset": index + 1,
|
|
224
|
+
"aria-setsize": siblingCount,
|
|
225
|
+
"aria-expanded": childCount > 0 ? true : void 0,
|
|
206
226
|
className: "unt-tree-node-wrap",
|
|
207
227
|
style: {
|
|
208
228
|
display: "flex",
|
|
@@ -216,7 +236,7 @@ function renderTreeNode({
|
|
|
216
236
|
NodeFrame,
|
|
217
237
|
{
|
|
218
238
|
node,
|
|
219
|
-
className: cn("node-enter unt-tree-node-frame", nodeFrameClassName),
|
|
239
|
+
className: cn("unt-node-enter unt-tree-node-frame", nodeFrameClassName),
|
|
220
240
|
style: {
|
|
221
241
|
justifyContent: axisToFlexJustify(alignX),
|
|
222
242
|
animationDuration: `${layoutState.nodeAnimDuration}s`,
|
|
@@ -228,6 +248,7 @@ function renderTreeNode({
|
|
|
228
248
|
debug ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
229
249
|
"div",
|
|
230
250
|
{
|
|
251
|
+
"aria-hidden": "true",
|
|
231
252
|
className: cn(
|
|
232
253
|
"unt-tree-debug-badge",
|
|
233
254
|
`unt-tree-debug-badge--${depth % 6}`
|
|
@@ -276,9 +297,11 @@ function TreeRenderer({
|
|
|
276
297
|
}) {
|
|
277
298
|
const rootLayoutRow = rootLayout === "row";
|
|
278
299
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
279
|
-
"
|
|
300
|
+
"div",
|
|
280
301
|
{
|
|
281
302
|
className: cn("unt-tree-renderer", rendererClassName),
|
|
303
|
+
role: "tree",
|
|
304
|
+
"aria-label": "Node tree",
|
|
282
305
|
style: {
|
|
283
306
|
gap,
|
|
284
307
|
display: "flex",
|
|
@@ -295,6 +318,7 @@ function TreeRenderer({
|
|
|
295
318
|
node,
|
|
296
319
|
index,
|
|
297
320
|
depth: 0,
|
|
321
|
+
siblingCount: nodeTree.length,
|
|
298
322
|
path: /* @__PURE__ */ new Set(),
|
|
299
323
|
flowDown,
|
|
300
324
|
alignX,
|
|
@@ -821,7 +845,7 @@ var NodeTree = React2.forwardRef(
|
|
|
821
845
|
const alignValue = resolvedAlign;
|
|
822
846
|
const alignX = typeof alignValue === "string" ? alignValue : alignValue.x;
|
|
823
847
|
const alignY = typeof alignValue === "string" ? "start" : alignValue.y;
|
|
824
|
-
const resolvedConnectionOpacity = connection?.opacity ?? (debug ? 1 : 0.
|
|
848
|
+
const resolvedConnectionOpacity = connection?.opacity ?? (debug ? 1 : 0.25);
|
|
825
849
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
826
850
|
"div",
|
|
827
851
|
{
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/node-tree.tsx","../src/utils/cn.ts","../src/components/tree-connections.tsx","../src/components/tree-renderer.tsx","../src/hooks/use-node-tree-layout.ts"],"sourcesContent":["export { NodeTree } from \"./components/node-tree\";\nexport type {\r\n NodeFrameProps,\r\n NodeTreeAnimationOptions,\r\n NodeTreeClassNameOptions,\r\n NodeTreeConnectionOptions,\r\n NodeTreeFrameOptions,\n NodeTreeLayoutOptions,\n NodeTreeProps,\n TreeNodeChildren,\n TreeNode,\n TreeNodeEdge,\n TreeNodeRenderContext,\n} from \"./types\";\n","import * as React from \"react\";\nimport \"../node-tree.css\";\nimport { cn } from \"../utils/cn\";\nimport { TreeConnections } from \"./tree-connections\";\nimport { TreeRenderer } from \"./tree-renderer\";\nimport { useNodeTreeLayout } from \"../hooks/use-node-tree-layout\";\nimport type { AlignAxis, NodeTreeProps } from \"../types\";\n\r\nconst NodeTree = React.forwardRef<HTMLDivElement, NodeTreeProps>(\r\n (\r\n {\r\n className,\r\n nodeTree,\r\n layout,\r\n connection,\r\n animation,\r\n nodeFrame,\r\n debug = false,\r\n style,\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const containerRef = React.useRef<HTMLDivElement | null>(null);\r\n const nodeRefs = React.useRef(new Map<string, HTMLDivElement>());\r\n const registerNode = React.useCallback(\r\n (id: string, element: HTMLDivElement | null) => {\r\n const registry = nodeRefs.current;\r\n if (element) {\r\n registry.set(id, element);\r\n } else {\r\n registry.delete(id);\r\n }\r\n },\r\n [],\r\n );\r\n\r\n const resolvedAlign = layout?.align ?? \"center\";\r\n const resolvedDirection = layout?.direction ?? \"down\";\r\n const resolvedRootLayout = layout?.root ?? \"stack\";\r\n const resolvedPaddingContainer = layout?.containerPadding ?? 128;\r\n const resolvedPadding = layout?.padding ?? 64;\r\n const resolvedGap = layout?.gap ?? 64;\r\n const resolvedStrokeColor = connection?.color ?? \"rgba(255,255,255)\";\r\n const resolvedStrokeWidth = connection?.width ?? 1;\r\n const resolvedAnimationDurationMs = animation?.durationMs ?? 2000;\r\n const resolvedNodeFrameStyle = nodeFrame?.style;\r\n\r\n const { doneNodes, layoutState } = useNodeTreeLayout({\r\n nodeTree,\r\n direction: resolvedDirection,\r\n gap: resolvedGap,\r\n padding: resolvedPadding,\r\n animationSpeed: resolvedAnimationDurationMs,\r\n debug,\r\n containerRef,\r\n nodeRefs,\r\n });\r\n\r\n const flowDown = resolvedDirection === \"down\";\r\n const alignValue = resolvedAlign;\r\n const alignX: AlignAxis =\r\n typeof alignValue === \"string\" ? alignValue : alignValue.x;\r\n const alignY: AlignAxis =\r\n typeof alignValue === \"string\" ? \"start\" : alignValue.y;\r\n const resolvedConnectionOpacity = connection?.opacity ?? (debug ? 1 : 0.1);\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n className={cn(\"unt-tree-root-container\", className?.root)}\r\n style={style}\r\n {...props}\r\n >\r\n <div\r\n ref={containerRef}\r\n className={cn(\"unt-tree-canvas\", className?.canvas)}\r\n style={{ padding: resolvedPaddingContainer }}\r\n >\r\n <TreeConnections\r\n layoutState={layoutState}\r\n debug={debug}\r\n strokeColor={resolvedStrokeColor}\r\n strokeWidth={resolvedStrokeWidth}\r\n opacity={resolvedConnectionOpacity}\r\n className={className?.connections}\r\n />\r\n <TreeRenderer\r\n nodeTree={nodeTree}\r\n rootLayout={resolvedRootLayout}\r\n flowDown={flowDown}\r\n alignX={alignX}\r\n alignY={alignY}\r\n gap={resolvedGap}\r\n debug={debug}\r\n layoutState={layoutState}\r\n doneNodes={doneNodes}\r\n registerNode={registerNode}\r\n rendererClassName={className?.renderer}\r\n nodeFrameClassName={className?.frame}\r\n nodeFrameStyle={resolvedNodeFrameStyle}\r\n />\r\n </div>\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nNodeTree.displayName = \"NodeTree\";\r\n\r\nexport { NodeTree };\r\n","import { clsx, type ClassValue } from \"clsx\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return clsx(inputs);\r\n}\r\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport type { NodeTreeLayoutState } from \"../types\";\n\r\ntype TreeConnectionsProps = {\r\n layoutState: NodeTreeLayoutState;\r\n debug: boolean;\r\n strokeColor: string;\r\n strokeWidth: number;\r\n opacity: number;\r\n className?: string;\r\n};\r\n\r\nexport function TreeConnections({\r\n layoutState,\r\n debug,\r\n strokeColor,\r\n strokeWidth,\r\n opacity,\r\n className,\r\n}: TreeConnectionsProps) {\r\n if (!layoutState.svgBounds) {\r\n return null;\r\n }\r\n\r\n return (\r\n <svg\r\n className={cn(\"unt-tree-connections\", className)}\r\n width={layoutState.svgBounds.width}\r\n height={layoutState.svgBounds.height}\r\n viewBox={`0 0 ${layoutState.svgBounds.width} ${layoutState.svgBounds.height}`}\r\n style={{\r\n left: layoutState.svgBounds.offsetX,\r\n top: layoutState.svgBounds.offsetY,\r\n opacity,\r\n }}\r\n >\r\n {layoutState.segments.map((segment) => {\r\n const debugPalette = [\r\n \"#22d3ee\",\r\n \"#a855f7\",\r\n \"#f59e0b\",\r\n \"#10b981\",\r\n \"#f97316\",\r\n \"#38bdf8\",\r\n ];\r\n const lineColor = debug\r\n ? debugPalette[segment.colorIndex % debugPalette.length]\r\n : strokeColor;\r\n return (\r\n <line\r\n key={`${segment.x1}-${segment.y1}-${segment.x2}-${segment.y2}-${segment.delay}`}\r\n x1={segment.x1 - layoutState.svgBounds!.offsetX}\r\n y1={segment.y1 - layoutState.svgBounds!.offsetY}\r\n x2={segment.x2 - layoutState.svgBounds!.offsetX}\r\n y2={segment.y2 - layoutState.svgBounds!.offsetY}\r\n className=\"node-line\"\r\n style={{\r\n strokeDasharray: segment.length,\r\n strokeDashoffset: segment.length,\r\n animationDelay: `${segment.delay}s`,\r\n animationDuration: `${segment.duration}s`,\r\n }}\r\n stroke={lineColor}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n );\r\n })}\r\n </svg>\r\n );\r\n}\r\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport type {\n AlignAxis,\n NodeFrameProps,\n NodeTreeLayoutState,\n TreeNode,\n} from \"../types\";\n\r\ntype TreeRendererProps = {\r\n nodeTree: TreeNode[];\n rootLayout: \"stack\" | \"row\";\r\n flowDown: boolean;\r\n alignX: AlignAxis;\r\n alignY: AlignAxis;\r\n gap: number;\r\n debug: boolean;\r\n layoutState: NodeTreeLayoutState;\r\n doneNodes: Set<string>;\r\n registerNode: (id: string, element: HTMLDivElement | null) => void;\r\n rendererClassName?: string;\r\n nodeFrameClassName?: string;\r\n nodeFrameStyle?: React.CSSProperties;\r\n};\r\n\r\nfunction axisToFlexAlign(axis: AlignAxis): React.CSSProperties[\"alignItems\"] {\r\n if (axis === \"start\") {\r\n return \"flex-start\";\r\n }\r\n if (axis === \"end\") {\r\n return \"flex-end\";\r\n }\r\n return \"center\";\r\n}\r\n\r\nfunction axisToFlexJustify(axis: AlignAxis): React.CSSProperties[\"justifyContent\"] {\r\n if (axis === \"start\") {\r\n return \"flex-start\";\r\n }\r\n if (axis === \"end\") {\r\n return \"flex-end\";\r\n }\r\n return \"center\";\r\n}\r\n\r\nfunction NodeFrame({ node, className, onRef, children, ...props }: NodeFrameProps) {\r\n return (\r\n <div\r\n ref={(element) => {\r\n onRef(node.id, element);\r\n }}\r\n className={cn(\"unt-tree-node-hit\", className)}\r\n data-nodeframe\r\n data-viewport-no-pan\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nfunction renderTreeNode({\r\n node,\r\n index,\r\n parentId,\r\n depth,\r\n path,\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n}: {\r\n node: TreeNode;\n index: number;\r\n parentId?: string;\r\n depth: number;\r\n path: Set<string>;\r\n flowDown: boolean;\r\n alignX: AlignAxis;\r\n alignY: AlignAxis;\r\n gap: number;\r\n debug: boolean;\r\n layoutState: NodeTreeLayoutState;\r\n doneNodes: Set<string>;\r\n registerNode: (id: string, element: HTMLDivElement | null) => void;\r\n nodeFrameClassName?: string;\r\n nodeFrameStyle?: React.CSSProperties;\r\n}): React.ReactNode {\r\n const stackUnder = !flowDown && node.children?.layout === \"stack\";\r\n if (path.has(node.id)) {\r\n return null;\r\n }\r\n\r\n path.add(node.id);\r\n const childrenLayoutIsStack = node.children?.layout === \"stack\" || !flowDown;\r\n const childCount = node.children?.nodes.length ?? 0;\r\n const isLeaf = childCount === 0;\r\n const pathIds = [...path];\r\n const childrenContent =\r\n node.children?.nodes && node.children.nodes.length > 0 ? (\r\n <div\r\n className=\"unt-tree-children\"\r\n style={{\r\n display: \"flex\",\r\n flexShrink: 0,\r\n flexDirection: childrenLayoutIsStack ? \"column\" : \"row\",\r\n alignItems: axisToFlexAlign(childrenLayoutIsStack ? alignX : alignY),\r\n justifyContent: axisToFlexJustify(childrenLayoutIsStack ? alignY : alignX),\r\n gap,\r\n marginTop: flowDown || stackUnder ? gap : 0,\r\n marginLeft: flowDown\r\n ? node.children?.layout === \"stack\"\r\n ? gap\r\n : 0\r\n : stackUnder\r\n ? gap / 2\r\n : gap,\r\n }}\r\n >\r\n {node.children.nodes.map((child, childIndex) =>\r\n renderTreeNode({\r\n node: child,\r\n index: childIndex,\r\n parentId: node.id,\r\n depth: depth + 1,\r\n path,\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n }),\r\n )}\r\n </div>\r\n ) : null;\r\n path.delete(node.id);\r\n\r\n return (\r\n <div\r\n key={`${node.id}-${index}`}\r\n className=\"unt-tree-node-wrap\"\r\n style={{\r\n display: \"flex\",\r\n position: \"relative\",\r\n flexDirection: flowDown || stackUnder ? \"column\" : \"row\",\r\n alignItems: axisToFlexAlign(flowDown ? alignX : alignY),\r\n justifyContent: axisToFlexJustify(flowDown ? alignY : alignX),\r\n }}\r\n >\r\n <NodeFrame\r\n node={node}\r\n className={cn(\"node-enter unt-tree-node-frame\", nodeFrameClassName)}\r\n style={{\r\n justifyContent: axisToFlexJustify(alignX),\r\n animationDuration: `${layoutState.nodeAnimDuration}s`,\r\n animationDelay: `${\r\n layoutState.nodeDelays.get(node.id) ?? depth * 0.08 + index * 0.04\r\n }s`,\r\n ...nodeFrameStyle,\r\n }}\r\n onRef={registerNode}\r\n >\r\n {debug ? (\r\n <div\r\n className={cn(\r\n \"unt-tree-debug-badge\",\r\n `unt-tree-debug-badge--${depth % 6}`,\r\n )}\r\n >\r\n <div>{`DEPTH: ${depth}`}</div>\r\n <div>{`PARENT-ID: ${parentId ?? \"root\"}`}</div>\r\n <div>{`NODE-ID: ${node.id}`}</div>\r\n <div>{`C-LAYOUT: ${node.children?.layout ?? \"N/A\"}`}</div>\r\n </div>\r\n ) : null}\r\n {node.render({\r\n node,\r\n index,\r\n depth,\r\n parentId,\r\n path: pathIds,\r\n isLeaf,\r\n childCount,\r\n isNodeAnimationDone: doneNodes.has(node.id),\r\n })}\r\n </NodeFrame>\r\n\r\n {childrenContent}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TreeRenderer({\r\n nodeTree,\r\n rootLayout,\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n rendererClassName,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n}: TreeRendererProps) {\r\n const rootLayoutRow = rootLayout === \"row\";\r\n return (\r\n <section\r\n className={cn(\"unt-tree-renderer\", rendererClassName)}\r\n style={{\r\n gap,\r\n display: \"flex\",\r\n width: \"100%\",\r\n overflow: \"visible\",\r\n position: \"relative\",\r\n zIndex: 10,\r\n flexDirection: rootLayoutRow ? \"row\" : \"column\",\r\n alignItems: axisToFlexAlign(rootLayoutRow ? alignY : alignX),\r\n justifyContent: axisToFlexJustify(rootLayoutRow ? alignX : alignY),\r\n }}\r\n >\r\n {nodeTree.map((node, index) =>\r\n renderTreeNode({\r\n node,\r\n index,\r\n depth: 0,\r\n path: new Set<string>(),\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n }),\r\n )}\r\n </section>\r\n );\r\n}\r\n","import * as React from \"react\";\nimport type {\n NodeTreeLayoutState,\n TreeNode,\n TreeNodeEdge,\n} from \"../types\";\n\ntype EdgeGeometry = {\n edge: TreeNodeEdge;\n fromX: number;\n fromY: number;\n fromBottom: number;\n fromCenterX: number;\n toX: number;\n toY: number;\n toLeft: number;\n toCenterY: number;\n};\n\ntype UseNodeTreeLayoutParams = {\n nodeTree: TreeNode[];\n direction: \"down\" | \"right\";\n gap: number;\n padding: number;\n animationSpeed: number;\n debug: boolean;\n containerRef: React.RefObject<HTMLDivElement | null>;\n nodeRefs: React.MutableRefObject<Map<string, HTMLDivElement>>;\n};\n\nconst EMPTY_LAYOUT: NodeTreeLayoutState = {\n segments: [],\n nodeDelays: new Map(),\n nodeAnimDuration: 0.42,\n animationTotal: 0,\n svgBounds: null,\n};\n\nfunction collectEdges(nodes: TreeNode[]) {\n const edges: TreeNodeEdge[] = [];\n const visiting = new Set<string>();\n const visit = (node: TreeNode) => {\n if (visiting.has(node.id)) {\n return;\n }\n visiting.add(node.id);\n if (node.children?.nodes && node.children.nodes.length > 0) {\n node.children.nodes.forEach((child, index) => {\n const key = `${node.id}=>${child.id}`;\n edges.push({\n key,\n from: node.id,\n to: child.id,\n index,\n count: node.children?.nodes.length ?? 1,\n });\n visit(child);\n });\n }\n visiting.delete(node.id);\n };\n\n nodes.forEach(visit);\n return edges;\n}\n\nfunction collectDescendants(nodes: TreeNode[]) {\n const map = new Map<string, string[]>();\n const visiting = new Set<string>();\n const visit = (node: TreeNode): string[] => {\n if (visiting.has(node.id)) {\n return [];\n }\n visiting.add(node.id);\n const descendants: string[] = [];\n node.children?.nodes.forEach((child) => {\n descendants.push(child.id);\n descendants.push(...visit(child));\n });\n map.set(node.id, descendants);\n visiting.delete(node.id);\n return descendants;\n };\n nodes.forEach(visit);\n return map;\n}\n\nexport function useNodeTreeLayout({\n nodeTree,\n direction,\n gap,\n padding,\n animationSpeed,\n debug,\n containerRef,\n nodeRefs,\n}: UseNodeTreeLayoutParams) {\n const [layoutState, setLayoutState] =\n React.useState<NodeTreeLayoutState>(EMPTY_LAYOUT);\n const [doneNodes, setDoneNodes] = React.useState<Set<string>>(\n () => new Set(),\n );\n const doneNodesRef = React.useRef<Set<string>>(new Set());\n const edges = React.useMemo(() => collectEdges(nodeTree), [nodeTree]);\n const descendantMap = React.useMemo(\n () => collectDescendants(nodeTree),\n [nodeTree],\n );\n\n const totalAnimationSec = Math.max(0.1, animationSpeed / 1000);\n\n const drawConnections = React.useCallback(() => {\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const flowDown = direction === \"down\";\n\n const getRelativeRect = (element: HTMLElement) => {\n let left = 0;\n let top = 0;\n let current: HTMLElement | null = element;\n while (current && current !== container) {\n left += current.offsetLeft;\n top += current.offsetTop;\n current = current.offsetParent as HTMLElement | null;\n }\n return {\n left,\n top,\n right: left + element.offsetWidth,\n bottom: top + element.offsetHeight,\n width: element.offsetWidth,\n height: element.offsetHeight,\n };\n };\n\n const rectMap = new Map<string, ReturnType<typeof getRelativeRect>>();\n nodeRefs.current.forEach((el, id) => {\n rectMap.set(id, getRelativeRect(el));\n });\n\n const nextSegments: NodeTreeLayoutState[\"segments\"] = [];\n const nextNodeDelays = new Map<string, number>();\n const baseSecondsPerPixel = 1 / 900;\n const baseNodeAnimDuration = 0.42;\n const edgeColorIndex = debug ? new Map<string, number>() : null;\n const edgeData = new Map<string, EdgeGeometry>();\n\n edges.forEach((edge) => {\n const fromRect = rectMap.get(edge.from);\n const toRect = rectMap.get(edge.to);\n if (!fromRect || !toRect) {\n return;\n }\n\n const fromX = flowDown ? fromRect.left + fromRect.width / 2 : fromRect.right;\n const fromY = flowDown\n ? fromRect.bottom\n : fromRect.top + fromRect.height / 2;\n const toX = flowDown ? toRect.left + toRect.width / 2 : toRect.left;\n const toY = flowDown ? toRect.top : toRect.top + toRect.height / 2;\n\n edgeData.set(edge.key, {\n edge,\n fromX,\n fromY,\n fromBottom: fromRect.bottom,\n fromCenterX: fromRect.left + fromRect.width / 2,\n toX,\n toY,\n toLeft: toRect.left,\n toCenterY: toRect.top + toRect.height / 2,\n });\n });\n\n const pushSegment = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n depth: number,\n delay: number,\n colorIndex: number,\n order: number,\n ) => {\n const length = Math.hypot(x2 - x1, y2 - y1);\n const duration = Math.max(0.05, length * baseSecondsPerPixel);\n nextSegments.push({\n x1,\n y1,\n x2,\n y2,\n length,\n depth,\n delay,\n duration,\n colorIndex,\n order,\n });\n return duration;\n };\n\n const visit = (node: TreeNode, depth: number, nodeDelay: number) => {\n const existing = nextNodeDelays.get(node.id) ?? 0;\n const resolvedDelay = Math.max(existing, nodeDelay);\n nextNodeDelays.set(node.id, resolvedDelay);\n\n const childEdges =\n node.children?.nodes\n .map((child) => edgeData.get(`${node.id}=>${child.id}`))\n .filter((edge): edge is EdgeGeometry => Boolean(edge)) ?? [];\n const stackLayout = node.children?.layout === \"stack\";\n const descendantIds =\n flowDown && stackLayout ? (descendantMap.get(node.id) ?? []) : [];\n const descendantLefts =\n flowDown && stackLayout\n ? descendantIds\n .map((id) => rectMap.get(id))\n .filter((rect): rect is NonNullable<typeof rect> => Boolean(rect))\n .map((rect) => rect.left)\n : [];\n const descendantMinLeft =\n descendantLefts.length > 0 ? Math.min(...descendantLefts) : undefined;\n const gutterX =\n flowDown && stackLayout\n ? (descendantMinLeft ??\n (childEdges.length > 0\n ? Math.min(...childEdges.map((edge) => edge.toLeft))\n : 0)) -\n gap / 2\n : 0;\n const gutterXRight =\n !flowDown && stackLayout\n ? (childEdges.length > 0\n ? Math.min(...childEdges.map((edge) => edge.toLeft))\n : 0) -\n gap / 2\n : 0;\n\n const orderedChildren =\n node.children?.nodes\n .map((child) => {\n const edge = edgeData.get(`${node.id}=>${child.id}`);\n if (!edge) {\n return null;\n }\n const dx = edge.toX - edge.fromX;\n const dy = edge.toY - edge.fromY;\n const length = Math.hypot(dx, dy);\n return { child, edge, length, toX: edge.toX };\n })\n .filter(\n (entry): entry is NonNullable<typeof entry> => Boolean(entry),\n ) ?? [];\n\n if (debug) {\n orderedChildren.sort((a, b) => {\n if (a.length !== b.length) {\n return a.length - b.length;\n }\n return a.toX - b.toX;\n });\n }\n\n orderedChildren.forEach((entry, index) => {\n const { child, edge } = entry;\n const edgeKey = edge.edge.key;\n let colorIndex = 0;\n if (edgeColorIndex) {\n if (!edgeColorIndex.has(edgeKey)) {\n edgeColorIndex.set(edgeKey, edgeColorIndex.size);\n }\n colorIndex = edgeColorIndex.get(edgeKey) ?? 0;\n }\n const order = orderedChildren.length - 1 - index;\n const edgeDelay = resolvedDelay + baseNodeAnimDuration + index * 0.04;\n let totalDuration = 0;\n if (flowDown && stackLayout) {\n const baseDrop = Math.max(12, gap / 2);\n const targetY = edge.toCenterY;\n const midY =\n edge.fromY + Math.min(baseDrop, (targetY - edge.fromY) * 0.6);\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n edge.fromX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromX,\n midY,\n gutterX,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterX,\n midY,\n gutterX,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterX,\n targetY,\n edge.toLeft,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else if (!flowDown && stackLayout) {\n const targetY = edge.toCenterY;\n const baseDrop = Math.max(12, gap / 2);\n const midY =\n edge.fromBottom +\n Math.min(baseDrop, (targetY - edge.fromBottom) * 0.6);\n totalDuration += pushSegment(\n edge.fromCenterX,\n edge.fromBottom,\n edge.fromCenterX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromCenterX,\n midY,\n gutterXRight,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterXRight,\n midY,\n gutterXRight,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterXRight,\n targetY,\n edge.toLeft,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else if (flowDown) {\n const midY = edge.fromY + (edge.toY - edge.fromY) * 0.5;\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n edge.fromX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromX,\n midY,\n edge.toX,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.toX,\n midY,\n edge.toX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else {\n const midX = edge.fromX + (edge.toX - edge.fromX) * 0.5;\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n midX,\n edge.fromY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n midX,\n edge.fromY,\n midX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n midX,\n edge.toY,\n edge.toX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n }\n visit(child, depth + 1, edgeDelay + totalDuration);\n });\n };\n\n nodeTree.forEach((node) => visit(node, 0, 0));\n\n if (nextSegments.length === 0) {\n setLayoutState((prev) => ({\n ...prev,\n segments: [],\n svgBounds: null,\n animationTotal: 0,\n }));\n setDoneNodes(new Set());\n doneNodesRef.current = new Set();\n return;\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n nextSegments.forEach((segment) => {\n minX = Math.min(minX, segment.x1, segment.x2);\n minY = Math.min(minY, segment.y1, segment.y2);\n maxX = Math.max(maxX, segment.x1, segment.x2);\n maxY = Math.max(maxY, segment.y1, segment.y2);\n });\n\n if (\n !Number.isFinite(minX) ||\n !Number.isFinite(minY) ||\n !Number.isFinite(maxX) ||\n !Number.isFinite(maxY)\n ) {\n return;\n }\n\n const width = Math.max(1, maxX - minX + padding * 2);\n const height = Math.max(1, maxY - minY + padding * 2);\n const offsetX = minX - padding;\n const offsetY = minY - padding;\n\n const maxLineEnd = Math.max(\n 0,\n ...nextSegments.map((segment) => segment.delay + segment.duration),\n );\n const maxNodeEnd =\n Math.max(0, ...Array.from(nextNodeDelays.values())) + baseNodeAnimDuration;\n const animationMax = Math.max(maxLineEnd, maxNodeEnd);\n const scale = animationMax > 0 ? totalAnimationSec / animationMax : 1;\n const scaledSegments = nextSegments\n .map((segment) => ({\n ...segment,\n delay: segment.delay * scale,\n duration: segment.duration * scale,\n }))\n .sort((a, b) => a.order - b.order);\n const scaledNodeDelays = new Map<string, number>();\n nextNodeDelays.forEach((value, key) => {\n scaledNodeDelays.set(key, value * scale);\n });\n\n setLayoutState({\n segments: scaledSegments,\n nodeDelays: scaledNodeDelays,\n nodeAnimDuration: baseNodeAnimDuration * scale,\n animationTotal: animationMax * scale,\n svgBounds: { width, height, offsetX, offsetY },\n });\n setDoneNodes(new Set());\n doneNodesRef.current = new Set();\n }, [\n animationSpeed,\n containerRef,\n debug,\n descendantMap,\n direction,\n edges,\n gap,\n nodeRefs,\n nodeTree,\n padding,\n totalAnimationSec,\n ]);\n\n React.useLayoutEffect(() => {\n const rafId = requestAnimationFrame(drawConnections);\n return () => cancelAnimationFrame(rafId);\n }, [drawConnections, nodeTree]);\n\n React.useEffect(() => {\n if (layoutState.animationTotal <= 0 || layoutState.nodeDelays.size === 0) {\n return;\n }\n\n const entries = Array.from(layoutState.nodeDelays.entries())\n .map(([id, delay]) => ({\n id,\n end: delay + layoutState.nodeAnimDuration,\n }))\n .sort((a, b) => a.end - b.end);\n\n doneNodesRef.current = new Set();\n setDoneNodes(new Set());\n\n const start = performance.now();\n let rafId = 0;\n let index = 0;\n\n const tick = () => {\n const elapsed = (performance.now() - start) / 1000;\n let updated = false;\n\n while (index < entries.length && elapsed >= entries[index].end) {\n doneNodesRef.current.add(entries[index].id);\n index += 1;\n updated = true;\n }\n\n if (updated) {\n setDoneNodes(new Set(doneNodesRef.current));\n }\n\n if (index < entries.length) {\n rafId = requestAnimationFrame(tick);\n }\n };\n\n rafId = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafId);\n }, [\n layoutState.animationTotal,\n layoutState.nodeAnimDuration,\n layoutState.nodeDelays,\n ]);\n\n return { doneNodes, layoutState };\n}\n"],"mappings":"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","names":["React","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/node-tree.tsx","../src/utils/cn.ts","../src/components/tree-connections.tsx","../src/components/tree-renderer.tsx","../src/hooks/use-node-tree-layout.ts"],"sourcesContent":["export { NodeTree } from \"./components/node-tree\";\nexport type {\r\n NodeFrameProps,\r\n NodeTreeAnimationOptions,\r\n NodeTreeClassNameOptions,\r\n NodeTreeConnectionOptions,\r\n NodeTreeFrameOptions,\n NodeTreeLayoutOptions,\n NodeTreeProps,\n TreeNodeChildren,\n TreeNode,\n TreeNodeEdge,\n TreeNodeRenderContext,\n} from \"./types\";\n","import * as React from \"react\";\r\nimport \"../node-tree.css\";\r\nimport { cn } from \"../utils/cn\";\r\nimport { TreeConnections } from \"./tree-connections\";\r\nimport { TreeRenderer } from \"./tree-renderer\";\r\nimport { useNodeTreeLayout } from \"../hooks/use-node-tree-layout\";\r\nimport type { AlignAxis, NodeTreeProps } from \"../types\";\r\n\r\nconst NodeTree = React.forwardRef<HTMLDivElement, NodeTreeProps>(\r\n (\r\n {\r\n className,\r\n nodeTree,\r\n layout,\r\n connection,\r\n animation,\r\n nodeFrame,\r\n debug = false,\r\n style,\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const containerRef = React.useRef<HTMLDivElement | null>(null);\r\n const nodeRefs = React.useRef(new Map<string, HTMLDivElement>());\r\n const registerNode = React.useCallback(\r\n (id: string, element: HTMLDivElement | null) => {\r\n const registry = nodeRefs.current;\r\n if (element) {\r\n registry.set(id, element);\r\n } else {\r\n registry.delete(id);\r\n }\r\n },\r\n [],\r\n );\r\n\r\n const resolvedAlign = layout?.align ?? \"center\";\r\n const resolvedDirection = layout?.direction ?? \"down\";\r\n const resolvedRootLayout = layout?.root ?? \"stack\";\r\n const resolvedPaddingContainer = layout?.containerPadding ?? 128;\r\n const resolvedPadding = layout?.padding ?? 64;\r\n const resolvedGap = layout?.gap ?? 64;\r\n const resolvedStrokeColor = connection?.color ?? \"rgba(255,255,255)\";\r\n const resolvedStrokeWidth = connection?.width ?? 1;\r\n const resolvedAnimationDurationMs = animation?.durationMs ?? 2000;\r\n const resolvedNodeFrameStyle = nodeFrame?.style;\r\n\r\n const { doneNodes, layoutState } = useNodeTreeLayout({\r\n nodeTree,\r\n direction: resolvedDirection,\r\n gap: resolvedGap,\r\n padding: resolvedPadding,\r\n animationSpeed: resolvedAnimationDurationMs,\r\n debug,\r\n containerRef,\r\n nodeRefs,\r\n });\r\n\r\n const flowDown = resolvedDirection === \"down\";\r\n const alignValue = resolvedAlign;\r\n const alignX: AlignAxis =\r\n typeof alignValue === \"string\" ? alignValue : alignValue.x;\r\n const alignY: AlignAxis =\r\n typeof alignValue === \"string\" ? \"start\" : alignValue.y;\r\n const resolvedConnectionOpacity = connection?.opacity ?? (debug ? 1 : 0.25);\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n className={cn(\"unt-tree-root-container\", className?.root)}\r\n style={style}\r\n {...props}\r\n >\r\n <div\r\n ref={containerRef}\r\n className={cn(\"unt-tree-canvas\", className?.canvas)}\r\n style={{ padding: resolvedPaddingContainer }}\r\n >\r\n <TreeConnections\r\n layoutState={layoutState}\r\n debug={debug}\r\n strokeColor={resolvedStrokeColor}\r\n strokeWidth={resolvedStrokeWidth}\r\n opacity={resolvedConnectionOpacity}\r\n className={className?.connections}\r\n />\r\n <TreeRenderer\r\n nodeTree={nodeTree}\r\n rootLayout={resolvedRootLayout}\r\n flowDown={flowDown}\r\n alignX={alignX}\r\n alignY={alignY}\r\n gap={resolvedGap}\r\n debug={debug}\r\n layoutState={layoutState}\r\n doneNodes={doneNodes}\r\n registerNode={registerNode}\r\n rendererClassName={className?.renderer}\r\n nodeFrameClassName={className?.frame}\r\n nodeFrameStyle={resolvedNodeFrameStyle}\r\n />\r\n </div>\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nNodeTree.displayName = \"NodeTree\";\r\n\r\nexport { NodeTree };\r\n","import { clsx, type ClassValue } from \"clsx\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return clsx(inputs);\r\n}\r\n","import * as React from \"react\";\r\nimport { cn } from \"../utils/cn\";\r\nimport type { NodeTreeLayoutState } from \"../types\";\r\n\r\ntype TreeConnectionsProps = {\r\n layoutState: NodeTreeLayoutState;\r\n debug: boolean;\r\n strokeColor: string;\r\n strokeWidth: number;\r\n opacity: number;\r\n className?: string;\r\n};\r\n\r\nexport function TreeConnections({\r\n layoutState,\r\n debug,\r\n strokeColor,\r\n strokeWidth,\r\n opacity,\r\n className,\r\n}: TreeConnectionsProps) {\r\n if (!layoutState.svgBounds) {\r\n return null;\r\n }\r\n\r\n return (\n <svg\n className={cn(\"unt-tree-connections\", className)}\n aria-hidden=\"true\"\n focusable=\"false\"\n role=\"presentation\"\n width={layoutState.svgBounds.width}\n height={layoutState.svgBounds.height}\n viewBox={`0 0 ${layoutState.svgBounds.width} ${layoutState.svgBounds.height}`}\n style={{\n left: layoutState.svgBounds.offsetX,\n top: layoutState.svgBounds.offsetY,\r\n opacity,\r\n }}\r\n >\r\n {layoutState.segments.map((segment) => {\r\n const debugPalette = [\r\n \"#22d3ee\",\r\n \"#a855f7\",\r\n \"#f59e0b\",\r\n \"#10b981\",\r\n \"#f97316\",\r\n \"#38bdf8\",\r\n ];\r\n const lineColor = debug\r\n ? debugPalette[segment.colorIndex % debugPalette.length]\r\n : strokeColor;\r\n return (\r\n <line\r\n key={`${segment.x1}-${segment.y1}-${segment.x2}-${segment.y2}-${segment.delay}`}\r\n x1={segment.x1 - layoutState.svgBounds!.offsetX}\r\n y1={segment.y1 - layoutState.svgBounds!.offsetY}\r\n x2={segment.x2 - layoutState.svgBounds!.offsetX}\r\n y2={segment.y2 - layoutState.svgBounds!.offsetY}\r\n className=\"unt-node-line\"\r\n style={{\r\n strokeDasharray: segment.length,\r\n strokeDashoffset: segment.length,\r\n animationDelay: `${segment.delay}s`,\r\n animationDuration: `${segment.duration}s`,\r\n }}\r\n stroke={lineColor}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n );\r\n })}\r\n </svg>\r\n );\r\n}\r\n","import * as React from \"react\";\r\nimport { cn } from \"../utils/cn\";\r\nimport type {\r\n AlignAxis,\r\n NodeFrameProps,\r\n NodeTreeLayoutState,\r\n TreeNode,\r\n} from \"../types\";\r\n\r\ntype TreeRendererProps = {\r\n nodeTree: TreeNode[];\r\n rootLayout: \"stack\" | \"row\";\r\n flowDown: boolean;\r\n alignX: AlignAxis;\r\n alignY: AlignAxis;\r\n gap: number;\r\n debug: boolean;\r\n layoutState: NodeTreeLayoutState;\r\n doneNodes: Set<string>;\r\n registerNode: (id: string, element: HTMLDivElement | null) => void;\r\n rendererClassName?: string;\r\n nodeFrameClassName?: string;\r\n nodeFrameStyle?: React.CSSProperties;\r\n};\r\n\r\nfunction axisToFlexAlign(axis: AlignAxis): React.CSSProperties[\"alignItems\"] {\r\n if (axis === \"start\") {\r\n return \"flex-start\";\r\n }\r\n if (axis === \"end\") {\r\n return \"flex-end\";\r\n }\r\n return \"center\";\r\n}\r\n\r\nfunction axisToFlexJustify(\r\n axis: AlignAxis,\r\n): React.CSSProperties[\"justifyContent\"] {\r\n if (axis === \"start\") {\r\n return \"flex-start\";\r\n }\r\n if (axis === \"end\") {\r\n return \"flex-end\";\r\n }\r\n return \"center\";\r\n}\r\n\r\nfunction NodeFrame({\r\n node,\r\n className,\r\n onRef,\r\n children,\r\n ...props\r\n}: NodeFrameProps) {\r\n return (\r\n <div\r\n ref={(element) => {\r\n onRef(node.id, element);\r\n }}\r\n className={cn(\"unt-tree-node-hit\", className)}\r\n data-nodeframe\r\n data-viewport-no-pan\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nfunction renderTreeNode({\n node,\n index,\n parentId,\n depth,\n siblingCount,\n path,\n flowDown,\n alignX,\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n}: {\r\n node: TreeNode;\n index: number;\n parentId?: string;\n depth: number;\n siblingCount: number;\n path: Set<string>;\n flowDown: boolean;\r\n alignX: AlignAxis;\r\n alignY: AlignAxis;\r\n gap: number;\r\n debug: boolean;\r\n layoutState: NodeTreeLayoutState;\r\n doneNodes: Set<string>;\r\n registerNode: (id: string, element: HTMLDivElement | null) => void;\r\n nodeFrameClassName?: string;\r\n nodeFrameStyle?: React.CSSProperties;\r\n}): React.ReactNode {\r\n const stackUnder = !flowDown && node.children?.layout === \"stack\";\r\n if (path.has(node.id)) {\r\n return null;\r\n }\r\n\r\n path.add(node.id);\r\n const childrenLayoutIsStack = node.children?.layout === \"stack\" || !flowDown;\n const childNodes = node.children?.nodes ?? [];\n const childCount = node.children?.nodes.length ?? 0;\n const isLeaf = childCount === 0;\n const pathIds = [...path];\n const childrenContent =\n childNodes.length > 0 ? (\n <div\n role=\"group\"\n className=\"unt-tree-children\"\n style={{\n display: \"flex\",\r\n flexShrink: 0,\r\n flexDirection: childrenLayoutIsStack ? \"column\" : \"row\",\r\n alignItems: axisToFlexAlign(childrenLayoutIsStack ? alignX : alignY),\r\n justifyContent: axisToFlexJustify(\r\n childrenLayoutIsStack ? alignY : alignX,\r\n ),\r\n gap,\r\n marginTop: flowDown || stackUnder ? gap : 0,\r\n marginLeft: flowDown\r\n ? node.children?.layout === \"stack\"\r\n ? gap\r\n : 0\r\n : stackUnder\r\n ? gap / 2\r\n : gap,\r\n }}\r\n >\n {childNodes.map((child, childIndex) =>\n renderTreeNode({\n node: child,\n index: childIndex,\n parentId: node.id,\n depth: depth + 1,\n siblingCount: childNodes.length,\n path,\n flowDown,\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n }),\r\n )}\r\n </div>\r\n ) : null;\r\n path.delete(node.id);\r\n\r\n return (\r\n <div\n key={`${node.id}-${index}`}\n role=\"treeitem\"\n aria-level={depth + 1}\n aria-posinset={index + 1}\n aria-setsize={siblingCount}\n aria-expanded={childCount > 0 ? true : undefined}\n className=\"unt-tree-node-wrap\"\n style={{\n display: \"flex\",\r\n position: \"relative\",\r\n flexDirection: flowDown || stackUnder ? \"column\" : \"row\",\r\n alignItems: axisToFlexAlign(flowDown ? alignX : alignY),\r\n justifyContent: axisToFlexJustify(flowDown ? alignY : alignX),\r\n }}\r\n >\r\n <NodeFrame\r\n node={node}\r\n className={cn(\"unt-node-enter unt-tree-node-frame\", nodeFrameClassName)}\r\n style={{\r\n justifyContent: axisToFlexJustify(alignX),\r\n animationDuration: `${layoutState.nodeAnimDuration}s`,\r\n animationDelay: `${\r\n layoutState.nodeDelays.get(node.id) ?? depth * 0.08 + index * 0.04\r\n }s`,\r\n ...nodeFrameStyle,\r\n }}\r\n onRef={registerNode}\r\n >\r\n {debug ? (\n <div\n aria-hidden=\"true\"\n className={cn(\n \"unt-tree-debug-badge\",\n `unt-tree-debug-badge--${depth % 6}`,\n )}\r\n >\r\n <div>{`DEPTH: ${depth}`}</div>\r\n <div>{`PARENT-ID: ${parentId ?? \"root\"}`}</div>\r\n <div>{`NODE-ID: ${node.id}`}</div>\r\n <div>{`C-LAYOUT: ${node.children?.layout ?? \"N/A\"}`}</div>\r\n </div>\r\n ) : null}\r\n {node.render({\r\n node,\r\n index,\r\n depth,\r\n parentId,\r\n path: pathIds,\r\n isLeaf,\r\n childCount,\r\n isNodeAnimationDone: doneNodes.has(node.id),\r\n })}\r\n </NodeFrame>\r\n\r\n {childrenContent}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TreeRenderer({\r\n nodeTree,\r\n rootLayout,\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n rendererClassName,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n}: TreeRendererProps) {\r\n const rootLayoutRow = rootLayout === \"row\";\r\n return (\n <div\n className={cn(\"unt-tree-renderer\", rendererClassName)}\n role=\"tree\"\n aria-label=\"Node tree\"\n style={{\n gap,\r\n display: \"flex\",\r\n width: \"100%\",\r\n overflow: \"visible\",\r\n position: \"relative\",\r\n zIndex: 10,\r\n flexDirection: rootLayoutRow ? \"row\" : \"column\",\r\n alignItems: axisToFlexAlign(rootLayoutRow ? alignY : alignX),\r\n justifyContent: axisToFlexJustify(rootLayoutRow ? alignX : alignY),\r\n }}\r\n >\r\n {nodeTree.map((node, index) =>\r\n renderTreeNode({\r\n node,\n index,\n depth: 0,\n siblingCount: nodeTree.length,\n path: new Set<string>(),\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n }),\r\n )}\r\n </div>\r\n );\r\n}\r\n","import * as React from \"react\";\nimport type {\n NodeTreeLayoutState,\n TreeNode,\n TreeNodeEdge,\n} from \"../types\";\n\ntype EdgeGeometry = {\n edge: TreeNodeEdge;\n fromX: number;\n fromY: number;\n fromBottom: number;\n fromCenterX: number;\n toX: number;\n toY: number;\n toLeft: number;\n toCenterY: number;\n};\n\ntype UseNodeTreeLayoutParams = {\n nodeTree: TreeNode[];\n direction: \"down\" | \"right\";\n gap: number;\n padding: number;\n animationSpeed: number;\n debug: boolean;\n containerRef: React.RefObject<HTMLDivElement | null>;\n nodeRefs: React.MutableRefObject<Map<string, HTMLDivElement>>;\n};\n\nconst EMPTY_LAYOUT: NodeTreeLayoutState = {\n segments: [],\n nodeDelays: new Map(),\n nodeAnimDuration: 0.42,\n animationTotal: 0,\n svgBounds: null,\n};\n\nfunction collectEdges(nodes: TreeNode[]) {\n const edges: TreeNodeEdge[] = [];\n const visiting = new Set<string>();\n const visit = (node: TreeNode) => {\n if (visiting.has(node.id)) {\n return;\n }\n visiting.add(node.id);\n if (node.children?.nodes && node.children.nodes.length > 0) {\n node.children.nodes.forEach((child, index) => {\n const key = `${node.id}=>${child.id}`;\n edges.push({\n key,\n from: node.id,\n to: child.id,\n index,\n count: node.children?.nodes.length ?? 1,\n });\n visit(child);\n });\n }\n visiting.delete(node.id);\n };\n\n nodes.forEach(visit);\n return edges;\n}\n\nfunction collectDescendants(nodes: TreeNode[]) {\n const map = new Map<string, string[]>();\n const visiting = new Set<string>();\n const visit = (node: TreeNode): string[] => {\n if (visiting.has(node.id)) {\n return [];\n }\n visiting.add(node.id);\n const descendants: string[] = [];\n node.children?.nodes.forEach((child) => {\n descendants.push(child.id);\n descendants.push(...visit(child));\n });\n map.set(node.id, descendants);\n visiting.delete(node.id);\n return descendants;\n };\n nodes.forEach(visit);\n return map;\n}\n\nexport function useNodeTreeLayout({\n nodeTree,\n direction,\n gap,\n padding,\n animationSpeed,\n debug,\n containerRef,\n nodeRefs,\n}: UseNodeTreeLayoutParams) {\n const [layoutState, setLayoutState] =\n React.useState<NodeTreeLayoutState>(EMPTY_LAYOUT);\n const [doneNodes, setDoneNodes] = React.useState<Set<string>>(\n () => new Set(),\n );\n const doneNodesRef = React.useRef<Set<string>>(new Set());\n const edges = React.useMemo(() => collectEdges(nodeTree), [nodeTree]);\n const descendantMap = React.useMemo(\n () => collectDescendants(nodeTree),\n [nodeTree],\n );\n\n const totalAnimationSec = Math.max(0.1, animationSpeed / 1000);\n\n const drawConnections = React.useCallback(() => {\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const flowDown = direction === \"down\";\n\n const getRelativeRect = (element: HTMLElement) => {\n let left = 0;\n let top = 0;\n let current: HTMLElement | null = element;\n while (current && current !== container) {\n left += current.offsetLeft;\n top += current.offsetTop;\n current = current.offsetParent as HTMLElement | null;\n }\n return {\n left,\n top,\n right: left + element.offsetWidth,\n bottom: top + element.offsetHeight,\n width: element.offsetWidth,\n height: element.offsetHeight,\n };\n };\n\n const rectMap = new Map<string, ReturnType<typeof getRelativeRect>>();\n nodeRefs.current.forEach((el, id) => {\n rectMap.set(id, getRelativeRect(el));\n });\n\n const nextSegments: NodeTreeLayoutState[\"segments\"] = [];\n const nextNodeDelays = new Map<string, number>();\n const baseSecondsPerPixel = 1 / 900;\n const baseNodeAnimDuration = 0.42;\n const edgeColorIndex = debug ? new Map<string, number>() : null;\n const edgeData = new Map<string, EdgeGeometry>();\n\n edges.forEach((edge) => {\n const fromRect = rectMap.get(edge.from);\n const toRect = rectMap.get(edge.to);\n if (!fromRect || !toRect) {\n return;\n }\n\n const fromX = flowDown ? fromRect.left + fromRect.width / 2 : fromRect.right;\n const fromY = flowDown\n ? fromRect.bottom\n : fromRect.top + fromRect.height / 2;\n const toX = flowDown ? toRect.left + toRect.width / 2 : toRect.left;\n const toY = flowDown ? toRect.top : toRect.top + toRect.height / 2;\n\n edgeData.set(edge.key, {\n edge,\n fromX,\n fromY,\n fromBottom: fromRect.bottom,\n fromCenterX: fromRect.left + fromRect.width / 2,\n toX,\n toY,\n toLeft: toRect.left,\n toCenterY: toRect.top + toRect.height / 2,\n });\n });\n\n const pushSegment = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n depth: number,\n delay: number,\n colorIndex: number,\n order: number,\n ) => {\n const length = Math.hypot(x2 - x1, y2 - y1);\n const duration = Math.max(0.05, length * baseSecondsPerPixel);\n nextSegments.push({\n x1,\n y1,\n x2,\n y2,\n length,\n depth,\n delay,\n duration,\n colorIndex,\n order,\n });\n return duration;\n };\n\n const visit = (node: TreeNode, depth: number, nodeDelay: number) => {\n const existing = nextNodeDelays.get(node.id) ?? 0;\n const resolvedDelay = Math.max(existing, nodeDelay);\n nextNodeDelays.set(node.id, resolvedDelay);\n\n const childEdges =\n node.children?.nodes\n .map((child) => edgeData.get(`${node.id}=>${child.id}`))\n .filter((edge): edge is EdgeGeometry => Boolean(edge)) ?? [];\n const stackLayout = node.children?.layout === \"stack\";\n const descendantIds =\n flowDown && stackLayout ? (descendantMap.get(node.id) ?? []) : [];\n const descendantLefts =\n flowDown && stackLayout\n ? descendantIds\n .map((id) => rectMap.get(id))\n .filter((rect): rect is NonNullable<typeof rect> => Boolean(rect))\n .map((rect) => rect.left)\n : [];\n const descendantMinLeft =\n descendantLefts.length > 0 ? Math.min(...descendantLefts) : undefined;\n const gutterX =\n flowDown && stackLayout\n ? (descendantMinLeft ??\n (childEdges.length > 0\n ? Math.min(...childEdges.map((edge) => edge.toLeft))\n : 0)) -\n gap / 2\n : 0;\n const gutterXRight =\n !flowDown && stackLayout\n ? (childEdges.length > 0\n ? Math.min(...childEdges.map((edge) => edge.toLeft))\n : 0) -\n gap / 2\n : 0;\n\n const orderedChildren =\n node.children?.nodes\n .map((child) => {\n const edge = edgeData.get(`${node.id}=>${child.id}`);\n if (!edge) {\n return null;\n }\n const dx = edge.toX - edge.fromX;\n const dy = edge.toY - edge.fromY;\n const length = Math.hypot(dx, dy);\n return { child, edge, length, toX: edge.toX };\n })\n .filter(\n (entry): entry is NonNullable<typeof entry> => Boolean(entry),\n ) ?? [];\n\n if (debug) {\n orderedChildren.sort((a, b) => {\n if (a.length !== b.length) {\n return a.length - b.length;\n }\n return a.toX - b.toX;\n });\n }\n\n orderedChildren.forEach((entry, index) => {\n const { child, edge } = entry;\n const edgeKey = edge.edge.key;\n let colorIndex = 0;\n if (edgeColorIndex) {\n if (!edgeColorIndex.has(edgeKey)) {\n edgeColorIndex.set(edgeKey, edgeColorIndex.size);\n }\n colorIndex = edgeColorIndex.get(edgeKey) ?? 0;\n }\n const order = orderedChildren.length - 1 - index;\n const edgeDelay = resolvedDelay + baseNodeAnimDuration + index * 0.04;\n let totalDuration = 0;\n if (flowDown && stackLayout) {\n const baseDrop = Math.max(12, gap / 2);\n const targetY = edge.toCenterY;\n const midY =\n edge.fromY + Math.min(baseDrop, (targetY - edge.fromY) * 0.6);\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n edge.fromX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromX,\n midY,\n gutterX,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterX,\n midY,\n gutterX,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterX,\n targetY,\n edge.toLeft,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else if (!flowDown && stackLayout) {\n const targetY = edge.toCenterY;\n const baseDrop = Math.max(12, gap / 2);\n const midY =\n edge.fromBottom +\n Math.min(baseDrop, (targetY - edge.fromBottom) * 0.6);\n totalDuration += pushSegment(\n edge.fromCenterX,\n edge.fromBottom,\n edge.fromCenterX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromCenterX,\n midY,\n gutterXRight,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterXRight,\n midY,\n gutterXRight,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterXRight,\n targetY,\n edge.toLeft,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else if (flowDown) {\n const midY = edge.fromY + (edge.toY - edge.fromY) * 0.5;\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n edge.fromX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromX,\n midY,\n edge.toX,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.toX,\n midY,\n edge.toX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else {\n const midX = edge.fromX + (edge.toX - edge.fromX) * 0.5;\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n midX,\n edge.fromY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n midX,\n edge.fromY,\n midX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n midX,\n edge.toY,\n edge.toX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n }\n visit(child, depth + 1, edgeDelay + totalDuration);\n });\n };\n\n nodeTree.forEach((node) => visit(node, 0, 0));\n\n if (nextSegments.length === 0) {\n setLayoutState((prev) => ({\n ...prev,\n segments: [],\n svgBounds: null,\n animationTotal: 0,\n }));\n setDoneNodes(new Set());\n doneNodesRef.current = new Set();\n return;\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n nextSegments.forEach((segment) => {\n minX = Math.min(minX, segment.x1, segment.x2);\n minY = Math.min(minY, segment.y1, segment.y2);\n maxX = Math.max(maxX, segment.x1, segment.x2);\n maxY = Math.max(maxY, segment.y1, segment.y2);\n });\n\n if (\n !Number.isFinite(minX) ||\n !Number.isFinite(minY) ||\n !Number.isFinite(maxX) ||\n !Number.isFinite(maxY)\n ) {\n return;\n }\n\n const width = Math.max(1, maxX - minX + padding * 2);\n const height = Math.max(1, maxY - minY + padding * 2);\n const offsetX = minX - padding;\n const offsetY = minY - padding;\n\n const maxLineEnd = Math.max(\n 0,\n ...nextSegments.map((segment) => segment.delay + segment.duration),\n );\n const maxNodeEnd =\n Math.max(0, ...Array.from(nextNodeDelays.values())) + baseNodeAnimDuration;\n const animationMax = Math.max(maxLineEnd, maxNodeEnd);\n const scale = animationMax > 0 ? totalAnimationSec / animationMax : 1;\n const scaledSegments = nextSegments\n .map((segment) => ({\n ...segment,\n delay: segment.delay * scale,\n duration: segment.duration * scale,\n }))\n .sort((a, b) => a.order - b.order);\n const scaledNodeDelays = new Map<string, number>();\n nextNodeDelays.forEach((value, key) => {\n scaledNodeDelays.set(key, value * scale);\n });\n\n setLayoutState({\n segments: scaledSegments,\n nodeDelays: scaledNodeDelays,\n nodeAnimDuration: baseNodeAnimDuration * scale,\n animationTotal: animationMax * scale,\n svgBounds: { width, height, offsetX, offsetY },\n });\n setDoneNodes(new Set());\n doneNodesRef.current = new Set();\n }, [\n animationSpeed,\n containerRef,\n debug,\n descendantMap,\n direction,\n edges,\n gap,\n nodeRefs,\n nodeTree,\n padding,\n totalAnimationSec,\n ]);\n\n React.useLayoutEffect(() => {\n const rafId = requestAnimationFrame(drawConnections);\n return () => cancelAnimationFrame(rafId);\n }, [drawConnections, nodeTree]);\n\n React.useEffect(() => {\n if (layoutState.animationTotal <= 0 || layoutState.nodeDelays.size === 0) {\n return;\n }\n\n const entries = Array.from(layoutState.nodeDelays.entries())\n .map(([id, delay]) => ({\n id,\n end: delay + layoutState.nodeAnimDuration,\n }))\n .sort((a, b) => a.end - b.end);\n\n doneNodesRef.current = new Set();\n setDoneNodes(new Set());\n\n const start = performance.now();\n let rafId = 0;\n let index = 0;\n\n const tick = () => {\n const elapsed = (performance.now() - start) / 1000;\n let updated = false;\n\n while (index < entries.length && elapsed >= entries[index].end) {\n doneNodesRef.current.add(entries[index].id);\n index += 1;\n updated = true;\n }\n\n if (updated) {\n setDoneNodes(new Set(doneNodesRef.current));\n }\n\n if (index < entries.length) {\n rafId = requestAnimationFrame(tick);\n }\n };\n\n rafId = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafId);\n }, [\n layoutState.animationTotal,\n layoutState.nodeAnimDuration,\n layoutState.nodeDelays,\n ]);\n\n return { doneNodes, layoutState };\n}\n"],"mappings":"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","names":["React","import_jsx_runtime","import_jsx_runtime"]}
|
package/dist/index.css
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
/* src/node-tree.css */
|
|
2
|
-
@keyframes unt-node-enter {
|
|
3
|
-
0% {
|
|
4
|
-
opacity: 0;
|
|
5
|
-
}
|
|
6
|
-
100% {
|
|
7
|
-
opacity: 1;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
2
|
.unt-tree-root-container {
|
|
11
3
|
position: relative;
|
|
12
4
|
width: 100%;
|
|
@@ -65,7 +57,15 @@
|
|
|
65
57
|
inset: 0;
|
|
66
58
|
z-index: 0;
|
|
67
59
|
}
|
|
68
|
-
|
|
60
|
+
@keyframes unt-node-enter {
|
|
61
|
+
0% {
|
|
62
|
+
opacity: 0;
|
|
63
|
+
}
|
|
64
|
+
100% {
|
|
65
|
+
opacity: 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
.unt-node-enter {
|
|
69
69
|
animation-name: unt-node-enter;
|
|
70
70
|
animation-timing-function: ease-out;
|
|
71
71
|
animation-fill-mode: both;
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
opacity: 1;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
.node-line {
|
|
82
|
+
.unt-node-line {
|
|
83
83
|
animation-name: unt-line-draw;
|
|
84
84
|
animation-timing-function: ease-out;
|
|
85
85
|
animation-fill-mode: both;
|
package/dist/index.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/node-tree.css"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../src/node-tree.css"],"sourcesContent":[".unt-tree-root-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 0;\r\n overflow: hidden;\r\n}\r\n\r\n.unt-tree-canvas {\r\n position: relative;\r\n}\r\n\r\n.unt-tree-node-hit {\r\n cursor: auto;\r\n}\r\n\r\n.unt-tree-node-frame {\r\n position: relative;\r\n display: flex;\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n padding: 1rem;\r\n}\r\n\r\n.unt-tree-debug-badge {\r\n position: absolute;\r\n top: 0.5rem;\r\n left: 0.5rem;\r\n z-index: 10;\r\n padding: 0.25rem 0.5rem;\r\n font-size: 0.75rem;\r\n line-height: 1rem;\r\n}\r\n\r\n.unt-tree-debug-badge--0 {\r\n background: #a7f3d0;\r\n color: #042f2e;\r\n}\r\n\r\n.unt-tree-debug-badge--1 {\r\n background: #bae6fd;\r\n color: #082f49;\r\n}\r\n\r\n.unt-tree-debug-badge--2 {\r\n background: #fde68a;\r\n color: #451a03;\r\n}\r\n\r\n.unt-tree-debug-badge--3 {\r\n background: #fecdd3;\r\n color: #4c0519;\r\n}\r\n\r\n.unt-tree-debug-badge--4 {\r\n background: #d9f99d;\r\n color: #1a2e05;\r\n}\r\n\r\n.unt-tree-debug-badge--5 {\r\n background: #ddd6fe;\r\n color: #2e1065;\r\n}\r\n\r\n.unt-tree-connections {\r\n pointer-events: none;\r\n position: absolute;\r\n inset: 0;\r\n z-index: 0;\r\n}\r\n\r\n@keyframes unt-node-enter {\r\n 0% {\r\n opacity: 0;\r\n }\r\n 100% {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n.unt-node-enter {\r\n animation-name: unt-node-enter;\r\n animation-timing-function: ease-out;\r\n animation-fill-mode: both;\r\n}\r\n\r\n@keyframes unt-line-draw {\r\n 0% {\r\n opacity: 0.2;\r\n }\r\n 100% {\r\n stroke-dashoffset: 0;\r\n opacity: 1;\r\n }\r\n}\r\n\r\n.unt-node-line {\r\n animation-name: unt-line-draw;\r\n animation-timing-function: ease-out;\r\n animation-fill-mode: both;\r\n}\r\n"],"mappings":";AAAA,CAAC;AACC,YAAU;AACV,SAAO;AACP,UAAQ;AACR,cAAY;AACZ,YAAU;AACZ;AAEA,CAAC;AACC,YAAU;AACZ;AAEA,CAAC;AACC,UAAQ;AACV;AAEA,CAAC;AACC,YAAU;AACV,WAAS;AACT,UAAQ,IAAI,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;AACtC,WAAS;AACX;AAEA,CAAC;AACC,YAAU;AACV,OAAK;AACL,QAAM;AACN,WAAS;AACT,WAAS,QAAQ;AACjB,aAAW;AACX,eAAa;AACf;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,kBAAgB;AAChB,YAAU;AACV,SAAO;AACP,WAAS;AACX;AAEA,WAAW;AACT;AACE,aAAS;AACX;AACA;AACE,aAAS;AACX;AACF;AAEA,CATW;AAUT,kBAAgB;AAChB,6BAA2B;AAC3B,uBAAqB;AACvB;AAEA,WAAW;AACT;AACE,aAAS;AACX;AACA;AACE,uBAAmB;AACnB,aAAS;AACX;AACF;AAEA,CAAC;AACC,kBAAgB;AAChB,6BAA2B;AAC3B,uBAAqB;AACvB;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,9 @@ function TreeConnections({
|
|
|
24
24
|
"svg",
|
|
25
25
|
{
|
|
26
26
|
className: cn("unt-tree-connections", className),
|
|
27
|
+
"aria-hidden": "true",
|
|
28
|
+
focusable: "false",
|
|
29
|
+
role: "presentation",
|
|
27
30
|
width: layoutState.svgBounds.width,
|
|
28
31
|
height: layoutState.svgBounds.height,
|
|
29
32
|
viewBox: `0 0 ${layoutState.svgBounds.width} ${layoutState.svgBounds.height}`,
|
|
@@ -49,7 +52,7 @@ function TreeConnections({
|
|
|
49
52
|
y1: segment.y1 - layoutState.svgBounds.offsetY,
|
|
50
53
|
x2: segment.x2 - layoutState.svgBounds.offsetX,
|
|
51
54
|
y2: segment.y2 - layoutState.svgBounds.offsetY,
|
|
52
|
-
className: "node-line",
|
|
55
|
+
className: "unt-node-line",
|
|
53
56
|
style: {
|
|
54
57
|
strokeDasharray: segment.length,
|
|
55
58
|
strokeDashoffset: segment.length,
|
|
@@ -87,7 +90,13 @@ function axisToFlexJustify(axis) {
|
|
|
87
90
|
}
|
|
88
91
|
return "center";
|
|
89
92
|
}
|
|
90
|
-
function NodeFrame({
|
|
93
|
+
function NodeFrame({
|
|
94
|
+
node,
|
|
95
|
+
className,
|
|
96
|
+
onRef,
|
|
97
|
+
children,
|
|
98
|
+
...props
|
|
99
|
+
}) {
|
|
91
100
|
return /* @__PURE__ */ jsx2(
|
|
92
101
|
"div",
|
|
93
102
|
{
|
|
@@ -107,6 +116,7 @@ function renderTreeNode({
|
|
|
107
116
|
index,
|
|
108
117
|
parentId,
|
|
109
118
|
depth,
|
|
119
|
+
siblingCount,
|
|
110
120
|
path,
|
|
111
121
|
flowDown,
|
|
112
122
|
alignX,
|
|
@@ -125,29 +135,34 @@ function renderTreeNode({
|
|
|
125
135
|
}
|
|
126
136
|
path.add(node.id);
|
|
127
137
|
const childrenLayoutIsStack = node.children?.layout === "stack" || !flowDown;
|
|
138
|
+
const childNodes = node.children?.nodes ?? [];
|
|
128
139
|
const childCount = node.children?.nodes.length ?? 0;
|
|
129
140
|
const isLeaf = childCount === 0;
|
|
130
141
|
const pathIds = [...path];
|
|
131
|
-
const childrenContent =
|
|
142
|
+
const childrenContent = childNodes.length > 0 ? /* @__PURE__ */ jsx2(
|
|
132
143
|
"div",
|
|
133
144
|
{
|
|
145
|
+
role: "group",
|
|
134
146
|
className: "unt-tree-children",
|
|
135
147
|
style: {
|
|
136
148
|
display: "flex",
|
|
137
149
|
flexShrink: 0,
|
|
138
150
|
flexDirection: childrenLayoutIsStack ? "column" : "row",
|
|
139
151
|
alignItems: axisToFlexAlign(childrenLayoutIsStack ? alignX : alignY),
|
|
140
|
-
justifyContent: axisToFlexJustify(
|
|
152
|
+
justifyContent: axisToFlexJustify(
|
|
153
|
+
childrenLayoutIsStack ? alignY : alignX
|
|
154
|
+
),
|
|
141
155
|
gap,
|
|
142
156
|
marginTop: flowDown || stackUnder ? gap : 0,
|
|
143
157
|
marginLeft: flowDown ? node.children?.layout === "stack" ? gap : 0 : stackUnder ? gap / 2 : gap
|
|
144
158
|
},
|
|
145
|
-
children:
|
|
159
|
+
children: childNodes.map(
|
|
146
160
|
(child, childIndex) => renderTreeNode({
|
|
147
161
|
node: child,
|
|
148
162
|
index: childIndex,
|
|
149
163
|
parentId: node.id,
|
|
150
164
|
depth: depth + 1,
|
|
165
|
+
siblingCount: childNodes.length,
|
|
151
166
|
path,
|
|
152
167
|
flowDown,
|
|
153
168
|
alignX,
|
|
@@ -167,6 +182,11 @@ function renderTreeNode({
|
|
|
167
182
|
return /* @__PURE__ */ jsxs(
|
|
168
183
|
"div",
|
|
169
184
|
{
|
|
185
|
+
role: "treeitem",
|
|
186
|
+
"aria-level": depth + 1,
|
|
187
|
+
"aria-posinset": index + 1,
|
|
188
|
+
"aria-setsize": siblingCount,
|
|
189
|
+
"aria-expanded": childCount > 0 ? true : void 0,
|
|
170
190
|
className: "unt-tree-node-wrap",
|
|
171
191
|
style: {
|
|
172
192
|
display: "flex",
|
|
@@ -180,7 +200,7 @@ function renderTreeNode({
|
|
|
180
200
|
NodeFrame,
|
|
181
201
|
{
|
|
182
202
|
node,
|
|
183
|
-
className: cn("node-enter unt-tree-node-frame", nodeFrameClassName),
|
|
203
|
+
className: cn("unt-node-enter unt-tree-node-frame", nodeFrameClassName),
|
|
184
204
|
style: {
|
|
185
205
|
justifyContent: axisToFlexJustify(alignX),
|
|
186
206
|
animationDuration: `${layoutState.nodeAnimDuration}s`,
|
|
@@ -192,6 +212,7 @@ function renderTreeNode({
|
|
|
192
212
|
debug ? /* @__PURE__ */ jsxs(
|
|
193
213
|
"div",
|
|
194
214
|
{
|
|
215
|
+
"aria-hidden": "true",
|
|
195
216
|
className: cn(
|
|
196
217
|
"unt-tree-debug-badge",
|
|
197
218
|
`unt-tree-debug-badge--${depth % 6}`
|
|
@@ -240,9 +261,11 @@ function TreeRenderer({
|
|
|
240
261
|
}) {
|
|
241
262
|
const rootLayoutRow = rootLayout === "row";
|
|
242
263
|
return /* @__PURE__ */ jsx2(
|
|
243
|
-
"
|
|
264
|
+
"div",
|
|
244
265
|
{
|
|
245
266
|
className: cn("unt-tree-renderer", rendererClassName),
|
|
267
|
+
role: "tree",
|
|
268
|
+
"aria-label": "Node tree",
|
|
246
269
|
style: {
|
|
247
270
|
gap,
|
|
248
271
|
display: "flex",
|
|
@@ -259,6 +282,7 @@ function TreeRenderer({
|
|
|
259
282
|
node,
|
|
260
283
|
index,
|
|
261
284
|
depth: 0,
|
|
285
|
+
siblingCount: nodeTree.length,
|
|
262
286
|
path: /* @__PURE__ */ new Set(),
|
|
263
287
|
flowDown,
|
|
264
288
|
alignX,
|
|
@@ -785,7 +809,7 @@ var NodeTree = React2.forwardRef(
|
|
|
785
809
|
const alignValue = resolvedAlign;
|
|
786
810
|
const alignX = typeof alignValue === "string" ? alignValue : alignValue.x;
|
|
787
811
|
const alignY = typeof alignValue === "string" ? "start" : alignValue.y;
|
|
788
|
-
const resolvedConnectionOpacity = connection?.opacity ?? (debug ? 1 : 0.
|
|
812
|
+
const resolvedConnectionOpacity = connection?.opacity ?? (debug ? 1 : 0.25);
|
|
789
813
|
return /* @__PURE__ */ jsx3(
|
|
790
814
|
"div",
|
|
791
815
|
{
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/node-tree.tsx","../src/utils/cn.ts","../src/components/tree-connections.tsx","../src/components/tree-renderer.tsx","../src/hooks/use-node-tree-layout.ts"],"sourcesContent":["import * as React from \"react\";\nimport \"../node-tree.css\";\nimport { cn } from \"../utils/cn\";\nimport { TreeConnections } from \"./tree-connections\";\nimport { TreeRenderer } from \"./tree-renderer\";\nimport { useNodeTreeLayout } from \"../hooks/use-node-tree-layout\";\nimport type { AlignAxis, NodeTreeProps } from \"../types\";\n\r\nconst NodeTree = React.forwardRef<HTMLDivElement, NodeTreeProps>(\r\n (\r\n {\r\n className,\r\n nodeTree,\r\n layout,\r\n connection,\r\n animation,\r\n nodeFrame,\r\n debug = false,\r\n style,\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const containerRef = React.useRef<HTMLDivElement | null>(null);\r\n const nodeRefs = React.useRef(new Map<string, HTMLDivElement>());\r\n const registerNode = React.useCallback(\r\n (id: string, element: HTMLDivElement | null) => {\r\n const registry = nodeRefs.current;\r\n if (element) {\r\n registry.set(id, element);\r\n } else {\r\n registry.delete(id);\r\n }\r\n },\r\n [],\r\n );\r\n\r\n const resolvedAlign = layout?.align ?? \"center\";\r\n const resolvedDirection = layout?.direction ?? \"down\";\r\n const resolvedRootLayout = layout?.root ?? \"stack\";\r\n const resolvedPaddingContainer = layout?.containerPadding ?? 128;\r\n const resolvedPadding = layout?.padding ?? 64;\r\n const resolvedGap = layout?.gap ?? 64;\r\n const resolvedStrokeColor = connection?.color ?? \"rgba(255,255,255)\";\r\n const resolvedStrokeWidth = connection?.width ?? 1;\r\n const resolvedAnimationDurationMs = animation?.durationMs ?? 2000;\r\n const resolvedNodeFrameStyle = nodeFrame?.style;\r\n\r\n const { doneNodes, layoutState } = useNodeTreeLayout({\r\n nodeTree,\r\n direction: resolvedDirection,\r\n gap: resolvedGap,\r\n padding: resolvedPadding,\r\n animationSpeed: resolvedAnimationDurationMs,\r\n debug,\r\n containerRef,\r\n nodeRefs,\r\n });\r\n\r\n const flowDown = resolvedDirection === \"down\";\r\n const alignValue = resolvedAlign;\r\n const alignX: AlignAxis =\r\n typeof alignValue === \"string\" ? alignValue : alignValue.x;\r\n const alignY: AlignAxis =\r\n typeof alignValue === \"string\" ? \"start\" : alignValue.y;\r\n const resolvedConnectionOpacity = connection?.opacity ?? (debug ? 1 : 0.1);\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n className={cn(\"unt-tree-root-container\", className?.root)}\r\n style={style}\r\n {...props}\r\n >\r\n <div\r\n ref={containerRef}\r\n className={cn(\"unt-tree-canvas\", className?.canvas)}\r\n style={{ padding: resolvedPaddingContainer }}\r\n >\r\n <TreeConnections\r\n layoutState={layoutState}\r\n debug={debug}\r\n strokeColor={resolvedStrokeColor}\r\n strokeWidth={resolvedStrokeWidth}\r\n opacity={resolvedConnectionOpacity}\r\n className={className?.connections}\r\n />\r\n <TreeRenderer\r\n nodeTree={nodeTree}\r\n rootLayout={resolvedRootLayout}\r\n flowDown={flowDown}\r\n alignX={alignX}\r\n alignY={alignY}\r\n gap={resolvedGap}\r\n debug={debug}\r\n layoutState={layoutState}\r\n doneNodes={doneNodes}\r\n registerNode={registerNode}\r\n rendererClassName={className?.renderer}\r\n nodeFrameClassName={className?.frame}\r\n nodeFrameStyle={resolvedNodeFrameStyle}\r\n />\r\n </div>\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nNodeTree.displayName = \"NodeTree\";\r\n\r\nexport { NodeTree };\r\n","import { clsx, type ClassValue } from \"clsx\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return clsx(inputs);\r\n}\r\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport type { NodeTreeLayoutState } from \"../types\";\n\r\ntype TreeConnectionsProps = {\r\n layoutState: NodeTreeLayoutState;\r\n debug: boolean;\r\n strokeColor: string;\r\n strokeWidth: number;\r\n opacity: number;\r\n className?: string;\r\n};\r\n\r\nexport function TreeConnections({\r\n layoutState,\r\n debug,\r\n strokeColor,\r\n strokeWidth,\r\n opacity,\r\n className,\r\n}: TreeConnectionsProps) {\r\n if (!layoutState.svgBounds) {\r\n return null;\r\n }\r\n\r\n return (\r\n <svg\r\n className={cn(\"unt-tree-connections\", className)}\r\n width={layoutState.svgBounds.width}\r\n height={layoutState.svgBounds.height}\r\n viewBox={`0 0 ${layoutState.svgBounds.width} ${layoutState.svgBounds.height}`}\r\n style={{\r\n left: layoutState.svgBounds.offsetX,\r\n top: layoutState.svgBounds.offsetY,\r\n opacity,\r\n }}\r\n >\r\n {layoutState.segments.map((segment) => {\r\n const debugPalette = [\r\n \"#22d3ee\",\r\n \"#a855f7\",\r\n \"#f59e0b\",\r\n \"#10b981\",\r\n \"#f97316\",\r\n \"#38bdf8\",\r\n ];\r\n const lineColor = debug\r\n ? debugPalette[segment.colorIndex % debugPalette.length]\r\n : strokeColor;\r\n return (\r\n <line\r\n key={`${segment.x1}-${segment.y1}-${segment.x2}-${segment.y2}-${segment.delay}`}\r\n x1={segment.x1 - layoutState.svgBounds!.offsetX}\r\n y1={segment.y1 - layoutState.svgBounds!.offsetY}\r\n x2={segment.x2 - layoutState.svgBounds!.offsetX}\r\n y2={segment.y2 - layoutState.svgBounds!.offsetY}\r\n className=\"node-line\"\r\n style={{\r\n strokeDasharray: segment.length,\r\n strokeDashoffset: segment.length,\r\n animationDelay: `${segment.delay}s`,\r\n animationDuration: `${segment.duration}s`,\r\n }}\r\n stroke={lineColor}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n );\r\n })}\r\n </svg>\r\n );\r\n}\r\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport type {\n AlignAxis,\n NodeFrameProps,\n NodeTreeLayoutState,\n TreeNode,\n} from \"../types\";\n\r\ntype TreeRendererProps = {\r\n nodeTree: TreeNode[];\n rootLayout: \"stack\" | \"row\";\r\n flowDown: boolean;\r\n alignX: AlignAxis;\r\n alignY: AlignAxis;\r\n gap: number;\r\n debug: boolean;\r\n layoutState: NodeTreeLayoutState;\r\n doneNodes: Set<string>;\r\n registerNode: (id: string, element: HTMLDivElement | null) => void;\r\n rendererClassName?: string;\r\n nodeFrameClassName?: string;\r\n nodeFrameStyle?: React.CSSProperties;\r\n};\r\n\r\nfunction axisToFlexAlign(axis: AlignAxis): React.CSSProperties[\"alignItems\"] {\r\n if (axis === \"start\") {\r\n return \"flex-start\";\r\n }\r\n if (axis === \"end\") {\r\n return \"flex-end\";\r\n }\r\n return \"center\";\r\n}\r\n\r\nfunction axisToFlexJustify(axis: AlignAxis): React.CSSProperties[\"justifyContent\"] {\r\n if (axis === \"start\") {\r\n return \"flex-start\";\r\n }\r\n if (axis === \"end\") {\r\n return \"flex-end\";\r\n }\r\n return \"center\";\r\n}\r\n\r\nfunction NodeFrame({ node, className, onRef, children, ...props }: NodeFrameProps) {\r\n return (\r\n <div\r\n ref={(element) => {\r\n onRef(node.id, element);\r\n }}\r\n className={cn(\"unt-tree-node-hit\", className)}\r\n data-nodeframe\r\n data-viewport-no-pan\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nfunction renderTreeNode({\r\n node,\r\n index,\r\n parentId,\r\n depth,\r\n path,\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n}: {\r\n node: TreeNode;\n index: number;\r\n parentId?: string;\r\n depth: number;\r\n path: Set<string>;\r\n flowDown: boolean;\r\n alignX: AlignAxis;\r\n alignY: AlignAxis;\r\n gap: number;\r\n debug: boolean;\r\n layoutState: NodeTreeLayoutState;\r\n doneNodes: Set<string>;\r\n registerNode: (id: string, element: HTMLDivElement | null) => void;\r\n nodeFrameClassName?: string;\r\n nodeFrameStyle?: React.CSSProperties;\r\n}): React.ReactNode {\r\n const stackUnder = !flowDown && node.children?.layout === \"stack\";\r\n if (path.has(node.id)) {\r\n return null;\r\n }\r\n\r\n path.add(node.id);\r\n const childrenLayoutIsStack = node.children?.layout === \"stack\" || !flowDown;\r\n const childCount = node.children?.nodes.length ?? 0;\r\n const isLeaf = childCount === 0;\r\n const pathIds = [...path];\r\n const childrenContent =\r\n node.children?.nodes && node.children.nodes.length > 0 ? (\r\n <div\r\n className=\"unt-tree-children\"\r\n style={{\r\n display: \"flex\",\r\n flexShrink: 0,\r\n flexDirection: childrenLayoutIsStack ? \"column\" : \"row\",\r\n alignItems: axisToFlexAlign(childrenLayoutIsStack ? alignX : alignY),\r\n justifyContent: axisToFlexJustify(childrenLayoutIsStack ? alignY : alignX),\r\n gap,\r\n marginTop: flowDown || stackUnder ? gap : 0,\r\n marginLeft: flowDown\r\n ? node.children?.layout === \"stack\"\r\n ? gap\r\n : 0\r\n : stackUnder\r\n ? gap / 2\r\n : gap,\r\n }}\r\n >\r\n {node.children.nodes.map((child, childIndex) =>\r\n renderTreeNode({\r\n node: child,\r\n index: childIndex,\r\n parentId: node.id,\r\n depth: depth + 1,\r\n path,\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n }),\r\n )}\r\n </div>\r\n ) : null;\r\n path.delete(node.id);\r\n\r\n return (\r\n <div\r\n key={`${node.id}-${index}`}\r\n className=\"unt-tree-node-wrap\"\r\n style={{\r\n display: \"flex\",\r\n position: \"relative\",\r\n flexDirection: flowDown || stackUnder ? \"column\" : \"row\",\r\n alignItems: axisToFlexAlign(flowDown ? alignX : alignY),\r\n justifyContent: axisToFlexJustify(flowDown ? alignY : alignX),\r\n }}\r\n >\r\n <NodeFrame\r\n node={node}\r\n className={cn(\"node-enter unt-tree-node-frame\", nodeFrameClassName)}\r\n style={{\r\n justifyContent: axisToFlexJustify(alignX),\r\n animationDuration: `${layoutState.nodeAnimDuration}s`,\r\n animationDelay: `${\r\n layoutState.nodeDelays.get(node.id) ?? depth * 0.08 + index * 0.04\r\n }s`,\r\n ...nodeFrameStyle,\r\n }}\r\n onRef={registerNode}\r\n >\r\n {debug ? (\r\n <div\r\n className={cn(\r\n \"unt-tree-debug-badge\",\r\n `unt-tree-debug-badge--${depth % 6}`,\r\n )}\r\n >\r\n <div>{`DEPTH: ${depth}`}</div>\r\n <div>{`PARENT-ID: ${parentId ?? \"root\"}`}</div>\r\n <div>{`NODE-ID: ${node.id}`}</div>\r\n <div>{`C-LAYOUT: ${node.children?.layout ?? \"N/A\"}`}</div>\r\n </div>\r\n ) : null}\r\n {node.render({\r\n node,\r\n index,\r\n depth,\r\n parentId,\r\n path: pathIds,\r\n isLeaf,\r\n childCount,\r\n isNodeAnimationDone: doneNodes.has(node.id),\r\n })}\r\n </NodeFrame>\r\n\r\n {childrenContent}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TreeRenderer({\r\n nodeTree,\r\n rootLayout,\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n rendererClassName,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n}: TreeRendererProps) {\r\n const rootLayoutRow = rootLayout === \"row\";\r\n return (\r\n <section\r\n className={cn(\"unt-tree-renderer\", rendererClassName)}\r\n style={{\r\n gap,\r\n display: \"flex\",\r\n width: \"100%\",\r\n overflow: \"visible\",\r\n position: \"relative\",\r\n zIndex: 10,\r\n flexDirection: rootLayoutRow ? \"row\" : \"column\",\r\n alignItems: axisToFlexAlign(rootLayoutRow ? alignY : alignX),\r\n justifyContent: axisToFlexJustify(rootLayoutRow ? alignX : alignY),\r\n }}\r\n >\r\n {nodeTree.map((node, index) =>\r\n renderTreeNode({\r\n node,\r\n index,\r\n depth: 0,\r\n path: new Set<string>(),\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n }),\r\n )}\r\n </section>\r\n );\r\n}\r\n","import * as React from \"react\";\nimport type {\n NodeTreeLayoutState,\n TreeNode,\n TreeNodeEdge,\n} from \"../types\";\n\ntype EdgeGeometry = {\n edge: TreeNodeEdge;\n fromX: number;\n fromY: number;\n fromBottom: number;\n fromCenterX: number;\n toX: number;\n toY: number;\n toLeft: number;\n toCenterY: number;\n};\n\ntype UseNodeTreeLayoutParams = {\n nodeTree: TreeNode[];\n direction: \"down\" | \"right\";\n gap: number;\n padding: number;\n animationSpeed: number;\n debug: boolean;\n containerRef: React.RefObject<HTMLDivElement | null>;\n nodeRefs: React.MutableRefObject<Map<string, HTMLDivElement>>;\n};\n\nconst EMPTY_LAYOUT: NodeTreeLayoutState = {\n segments: [],\n nodeDelays: new Map(),\n nodeAnimDuration: 0.42,\n animationTotal: 0,\n svgBounds: null,\n};\n\nfunction collectEdges(nodes: TreeNode[]) {\n const edges: TreeNodeEdge[] = [];\n const visiting = new Set<string>();\n const visit = (node: TreeNode) => {\n if (visiting.has(node.id)) {\n return;\n }\n visiting.add(node.id);\n if (node.children?.nodes && node.children.nodes.length > 0) {\n node.children.nodes.forEach((child, index) => {\n const key = `${node.id}=>${child.id}`;\n edges.push({\n key,\n from: node.id,\n to: child.id,\n index,\n count: node.children?.nodes.length ?? 1,\n });\n visit(child);\n });\n }\n visiting.delete(node.id);\n };\n\n nodes.forEach(visit);\n return edges;\n}\n\nfunction collectDescendants(nodes: TreeNode[]) {\n const map = new Map<string, string[]>();\n const visiting = new Set<string>();\n const visit = (node: TreeNode): string[] => {\n if (visiting.has(node.id)) {\n return [];\n }\n visiting.add(node.id);\n const descendants: string[] = [];\n node.children?.nodes.forEach((child) => {\n descendants.push(child.id);\n descendants.push(...visit(child));\n });\n map.set(node.id, descendants);\n visiting.delete(node.id);\n return descendants;\n };\n nodes.forEach(visit);\n return map;\n}\n\nexport function useNodeTreeLayout({\n nodeTree,\n direction,\n gap,\n padding,\n animationSpeed,\n debug,\n containerRef,\n nodeRefs,\n}: UseNodeTreeLayoutParams) {\n const [layoutState, setLayoutState] =\n React.useState<NodeTreeLayoutState>(EMPTY_LAYOUT);\n const [doneNodes, setDoneNodes] = React.useState<Set<string>>(\n () => new Set(),\n );\n const doneNodesRef = React.useRef<Set<string>>(new Set());\n const edges = React.useMemo(() => collectEdges(nodeTree), [nodeTree]);\n const descendantMap = React.useMemo(\n () => collectDescendants(nodeTree),\n [nodeTree],\n );\n\n const totalAnimationSec = Math.max(0.1, animationSpeed / 1000);\n\n const drawConnections = React.useCallback(() => {\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const flowDown = direction === \"down\";\n\n const getRelativeRect = (element: HTMLElement) => {\n let left = 0;\n let top = 0;\n let current: HTMLElement | null = element;\n while (current && current !== container) {\n left += current.offsetLeft;\n top += current.offsetTop;\n current = current.offsetParent as HTMLElement | null;\n }\n return {\n left,\n top,\n right: left + element.offsetWidth,\n bottom: top + element.offsetHeight,\n width: element.offsetWidth,\n height: element.offsetHeight,\n };\n };\n\n const rectMap = new Map<string, ReturnType<typeof getRelativeRect>>();\n nodeRefs.current.forEach((el, id) => {\n rectMap.set(id, getRelativeRect(el));\n });\n\n const nextSegments: NodeTreeLayoutState[\"segments\"] = [];\n const nextNodeDelays = new Map<string, number>();\n const baseSecondsPerPixel = 1 / 900;\n const baseNodeAnimDuration = 0.42;\n const edgeColorIndex = debug ? new Map<string, number>() : null;\n const edgeData = new Map<string, EdgeGeometry>();\n\n edges.forEach((edge) => {\n const fromRect = rectMap.get(edge.from);\n const toRect = rectMap.get(edge.to);\n if (!fromRect || !toRect) {\n return;\n }\n\n const fromX = flowDown ? fromRect.left + fromRect.width / 2 : fromRect.right;\n const fromY = flowDown\n ? fromRect.bottom\n : fromRect.top + fromRect.height / 2;\n const toX = flowDown ? toRect.left + toRect.width / 2 : toRect.left;\n const toY = flowDown ? toRect.top : toRect.top + toRect.height / 2;\n\n edgeData.set(edge.key, {\n edge,\n fromX,\n fromY,\n fromBottom: fromRect.bottom,\n fromCenterX: fromRect.left + fromRect.width / 2,\n toX,\n toY,\n toLeft: toRect.left,\n toCenterY: toRect.top + toRect.height / 2,\n });\n });\n\n const pushSegment = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n depth: number,\n delay: number,\n colorIndex: number,\n order: number,\n ) => {\n const length = Math.hypot(x2 - x1, y2 - y1);\n const duration = Math.max(0.05, length * baseSecondsPerPixel);\n nextSegments.push({\n x1,\n y1,\n x2,\n y2,\n length,\n depth,\n delay,\n duration,\n colorIndex,\n order,\n });\n return duration;\n };\n\n const visit = (node: TreeNode, depth: number, nodeDelay: number) => {\n const existing = nextNodeDelays.get(node.id) ?? 0;\n const resolvedDelay = Math.max(existing, nodeDelay);\n nextNodeDelays.set(node.id, resolvedDelay);\n\n const childEdges =\n node.children?.nodes\n .map((child) => edgeData.get(`${node.id}=>${child.id}`))\n .filter((edge): edge is EdgeGeometry => Boolean(edge)) ?? [];\n const stackLayout = node.children?.layout === \"stack\";\n const descendantIds =\n flowDown && stackLayout ? (descendantMap.get(node.id) ?? []) : [];\n const descendantLefts =\n flowDown && stackLayout\n ? descendantIds\n .map((id) => rectMap.get(id))\n .filter((rect): rect is NonNullable<typeof rect> => Boolean(rect))\n .map((rect) => rect.left)\n : [];\n const descendantMinLeft =\n descendantLefts.length > 0 ? Math.min(...descendantLefts) : undefined;\n const gutterX =\n flowDown && stackLayout\n ? (descendantMinLeft ??\n (childEdges.length > 0\n ? Math.min(...childEdges.map((edge) => edge.toLeft))\n : 0)) -\n gap / 2\n : 0;\n const gutterXRight =\n !flowDown && stackLayout\n ? (childEdges.length > 0\n ? Math.min(...childEdges.map((edge) => edge.toLeft))\n : 0) -\n gap / 2\n : 0;\n\n const orderedChildren =\n node.children?.nodes\n .map((child) => {\n const edge = edgeData.get(`${node.id}=>${child.id}`);\n if (!edge) {\n return null;\n }\n const dx = edge.toX - edge.fromX;\n const dy = edge.toY - edge.fromY;\n const length = Math.hypot(dx, dy);\n return { child, edge, length, toX: edge.toX };\n })\n .filter(\n (entry): entry is NonNullable<typeof entry> => Boolean(entry),\n ) ?? [];\n\n if (debug) {\n orderedChildren.sort((a, b) => {\n if (a.length !== b.length) {\n return a.length - b.length;\n }\n return a.toX - b.toX;\n });\n }\n\n orderedChildren.forEach((entry, index) => {\n const { child, edge } = entry;\n const edgeKey = edge.edge.key;\n let colorIndex = 0;\n if (edgeColorIndex) {\n if (!edgeColorIndex.has(edgeKey)) {\n edgeColorIndex.set(edgeKey, edgeColorIndex.size);\n }\n colorIndex = edgeColorIndex.get(edgeKey) ?? 0;\n }\n const order = orderedChildren.length - 1 - index;\n const edgeDelay = resolvedDelay + baseNodeAnimDuration + index * 0.04;\n let totalDuration = 0;\n if (flowDown && stackLayout) {\n const baseDrop = Math.max(12, gap / 2);\n const targetY = edge.toCenterY;\n const midY =\n edge.fromY + Math.min(baseDrop, (targetY - edge.fromY) * 0.6);\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n edge.fromX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromX,\n midY,\n gutterX,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterX,\n midY,\n gutterX,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterX,\n targetY,\n edge.toLeft,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else if (!flowDown && stackLayout) {\n const targetY = edge.toCenterY;\n const baseDrop = Math.max(12, gap / 2);\n const midY =\n edge.fromBottom +\n Math.min(baseDrop, (targetY - edge.fromBottom) * 0.6);\n totalDuration += pushSegment(\n edge.fromCenterX,\n edge.fromBottom,\n edge.fromCenterX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromCenterX,\n midY,\n gutterXRight,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterXRight,\n midY,\n gutterXRight,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterXRight,\n targetY,\n edge.toLeft,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else if (flowDown) {\n const midY = edge.fromY + (edge.toY - edge.fromY) * 0.5;\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n edge.fromX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromX,\n midY,\n edge.toX,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.toX,\n midY,\n edge.toX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else {\n const midX = edge.fromX + (edge.toX - edge.fromX) * 0.5;\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n midX,\n edge.fromY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n midX,\n edge.fromY,\n midX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n midX,\n edge.toY,\n edge.toX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n }\n visit(child, depth + 1, edgeDelay + totalDuration);\n });\n };\n\n nodeTree.forEach((node) => visit(node, 0, 0));\n\n if (nextSegments.length === 0) {\n setLayoutState((prev) => ({\n ...prev,\n segments: [],\n svgBounds: null,\n animationTotal: 0,\n }));\n setDoneNodes(new Set());\n doneNodesRef.current = new Set();\n return;\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n nextSegments.forEach((segment) => {\n minX = Math.min(minX, segment.x1, segment.x2);\n minY = Math.min(minY, segment.y1, segment.y2);\n maxX = Math.max(maxX, segment.x1, segment.x2);\n maxY = Math.max(maxY, segment.y1, segment.y2);\n });\n\n if (\n !Number.isFinite(minX) ||\n !Number.isFinite(minY) ||\n !Number.isFinite(maxX) ||\n !Number.isFinite(maxY)\n ) {\n return;\n }\n\n const width = Math.max(1, maxX - minX + padding * 2);\n const height = Math.max(1, maxY - minY + padding * 2);\n const offsetX = minX - padding;\n const offsetY = minY - padding;\n\n const maxLineEnd = Math.max(\n 0,\n ...nextSegments.map((segment) => segment.delay + segment.duration),\n );\n const maxNodeEnd =\n Math.max(0, ...Array.from(nextNodeDelays.values())) + baseNodeAnimDuration;\n const animationMax = Math.max(maxLineEnd, maxNodeEnd);\n const scale = animationMax > 0 ? totalAnimationSec / animationMax : 1;\n const scaledSegments = nextSegments\n .map((segment) => ({\n ...segment,\n delay: segment.delay * scale,\n duration: segment.duration * scale,\n }))\n .sort((a, b) => a.order - b.order);\n const scaledNodeDelays = new Map<string, number>();\n nextNodeDelays.forEach((value, key) => {\n scaledNodeDelays.set(key, value * scale);\n });\n\n setLayoutState({\n segments: scaledSegments,\n nodeDelays: scaledNodeDelays,\n nodeAnimDuration: baseNodeAnimDuration * scale,\n animationTotal: animationMax * scale,\n svgBounds: { width, height, offsetX, offsetY },\n });\n setDoneNodes(new Set());\n doneNodesRef.current = new Set();\n }, [\n animationSpeed,\n containerRef,\n debug,\n descendantMap,\n direction,\n edges,\n gap,\n nodeRefs,\n nodeTree,\n padding,\n totalAnimationSec,\n ]);\n\n React.useLayoutEffect(() => {\n const rafId = requestAnimationFrame(drawConnections);\n return () => cancelAnimationFrame(rafId);\n }, [drawConnections, nodeTree]);\n\n React.useEffect(() => {\n if (layoutState.animationTotal <= 0 || layoutState.nodeDelays.size === 0) {\n return;\n }\n\n const entries = Array.from(layoutState.nodeDelays.entries())\n .map(([id, delay]) => ({\n id,\n end: delay + layoutState.nodeAnimDuration,\n }))\n .sort((a, b) => a.end - b.end);\n\n doneNodesRef.current = new Set();\n setDoneNodes(new Set());\n\n const start = performance.now();\n let rafId = 0;\n let index = 0;\n\n const tick = () => {\n const elapsed = (performance.now() - start) / 1000;\n let updated = false;\n\n while (index < entries.length && elapsed >= entries[index].end) {\n doneNodesRef.current.add(entries[index].id);\n index += 1;\n updated = true;\n }\n\n if (updated) {\n setDoneNodes(new Set(doneNodesRef.current));\n }\n\n if (index < entries.length) {\n rafId = requestAnimationFrame(tick);\n }\n };\n\n rafId = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafId);\n }, [\n layoutState.animationTotal,\n layoutState.nodeAnimDuration,\n layoutState.nodeDelays,\n ]);\n\n return { doneNodes, layoutState };\n}\n"],"mappings":"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","names":["React","jsx","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/node-tree.tsx","../src/utils/cn.ts","../src/components/tree-connections.tsx","../src/components/tree-renderer.tsx","../src/hooks/use-node-tree-layout.ts"],"sourcesContent":["import * as React from \"react\";\r\nimport \"../node-tree.css\";\r\nimport { cn } from \"../utils/cn\";\r\nimport { TreeConnections } from \"./tree-connections\";\r\nimport { TreeRenderer } from \"./tree-renderer\";\r\nimport { useNodeTreeLayout } from \"../hooks/use-node-tree-layout\";\r\nimport type { AlignAxis, NodeTreeProps } from \"../types\";\r\n\r\nconst NodeTree = React.forwardRef<HTMLDivElement, NodeTreeProps>(\r\n (\r\n {\r\n className,\r\n nodeTree,\r\n layout,\r\n connection,\r\n animation,\r\n nodeFrame,\r\n debug = false,\r\n style,\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const containerRef = React.useRef<HTMLDivElement | null>(null);\r\n const nodeRefs = React.useRef(new Map<string, HTMLDivElement>());\r\n const registerNode = React.useCallback(\r\n (id: string, element: HTMLDivElement | null) => {\r\n const registry = nodeRefs.current;\r\n if (element) {\r\n registry.set(id, element);\r\n } else {\r\n registry.delete(id);\r\n }\r\n },\r\n [],\r\n );\r\n\r\n const resolvedAlign = layout?.align ?? \"center\";\r\n const resolvedDirection = layout?.direction ?? \"down\";\r\n const resolvedRootLayout = layout?.root ?? \"stack\";\r\n const resolvedPaddingContainer = layout?.containerPadding ?? 128;\r\n const resolvedPadding = layout?.padding ?? 64;\r\n const resolvedGap = layout?.gap ?? 64;\r\n const resolvedStrokeColor = connection?.color ?? \"rgba(255,255,255)\";\r\n const resolvedStrokeWidth = connection?.width ?? 1;\r\n const resolvedAnimationDurationMs = animation?.durationMs ?? 2000;\r\n const resolvedNodeFrameStyle = nodeFrame?.style;\r\n\r\n const { doneNodes, layoutState } = useNodeTreeLayout({\r\n nodeTree,\r\n direction: resolvedDirection,\r\n gap: resolvedGap,\r\n padding: resolvedPadding,\r\n animationSpeed: resolvedAnimationDurationMs,\r\n debug,\r\n containerRef,\r\n nodeRefs,\r\n });\r\n\r\n const flowDown = resolvedDirection === \"down\";\r\n const alignValue = resolvedAlign;\r\n const alignX: AlignAxis =\r\n typeof alignValue === \"string\" ? alignValue : alignValue.x;\r\n const alignY: AlignAxis =\r\n typeof alignValue === \"string\" ? \"start\" : alignValue.y;\r\n const resolvedConnectionOpacity = connection?.opacity ?? (debug ? 1 : 0.25);\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n className={cn(\"unt-tree-root-container\", className?.root)}\r\n style={style}\r\n {...props}\r\n >\r\n <div\r\n ref={containerRef}\r\n className={cn(\"unt-tree-canvas\", className?.canvas)}\r\n style={{ padding: resolvedPaddingContainer }}\r\n >\r\n <TreeConnections\r\n layoutState={layoutState}\r\n debug={debug}\r\n strokeColor={resolvedStrokeColor}\r\n strokeWidth={resolvedStrokeWidth}\r\n opacity={resolvedConnectionOpacity}\r\n className={className?.connections}\r\n />\r\n <TreeRenderer\r\n nodeTree={nodeTree}\r\n rootLayout={resolvedRootLayout}\r\n flowDown={flowDown}\r\n alignX={alignX}\r\n alignY={alignY}\r\n gap={resolvedGap}\r\n debug={debug}\r\n layoutState={layoutState}\r\n doneNodes={doneNodes}\r\n registerNode={registerNode}\r\n rendererClassName={className?.renderer}\r\n nodeFrameClassName={className?.frame}\r\n nodeFrameStyle={resolvedNodeFrameStyle}\r\n />\r\n </div>\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nNodeTree.displayName = \"NodeTree\";\r\n\r\nexport { NodeTree };\r\n","import { clsx, type ClassValue } from \"clsx\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return clsx(inputs);\r\n}\r\n","import * as React from \"react\";\r\nimport { cn } from \"../utils/cn\";\r\nimport type { NodeTreeLayoutState } from \"../types\";\r\n\r\ntype TreeConnectionsProps = {\r\n layoutState: NodeTreeLayoutState;\r\n debug: boolean;\r\n strokeColor: string;\r\n strokeWidth: number;\r\n opacity: number;\r\n className?: string;\r\n};\r\n\r\nexport function TreeConnections({\r\n layoutState,\r\n debug,\r\n strokeColor,\r\n strokeWidth,\r\n opacity,\r\n className,\r\n}: TreeConnectionsProps) {\r\n if (!layoutState.svgBounds) {\r\n return null;\r\n }\r\n\r\n return (\n <svg\n className={cn(\"unt-tree-connections\", className)}\n aria-hidden=\"true\"\n focusable=\"false\"\n role=\"presentation\"\n width={layoutState.svgBounds.width}\n height={layoutState.svgBounds.height}\n viewBox={`0 0 ${layoutState.svgBounds.width} ${layoutState.svgBounds.height}`}\n style={{\n left: layoutState.svgBounds.offsetX,\n top: layoutState.svgBounds.offsetY,\r\n opacity,\r\n }}\r\n >\r\n {layoutState.segments.map((segment) => {\r\n const debugPalette = [\r\n \"#22d3ee\",\r\n \"#a855f7\",\r\n \"#f59e0b\",\r\n \"#10b981\",\r\n \"#f97316\",\r\n \"#38bdf8\",\r\n ];\r\n const lineColor = debug\r\n ? debugPalette[segment.colorIndex % debugPalette.length]\r\n : strokeColor;\r\n return (\r\n <line\r\n key={`${segment.x1}-${segment.y1}-${segment.x2}-${segment.y2}-${segment.delay}`}\r\n x1={segment.x1 - layoutState.svgBounds!.offsetX}\r\n y1={segment.y1 - layoutState.svgBounds!.offsetY}\r\n x2={segment.x2 - layoutState.svgBounds!.offsetX}\r\n y2={segment.y2 - layoutState.svgBounds!.offsetY}\r\n className=\"unt-node-line\"\r\n style={{\r\n strokeDasharray: segment.length,\r\n strokeDashoffset: segment.length,\r\n animationDelay: `${segment.delay}s`,\r\n animationDuration: `${segment.duration}s`,\r\n }}\r\n stroke={lineColor}\r\n strokeWidth={strokeWidth}\r\n strokeLinecap=\"round\"\r\n />\r\n );\r\n })}\r\n </svg>\r\n );\r\n}\r\n","import * as React from \"react\";\r\nimport { cn } from \"../utils/cn\";\r\nimport type {\r\n AlignAxis,\r\n NodeFrameProps,\r\n NodeTreeLayoutState,\r\n TreeNode,\r\n} from \"../types\";\r\n\r\ntype TreeRendererProps = {\r\n nodeTree: TreeNode[];\r\n rootLayout: \"stack\" | \"row\";\r\n flowDown: boolean;\r\n alignX: AlignAxis;\r\n alignY: AlignAxis;\r\n gap: number;\r\n debug: boolean;\r\n layoutState: NodeTreeLayoutState;\r\n doneNodes: Set<string>;\r\n registerNode: (id: string, element: HTMLDivElement | null) => void;\r\n rendererClassName?: string;\r\n nodeFrameClassName?: string;\r\n nodeFrameStyle?: React.CSSProperties;\r\n};\r\n\r\nfunction axisToFlexAlign(axis: AlignAxis): React.CSSProperties[\"alignItems\"] {\r\n if (axis === \"start\") {\r\n return \"flex-start\";\r\n }\r\n if (axis === \"end\") {\r\n return \"flex-end\";\r\n }\r\n return \"center\";\r\n}\r\n\r\nfunction axisToFlexJustify(\r\n axis: AlignAxis,\r\n): React.CSSProperties[\"justifyContent\"] {\r\n if (axis === \"start\") {\r\n return \"flex-start\";\r\n }\r\n if (axis === \"end\") {\r\n return \"flex-end\";\r\n }\r\n return \"center\";\r\n}\r\n\r\nfunction NodeFrame({\r\n node,\r\n className,\r\n onRef,\r\n children,\r\n ...props\r\n}: NodeFrameProps) {\r\n return (\r\n <div\r\n ref={(element) => {\r\n onRef(node.id, element);\r\n }}\r\n className={cn(\"unt-tree-node-hit\", className)}\r\n data-nodeframe\r\n data-viewport-no-pan\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nfunction renderTreeNode({\n node,\n index,\n parentId,\n depth,\n siblingCount,\n path,\n flowDown,\n alignX,\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n}: {\r\n node: TreeNode;\n index: number;\n parentId?: string;\n depth: number;\n siblingCount: number;\n path: Set<string>;\n flowDown: boolean;\r\n alignX: AlignAxis;\r\n alignY: AlignAxis;\r\n gap: number;\r\n debug: boolean;\r\n layoutState: NodeTreeLayoutState;\r\n doneNodes: Set<string>;\r\n registerNode: (id: string, element: HTMLDivElement | null) => void;\r\n nodeFrameClassName?: string;\r\n nodeFrameStyle?: React.CSSProperties;\r\n}): React.ReactNode {\r\n const stackUnder = !flowDown && node.children?.layout === \"stack\";\r\n if (path.has(node.id)) {\r\n return null;\r\n }\r\n\r\n path.add(node.id);\r\n const childrenLayoutIsStack = node.children?.layout === \"stack\" || !flowDown;\n const childNodes = node.children?.nodes ?? [];\n const childCount = node.children?.nodes.length ?? 0;\n const isLeaf = childCount === 0;\n const pathIds = [...path];\n const childrenContent =\n childNodes.length > 0 ? (\n <div\n role=\"group\"\n className=\"unt-tree-children\"\n style={{\n display: \"flex\",\r\n flexShrink: 0,\r\n flexDirection: childrenLayoutIsStack ? \"column\" : \"row\",\r\n alignItems: axisToFlexAlign(childrenLayoutIsStack ? alignX : alignY),\r\n justifyContent: axisToFlexJustify(\r\n childrenLayoutIsStack ? alignY : alignX,\r\n ),\r\n gap,\r\n marginTop: flowDown || stackUnder ? gap : 0,\r\n marginLeft: flowDown\r\n ? node.children?.layout === \"stack\"\r\n ? gap\r\n : 0\r\n : stackUnder\r\n ? gap / 2\r\n : gap,\r\n }}\r\n >\n {childNodes.map((child, childIndex) =>\n renderTreeNode({\n node: child,\n index: childIndex,\n parentId: node.id,\n depth: depth + 1,\n siblingCount: childNodes.length,\n path,\n flowDown,\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n }),\r\n )}\r\n </div>\r\n ) : null;\r\n path.delete(node.id);\r\n\r\n return (\r\n <div\n key={`${node.id}-${index}`}\n role=\"treeitem\"\n aria-level={depth + 1}\n aria-posinset={index + 1}\n aria-setsize={siblingCount}\n aria-expanded={childCount > 0 ? true : undefined}\n className=\"unt-tree-node-wrap\"\n style={{\n display: \"flex\",\r\n position: \"relative\",\r\n flexDirection: flowDown || stackUnder ? \"column\" : \"row\",\r\n alignItems: axisToFlexAlign(flowDown ? alignX : alignY),\r\n justifyContent: axisToFlexJustify(flowDown ? alignY : alignX),\r\n }}\r\n >\r\n <NodeFrame\r\n node={node}\r\n className={cn(\"unt-node-enter unt-tree-node-frame\", nodeFrameClassName)}\r\n style={{\r\n justifyContent: axisToFlexJustify(alignX),\r\n animationDuration: `${layoutState.nodeAnimDuration}s`,\r\n animationDelay: `${\r\n layoutState.nodeDelays.get(node.id) ?? depth * 0.08 + index * 0.04\r\n }s`,\r\n ...nodeFrameStyle,\r\n }}\r\n onRef={registerNode}\r\n >\r\n {debug ? (\n <div\n aria-hidden=\"true\"\n className={cn(\n \"unt-tree-debug-badge\",\n `unt-tree-debug-badge--${depth % 6}`,\n )}\r\n >\r\n <div>{`DEPTH: ${depth}`}</div>\r\n <div>{`PARENT-ID: ${parentId ?? \"root\"}`}</div>\r\n <div>{`NODE-ID: ${node.id}`}</div>\r\n <div>{`C-LAYOUT: ${node.children?.layout ?? \"N/A\"}`}</div>\r\n </div>\r\n ) : null}\r\n {node.render({\r\n node,\r\n index,\r\n depth,\r\n parentId,\r\n path: pathIds,\r\n isLeaf,\r\n childCount,\r\n isNodeAnimationDone: doneNodes.has(node.id),\r\n })}\r\n </NodeFrame>\r\n\r\n {childrenContent}\r\n </div>\r\n );\r\n}\r\n\r\nexport function TreeRenderer({\r\n nodeTree,\r\n rootLayout,\r\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n rendererClassName,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n}: TreeRendererProps) {\r\n const rootLayoutRow = rootLayout === \"row\";\r\n return (\n <div\n className={cn(\"unt-tree-renderer\", rendererClassName)}\n role=\"tree\"\n aria-label=\"Node tree\"\n style={{\n gap,\r\n display: \"flex\",\r\n width: \"100%\",\r\n overflow: \"visible\",\r\n position: \"relative\",\r\n zIndex: 10,\r\n flexDirection: rootLayoutRow ? \"row\" : \"column\",\r\n alignItems: axisToFlexAlign(rootLayoutRow ? alignY : alignX),\r\n justifyContent: axisToFlexJustify(rootLayoutRow ? alignX : alignY),\r\n }}\r\n >\r\n {nodeTree.map((node, index) =>\r\n renderTreeNode({\r\n node,\n index,\n depth: 0,\n siblingCount: nodeTree.length,\n path: new Set<string>(),\n flowDown,\r\n alignX,\r\n alignY,\r\n gap,\r\n debug,\r\n layoutState,\r\n doneNodes,\r\n registerNode,\r\n nodeFrameClassName,\r\n nodeFrameStyle,\r\n }),\r\n )}\r\n </div>\r\n );\r\n}\r\n","import * as React from \"react\";\nimport type {\n NodeTreeLayoutState,\n TreeNode,\n TreeNodeEdge,\n} from \"../types\";\n\ntype EdgeGeometry = {\n edge: TreeNodeEdge;\n fromX: number;\n fromY: number;\n fromBottom: number;\n fromCenterX: number;\n toX: number;\n toY: number;\n toLeft: number;\n toCenterY: number;\n};\n\ntype UseNodeTreeLayoutParams = {\n nodeTree: TreeNode[];\n direction: \"down\" | \"right\";\n gap: number;\n padding: number;\n animationSpeed: number;\n debug: boolean;\n containerRef: React.RefObject<HTMLDivElement | null>;\n nodeRefs: React.MutableRefObject<Map<string, HTMLDivElement>>;\n};\n\nconst EMPTY_LAYOUT: NodeTreeLayoutState = {\n segments: [],\n nodeDelays: new Map(),\n nodeAnimDuration: 0.42,\n animationTotal: 0,\n svgBounds: null,\n};\n\nfunction collectEdges(nodes: TreeNode[]) {\n const edges: TreeNodeEdge[] = [];\n const visiting = new Set<string>();\n const visit = (node: TreeNode) => {\n if (visiting.has(node.id)) {\n return;\n }\n visiting.add(node.id);\n if (node.children?.nodes && node.children.nodes.length > 0) {\n node.children.nodes.forEach((child, index) => {\n const key = `${node.id}=>${child.id}`;\n edges.push({\n key,\n from: node.id,\n to: child.id,\n index,\n count: node.children?.nodes.length ?? 1,\n });\n visit(child);\n });\n }\n visiting.delete(node.id);\n };\n\n nodes.forEach(visit);\n return edges;\n}\n\nfunction collectDescendants(nodes: TreeNode[]) {\n const map = new Map<string, string[]>();\n const visiting = new Set<string>();\n const visit = (node: TreeNode): string[] => {\n if (visiting.has(node.id)) {\n return [];\n }\n visiting.add(node.id);\n const descendants: string[] = [];\n node.children?.nodes.forEach((child) => {\n descendants.push(child.id);\n descendants.push(...visit(child));\n });\n map.set(node.id, descendants);\n visiting.delete(node.id);\n return descendants;\n };\n nodes.forEach(visit);\n return map;\n}\n\nexport function useNodeTreeLayout({\n nodeTree,\n direction,\n gap,\n padding,\n animationSpeed,\n debug,\n containerRef,\n nodeRefs,\n}: UseNodeTreeLayoutParams) {\n const [layoutState, setLayoutState] =\n React.useState<NodeTreeLayoutState>(EMPTY_LAYOUT);\n const [doneNodes, setDoneNodes] = React.useState<Set<string>>(\n () => new Set(),\n );\n const doneNodesRef = React.useRef<Set<string>>(new Set());\n const edges = React.useMemo(() => collectEdges(nodeTree), [nodeTree]);\n const descendantMap = React.useMemo(\n () => collectDescendants(nodeTree),\n [nodeTree],\n );\n\n const totalAnimationSec = Math.max(0.1, animationSpeed / 1000);\n\n const drawConnections = React.useCallback(() => {\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const flowDown = direction === \"down\";\n\n const getRelativeRect = (element: HTMLElement) => {\n let left = 0;\n let top = 0;\n let current: HTMLElement | null = element;\n while (current && current !== container) {\n left += current.offsetLeft;\n top += current.offsetTop;\n current = current.offsetParent as HTMLElement | null;\n }\n return {\n left,\n top,\n right: left + element.offsetWidth,\n bottom: top + element.offsetHeight,\n width: element.offsetWidth,\n height: element.offsetHeight,\n };\n };\n\n const rectMap = new Map<string, ReturnType<typeof getRelativeRect>>();\n nodeRefs.current.forEach((el, id) => {\n rectMap.set(id, getRelativeRect(el));\n });\n\n const nextSegments: NodeTreeLayoutState[\"segments\"] = [];\n const nextNodeDelays = new Map<string, number>();\n const baseSecondsPerPixel = 1 / 900;\n const baseNodeAnimDuration = 0.42;\n const edgeColorIndex = debug ? new Map<string, number>() : null;\n const edgeData = new Map<string, EdgeGeometry>();\n\n edges.forEach((edge) => {\n const fromRect = rectMap.get(edge.from);\n const toRect = rectMap.get(edge.to);\n if (!fromRect || !toRect) {\n return;\n }\n\n const fromX = flowDown ? fromRect.left + fromRect.width / 2 : fromRect.right;\n const fromY = flowDown\n ? fromRect.bottom\n : fromRect.top + fromRect.height / 2;\n const toX = flowDown ? toRect.left + toRect.width / 2 : toRect.left;\n const toY = flowDown ? toRect.top : toRect.top + toRect.height / 2;\n\n edgeData.set(edge.key, {\n edge,\n fromX,\n fromY,\n fromBottom: fromRect.bottom,\n fromCenterX: fromRect.left + fromRect.width / 2,\n toX,\n toY,\n toLeft: toRect.left,\n toCenterY: toRect.top + toRect.height / 2,\n });\n });\n\n const pushSegment = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n depth: number,\n delay: number,\n colorIndex: number,\n order: number,\n ) => {\n const length = Math.hypot(x2 - x1, y2 - y1);\n const duration = Math.max(0.05, length * baseSecondsPerPixel);\n nextSegments.push({\n x1,\n y1,\n x2,\n y2,\n length,\n depth,\n delay,\n duration,\n colorIndex,\n order,\n });\n return duration;\n };\n\n const visit = (node: TreeNode, depth: number, nodeDelay: number) => {\n const existing = nextNodeDelays.get(node.id) ?? 0;\n const resolvedDelay = Math.max(existing, nodeDelay);\n nextNodeDelays.set(node.id, resolvedDelay);\n\n const childEdges =\n node.children?.nodes\n .map((child) => edgeData.get(`${node.id}=>${child.id}`))\n .filter((edge): edge is EdgeGeometry => Boolean(edge)) ?? [];\n const stackLayout = node.children?.layout === \"stack\";\n const descendantIds =\n flowDown && stackLayout ? (descendantMap.get(node.id) ?? []) : [];\n const descendantLefts =\n flowDown && stackLayout\n ? descendantIds\n .map((id) => rectMap.get(id))\n .filter((rect): rect is NonNullable<typeof rect> => Boolean(rect))\n .map((rect) => rect.left)\n : [];\n const descendantMinLeft =\n descendantLefts.length > 0 ? Math.min(...descendantLefts) : undefined;\n const gutterX =\n flowDown && stackLayout\n ? (descendantMinLeft ??\n (childEdges.length > 0\n ? Math.min(...childEdges.map((edge) => edge.toLeft))\n : 0)) -\n gap / 2\n : 0;\n const gutterXRight =\n !flowDown && stackLayout\n ? (childEdges.length > 0\n ? Math.min(...childEdges.map((edge) => edge.toLeft))\n : 0) -\n gap / 2\n : 0;\n\n const orderedChildren =\n node.children?.nodes\n .map((child) => {\n const edge = edgeData.get(`${node.id}=>${child.id}`);\n if (!edge) {\n return null;\n }\n const dx = edge.toX - edge.fromX;\n const dy = edge.toY - edge.fromY;\n const length = Math.hypot(dx, dy);\n return { child, edge, length, toX: edge.toX };\n })\n .filter(\n (entry): entry is NonNullable<typeof entry> => Boolean(entry),\n ) ?? [];\n\n if (debug) {\n orderedChildren.sort((a, b) => {\n if (a.length !== b.length) {\n return a.length - b.length;\n }\n return a.toX - b.toX;\n });\n }\n\n orderedChildren.forEach((entry, index) => {\n const { child, edge } = entry;\n const edgeKey = edge.edge.key;\n let colorIndex = 0;\n if (edgeColorIndex) {\n if (!edgeColorIndex.has(edgeKey)) {\n edgeColorIndex.set(edgeKey, edgeColorIndex.size);\n }\n colorIndex = edgeColorIndex.get(edgeKey) ?? 0;\n }\n const order = orderedChildren.length - 1 - index;\n const edgeDelay = resolvedDelay + baseNodeAnimDuration + index * 0.04;\n let totalDuration = 0;\n if (flowDown && stackLayout) {\n const baseDrop = Math.max(12, gap / 2);\n const targetY = edge.toCenterY;\n const midY =\n edge.fromY + Math.min(baseDrop, (targetY - edge.fromY) * 0.6);\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n edge.fromX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromX,\n midY,\n gutterX,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterX,\n midY,\n gutterX,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterX,\n targetY,\n edge.toLeft,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else if (!flowDown && stackLayout) {\n const targetY = edge.toCenterY;\n const baseDrop = Math.max(12, gap / 2);\n const midY =\n edge.fromBottom +\n Math.min(baseDrop, (targetY - edge.fromBottom) * 0.6);\n totalDuration += pushSegment(\n edge.fromCenterX,\n edge.fromBottom,\n edge.fromCenterX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromCenterX,\n midY,\n gutterXRight,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterXRight,\n midY,\n gutterXRight,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n gutterXRight,\n targetY,\n edge.toLeft,\n targetY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else if (flowDown) {\n const midY = edge.fromY + (edge.toY - edge.fromY) * 0.5;\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n edge.fromX,\n midY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.fromX,\n midY,\n edge.toX,\n midY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n edge.toX,\n midY,\n edge.toX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n } else {\n const midX = edge.fromX + (edge.toX - edge.fromX) * 0.5;\n totalDuration += pushSegment(\n edge.fromX,\n edge.fromY,\n midX,\n edge.fromY,\n depth,\n edgeDelay,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n midX,\n edge.fromY,\n midX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n totalDuration += pushSegment(\n midX,\n edge.toY,\n edge.toX,\n edge.toY,\n depth,\n edgeDelay + totalDuration,\n colorIndex,\n order,\n );\n }\n visit(child, depth + 1, edgeDelay + totalDuration);\n });\n };\n\n nodeTree.forEach((node) => visit(node, 0, 0));\n\n if (nextSegments.length === 0) {\n setLayoutState((prev) => ({\n ...prev,\n segments: [],\n svgBounds: null,\n animationTotal: 0,\n }));\n setDoneNodes(new Set());\n doneNodesRef.current = new Set();\n return;\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n nextSegments.forEach((segment) => {\n minX = Math.min(minX, segment.x1, segment.x2);\n minY = Math.min(minY, segment.y1, segment.y2);\n maxX = Math.max(maxX, segment.x1, segment.x2);\n maxY = Math.max(maxY, segment.y1, segment.y2);\n });\n\n if (\n !Number.isFinite(minX) ||\n !Number.isFinite(minY) ||\n !Number.isFinite(maxX) ||\n !Number.isFinite(maxY)\n ) {\n return;\n }\n\n const width = Math.max(1, maxX - minX + padding * 2);\n const height = Math.max(1, maxY - minY + padding * 2);\n const offsetX = minX - padding;\n const offsetY = minY - padding;\n\n const maxLineEnd = Math.max(\n 0,\n ...nextSegments.map((segment) => segment.delay + segment.duration),\n );\n const maxNodeEnd =\n Math.max(0, ...Array.from(nextNodeDelays.values())) + baseNodeAnimDuration;\n const animationMax = Math.max(maxLineEnd, maxNodeEnd);\n const scale = animationMax > 0 ? totalAnimationSec / animationMax : 1;\n const scaledSegments = nextSegments\n .map((segment) => ({\n ...segment,\n delay: segment.delay * scale,\n duration: segment.duration * scale,\n }))\n .sort((a, b) => a.order - b.order);\n const scaledNodeDelays = new Map<string, number>();\n nextNodeDelays.forEach((value, key) => {\n scaledNodeDelays.set(key, value * scale);\n });\n\n setLayoutState({\n segments: scaledSegments,\n nodeDelays: scaledNodeDelays,\n nodeAnimDuration: baseNodeAnimDuration * scale,\n animationTotal: animationMax * scale,\n svgBounds: { width, height, offsetX, offsetY },\n });\n setDoneNodes(new Set());\n doneNodesRef.current = new Set();\n }, [\n animationSpeed,\n containerRef,\n debug,\n descendantMap,\n direction,\n edges,\n gap,\n nodeRefs,\n nodeTree,\n padding,\n totalAnimationSec,\n ]);\n\n React.useLayoutEffect(() => {\n const rafId = requestAnimationFrame(drawConnections);\n return () => cancelAnimationFrame(rafId);\n }, [drawConnections, nodeTree]);\n\n React.useEffect(() => {\n if (layoutState.animationTotal <= 0 || layoutState.nodeDelays.size === 0) {\n return;\n }\n\n const entries = Array.from(layoutState.nodeDelays.entries())\n .map(([id, delay]) => ({\n id,\n end: delay + layoutState.nodeAnimDuration,\n }))\n .sort((a, b) => a.end - b.end);\n\n doneNodesRef.current = new Set();\n setDoneNodes(new Set());\n\n const start = performance.now();\n let rafId = 0;\n let index = 0;\n\n const tick = () => {\n const elapsed = (performance.now() - start) / 1000;\n let updated = false;\n\n while (index < entries.length && elapsed >= entries[index].end) {\n doneNodesRef.current.add(entries[index].id);\n index += 1;\n updated = true;\n }\n\n if (updated) {\n setDoneNodes(new Set(doneNodesRef.current));\n }\n\n if (index < entries.length) {\n rafId = requestAnimationFrame(tick);\n }\n };\n\n rafId = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafId);\n }, [\n layoutState.animationTotal,\n layoutState.nodeAnimDuration,\n layoutState.nodeDelays,\n ]);\n\n return { doneNodes, layoutState };\n}\n"],"mappings":"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","names":["React","jsx","jsx","jsxs"]}
|
package/dist/node-tree.css
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
/* src/node-tree.css */
|
|
2
|
-
@keyframes unt-node-enter {
|
|
3
|
-
0% {
|
|
4
|
-
opacity: 0;
|
|
5
|
-
}
|
|
6
|
-
100% {
|
|
7
|
-
opacity: 1;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
2
|
.unt-tree-root-container {
|
|
11
3
|
position: relative;
|
|
12
4
|
width: 100%;
|
|
@@ -65,7 +57,15 @@
|
|
|
65
57
|
inset: 0;
|
|
66
58
|
z-index: 0;
|
|
67
59
|
}
|
|
68
|
-
|
|
60
|
+
@keyframes unt-node-enter {
|
|
61
|
+
0% {
|
|
62
|
+
opacity: 0;
|
|
63
|
+
}
|
|
64
|
+
100% {
|
|
65
|
+
opacity: 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
.unt-node-enter {
|
|
69
69
|
animation-name: unt-node-enter;
|
|
70
70
|
animation-timing-function: ease-out;
|
|
71
71
|
animation-fill-mode: both;
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
opacity: 1;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
.node-line {
|
|
82
|
+
.unt-node-line {
|
|
83
83
|
animation-name: unt-line-draw;
|
|
84
84
|
animation-timing-function: ease-out;
|
|
85
85
|
animation-fill-mode: both;
|
package/dist/node-tree.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/node-tree.css"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../src/node-tree.css"],"sourcesContent":[".unt-tree-root-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n min-height: 0;\r\n overflow: hidden;\r\n}\r\n\r\n.unt-tree-canvas {\r\n position: relative;\r\n}\r\n\r\n.unt-tree-node-hit {\r\n cursor: auto;\r\n}\r\n\r\n.unt-tree-node-frame {\r\n position: relative;\r\n display: flex;\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n padding: 1rem;\r\n}\r\n\r\n.unt-tree-debug-badge {\r\n position: absolute;\r\n top: 0.5rem;\r\n left: 0.5rem;\r\n z-index: 10;\r\n padding: 0.25rem 0.5rem;\r\n font-size: 0.75rem;\r\n line-height: 1rem;\r\n}\r\n\r\n.unt-tree-debug-badge--0 {\r\n background: #a7f3d0;\r\n color: #042f2e;\r\n}\r\n\r\n.unt-tree-debug-badge--1 {\r\n background: #bae6fd;\r\n color: #082f49;\r\n}\r\n\r\n.unt-tree-debug-badge--2 {\r\n background: #fde68a;\r\n color: #451a03;\r\n}\r\n\r\n.unt-tree-debug-badge--3 {\r\n background: #fecdd3;\r\n color: #4c0519;\r\n}\r\n\r\n.unt-tree-debug-badge--4 {\r\n background: #d9f99d;\r\n color: #1a2e05;\r\n}\r\n\r\n.unt-tree-debug-badge--5 {\r\n background: #ddd6fe;\r\n color: #2e1065;\r\n}\r\n\r\n.unt-tree-connections {\r\n pointer-events: none;\r\n position: absolute;\r\n inset: 0;\r\n z-index: 0;\r\n}\r\n\r\n@keyframes unt-node-enter {\r\n 0% {\r\n opacity: 0;\r\n }\r\n 100% {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n.unt-node-enter {\r\n animation-name: unt-node-enter;\r\n animation-timing-function: ease-out;\r\n animation-fill-mode: both;\r\n}\r\n\r\n@keyframes unt-line-draw {\r\n 0% {\r\n opacity: 0.2;\r\n }\r\n 100% {\r\n stroke-dashoffset: 0;\r\n opacity: 1;\r\n }\r\n}\r\n\r\n.unt-node-line {\r\n animation-name: unt-line-draw;\r\n animation-timing-function: ease-out;\r\n animation-fill-mode: both;\r\n}\r\n"],"mappings":";AAAA,CAAC;AACC,YAAU;AACV,SAAO;AACP,UAAQ;AACR,cAAY;AACZ,YAAU;AACZ;AAEA,CAAC;AACC,YAAU;AACZ;AAEA,CAAC;AACC,UAAQ;AACV;AAEA,CAAC;AACC,YAAU;AACV,WAAS;AACT,UAAQ,IAAI,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;AACtC,WAAS;AACX;AAEA,CAAC;AACC,YAAU;AACV,OAAK;AACL,QAAM;AACN,WAAS;AACT,WAAS,QAAQ;AACjB,aAAW;AACX,eAAa;AACf;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,kBAAgB;AAChB,YAAU;AACV,SAAO;AACP,WAAS;AACX;AAEA,WAAW;AACT;AACE,aAAS;AACX;AACA;AACE,aAAS;AACX;AACF;AAEA,CATW;AAUT,kBAAgB;AAChB,6BAA2B;AAC3B,uBAAqB;AACvB;AAEA,WAAW;AACT;AACE,aAAS;AACX;AACA;AACE,uBAAmB;AACnB,aAAS;AACX;AACF;AAEA,CAAC;AACC,kBAAgB;AAChB,6BAA2B;AAC3B,uBAAqB;AACvB;","names":[]}
|