@tree-ia/design-system 2.4.1 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -0
- package/dist/index.d.mts +0 -0
- package/dist/index.d.mts.map +0 -0
- package/dist/index.mjs +89 -24
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +0 -0
- package/package.json +10 -11
package/README.md
CHANGED
|
File without changes
|
package/dist/index.d.mts
CHANGED
|
File without changes
|
package/dist/index.d.mts.map
CHANGED
|
File without changes
|
package/dist/index.mjs
CHANGED
|
@@ -1261,11 +1261,22 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1261
1261
|
const [expandedIds, setExpandedIds] = useState(() => new Set(defaultExpandedIds ?? []));
|
|
1262
1262
|
const cubicBezier = "cubic-bezier(0.4, 0, 0.2, 1)";
|
|
1263
1263
|
useEffect(() => {
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1264
|
+
function collectAncestorsOfActive(items, acc) {
|
|
1265
|
+
let hasActive = false;
|
|
1266
|
+
for (const item of items) {
|
|
1267
|
+
const selfActive = currentPath === item.href;
|
|
1268
|
+
let childActive = false;
|
|
1269
|
+
if (item.children && item.children.length > 0) {
|
|
1270
|
+
childActive = collectAncestorsOfActive(item.children, acc);
|
|
1271
|
+
if (childActive) acc.push(item.id);
|
|
1272
|
+
}
|
|
1273
|
+
if (selfActive || childActive) hasActive = true;
|
|
1274
|
+
}
|
|
1275
|
+
return hasActive;
|
|
1268
1276
|
}
|
|
1277
|
+
const idsToExpand = [];
|
|
1278
|
+
collectAncestorsOfActive(menuItems, idsToExpand);
|
|
1279
|
+
if (footerItems) collectAncestorsOfActive(footerItems, idsToExpand);
|
|
1269
1280
|
if (idsToExpand.length > 0) setExpandedIds((prev) => {
|
|
1270
1281
|
const next = new Set(prev);
|
|
1271
1282
|
for (const id of idsToExpand) next.add(id);
|
|
@@ -1293,6 +1304,27 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1293
1304
|
return next;
|
|
1294
1305
|
});
|
|
1295
1306
|
}
|
|
1307
|
+
/** True if the item or any nested descendant matches `currentPath`. */
|
|
1308
|
+
function hasActiveDescendant(item) {
|
|
1309
|
+
if (!item.children) return false;
|
|
1310
|
+
for (const child of item.children) {
|
|
1311
|
+
if (currentPath === child.href) return true;
|
|
1312
|
+
if (hasActiveDescendant(child)) return true;
|
|
1313
|
+
}
|
|
1314
|
+
return false;
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* Counts how many descendant nodes are currently visible in the tree —
|
|
1318
|
+
* i.e. all direct children, plus all descendants of expanded children
|
|
1319
|
+
* (recurse only inside expanded branches). Used to size the `maxHeight`
|
|
1320
|
+
* animation container so it fits the full expanded subtree.
|
|
1321
|
+
*/
|
|
1322
|
+
function countVisibleDescendants(item) {
|
|
1323
|
+
if (!item.children || item.children.length === 0) return 0;
|
|
1324
|
+
let count = item.children.length;
|
|
1325
|
+
for (const child of item.children) if (expandedIds.has(child.id)) count += countVisibleDescendants(child);
|
|
1326
|
+
return count;
|
|
1327
|
+
}
|
|
1296
1328
|
/** Group items by section — items before any section go into a null group */
|
|
1297
1329
|
function groupBySection(items) {
|
|
1298
1330
|
const groups = [];
|
|
@@ -1316,6 +1348,57 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1316
1348
|
children: section
|
|
1317
1349
|
});
|
|
1318
1350
|
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Renders a nested child item (inside an expanded parent). Recursive —
|
|
1353
|
+
* if the child itself has `children`, renders as expandable and recurses.
|
|
1354
|
+
* Styling is the "child" variant (smaller icon, smaller text, indented)
|
|
1355
|
+
* regardless of depth, to keep visual consistency across levels.
|
|
1356
|
+
*/
|
|
1357
|
+
function renderChildItem(item) {
|
|
1358
|
+
const ChildIcon = item.icon;
|
|
1359
|
+
const childActive = currentPath === item.href;
|
|
1360
|
+
const hasChildren = item.children && item.children.length > 0;
|
|
1361
|
+
const isExpanded = expandedIds.has(item.id);
|
|
1362
|
+
const isChildActive = hasActiveDescendant(item);
|
|
1363
|
+
if (hasChildren) return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
|
|
1364
|
+
onClick: () => toggleExpand(item.id),
|
|
1365
|
+
className: cn$29("w-full flex items-center pl-4 pr-4 py-2 rounded-r-lg text-[13px] cursor-pointer", childActive || isChildActive ? "text-[var(--dashboard-sidebar-active-text,#ff521d)] font-semibold" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:text-[var(--dashboard-sidebar-active-text,#ff521d)]"),
|
|
1366
|
+
style: { transition: "background-color 200ms, color 200ms" },
|
|
1367
|
+
children: [
|
|
1368
|
+
/* @__PURE__ */ jsx(ChildIcon, {
|
|
1369
|
+
size: 15,
|
|
1370
|
+
className: "mr-2 flex-shrink-0"
|
|
1371
|
+
}),
|
|
1372
|
+
/* @__PURE__ */ jsx("span", {
|
|
1373
|
+
className: "whitespace-nowrap flex-1 text-left",
|
|
1374
|
+
children: item.label
|
|
1375
|
+
}),
|
|
1376
|
+
/* @__PURE__ */ jsx(ChevronRight, {
|
|
1377
|
+
size: 12,
|
|
1378
|
+
className: cn$29("ml-auto flex-shrink-0 transition-transform duration-200", isExpanded ? "rotate-90" : "")
|
|
1379
|
+
})
|
|
1380
|
+
]
|
|
1381
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1382
|
+
className: "overflow-hidden transition-all duration-200 ml-7 border-l-2 border-[var(--dashboard-sidebar-border,#e0dfe3)]",
|
|
1383
|
+
style: { maxHeight: isExpanded ? `${countVisibleDescendants(item) * 40}px` : "0" },
|
|
1384
|
+
children: item.children.map((grandchild) => renderChildItem(grandchild))
|
|
1385
|
+
})] }, item.id);
|
|
1386
|
+
return /* @__PURE__ */ jsx(LinkComponent, {
|
|
1387
|
+
href: item.href,
|
|
1388
|
+
className: "block",
|
|
1389
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1390
|
+
className: cn$29("w-full flex items-center pl-4 pr-4 py-2 rounded-r-lg text-[13px] cursor-pointer", childActive ? "text-[var(--dashboard-sidebar-active-text,#ff521d)] font-semibold border-l-2 border-[var(--dashboard-primary,#ff521d)] -ml-[2px]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:text-[var(--dashboard-sidebar-active-text,#ff521d)]"),
|
|
1391
|
+
style: { transition: "background-color 200ms, color 200ms" },
|
|
1392
|
+
children: [/* @__PURE__ */ jsx(ChildIcon, {
|
|
1393
|
+
size: 15,
|
|
1394
|
+
className: "mr-2 flex-shrink-0"
|
|
1395
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1396
|
+
className: "whitespace-nowrap",
|
|
1397
|
+
children: item.label
|
|
1398
|
+
})]
|
|
1399
|
+
})
|
|
1400
|
+
}, item.id);
|
|
1401
|
+
}
|
|
1319
1402
|
function renderMenuItem(item, collapsed, mobile) {
|
|
1320
1403
|
const Icon = item.icon;
|
|
1321
1404
|
const hasChildren = item.children && item.children.length > 0;
|
|
@@ -1343,26 +1426,8 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1343
1426
|
})] })]
|
|
1344
1427
|
}), (!collapsed || mobile) && /* @__PURE__ */ jsx("div", {
|
|
1345
1428
|
className: "overflow-hidden transition-all duration-200 ml-7 border-l-2 border-[var(--dashboard-sidebar-border,#e0dfe3)]",
|
|
1346
|
-
style: { maxHeight: isExpanded ? `${item
|
|
1347
|
-
children: item.children.map((child) =>
|
|
1348
|
-
const ChildIcon = child.icon;
|
|
1349
|
-
const childActive = currentPath === child.href;
|
|
1350
|
-
return /* @__PURE__ */ jsx(LinkComponent, {
|
|
1351
|
-
href: child.href,
|
|
1352
|
-
className: "block",
|
|
1353
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1354
|
-
className: cn$29("w-full flex items-center pl-4 pr-4 py-2 rounded-r-lg text-[13px] cursor-pointer", childActive ? "text-[var(--dashboard-sidebar-active-text,#ff521d)] font-semibold border-l-2 border-[var(--dashboard-primary,#ff521d)] -ml-[2px]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:text-[var(--dashboard-sidebar-active-text,#ff521d)]"),
|
|
1355
|
-
style: { transition: "background-color 200ms, color 200ms" },
|
|
1356
|
-
children: [/* @__PURE__ */ jsx(ChildIcon, {
|
|
1357
|
-
size: 15,
|
|
1358
|
-
className: "mr-2 flex-shrink-0"
|
|
1359
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
1360
|
-
className: "whitespace-nowrap",
|
|
1361
|
-
children: child.label
|
|
1362
|
-
})]
|
|
1363
|
-
})
|
|
1364
|
-
}, child.id);
|
|
1365
|
-
})
|
|
1429
|
+
style: { maxHeight: isExpanded ? `${countVisibleDescendants(item) * 40}px` : "0" },
|
|
1430
|
+
children: item.children.map((child) => renderChildItem(child))
|
|
1366
1431
|
})] }, item.id);
|
|
1367
1432
|
return /* @__PURE__ */ jsx(LinkComponent, {
|
|
1368
1433
|
href: item.href,
|