@principal-ade/dynamic-file-tree 0.1.56 → 0.1.58

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.d.ts CHANGED
@@ -20,6 +20,8 @@ export { MultiFileTree, MultiFileTreeCore } from './src/components/MultiFileTree
20
20
  export type { MultiFileTreeProps, MultiFileTreeCoreProps } from './src/components/MultiFileTree';
21
21
  export { StoryboardWorkflowsTreeCore } from './src/components/StoryboardWorkflowsTree/StoryboardWorkflowsTreeCore';
22
22
  export type { StoryboardWorkflowsTreeProps, StoryboardWorkflowNodeData, StoryboardWorkflowNodeType, DiscoveredStoryboard, DiscoveredWorkflow, } from './src/components/StoryboardWorkflowsTree/types';
23
+ export { CanvasListTreeCore } from './src/components/CanvasListTree/CanvasListTreeCore';
24
+ export type { CanvasListTreeProps, CanvasListNodeData, CanvasListNodeType, DiscoveredCanvas, } from './src/components/CanvasListTree/types';
23
25
  export { TelemetryCoverageFileTree, calculateTelemetryCoverageStats, } from './src/components/TelemetryCoverageFileTree';
24
26
  export type { TelemetryCoverageFileTreeProps, FileTelemetryCoverage, TelemetryCoverageStatus, } from './src/components/TelemetryCoverageFileTree';
25
27
  export { TelemetryCoverageFileTreeContainer } from './src/components/TelemetryCoverageFileTreeContainer';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,YAAY,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAGxG,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAGhG,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,YAAY,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAGnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAGjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,SAAS,EACV,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;AACzF,YAAY,EAAE,+BAA+B,EAAE,MAAM,6CAA6C,CAAC;AAGnG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAClF,YAAY,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAGjG,OAAO,EAAE,2BAA2B,EAAE,MAAM,sEAAsE,CAAC;AACnH,YAAY,EACV,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EACL,yBAAyB,EACzB,+BAA+B,GAChC,MAAM,4CAA4C,CAAC;AACpD,YAAY,EACV,8BAA8B,EAC9B,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EAAE,kCAAkC,EAAE,MAAM,qDAAqD,CAAC;AACzG,YAAY,EAAE,uCAAuC,EAAE,MAAM,qDAAqD,CAAC;AAGnH,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,YAAY,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAGxG,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAGhG,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,YAAY,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAGnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAGjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,SAAS,EACV,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;AACzF,YAAY,EAAE,+BAA+B,EAAE,MAAM,6CAA6C,CAAC;AAGnG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAClF,YAAY,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAGjG,OAAO,EAAE,2BAA2B,EAAE,MAAM,sEAAsE,CAAC;AACnH,YAAY,EACV,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oDAAoD,CAAC;AACxF,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EACL,yBAAyB,EACzB,+BAA+B,GAChC,MAAM,4CAA4C,CAAC;AACpD,YAAY,EACV,8BAA8B,EAC9B,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EAAE,kCAAkC,EAAE,MAAM,qDAAqD,CAAC;AACzG,YAAY,EAAE,uCAAuC,EAAE,MAAM,qDAAqD,CAAC;AAGnH,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.mjs CHANGED
@@ -2081,6 +2081,171 @@ var StoryboardWorkflowsTreeCore = ({
2081
2081
  ...dndProps
2082
2082
  }, NodeRenderer));
2083
2083
  };
2084
+ // src/components/CanvasListTree/CanvasListTreeCore.tsx
2085
+ import { Package as Package2, Folder, LayoutDashboard as LayoutDashboard2, FileText } from "lucide-react";
2086
+ import React12, { useMemo as useMemo10, useRef as useRef6 } from "react";
2087
+ import { Tree as Tree4 } from "react-arborist";
2088
+ var buildTreeData2 = (canvases) => {
2089
+ const packagesMap = new Map;
2090
+ const rootCanvases = [];
2091
+ for (const canvas of canvases) {
2092
+ if (canvas.scope === "package" && canvas.packageName) {
2093
+ const existing = packagesMap.get(canvas.packageName) || [];
2094
+ existing.push(canvas);
2095
+ packagesMap.set(canvas.packageName, existing);
2096
+ } else {
2097
+ rootCanvases.push(canvas);
2098
+ }
2099
+ }
2100
+ const buildCanvasNode = (canvas) => {
2101
+ const children = [];
2102
+ children.push({
2103
+ id: `canvas:${canvas.id}`,
2104
+ name: "Canvas",
2105
+ type: "canvas",
2106
+ canvas
2107
+ });
2108
+ if (canvas.markdownPath) {
2109
+ children.push({
2110
+ id: `overview:${canvas.id}`,
2111
+ name: "Overview",
2112
+ type: "overview",
2113
+ canvas,
2114
+ markdownPath: canvas.markdownPath
2115
+ });
2116
+ }
2117
+ return {
2118
+ id: `canvas-folder:${canvas.id}`,
2119
+ name: canvas.name,
2120
+ type: "canvas-folder",
2121
+ canvas,
2122
+ children
2123
+ };
2124
+ };
2125
+ const hasMultiplePackages = packagesMap.size > 1;
2126
+ const hasRootAndPackages = packagesMap.size > 0 && rootCanvases.length > 0;
2127
+ const shouldShowPackageLevel = hasMultiplePackages || hasRootAndPackages;
2128
+ if (shouldShowPackageLevel) {
2129
+ const result = [];
2130
+ for (const [packageName, packageCanvases] of packagesMap) {
2131
+ const canvasNodes = packageCanvases.map(buildCanvasNode).sort((a, b) => a.name.localeCompare(b.name));
2132
+ result.push({
2133
+ id: `package:${packageName}`,
2134
+ name: packageName,
2135
+ type: "package",
2136
+ packageName,
2137
+ scope: "package",
2138
+ children: canvasNodes
2139
+ });
2140
+ }
2141
+ if (rootCanvases.length > 0) {
2142
+ const rootCanvasNodes = rootCanvases.map(buildCanvasNode).sort((a, b) => a.name.localeCompare(b.name));
2143
+ result.push({
2144
+ id: "package:root",
2145
+ name: "Root",
2146
+ type: "package",
2147
+ packageName: "root",
2148
+ scope: "root",
2149
+ children: rootCanvasNodes
2150
+ });
2151
+ }
2152
+ return result.sort((a, b) => {
2153
+ if (a.packageName === "root")
2154
+ return 1;
2155
+ if (b.packageName === "root")
2156
+ return -1;
2157
+ return a.name.localeCompare(b.name);
2158
+ });
2159
+ } else {
2160
+ const allCanvases = [...rootCanvases];
2161
+ for (const packageCanvases of packagesMap.values()) {
2162
+ allCanvases.push(...packageCanvases);
2163
+ }
2164
+ return allCanvases.map(buildCanvasNode).sort((a, b) => a.name.localeCompare(b.name));
2165
+ }
2166
+ };
2167
+ var CanvasListTreeCore = ({
2168
+ canvases,
2169
+ theme,
2170
+ onClick,
2171
+ selectedNodeId,
2172
+ defaultOpen = false,
2173
+ initialOpenState,
2174
+ horizontalNodePadding = "16px",
2175
+ verticalNodePadding = "6px",
2176
+ verticalPadding = "20px",
2177
+ enableDragAndDrop = false
2178
+ }) => {
2179
+ const dndProps = getDndProps(enableDragAndDrop);
2180
+ const rowHeight = useMemo10(() => {
2181
+ const paddingValue = parseFloat(verticalNodePadding);
2182
+ const contentLineHeight = 20;
2183
+ const borderHeight = 2;
2184
+ return contentLineHeight + paddingValue * 2 + borderHeight;
2185
+ }, [verticalNodePadding]);
2186
+ const treeData = useMemo10(() => buildTreeData2(canvases), [canvases]);
2187
+ const NodeRenderer = (props) => {
2188
+ const { node } = props;
2189
+ const data = node.data;
2190
+ const icon = data.type === "package" ? /* @__PURE__ */ React12.createElement(Package2, {
2191
+ size: 16
2192
+ }) : data.type === "canvas-folder" ? /* @__PURE__ */ React12.createElement(Folder, {
2193
+ size: 16
2194
+ }) : data.type === "overview" ? /* @__PURE__ */ React12.createElement(FileText, {
2195
+ size: 16
2196
+ }) : /* @__PURE__ */ React12.createElement(LayoutDashboard2, {
2197
+ size: 16
2198
+ });
2199
+ const nameColor = data.type === "package" ? theme.colors.primary : data.type === "canvas-folder" ? theme.colors.textSecondary : data.type === "overview" ? theme.colors.info || "#3b82f6" : theme.colors.warning || "#f59e0b";
2200
+ const nodeHorizontalPadding = data.type === "overview" || data.type === "canvas" ? `calc(${horizontalNodePadding} + 12px)` : horizontalNodePadding;
2201
+ return /* @__PURE__ */ React12.createElement(TreeNode, {
2202
+ ...props,
2203
+ theme,
2204
+ nameColor,
2205
+ leftIcon: icon,
2206
+ horizontalNodePadding: nodeHorizontalPadding,
2207
+ verticalNodePadding
2208
+ });
2209
+ };
2210
+ const lastSelectionRef = useRef6(null);
2211
+ const handleSelect = (selectedNodes) => {
2212
+ if (selectedNodes.length === 0)
2213
+ return;
2214
+ const node = selectedNodes[0];
2215
+ const nodeData = node.data;
2216
+ const now = Date.now();
2217
+ const lastSelection = lastSelectionRef.current;
2218
+ if (lastSelection && lastSelection.nodeId === nodeData.id && now - lastSelection.timestamp < 50) {
2219
+ return;
2220
+ }
2221
+ lastSelectionRef.current = { nodeId: nodeData.id, timestamp: now };
2222
+ if (nodeData.type === "overview" || nodeData.type === "canvas") {
2223
+ onClick(nodeData);
2224
+ }
2225
+ };
2226
+ const initialHeight = 600;
2227
+ const [containerRef, containerHeight] = useContainerHeight(initialHeight);
2228
+ return /* @__PURE__ */ React12.createElement("div", {
2229
+ ref: containerRef,
2230
+ style: {
2231
+ backgroundColor: theme.colors.background,
2232
+ color: theme.colors.text,
2233
+ fontFamily: theme.fonts.body,
2234
+ height: "100%",
2235
+ ...verticalPadding ? { paddingTop: verticalPadding, paddingBottom: verticalPadding } : {}
2236
+ }
2237
+ }, /* @__PURE__ */ React12.createElement(Tree4, {
2238
+ initialData: treeData,
2239
+ onSelect: handleSelect,
2240
+ openByDefault: defaultOpen,
2241
+ ...initialOpenState !== undefined && { initialOpenState },
2242
+ ...selectedNodeId !== undefined && { selection: selectedNodeId },
2243
+ width: "100%",
2244
+ height: containerHeight,
2245
+ rowHeight,
2246
+ ...dndProps
2247
+ }, NodeRenderer));
2248
+ };
2084
2249
  // src/components/TelemetryCoverageFileTree.tsx
2085
2250
  import {
2086
2251
  Activity,
@@ -2088,9 +2253,9 @@ import {
2088
2253
  Circle,
2089
2254
  TestTube
2090
2255
  } from "lucide-react";
2091
- import React12, { useMemo as useMemo10, useRef as useRef6 } from "react";
2092
- import { Tree as Tree4 } from "react-arborist";
2093
- var TelemetryCoverageContext = React12.createContext(null);
2256
+ import React13, { useMemo as useMemo11, useRef as useRef7 } from "react";
2257
+ import { Tree as Tree5 } from "react-arborist";
2258
+ var TelemetryCoverageContext = React13.createContext(null);
2094
2259
  var DEFAULT_TEST_PATTERNS = [
2095
2260
  /\.test\.[jt]sx?$/,
2096
2261
  /\.spec\.[jt]sx?$/,
@@ -2107,7 +2272,7 @@ var getCoverageStatusDisplay = (coverage, _theme) => {
2107
2272
  switch (status) {
2108
2273
  case "covered":
2109
2274
  return {
2110
- icon: /* @__PURE__ */ React12.createElement(Activity, {
2275
+ icon: /* @__PURE__ */ React13.createElement(Activity, {
2111
2276
  size: 14
2112
2277
  }),
2113
2278
  color: "#22c55e",
@@ -2116,7 +2281,7 @@ var getCoverageStatusDisplay = (coverage, _theme) => {
2116
2281
  };
2117
2282
  case "partial":
2118
2283
  return {
2119
- icon: /* @__PURE__ */ React12.createElement(CircleDot, {
2284
+ icon: /* @__PURE__ */ React13.createElement(CircleDot, {
2120
2285
  size: 14
2121
2286
  }),
2122
2287
  color: "#eab308",
@@ -2125,7 +2290,7 @@ var getCoverageStatusDisplay = (coverage, _theme) => {
2125
2290
  };
2126
2291
  case "none":
2127
2292
  return {
2128
- icon: /* @__PURE__ */ React12.createElement(Circle, {
2293
+ icon: /* @__PURE__ */ React13.createElement(Circle, {
2129
2294
  size: 14
2130
2295
  }),
2131
2296
  color: "#6b7280",
@@ -2227,7 +2392,7 @@ var TelemetryCoverageFileTree = ({
2227
2392
  enableDragAndDrop = false
2228
2393
  }) => {
2229
2394
  const dndProps = getDndProps(enableDragAndDrop);
2230
- const coverageMap = useMemo10(() => {
2395
+ const coverageMap = useMemo11(() => {
2231
2396
  const map = new Map;
2232
2397
  coverageData.forEach((item) => {
2233
2398
  map.set(item.filePath, item);
@@ -2236,7 +2401,7 @@ var TelemetryCoverageFileTree = ({
2236
2401
  }, [coverageData]);
2237
2402
  const NodeRenderer = (props) => {
2238
2403
  const { node } = props;
2239
- const ctx = React12.useContext(TelemetryCoverageContext);
2404
+ const ctx = React13.useContext(TelemetryCoverageContext);
2240
2405
  const coverage = ctx?.coverageMap.get(node.data.id);
2241
2406
  const hasTracedChildren = ctx?.hasTracedChildrenMap.get(node.data.id);
2242
2407
  const coverageDisplay = coverage ? getCoverageStatusDisplay(coverage, theme) : null;
@@ -2248,11 +2413,11 @@ var TelemetryCoverageFileTree = ({
2248
2413
  } else if (node.data.isTestFile) {
2249
2414
  nameColor = "#6b728080";
2250
2415
  }
2251
- const leftIcon = node.data.isTestFile && !coverage ? /* @__PURE__ */ React12.createElement(TestTube, {
2416
+ const leftIcon = node.data.isTestFile && !coverage ? /* @__PURE__ */ React13.createElement(TestTube, {
2252
2417
  size: 14,
2253
2418
  style: { marginRight: 4, color: "#6b7280" }
2254
2419
  }) : null;
2255
- const rightContent = coverageDisplay ? /* @__PURE__ */ React12.createElement("div", {
2420
+ const rightContent = coverageDisplay ? /* @__PURE__ */ React13.createElement("div", {
2256
2421
  style: {
2257
2422
  display: "flex",
2258
2423
  alignItems: "center",
@@ -2260,14 +2425,14 @@ var TelemetryCoverageFileTree = ({
2260
2425
  marginRight: "8px"
2261
2426
  },
2262
2427
  title: coverageDisplay.label
2263
- }, coverageDisplay.icon, /* @__PURE__ */ React12.createElement("span", {
2428
+ }, coverageDisplay.icon, /* @__PURE__ */ React13.createElement("span", {
2264
2429
  style: {
2265
2430
  marginLeft: "4px",
2266
2431
  fontSize: theme.fontSizes[0],
2267
2432
  fontWeight: "bold",
2268
2433
  fontFamily: "monospace"
2269
2434
  }
2270
- }, coverageDisplay.badge)) : node.data.isTestFile ? /* @__PURE__ */ React12.createElement("div", {
2435
+ }, coverageDisplay.badge)) : node.data.isTestFile ? /* @__PURE__ */ React13.createElement("div", {
2271
2436
  style: {
2272
2437
  display: "flex",
2273
2438
  alignItems: "center",
@@ -2276,10 +2441,10 @@ var TelemetryCoverageFileTree = ({
2276
2441
  opacity: 0.5
2277
2442
  },
2278
2443
  title: "No telemetry instrumentation"
2279
- }, /* @__PURE__ */ React12.createElement(Circle, {
2444
+ }, /* @__PURE__ */ React13.createElement(Circle, {
2280
2445
  size: 14
2281
2446
  })) : null;
2282
- return /* @__PURE__ */ React12.createElement(TreeNode, {
2447
+ return /* @__PURE__ */ React13.createElement(TreeNode, {
2283
2448
  ...props,
2284
2449
  theme,
2285
2450
  rightContent,
@@ -2294,16 +2459,16 @@ var TelemetryCoverageFileTree = ({
2294
2459
  }
2295
2460
  });
2296
2461
  };
2297
- const treeStructure = useMemo10(() => {
2462
+ const treeStructure = useMemo11(() => {
2298
2463
  return transformTreeStructure2(fileTree, showOnlyTestFiles, testFilePatterns);
2299
2464
  }, [fileTree, showOnlyTestFiles, testFilePatterns]);
2300
- const treeData = useMemo10(() => {
2465
+ const treeData = useMemo11(() => {
2301
2466
  if (showUncoveredFiles) {
2302
2467
  return treeStructure;
2303
2468
  }
2304
2469
  return filterCoveredNodes(treeStructure, coverageMap);
2305
2470
  }, [treeStructure, showUncoveredFiles, coverageMap]);
2306
- const hasTracedChildrenMap = useMemo10(() => {
2471
+ const hasTracedChildrenMap = useMemo11(() => {
2307
2472
  const map = new Map;
2308
2473
  const markTracedParents = (nodes) => {
2309
2474
  let hasTraced = false;
@@ -2325,7 +2490,7 @@ var TelemetryCoverageFileTree = ({
2325
2490
  markTracedParents(treeData);
2326
2491
  return map;
2327
2492
  }, [treeData, coverageMap]);
2328
- const lastSelectionRef = useRef6(null);
2493
+ const lastSelectionRef = useRef7(null);
2329
2494
  const handleSelect = (selectedNodes) => {
2330
2495
  const selectedFiles = selectedNodes.filter((node) => !node.data.children).map((node) => node.data.id);
2331
2496
  const selectedDirs = selectedNodes.filter((node) => node.data.children).map((node) => node.data.id);
@@ -2344,7 +2509,7 @@ var TelemetryCoverageFileTree = ({
2344
2509
  onDirectorySelect(selectedDirs);
2345
2510
  }
2346
2511
  };
2347
- const calculatedHeight = useMemo10(() => {
2512
+ const calculatedHeight = useMemo11(() => {
2348
2513
  if (autoHeight) {
2349
2514
  const visibleNodeCount = countVisibleNodes3(treeData, openByDefault);
2350
2515
  return visibleNodeCount * 28;
@@ -2352,7 +2517,7 @@ var TelemetryCoverageFileTree = ({
2352
2517
  return initialHeight;
2353
2518
  }, [autoHeight, treeData, openByDefault, initialHeight]);
2354
2519
  const [containerRef, containerHeight] = useContainerHeight(calculatedHeight);
2355
- return /* @__PURE__ */ React12.createElement("div", {
2520
+ return /* @__PURE__ */ React13.createElement("div", {
2356
2521
  ref: containerRef,
2357
2522
  style: {
2358
2523
  backgroundColor: transparentBackground ? "transparent" : theme.colors.background,
@@ -2361,9 +2526,9 @@ var TelemetryCoverageFileTree = ({
2361
2526
  ...autoHeight ? {} : { height: "100%" },
2362
2527
  ...verticalPadding ? { paddingTop: verticalPadding, paddingBottom: verticalPadding } : {}
2363
2528
  }
2364
- }, /* @__PURE__ */ React12.createElement(TelemetryCoverageContext.Provider, {
2529
+ }, /* @__PURE__ */ React13.createElement(TelemetryCoverageContext.Provider, {
2365
2530
  value: { coverageMap, hasTracedChildrenMap }
2366
- }, /* @__PURE__ */ React12.createElement(Tree4, {
2531
+ }, /* @__PURE__ */ React13.createElement(Tree5, {
2367
2532
  data: treeData,
2368
2533
  onSelect: handleSelect,
2369
2534
  ...selectedFile !== undefined && { selection: selectedFile },
@@ -2392,7 +2557,7 @@ var calculateTelemetryCoverageStats = (coverageData) => {
2392
2557
  };
2393
2558
  // src/components/TelemetryCoverageFileTreeContainer.tsx
2394
2559
  import { RefreshCw as RefreshCw2, Eye as Eye2, EyeOff as EyeOff2, AlertCircle as AlertCircle4, Activity as Activity2 } from "lucide-react";
2395
- import React13, { useState as useState7, useMemo as useMemo11 } from "react";
2560
+ import React14, { useState as useState7, useMemo as useMemo12 } from "react";
2396
2561
  var TelemetryCoverageFileTreeContainer = ({
2397
2562
  fileTree,
2398
2563
  theme,
@@ -2414,10 +2579,10 @@ var TelemetryCoverageFileTreeContainer = ({
2414
2579
  }) => {
2415
2580
  const [filters, setFilters] = useState7([]);
2416
2581
  const [showUncoveredFiles, setShowUncoveredFiles] = useState7(true);
2417
- const selectedDirectories = useMemo11(() => {
2582
+ const selectedDirectories = useMemo12(() => {
2418
2583
  return filters.filter((f) => f.mode === "include").map((f) => f.path);
2419
2584
  }, [filters]);
2420
- const stats = useMemo11(() => calculateTelemetryCoverageStats(coverageData), [coverageData]);
2585
+ const stats = useMemo12(() => calculateTelemetryCoverageStats(coverageData), [coverageData]);
2421
2586
  const handleRefresh = () => {
2422
2587
  onRefresh?.();
2423
2588
  };
@@ -2425,34 +2590,34 @@ var TelemetryCoverageFileTreeContainer = ({
2425
2590
  setShowUncoveredFiles(!showUncoveredFiles);
2426
2591
  };
2427
2592
  const percentageColor = stats.percentage >= 80 ? "#22c55e" : stats.percentage >= 50 ? "#eab308" : stats.percentage > 0 ? "#f97316" : "#6b7280";
2428
- return /* @__PURE__ */ React13.createElement("div", {
2593
+ return /* @__PURE__ */ React14.createElement("div", {
2429
2594
  style: { display: "flex", flexDirection: "column", height: "100%" }
2430
- }, showControls && /* @__PURE__ */ React13.createElement("div", {
2595
+ }, showControls && /* @__PURE__ */ React14.createElement("div", {
2431
2596
  style: {
2432
2597
  padding: "12px",
2433
2598
  borderBottom: `1px solid ${theme.colors.border || "#e0e0e0"}`,
2434
2599
  backgroundColor: theme.colors.backgroundSecondary || theme.colors.background
2435
2600
  }
2436
- }, /* @__PURE__ */ React13.createElement("div", {
2601
+ }, /* @__PURE__ */ React14.createElement("div", {
2437
2602
  style: {
2438
2603
  display: "flex",
2439
2604
  alignItems: "center",
2440
2605
  justifyContent: "space-between",
2441
2606
  marginBottom: "8px"
2442
2607
  }
2443
- }, /* @__PURE__ */ React13.createElement("div", {
2608
+ }, /* @__PURE__ */ React14.createElement("div", {
2444
2609
  style: { display: "flex", alignItems: "center", gap: "8px" }
2445
- }, /* @__PURE__ */ React13.createElement(Activity2, {
2610
+ }, /* @__PURE__ */ React14.createElement(Activity2, {
2446
2611
  size: 16,
2447
2612
  color: theme.colors.primary
2448
- }), /* @__PURE__ */ React13.createElement("h3", {
2613
+ }), /* @__PURE__ */ React14.createElement("h3", {
2449
2614
  style: {
2450
2615
  margin: 0,
2451
2616
  fontSize: theme.fontSizes[1],
2452
2617
  fontWeight: "bold",
2453
2618
  color: theme.colors.text
2454
2619
  }
2455
- }, title), stats.testFiles > 0 && /* @__PURE__ */ React13.createElement("span", {
2620
+ }, title), stats.testFiles > 0 && /* @__PURE__ */ React14.createElement("span", {
2456
2621
  style: {
2457
2622
  backgroundColor: percentageColor,
2458
2623
  color: "#ffffff",
@@ -2462,14 +2627,14 @@ var TelemetryCoverageFileTreeContainer = ({
2462
2627
  fontWeight: "bold",
2463
2628
  fontFamily: "monospace"
2464
2629
  }
2465
- }, stats.percentage, "%"), isLoading && /* @__PURE__ */ React13.createElement(RefreshCw2, {
2630
+ }, stats.percentage, "%"), isLoading && /* @__PURE__ */ React14.createElement(RefreshCw2, {
2466
2631
  size: 16,
2467
2632
  color: theme.colors.text,
2468
2633
  className: "telemetry-coverage-spinner",
2469
2634
  style: { animation: "spin 1s linear infinite" }
2470
- })), /* @__PURE__ */ React13.createElement("div", {
2635
+ })), /* @__PURE__ */ React14.createElement("div", {
2471
2636
  style: { display: "flex", gap: "8px" }
2472
- }, /* @__PURE__ */ React13.createElement("button", {
2637
+ }, /* @__PURE__ */ React14.createElement("button", {
2473
2638
  onClick: toggleShowUncoveredFiles,
2474
2639
  style: {
2475
2640
  background: "none",
@@ -2484,11 +2649,11 @@ var TelemetryCoverageFileTreeContainer = ({
2484
2649
  color: theme.colors.text
2485
2650
  },
2486
2651
  title: showUncoveredFiles ? "Show only covered files" : "Show all test files"
2487
- }, showUncoveredFiles ? /* @__PURE__ */ React13.createElement(EyeOff2, {
2652
+ }, showUncoveredFiles ? /* @__PURE__ */ React14.createElement(EyeOff2, {
2488
2653
  size: 14
2489
- }) : /* @__PURE__ */ React13.createElement(Eye2, {
2654
+ }) : /* @__PURE__ */ React14.createElement(Eye2, {
2490
2655
  size: 14
2491
- }), showUncoveredFiles ? "Hide uncovered" : "Show all"), onRefresh && /* @__PURE__ */ React13.createElement("button", {
2656
+ }), showUncoveredFiles ? "Hide uncovered" : "Show all"), onRefresh && /* @__PURE__ */ React14.createElement("button", {
2492
2657
  onClick: handleRefresh,
2493
2658
  disabled: isLoading,
2494
2659
  style: {
@@ -2505,9 +2670,9 @@ var TelemetryCoverageFileTreeContainer = ({
2505
2670
  opacity: isLoading ? 0.6 : 1
2506
2671
  },
2507
2672
  title: "Refresh coverage data"
2508
- }, /* @__PURE__ */ React13.createElement(RefreshCw2, {
2673
+ }, /* @__PURE__ */ React14.createElement(RefreshCw2, {
2509
2674
  size: 14
2510
- }), "Refresh"))), error && /* @__PURE__ */ React13.createElement("div", {
2675
+ }), "Refresh"))), error && /* @__PURE__ */ React14.createElement("div", {
2511
2676
  style: {
2512
2677
  display: "flex",
2513
2678
  alignItems: "center",
@@ -2520,36 +2685,36 @@ var TelemetryCoverageFileTreeContainer = ({
2520
2685
  color: "#856404",
2521
2686
  marginBottom: "8px"
2522
2687
  }
2523
- }, /* @__PURE__ */ React13.createElement(AlertCircle4, {
2688
+ }, /* @__PURE__ */ React14.createElement(AlertCircle4, {
2524
2689
  size: 14
2525
- }), error), !error && stats.testFiles > 0 && /* @__PURE__ */ React13.createElement("div", {
2690
+ }), error), !error && stats.testFiles > 0 && /* @__PURE__ */ React14.createElement("div", {
2526
2691
  style: {
2527
2692
  display: "flex",
2528
2693
  gap: "16px",
2529
2694
  fontSize: theme.fontSizes[0],
2530
2695
  color: theme.colors.textSecondary || "#666"
2531
2696
  }
2532
- }, /* @__PURE__ */ React13.createElement("span", null, /* @__PURE__ */ React13.createElement("strong", {
2697
+ }, /* @__PURE__ */ React14.createElement("span", null, /* @__PURE__ */ React14.createElement("strong", {
2533
2698
  style: { color: "#22c55e" }
2534
- }, stats.coveredFiles), " covered"), stats.partialFiles > 0 && /* @__PURE__ */ React13.createElement("span", null, /* @__PURE__ */ React13.createElement("strong", {
2699
+ }, stats.coveredFiles), " covered"), stats.partialFiles > 0 && /* @__PURE__ */ React14.createElement("span", null, /* @__PURE__ */ React14.createElement("strong", {
2535
2700
  style: { color: "#eab308" }
2536
- }, stats.partialFiles), " partial"), /* @__PURE__ */ React13.createElement("span", null, /* @__PURE__ */ React13.createElement("strong", {
2701
+ }, stats.partialFiles), " partial"), /* @__PURE__ */ React14.createElement("span", null, /* @__PURE__ */ React14.createElement("strong", {
2537
2702
  style: { color: "#6b7280" }
2538
- }, stats.uncoveredFiles), " uncovered"), /* @__PURE__ */ React13.createElement("span", {
2703
+ }, stats.uncoveredFiles), " uncovered"), /* @__PURE__ */ React14.createElement("span", {
2539
2704
  style: { marginLeft: "auto" }
2540
- }, stats.totalTraced, "/", stats.totalTests, " tests traced")), !error && stats.testFiles === 0 && /* @__PURE__ */ React13.createElement("div", {
2705
+ }, stats.totalTraced, "/", stats.totalTests, " tests traced")), !error && stats.testFiles === 0 && /* @__PURE__ */ React14.createElement("div", {
2541
2706
  style: {
2542
2707
  fontSize: theme.fontSizes[0],
2543
2708
  color: theme.colors.textSecondary || "#666"
2544
2709
  }
2545
- }, "No test files with coverage data found")), /* @__PURE__ */ React13.createElement(DirectoryFilterInput, {
2710
+ }, "No test files with coverage data found")), /* @__PURE__ */ React14.createElement(DirectoryFilterInput, {
2546
2711
  fileTree,
2547
2712
  theme,
2548
2713
  filters,
2549
2714
  onFiltersChange: setFilters
2550
- }), /* @__PURE__ */ React13.createElement("div", {
2715
+ }), /* @__PURE__ */ React14.createElement("div", {
2551
2716
  style: { flex: 1, marginTop: "1rem", overflow: "hidden" }
2552
- }, /* @__PURE__ */ React13.createElement(TelemetryCoverageFileTree, {
2717
+ }, /* @__PURE__ */ React14.createElement(TelemetryCoverageFileTree, {
2553
2718
  fileTree,
2554
2719
  theme,
2555
2720
  coverageData,
@@ -2587,5 +2752,6 @@ export {
2587
2752
  GitOrderedFileList,
2588
2753
  FileTreeContainer,
2589
2754
  DynamicFileTree,
2590
- DirectoryFilterInput
2755
+ DirectoryFilterInput,
2756
+ CanvasListTreeCore
2591
2757
  };
@@ -0,0 +1,12 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { CanvasListTreeCore } from './CanvasListTreeCore';
3
+ declare const meta: Meta<typeof CanvasListTreeCore>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof CanvasListTreeCore>;
6
+ export declare const MultiPackage: Story;
7
+ export declare const SinglePackage: Story;
8
+ export declare const RootOnly: Story;
9
+ export declare const Empty: Story;
10
+ export declare const TerminalTheme: Story;
11
+ export declare const MatrixTheme: Story;
12
+ //# sourceMappingURL=CanvasListTree.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanvasListTree.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/CanvasListTree/CanvasListTree.stories.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA0G1D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,kBAAkB,CAmCzC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAyBjD,eAAO,MAAM,YAAY,EAAE,KAU1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAU3B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAUnB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAU3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAUzB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { CanvasListTreeProps } from './types';
3
+ export declare const CanvasListTreeCore: React.FC<CanvasListTreeProps>;
4
+ //# sourceMappingURL=CanvasListTreeCore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanvasListTreeCore.d.ts","sourceRoot":"","sources":["../../../../src/components/CanvasListTree/CanvasListTreeCore.tsx"],"names":[],"mappings":"AACA,OAAO,KAA0B,MAAM,OAAO,CAAC;AAO/C,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,SAAS,CAAC;AAkHjB,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAuI5D,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { Theme } from '@principal-ade/industry-theme';
2
+ import type { DiscoveredCanvas } from '@principal-ai/principal-view-core';
3
+ import type { TreeNodeData } from '../TreeNode';
4
+ export type { DiscoveredCanvas };
5
+ export type CanvasListNodeType = 'package' | 'canvas-folder' | 'canvas' | 'overview';
6
+ export interface CanvasListNodeData extends TreeNodeData {
7
+ type: CanvasListNodeType;
8
+ children?: CanvasListNodeData[];
9
+ canvas?: DiscoveredCanvas;
10
+ packageName?: string;
11
+ scope?: 'package' | 'root';
12
+ markdownPath?: string;
13
+ }
14
+ export interface CanvasListTreeProps {
15
+ canvases: DiscoveredCanvas[];
16
+ theme: Theme;
17
+ onClick: (node: CanvasListNodeData) => void;
18
+ selectedNodeId?: string;
19
+ defaultOpen?: boolean;
20
+ initialOpenState?: Record<string, boolean>;
21
+ horizontalNodePadding?: string;
22
+ verticalNodePadding?: string;
23
+ verticalPadding?: string;
24
+ enableDragAndDrop?: boolean;
25
+ }
26
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/CanvasListTree/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,eAAe,GAAG,QAAQ,GAAG,UAAU,CAAC;AAErF,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAGhC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ade/dynamic-file-tree",
3
- "version": "0.1.56",
3
+ "version": "0.1.58",
4
4
  "description": "React component for selective directory filtering and file tree visualization",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "peerDependencies": {
50
50
  "@principal-ade/industry-theme": ">=0.1.0",
51
- "@principal-ai/principal-view-core": "^0.19.0",
51
+ "@principal-ai/principal-view-core": "^0.21.0",
52
52
  "@principal-ai/repository-abstraction": "^0.5.2",
53
53
  "lucide-react": ">=0.263.0",
54
54
  "react": ">=19.0.0",
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "devDependencies": {
72
72
  "@principal-ade/industry-theme": "^0.1.0",
73
- "@principal-ai/principal-view-core": "^0.19.0",
73
+ "@principal-ai/principal-view-core": "^0.21.0",
74
74
  "@principal-ai/repository-abstraction": "^0.5.2",
75
75
  "@eslint/js": "^9.32.0",
76
76
  "@storybook/addon-docs": "^9.1.3",