@acronis-platform/ui-react 5.0.0 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/components/ui/area-chart/area-chart.js +191 -85
  2. package/dist/components/ui/area-chart/area-chart.js.map +1 -1
  3. package/dist/components/ui/bar-chart/bar-chart.js +288 -225
  4. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  5. package/dist/components/ui/card-widget-carousel/card-widget-carousel.js +85 -0
  6. package/dist/components/ui/card-widget-carousel/card-widget-carousel.js.map +1 -0
  7. package/dist/components/ui/card-widget-carousel/card-widget.js +82 -0
  8. package/dist/components/ui/card-widget-carousel/card-widget.js.map +1 -0
  9. package/dist/components/ui/category-bar/category-bar.js.map +1 -1
  10. package/dist/components/ui/chart/chart-format.js +25 -22
  11. package/dist/components/ui/chart/chart-format.js.map +1 -1
  12. package/dist/components/ui/chart/chart-palette.js +9 -8
  13. package/dist/components/ui/chart/chart-palette.js.map +1 -1
  14. package/dist/components/ui/chart/chart.js +118 -83
  15. package/dist/components/ui/chart/chart.js.map +1 -1
  16. package/dist/components/ui/chart-state/chart-state.js +15 -7
  17. package/dist/components/ui/chart-state/chart-state.js.map +1 -1
  18. package/dist/components/ui/line-chart/line-chart.js +194 -86
  19. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  20. package/dist/components/ui/scatter-chart/scatter-chart.js +5 -2
  21. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  22. package/dist/components/ui/separator/separator.js +52 -10
  23. package/dist/components/ui/separator/separator.js.map +1 -1
  24. package/dist/components/ui/sidebar-secondary/sidebar-secondary.js +144 -121
  25. package/dist/components/ui/sidebar-secondary/sidebar-secondary.js.map +1 -1
  26. package/dist/components/ui/tree-item/tree-item.js +67 -0
  27. package/dist/components/ui/tree-item/tree-item.js.map +1 -0
  28. package/dist/components/ui/treemap/treemap.js +73 -66
  29. package/dist/components/ui/treemap/treemap.js.map +1 -1
  30. package/dist/index.js +109 -107
  31. package/dist/llms/area-chart.md +2 -1
  32. package/dist/llms/bar-chart.md +132 -33
  33. package/dist/llms/card-widget-carousel.md +252 -0
  34. package/dist/llms/category-bar.md +2 -2
  35. package/dist/llms/chart-state.md +17 -4
  36. package/dist/llms/line-chart.md +2 -1
  37. package/dist/llms/metric.md +10 -5
  38. package/dist/llms/scatter-chart.md +2 -1
  39. package/dist/llms/separator.md +27 -8
  40. package/dist/llms/sidebar-secondary.md +235 -4
  41. package/dist/llms/tree-item.md +359 -0
  42. package/dist/llms/treemap.md +47 -36
  43. package/dist/llms.txt +4 -3
  44. package/dist/react.js +109 -107
  45. package/dist/src/components/ui/area-chart/area-chart.d.ts +10 -0
  46. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +75 -10
  47. package/dist/src/components/ui/bar-chart/bar-chart.docs.d.ts +146 -0
  48. package/dist/src/components/ui/bar-chart/index.d.ts +1 -1
  49. package/dist/src/components/ui/card-widget-carousel/card-widget-carousel.d.ts +9 -0
  50. package/dist/src/components/ui/card-widget-carousel/card-widget.d.ts +43 -0
  51. package/dist/src/components/ui/card-widget-carousel/index.d.ts +2 -0
  52. package/dist/src/components/ui/chart/chart-format.d.ts +9 -1
  53. package/dist/src/components/ui/chart/chart-palette.d.ts +38 -10
  54. package/dist/src/components/ui/chart/index.d.ts +2 -2
  55. package/dist/src/components/ui/line-chart/line-chart.d.ts +11 -1
  56. package/dist/src/components/ui/separator/separator.d.ts +9 -1
  57. package/dist/src/components/ui/sidebar-secondary/sidebar-secondary.d.ts +23 -3
  58. package/dist/src/components/ui/tree-item/index.d.ts +1 -0
  59. package/dist/src/components/ui/tree-item/tree-item.d.ts +64 -0
  60. package/dist/src/components/ui/treemap/treemap.d.ts +16 -5
  61. package/dist/src/index.d.ts +2 -1
  62. package/dist/ui-react.css +1 -1
  63. package/package.json +3 -3
  64. package/dist/components/ui/meter/meter.js +0 -79
  65. package/dist/components/ui/meter/meter.js.map +0 -1
  66. package/dist/llms/meter.md +0 -177
  67. package/dist/src/components/ui/meter/index.d.ts +0 -1
  68. package/dist/src/components/ui/meter/meter.d.ts +0 -25
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar-secondary.js","names":[],"sources":["../../../../src/components/ui/sidebar-secondary/sidebar-secondary.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport { Collapsible } from '@base-ui/react/collapsible';\nimport {\n ChevronDownIcon,\n SquareArrowUpRightIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\nimport { useDocDir } from '@/lib/use-doc-dir';\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@/components/ui/tooltip';\n\n/**\n * Tracks whether `ref`'s element is clipping its own content (`scrollWidth >\n * clientWidth`) — used to gate a tooltip so it only opens when a truncated\n * label is actually cut off. Re-measures via `ResizeObserver` (covers the\n * rail's expand/collapse width transition); `enabled` skips measurement\n * entirely (e.g. while collapsed, where the label is `sr-only`).\n */\nfunction useIsOverflowing<T extends Element>(\n ref: React.RefObject<T | null>,\n { enabled }: { enabled: boolean }\n): boolean {\n const [isOverflowing, setIsOverflowing] = React.useState(false);\n\n React.useEffect(() => {\n const element = ref.current;\n if (!enabled || !element) {\n setIsOverflowing(false);\n return;\n }\n const measure = () =>\n setIsOverflowing(element.scrollWidth > element.clientWidth);\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [ref, enabled]);\n\n return isOverflowing;\n}\n\n// Resize constraints — mirrors the design-token defaults.\n// CSS still uses `var(--ui-sidebar-secondary-expanded-container-width)` so\n// brands that override the token get the correct visual width; these JS\n// constants only govern the drag-resize clamping range.\nconst SIDEBAR_EXPANDED_WIDTH = 256; // --ui-sidebar-secondary-expanded-container-width\nconst SIDEBAR_MAX_WIDTH = SIDEBAR_EXPANDED_WIDTH * 2;\n\n// Composable SidebarSecondary primitives mirroring the Figma \"SidebarSecondary\"\n// component set (node 2468:59502, variant expanded|collapsed). Every color and\n// metric is wired to a next-gen `--ui-sidebar-secondary-*` token from\n// @acronis-platform/tokens-pd — no hex, no invented tokens.\n//\n// Like SidebarPrimary, expanded/collapsed is a width-reflow state (not a panel\n// show/hide), modelled as a controlled/uncontrolled `expanded` prop (default\n// true) that sets `data-state=\"expanded|collapsed\"` on the root and is shared to\n// descendants via context. The collapsed rail replaces the section list with a\n// vertical breadcrumb (parent → separator → current page), toggled purely by the\n// `data-[state]` selectors so it is SSR-present and needs no JS branch.\n//\n// Menu-item color wiring DIVERGES from Primary (DESIGN §6.2): Secondary recolors\n// only the CONTAINER per selected/unselected; the icon and label use the shared\n// `--ui-sidebar-secondary-menu-item-global-{icon,label}-color-color` tokens\n// across both variants and every interaction state (the next-gen token sync\n// collapsed the former per-state idle/hover/active icon+label colors into a\n// single value each). So the cva base carries the global icon/label colors and\n// the two variants only swap the container fill.\n//\n// R6 (collapsed separator icon): resolved from the Figma node metadata — the\n// collapsed `iconSeparator` instance's mainComponent is \"ChevronDown\" (updated\n// from ChevronRight), so the separator defaults to `ChevronDownIcon` (16px),\n// tinted by `--ui-sidebar-secondary-collapsed-icon-separator-color`. In the\n// vertical breadcrumb flow (writing-mode: vertical-rl) the downward chevron\n// visually points \"forward\" in the reading direction. The disclosure chevron\n// uses `ChevronDownIcon` rotated via `data-panel-open`. The focus ring reuses the\n// shared `--ui-focus-brand` (no sidebar focus token exists — R1).\n\nconst defaultResizeTooltipExpanded = (\n <>\n <span className=\"font-semibold\">Resize:</span> Drag\n <br />\n <span className=\"font-semibold\">Collapse:</span> Click\n <br />\n <span className=\"font-semibold\">Reset size:</span> Double click\n </>\n);\n\nconst defaultResizeTooltipCollapsed = (\n <>\n <span className=\"font-semibold\">Resize:</span> Drag\n <br />\n <span className=\"font-semibold\">Expand:</span> Click\n </>\n);\n\ninterface SidebarSecondaryContextValue {\n expanded: boolean;\n /** Flip the panel width — drives the controlled/uncontrolled `expanded` state. */\n toggleExpanded: () => void;\n /** Whether resize is enabled. */\n resizable: boolean;\n /** Current width in px (only meaningful when resizable + expanded). */\n width: number;\n /** Update the width (used by the resize edge during drag). */\n setWidth: (width: number) => void;\n /** Min resize width — derived from `--ui-sidebar-secondary-expanded-container-width`. */\n minWidth: number;\n /** Max resize width — expanded-width × RESIZE_MAX_WIDTH_FACTOR. */\n maxWidth: number;\n /** Default (reset) width — equals expanded-container-width token. */\n defaultWidth: number;\n /** Label registered by `SidebarSecondaryHeader` — consumed by the collapsed breadcrumb. */\n headerLabel: React.ReactNode;\n /** Register the header label (called by `SidebarSecondaryHeader`). */\n setHeaderLabel: (label: React.ReactNode) => void;\n /** Label of the currently selected `MenuItem` — consumed by the collapsed breadcrumb. */\n selectedLabel: React.ReactNode;\n /** Register the selected item label (called by `SidebarSecondaryMenuItem`). */\n setSelectedLabel: (label: React.ReactNode) => void;\n /** Accessible label for the resize edge separator. */\n resizeAriaLabel: string;\n /** Tooltip content shown when the sidebar is expanded. */\n resizeTooltipExpanded: React.ReactNode;\n /** Tooltip content shown when the sidebar is collapsed. */\n resizeTooltipCollapsed: React.ReactNode;\n}\n\nconst SidebarSecondaryContext =\n React.createContext<SidebarSecondaryContextValue | null>(null);\n\nfunction useSidebarSecondaryContext(): SidebarSecondaryContextValue {\n // Default to expanded so parts render standalone (in isolation tests /\n // stories) without a wrapping root; the toggle is a no-op outside a root.\n return (\n React.useContext(SidebarSecondaryContext) ?? {\n expanded: true,\n toggleExpanded: () => {},\n resizable: false,\n width: SIDEBAR_EXPANDED_WIDTH,\n setWidth: () => {},\n minWidth: SIDEBAR_EXPANDED_WIDTH,\n maxWidth: SIDEBAR_MAX_WIDTH,\n defaultWidth: SIDEBAR_EXPANDED_WIDTH,\n headerLabel: undefined,\n setHeaderLabel: () => {},\n selectedLabel: undefined,\n setSelectedLabel: () => {},\n resizeAriaLabel: 'Resize sidebar',\n resizeTooltipExpanded: defaultResizeTooltipExpanded,\n resizeTooltipCollapsed: defaultResizeTooltipCollapsed,\n }\n );\n}\n\n/**\n * Controlled + uncontrolled boolean state (the Base UI idiom). When `controlled`\n * is provided it wins and the setter only emits the change callback; otherwise\n * the setter updates internal state. `onChange` is ALWAYS invoked with the next\n * value so a consumer can react in either mode.\n */\nfunction useControllableBoolean(\n controlled: boolean | undefined,\n defaultValue: boolean,\n onChange?: (next: boolean) => void\n): [boolean, (next: boolean) => void] {\n const [uncontrolled, setUncontrolled] = React.useState(defaultValue);\n const isControlled = controlled !== undefined;\n const value = isControlled ? controlled : uncontrolled;\n const setValue = React.useCallback(\n (next: boolean) => {\n if (!isControlled) setUncontrolled(next);\n onChange?.(next);\n },\n [isControlled, onChange]\n );\n return [value, setValue];\n}\n\nexport interface SidebarSecondaryProps extends React.ComponentPropsWithoutRef<'nav'> {\n /** Controlled expanded (rail width) state. */\n expanded?: boolean;\n /** Uncontrolled initial expanded state. Defaults to `true` (full width). */\n defaultExpanded?: boolean;\n /** Fires when the expanded state changes (e.g. a consumer toggle). */\n onExpandedChange?: (expanded: boolean) => void;\n /**\n * Enable the draggable resize edge on the right border.\n * When `true`, the sidebar can be resized between the expanded-width token\n * and twice that value.\n */\n resizable?: boolean;\n /** Controlled width in px (only used when `resizable`). */\n width?: number;\n /** Fires when the width changes due to a drag interaction. */\n onWidthChange?: (width: number) => void;\n /** Accessible label for the resize edge (`role=\"separator\"`). Defaults to `'Resize sidebar'`. */\n resizeAriaLabel?: string;\n /** Tooltip content shown when the sidebar is expanded. Pass `null` to hide the tooltip entirely. */\n resizeTooltipExpanded?: React.ReactNode;\n /** Tooltip content shown when the sidebar is collapsed. Pass `null` to hide the tooltip entirely. */\n resizeTooltipCollapsed?: React.ReactNode;\n /**\n * Replace the rendered `<nav>` with another element or component\n * (Base UI composition). Accepts a React element or a render function.\n */\n render?: useRender.RenderProp;\n}\n\n// ---------------------------------------------------------------------------\n// SidebarSecondaryResizeEdge — internal drag/click handle on the right edge\n// ---------------------------------------------------------------------------\n// Styled after `ResizableHandle` (Figma 4649:6681): a hit area that takes up no\n// layout space around a 1px divider, idle → `--ui-border-on-surface-border`,\n// hover → `--ui-resizable-border-color-hover`,\n// drag → `--ui-resizable-border-color-active`.\n// ---------------------------------------------------------------------------\n\nfunction SidebarSecondaryResizeEdge() {\n const ctx = useSidebarSecondaryContext();\n const { expanded, toggleExpanded, resizable } = ctx;\n const dir = useDocDir();\n\n // Mutable ref so the closure-captured pointermove handler always reads\n // the latest context without re-attaching listeners.\n const ctxRef = React.useRef(ctx);\n ctxRef.current = ctx;\n\n // Track whether a pointermove actually happened between down→up so we can\n // suppress the click that the browser fires after every pointerup.\n const didDragRef = React.useRef(false);\n\n // Hide the tooltip while dragging.\n const [tooltipOpen, setTooltipOpen] = React.useState(false);\n const [dragging, setDragging] = React.useState(false);\n\n // Delay single-click so a double-click can cancel it.\n const clickTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n\n // Clear any pending click timer on unmount.\n React.useEffect(() => {\n return () => {\n if (clickTimerRef.current) clearTimeout(clickTimerRef.current);\n };\n }, []);\n\n if (!resizable) return null;\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n e.preventDefault();\n const el = e.currentTarget;\n el.setPointerCapture(e.pointerId);\n didDragRef.current = false;\n setDragging(true);\n setTooltipOpen(false);\n\n // Disable the width transition while dragging so resize follows the\n // cursor without animation lag.\n const sidebarEl = el.closest('[data-state]') as HTMLElement | null;\n if (!sidebarEl) {\n setDragging(false);\n el.releasePointerCapture(e.pointerId);\n return;\n }\n sidebarEl.style.transitionProperty = 'none';\n const isRtl = getComputedStyle(sidebarEl).direction === 'rtl';\n const sidebarRect = sidebarEl.getBoundingClientRect();\n\n const { minWidth, maxWidth } = ctxRef.current;\n const collapseThreshold = minWidth / 2;\n\n const onPointerMove = (ev: PointerEvent) => {\n didDragRef.current = true;\n const newWidth = isRtl\n ? sidebarRect.right - ev.clientX\n : ev.clientX - sidebarRect.left;\n const { expanded: isExpanded } = ctxRef.current;\n\n if (isExpanded) {\n if (newWidth < collapseThreshold) {\n ctxRef.current.toggleExpanded();\n } else {\n ctxRef.current.setWidth(\n Math.min(Math.max(newWidth, minWidth), maxWidth)\n );\n }\n } else {\n if (newWidth > collapseThreshold) {\n ctxRef.current.toggleExpanded();\n }\n }\n };\n\n const onPointerUp = () => {\n setDragging(false);\n // Restore transition so collapse/expand animates.\n if (sidebarEl) sidebarEl.style.transitionProperty = '';\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n };\n\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n };\n\n const handleClick = () => {\n // Suppress click when the interaction was a drag.\n if (didDragRef.current) return;\n // Cancel any pending click timer (dblclick fires two clicks).\n if (clickTimerRef.current) clearTimeout(clickTimerRef.current);\n // Wait to see if a double-click follows.\n clickTimerRef.current = setTimeout(() => {\n toggleExpanded();\n }, 250);\n };\n\n const handleDoubleClick = () => {\n // Cancel the pending single-click toggle.\n if (clickTimerRef.current) {\n clearTimeout(clickTimerRef.current);\n clickTimerRef.current = null;\n }\n if (!expanded) toggleExpanded();\n ctxRef.current.setWidth(ctxRef.current.defaultWidth);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const {\n minWidth,\n maxWidth,\n defaultWidth,\n width: w,\n setWidth: sw,\n expanded: exp,\n toggleExpanded: te,\n } = ctxRef.current;\n const step = 16;\n const growKey = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';\n const shrinkKey = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';\n if (e.key === growKey && exp) {\n e.preventDefault();\n sw(Math.min(w + step, maxWidth));\n } else if (e.key === growKey && !exp) {\n e.preventDefault();\n te();\n } else if (e.key === shrinkKey && exp) {\n e.preventDefault();\n const next = w - step;\n if (next < minWidth) {\n te();\n } else {\n sw(next);\n }\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n te();\n } else if (e.key === 'Home') {\n e.preventDefault();\n if (!exp) te();\n sw(defaultWidth);\n }\n };\n\n const handleTooltipOpenChange = (open: boolean) => {\n // Never open the tooltip while dragging.\n if (dragging) return;\n setTooltipOpen(open);\n };\n\n return (\n <Tooltip open={tooltipOpen} onOpenChange={handleTooltipOpenChange} trackCursorAxis=\"y\">\n <TooltipTrigger\n render={\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={ctx.resizeAriaLabel}\n className={cn(\n // 17px hit area, absolutely positioned on inline-end edge.\n // The sidebar's own border-e provides the visible 1px line; its color\n // changes via :has() on hover/active/focus-visible.\n 'absolute end-0 top-0 h-full w-[17px] ltr:translate-x-1/2 rtl:-translate-x-1/2 cursor-[var(--ui-resizable-cursor,ew-resize)] z-10',\n // On focus: 1px active-color line (after pseudo, CSS border for pixel-snap) + 3px box-shadow ring centered on it.\n 'after:absolute after:inset-y-0 after:inset-x-0 after:mx-auto after:w-0 after:pointer-events-none',\n 'after:[border-inline-start-width:var(--ui-resizable-border-width,1px)] after:border-solid after:border-transparent',\n 'focus-visible:outline-none focus-visible:after:[border-inline-start-color:var(--ui-resizable-border-color-active)] focus-visible:after:[box-shadow:0_0_0_3px_var(--ui-focus-primary)]'\n )}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onPointerDown={handlePointerDown}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n />\n }\n />\n {(expanded ? ctx.resizeTooltipExpanded : ctx.resizeTooltipCollapsed) !=\n null && (\n <TooltipContent side={dir === 'rtl' ? 'left' : 'right'} align=\"center\">\n {expanded ? ctx.resizeTooltipExpanded : ctx.resizeTooltipCollapsed}\n </TooltipContent>\n )}\n </Tooltip>\n );\n}\n\nconst SidebarSecondary = React.forwardRef<HTMLElement, SidebarSecondaryProps>(\n (\n {\n className,\n expanded: expandedProp,\n defaultExpanded = true,\n onExpandedChange,\n resizable: resizableProp = true,\n width: widthProp,\n onWidthChange,\n resizeAriaLabel = 'Resize sidebar',\n resizeTooltipExpanded = defaultResizeTooltipExpanded,\n resizeTooltipCollapsed = defaultResizeTooltipCollapsed,\n 'aria-label': ariaLabel = 'Section navigation',\n render,\n children,\n ...props\n },\n ref\n ) => {\n const [expanded, setExpanded] = useControllableBoolean(\n expandedProp,\n defaultExpanded,\n onExpandedChange\n );\n\n // Width is independent of expanded/collapsed — it persists across cycles.\n const [width, setWidthState] = React.useState(SIDEBAR_EXPANDED_WIDTH);\n const isWidthControlled = widthProp !== undefined;\n const currentWidth = isWidthControlled ? widthProp : width;\n const setWidth = React.useCallback(\n (next: number) => {\n if (!isWidthControlled) setWidthState(next);\n onWidthChange?.(next);\n },\n [isWidthControlled, onWidthChange]\n );\n\n // Collapse is driven by the consumer through the layout context — the\n // `SidebarSecondaryCollapseTrigger` calls `toggleExpanded`, which updates\n // uncontrolled state and always emits `onExpandedChange`. Controlled\n // consumers ignore the internal state and react to the callback.\n // Breadcrumb auto-wiring: Header and the selected MenuItem register their\n // labels so the collapsed breadcrumb can display them without manual props.\n const [headerLabel, setHeaderLabel] =\n React.useState<React.ReactNode>(undefined);\n const [selectedLabel, setSelectedLabel] =\n React.useState<React.ReactNode>(undefined);\n\n const context = React.useMemo<SidebarSecondaryContextValue>(\n () => ({\n expanded,\n toggleExpanded: () => setExpanded(!expanded),\n resizable: resizableProp,\n width: currentWidth,\n setWidth,\n minWidth: SIDEBAR_EXPANDED_WIDTH,\n maxWidth: SIDEBAR_MAX_WIDTH,\n defaultWidth: SIDEBAR_EXPANDED_WIDTH,\n headerLabel,\n setHeaderLabel,\n selectedLabel,\n setSelectedLabel,\n resizeAriaLabel,\n resizeTooltipExpanded,\n resizeTooltipCollapsed,\n }),\n [\n expanded,\n setExpanded,\n resizableProp,\n currentWidth,\n setWidth,\n headerLabel,\n selectedLabel,\n resizeAriaLabel,\n resizeTooltipExpanded,\n resizeTooltipCollapsed,\n ]\n );\n\n // When resizable + expanded, apply inline width ONLY when the user has\n // actively resized (or width is controlled). Otherwise the CSS token\n // `--ui-sidebar-secondary-expanded-container-width` drives the width,\n // so brand overrides are honoured and no inline style wins specificity.\n const hasWidthOverride =\n isWidthControlled || currentWidth !== SIDEBAR_EXPANDED_WIDTH;\n const inlineStyle: React.CSSProperties | undefined =\n resizableProp && expanded && hasWidthOverride\n ? { width: currentWidth }\n : undefined;\n\n const element = useRender({\n render,\n ref,\n defaultTagName: 'nav',\n props: mergeProps<'nav'>(\n {\n 'aria-label': ariaLabel,\n // `data-state` drives every collapsed/expanded token switch via\n // attribute selectors; typed loosely because React's nav attribute\n // map doesn't include arbitrary data-* keys as literals.\n ...({ 'data-state': expanded ? 'expanded' : 'collapsed' } as Record<\n string,\n string\n >),\n style: inlineStyle,\n className: cn(\n 'group/sidebar relative flex h-full flex-col bg-[var(--ui-sidebar-secondary-global-container-color)] border-e border-[var(--ui-sidebar-secondary-global-container-border-color)] [border-inline-end-width:var(--ui-sidebar-secondary-global-container-border-width)] w-[var(--ui-sidebar-secondary-collapsed-container-width)] data-[state=expanded]:w-[var(--ui-sidebar-secondary-expanded-container-width)] transition-[width]',\n resizableProp &&\n 'transition-[width,border-color] has-[[role=separator]:hover]:[border-inline-end-color:var(--ui-resizable-border-color-hover)] has-[[role=separator]:active]:[border-inline-end-color:var(--ui-resizable-border-color-active)] has-[[role=separator]:focus-visible]:[border-inline-end-color:var(--ui-resizable-border-color-active)]',\n className\n ),\n children: (\n <>\n <SidebarSecondaryCollapsedBreadcrumb />\n {children}\n <SidebarSecondaryResizeEdge />\n </>\n ),\n },\n props\n ),\n });\n\n return (\n <SidebarSecondaryContext.Provider value={context}>\n {element}\n </SidebarSecondaryContext.Provider>\n );\n }\n);\nSidebarSecondary.displayName = 'SidebarSecondary';\n\nexport interface SidebarSecondaryHeaderProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Heading text (or pass as children). */\n label?: React.ReactNode;\n}\n\nconst SidebarSecondaryHeader = React.forwardRef<\n HTMLDivElement,\n SidebarSecondaryHeaderProps\n>(({ className, label, children, ...props }, ref) => {\n const { setHeaderLabel } = useSidebarSecondaryContext();\n const resolvedLabel = label ?? children;\n\n // Register the header text so the collapsed breadcrumb can auto-display it.\n React.useEffect(() => {\n setHeaderLabel(resolvedLabel);\n }, [resolvedLabel, setHeaderLabel]);\n\n return (\n <div\n ref={ref}\n className={cn(\n 'hidden items-center shrink-0',\n 'group-data-[state=expanded]/sidebar:flex',\n 'px-[var(--ui-sidebar-secondary-global-container-header-padding-x)] py-[var(--ui-sidebar-secondary-global-container-header-padding-y)]',\n className\n )}\n {...props}\n >\n <h2 className=\"ui-sidebar-secondary-global-header-label-text-style truncate text-[var(--ui-sidebar-secondary-global-header-label-color)]\">\n {resolvedLabel}\n </h2>\n </div>\n );\n});\nSidebarSecondaryHeader.displayName = 'SidebarSecondaryHeader';\n\nconst SidebarSecondaryContent = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<'div'>\n>(({ className, ...props }, ref) => (\n // Expanded: the section list. Hidden in collapsed mode, where the\n // CollapsedBreadcrumb sibling takes over.\n <div\n ref={ref}\n className={cn(\n 'flex flex-1 flex-col overflow-y-auto gap-[var(--ui-sidebar-secondary-global-section-list-gap)]',\n 'hidden group-data-[state=expanded]/sidebar:flex',\n className\n )}\n {...props}\n />\n));\nSidebarSecondaryContent.displayName = 'SidebarSecondaryContent';\n\nexport interface SidebarSecondaryCollapsedBreadcrumbProps extends React.ComponentPropsWithoutRef<'div'> {\n /**\n * The parent section label (breadcrumbLabel).\n * Auto-derived from the `SidebarSecondaryHeader` label when omitted.\n */\n parentLabel?: React.ReactNode;\n /**\n * The current page label (labelCurrentPage).\n * Auto-derived from the selected `SidebarSecondaryMenuItem` when omitted.\n */\n currentLabel?: React.ReactNode;\n /** Separator between the two; defaults to a 16px ChevronDownIcon. */\n separator?: React.ReactNode;\n}\n\nconst SidebarSecondaryCollapsedBreadcrumb = React.forwardRef<\n HTMLDivElement,\n SidebarSecondaryCollapsedBreadcrumbProps\n>(({ className, parentLabel, currentLabel, separator, ...props }, ref) => {\n const { headerLabel, selectedLabel } = useSidebarSecondaryContext();\n const resolvedParent = parentLabel ?? headerLabel;\n const resolvedCurrent = currentLabel ?? selectedLabel;\n\n return (\n // Shown only in collapsed mode — toggled by the same data-[state] selector so\n // it stays in the DOM (SSR-present) with no JS branch. Laid out vertically:\n // parent → separator → current page.\n <div\n ref={ref}\n className={cn(\n 'flex flex-1 flex-col items-center min-h-0',\n 'gap-[var(--ui-sidebar-secondary-collapsed-container-content-gap)] py-[var(--ui-sidebar-secondary-collapsed-container-content-padding-y)]',\n 'flex group-data-[state=expanded]/sidebar:hidden',\n className\n )}\n {...props}\n >\n <span className=\"[writing-mode:vertical-rl] [direction:ltr] shrink-0 ui-sidebar-secondary-collapsed-breadcrumb-label-text-style text-[var(--ui-sidebar-secondary-collapsed-breadcrumb-label-color)]\">\n {resolvedParent}\n </span>\n <span\n aria-hidden=\"true\"\n className=\"inline-flex items-center text-[var(--ui-sidebar-secondary-collapsed-icon-separator-color)] [&>svg]:size-[var(--ui-sidebar-secondary-collapsed-icon-separator-size)]\"\n >\n {separator ?? <ChevronDownIcon size={16} />}\n </span>\n <span className=\"[writing-mode:vertical-rl] [direction:ltr] flex-1 min-h-0 overflow-hidden ui-sidebar-secondary-collapsed-label-current-page-text-style text-[var(--ui-sidebar-secondary-collapsed-label-current-page-color)]\">\n {resolvedCurrent}\n </span>\n </div>\n );\n});\nSidebarSecondaryCollapsedBreadcrumb.displayName =\n 'SidebarSecondaryCollapsedBreadcrumb';\n\nconst SidebarSecondaryFooter = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<'div'>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col shrink-0',\n 'border-t border-[var(--ui-sidebar-secondary-global-container-footer-border-color)] [border-top-width:var(--ui-sidebar-secondary-global-container-footer-border-width)]',\n 'py-[var(--ui-sidebar-secondary-section-container-padding-y)]',\n className\n )}\n {...props}\n />\n));\nSidebarSecondaryFooter.displayName = 'SidebarSecondaryFooter';\n\n// A section can be a static group (label + items) or an EXPANDABLE disclosure\n// (Figma Section `expandable=yes-*`): the label becomes a chevron toggle that\n// shows/hides the whole item list. Whether a section is expandable is shared to\n// its label + menu via this context (default: static), so the same `SectionLabel`\n// / `Menu` parts adapt without a separate component set.\ninterface SidebarSecondarySectionContextValue {\n expandable: boolean;\n}\n\nconst SidebarSecondarySectionContext =\n React.createContext<SidebarSecondarySectionContextValue>({\n expandable: false,\n });\n\nconst SECTION_STATIC: SidebarSecondarySectionContextValue = {\n expandable: false,\n};\nconst SECTION_EXPANDABLE: SidebarSecondarySectionContextValue = {\n expandable: true,\n};\n\nexport interface SidebarSecondarySectionProps extends React.ComponentPropsWithoutRef<'div'> {\n /**\n * Make the section a collapsible disclosure: the `SidebarSecondarySectionLabel`\n * becomes a chevron toggle and the `SidebarSecondaryMenu` becomes its panel.\n */\n expandable?: boolean;\n /** Controlled open state (expandable sections only). */\n open?: boolean;\n /** Uncontrolled initial open state (expandable sections only). Defaults to open. */\n defaultOpen?: boolean;\n /** Fires with the next open value when an expandable section toggles. */\n onOpenChange?: (open: boolean) => void;\n}\n\nconst SidebarSecondarySection = React.forwardRef<\n HTMLDivElement,\n SidebarSecondarySectionProps\n>(\n (\n {\n className,\n expandable = false,\n open,\n defaultOpen = true,\n onOpenChange,\n children,\n ...props\n },\n ref\n ) => {\n // Sections are separated by vertical padding + the section label; the next-gen\n // token sync removed the inter-section divider (no\n // `--ui-sidebar-secondary-section-container-border-*` token survives).\n const sectionClass = cn(\n 'flex flex-col py-[var(--ui-sidebar-secondary-section-container-padding-y)]',\n className\n );\n\n if (!expandable) {\n return (\n <SidebarSecondarySectionContext.Provider value={SECTION_STATIC}>\n <div ref={ref} className={sectionClass} {...props}>\n {children}\n </div>\n </SidebarSecondarySectionContext.Provider>\n );\n }\n\n // Expandable: Base UI Collapsible owns the open state (controlled or\n // uncontrolled) + the aria-expanded/aria-controls wiring on the trigger.\n return (\n <SidebarSecondarySectionContext.Provider value={SECTION_EXPANDABLE}>\n <Collapsible.Root\n ref={ref}\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n render={<div className={sectionClass} />}\n {...props}\n >\n {children}\n </Collapsible.Root>\n </SidebarSecondarySectionContext.Provider>\n );\n }\n);\nSidebarSecondarySection.displayName = 'SidebarSecondarySection';\n\nexport interface SidebarSecondarySectionLabelProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Trailing header actions (e.g. a ghost `ButtonIcon`). Rendered outside the toggle. */\n actions?: React.ReactNode;\n /**\n * A rollup badge (e.g. a `Tag` with an unread count) shown in the header only\n * when an expandable section is collapsed. Ignored for static sections.\n */\n unreadRollup?: React.ReactNode;\n}\n\nconst sectionLabelTextClass =\n 'ui-sidebar-secondary-section-label-section-text-style text-[var(--ui-sidebar-secondary-section-label-section-color)]';\nconst sectionHeaderPadClass =\n 'min-h-[var(--ui-sidebar-secondary-menu-item-global-container-height-min)] py-[var(--ui-sidebar-secondary-section-container-header-padding-y)] px-[var(--ui-sidebar-secondary-section-container-header-padding-x)]';\n\nconst SidebarSecondarySectionLabel = React.forwardRef<\n HTMLDivElement,\n SidebarSecondarySectionLabelProps\n>(({ className, actions, unreadRollup, children, ...props }, ref) => {\n const { expandable } = React.useContext(SidebarSecondarySectionContext);\n const dir = useDocDir();\n const rowRef = React.useRef<HTMLDivElement>(null);\n const labelRef = React.useRef<HTMLSpanElement>(null);\n const isOverflowing = useIsOverflowing(labelRef, { enabled: true });\n const setRowRef = (node: HTMLDivElement | null) => {\n rowRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n };\n\n // Anchored to the row (not the label span) so it lines up with the\n // sidebar's right edge regardless of how much the label shrinks for\n // trailing actions/rollup.\n const labelTooltip = (\n <Tooltip disabled={!isOverflowing}>\n <TooltipTrigger\n render={\n <span\n ref={labelRef}\n className=\"min-w-0 flex-1 truncate\"\n />\n }\n >\n {children}\n </TooltipTrigger>\n <TooltipContent anchor={rowRef} side={dir === 'rtl' ? 'left' : 'right'}>\n {children}\n </TooltipContent>\n </Tooltip>\n );\n\n if (!expandable) {\n // Static header: preserve the original markup when there are no actions so\n // existing layouts/baselines are unchanged.\n const base = cn(sectionLabelTextClass, sectionHeaderPadClass, className);\n if (actions == null) {\n return (\n <div\n ref={setRowRef}\n className={cn(\n base,\n 'flex items-center'\n )}\n {...props}\n >\n {labelTooltip}\n </div>\n );\n }\n return (\n <div\n ref={setRowRef}\n className={cn(\n base,\n 'flex items-center gap-[var(--ui-sidebar-secondary-section-container-header-gap)]'\n )}\n {...props}\n >\n {labelTooltip}\n <span className=\"flex shrink-0 items-center\">{actions}</span>\n </div>\n );\n }\n\n // Expandable header: a chevron toggle (the Collapsible trigger) plus optional\n // trailing actions kept OUTSIDE the trigger button (no nested buttons). The\n // unread-rollup badge sits inside the trigger and shows only while collapsed.\n return (\n <div\n ref={setRowRef}\n className={cn(\n 'flex items-center gap-[var(--ui-sidebar-secondary-section-container-header-gap)]',\n sectionHeaderPadClass,\n className\n )}\n {...props}\n >\n <Collapsible.Trigger\n className={cn(\n 'group/section flex min-w-0 flex-1 items-center gap-[var(--ui-sidebar-secondary-section-container-header-gap)] text-start cursor-pointer',\n sectionLabelTextClass,\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-inset'\n )}\n >\n <ChevronDownIcon\n size={16}\n aria-hidden=\"true\"\n className=\"shrink-0 ltr:-rotate-90 rtl:rotate-90 transition-transform group-data-[panel-open]/section:rotate-0 text-[var(--ui-sidebar-secondary-section-icon-arrow-color)]\"\n />\n {labelTooltip}\n {unreadRollup != null && (\n <span className=\"flex shrink-0 items-center group-data-[panel-open]/section:hidden\">\n {unreadRollup}\n </span>\n )}\n </Collapsible.Trigger>\n {actions != null && (\n <span className=\"flex shrink-0 items-center\">{actions}</span>\n )}\n </div>\n );\n});\nSidebarSecondarySectionLabel.displayName = 'SidebarSecondarySectionLabel';\n\nconst SidebarSecondaryMenu = React.forwardRef<\n HTMLUListElement,\n React.ComponentPropsWithoutRef<'ul'>\n>(({ className, ...props }, ref) => {\n const { expandable } = React.useContext(SidebarSecondarySectionContext);\n const list = (\n <ul\n ref={ref}\n className={cn(\n 'flex flex-col gap-[var(--ui-sidebar-secondary-section-menu-item-list-gap)]',\n className\n )}\n {...props}\n />\n );\n // Inside an expandable section the item list IS the collapsible panel, so it\n // mounts/unmounts with the section's open state.\n return expandable ? <Collapsible.Panel>{list}</Collapsible.Panel> : list;\n});\nSidebarSecondaryMenu.displayName = 'SidebarSecondaryMenu';\n\n// Shared row geometry + the GLOBAL icon/label state colors (shared across\n// selected/unselected — DESIGN §6.2). The cva `variant` only swaps the container\n// fill. Each interaction state is wired to its own token even where acronis's\n// value is unchanged (runtime var() references honor brand overrides only on the\n// referenced token).\nconst sidebarSecondaryRowClasses =\n 'group/row flex w-full items-start gap-[var(--ui-sidebar-secondary-menu-item-global-container-gap)] min-h-[var(--ui-sidebar-secondary-menu-item-global-container-height-min)] px-[var(--ui-sidebar-secondary-menu-item-global-container-padding-x)] py-[var(--ui-sidebar-secondary-menu-item-global-container-padding-y)] no-underline ui-sidebar-secondary-menu-item-global-label-text-style transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-inset text-[var(--ui-sidebar-secondary-menu-item-global-label-color-color)] [&_svg]:shrink-0 [&_svg]:size-[var(--ui-sidebar-secondary-menu-item-global-icon-size)] [&_svg]:text-[var(--ui-sidebar-secondary-menu-item-global-icon-color-color)]';\n\nconst sidebarSecondaryMenuItemVariants = cva(sidebarSecondaryRowClasses, {\n variants: {\n variant: {\n unselected:\n 'bg-[var(--ui-sidebar-secondary-menu-item-unselected-container-color-idle)] hover:bg-[var(--ui-sidebar-secondary-menu-item-unselected-container-color-hover)] active:bg-[var(--ui-sidebar-secondary-menu-item-unselected-container-color-active)]',\n selected:\n 'bg-[var(--ui-sidebar-secondary-menu-item-selected-container-color-idle)] hover:bg-[var(--ui-sidebar-secondary-menu-item-selected-container-color-hover)] active:bg-[var(--ui-sidebar-secondary-menu-item-selected-container-color-active)]',\n },\n },\n defaultVariants: {\n variant: 'unselected',\n },\n});\n\nexport interface SidebarSecondaryMenuItemProps\n extends\n Omit<React.ComponentPropsWithoutRef<'a'>, 'children'>,\n Omit<VariantProps<typeof sidebarSecondaryMenuItemVariants>, 'variant'> {\n /** Marks the current route: sets the `selected` variant + `aria-current=\"page\"`. */\n selected?: boolean;\n /** Optional leading 16px icon (`hasIcon` in Figma). */\n icon?: React.ReactNode;\n /** Trailing extras (tag, shortcut, external-link icon — `hasExtras` in Figma). */\n extras?: React.ReactNode;\n children?: React.ReactNode;\n /** Replace the rendered `<a>` (e.g. a router `Link` or a `<button>`). */\n render?: useRender.RenderProp;\n}\n\nconst SidebarSecondaryMenuItem = React.forwardRef<\n HTMLAnchorElement,\n SidebarSecondaryMenuItemProps\n>(\n (\n { className, selected = false, icon, extras, render, children, ...props },\n ref\n ) => {\n const { expanded, setSelectedLabel } = useSidebarSecondaryContext();\n const { expandable } = React.useContext(SidebarSecondarySectionContext);\n const dir = useDocDir();\n const rowRef = React.useRef<HTMLAnchorElement>(null);\n const labelRef = React.useRef<HTMLSpanElement>(null);\n const isOverflowing = useIsOverflowing(labelRef, { enabled: expanded });\n\n // Register this item's label when selected so the collapsed breadcrumb\n // auto-displays the current page without manual props.\n React.useEffect(() => {\n if (selected) setSelectedLabel(children);\n }, [selected, children, setSelectedLabel]);\n\n const inner = useRender({\n render,\n ref: [ref, rowRef],\n defaultTagName: 'a',\n props: mergeProps<'a'>(\n {\n className: cn(\n sidebarSecondaryMenuItemVariants({\n variant: selected ? 'selected' : 'unselected',\n }),\n // Inside an expandable section, increase start padding so the\n // label aligns with the section header text (after chevron + gap)\n // while keeping the container full-width for hover/active fills.\n expandable &&\n 'ps-[calc(var(--ui-sidebar-secondary-menu-item-global-container-padding-x)+var(--ui-sidebar-secondary-section-container-header-gap)+16px)]',\n className\n ),\n 'aria-current': selected ? 'page' : undefined,\n onKeyDown: (e: React.KeyboardEvent<HTMLAnchorElement>) => {\n if (e.key === ' ') {\n e.preventDefault();\n e.currentTarget.click();\n }\n },\n children: (\n <>\n {icon != null && (\n <span className=\"flex shrink-0 items-center self-start mt-[var(--ui-sidebar-secondary-menu-item-global-icon-margin-t)]\">\n {icon}\n </span>\n )}\n {/* Keep the label in the DOM as `sr-only` in collapsed/rail mode so\n an icon-only row keeps an accessible name (a11y §7). The tooltip\n trigger is the label span itself — it only opens when the label\n is actually clipped. It's anchored to the row (not the label\n span) so it lines up with the sidebar's right edge regardless\n of how much the label shrinks for extras. */}\n <Tooltip disabled={!isOverflowing}>\n <TooltipTrigger\n render={\n <span\n ref={labelRef}\n className={cn(\n 'flex-1 min-w-[60px] truncate text-start',\n !expanded && 'sr-only'\n )}\n />\n }\n >\n {children}\n </TooltipTrigger>\n <TooltipContent\n anchor={rowRef}\n side={dir === 'rtl' ? 'left' : 'right'}\n >\n {children}\n </TooltipContent>\n </Tooltip>\n {extras}\n </>\n ),\n },\n props\n ),\n });\n\n return (\n <li className=\"contents\">\n {/* In collapsed/rail mode the label above is `sr-only` (zero-size), so\n it never receives the hover that would open its tooltip — wrap the\n whole row so the icon itself is hoverable and always shows the\n item's label as a tooltip while collapsed. */}\n <Tooltip disabled={expanded}>\n <TooltipTrigger render={inner} />\n <TooltipContent side={dir === 'rtl' ? 'left' : 'right'}>\n {children}\n </TooltipContent>\n </Tooltip>\n </li>\n );\n }\n);\nSidebarSecondaryMenuItem.displayName = 'SidebarSecondaryMenuItem';\n\nexport interface SidebarSecondaryMenuItemExtrasProps extends React.ComponentPropsWithoutRef<'span'> {\n /** Which trailing affordance to render. */\n variant: 'tag' | 'externalLink' | 'shortcut' | 'tag-externalLink';\n /** Shortcut text for the `shortcut` variant. */\n shortcut?: string;\n /** Tag content for the `tag` / `tag-externalLink` variants. */\n tag?: React.ReactNode;\n}\n\nconst SidebarSecondaryMenuItemExtras = React.forwardRef<\n HTMLSpanElement,\n SidebarSecondaryMenuItemExtrasProps\n>(({ className, variant, shortcut, tag, children, ...props }, ref) => {\n const { expanded } = useSidebarSecondaryContext();\n const showTag = variant === 'tag' || variant === 'tag-externalLink';\n const showExternal =\n variant === 'externalLink' || variant === 'tag-externalLink';\n const showShortcut = variant === 'shortcut';\n\n return (\n <span\n ref={ref}\n className={cn(\n 'inline-flex items-center shrink-0 min-h-6 overflow-clip gap-[var(--ui-sidebar-secondary-menu-item-extras-global-container-gap)]',\n !expanded && 'hidden',\n className\n )}\n {...props}\n >\n {showTag && (tag ?? children)}\n {showShortcut && (\n <span className=\"ui-sidebar-secondary-menu-item-extras-global-shortcut-text-style text-[var(--ui-sidebar-secondary-menu-item-extras-global-shortcut-color)]\">\n {shortcut ?? children}\n </span>\n )}\n {showExternal && (\n <SquareArrowUpRightIcon\n size={16}\n className=\"text-[var(--ui-sidebar-secondary-menu-item-extras-global-external-icon-color)] size-[var(--ui-sidebar-secondary-menu-item-extras-global-external-icon-size)]\"\n />\n )}\n </span>\n );\n});\nSidebarSecondaryMenuItemExtras.displayName = 'SidebarSecondaryMenuItemExtras';\n\nexport interface SidebarSecondaryCollapseTriggerProps extends Omit<\n React.ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n /** Leading 16px icon (e.g. a panel-left glyph). Rotates 180° between expanded/collapsed — same as `SidebarPrimaryCollapseTrigger`. */\n icon?: React.ReactNode;\n /** Tooltip text shown when the sidebar is collapsed. Defaults to `'Expand'`. */\n expandTooltip?: React.ReactNode;\n /** Trailing extras (e.g. a keyboard shortcut hint), same slot as `SidebarSecondaryMenuItem`. */\n extras?: React.ReactNode;\n children?: React.ReactNode;\n}\n\n// The footer \"Collapse menu\" affordance. A row-styled `<button>` that flips the\n// panel width via the layout context — the live wiring for the controllable\n// `expanded` state (B1). Keeps its label as `sr-only` in collapsed mode.\n// When collapsed, wraps the button in a Tooltip showing \"Expand\".\nconst SidebarSecondaryCollapseTrigger = React.forwardRef<\n HTMLButtonElement,\n SidebarSecondaryCollapseTriggerProps\n>(\n (\n {\n className,\n icon,\n expandTooltip = 'Expand',\n extras,\n children,\n onClick,\n ...props\n },\n ref\n ) => {\n const { expanded, toggleExpanded } = useSidebarSecondaryContext();\n const dir = useDocDir();\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const labelRef = React.useRef<HTMLSpanElement>(null);\n const isOverflowing = useIsOverflowing(labelRef, { enabled: expanded });\n\n const button = (\n <button\n ref={(node) => {\n buttonRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }}\n type=\"button\"\n aria-expanded={expanded}\n className={cn(\n sidebarSecondaryMenuItemVariants({ variant: 'unselected' }),\n 'text-start',\n className\n )}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) toggleExpanded();\n }}\n {...props}\n >\n {icon != null && (\n <span\n className={cn(\n 'flex shrink-0 items-center self-start mt-[var(--ui-sidebar-secondary-menu-item-global-icon-margin-t)] transition-transform',\n expanded ? 'rtl:rotate-180' : 'ltr:rotate-180'\n )}\n >\n {icon}\n </span>\n )}\n <Tooltip disabled={!isOverflowing}>\n <TooltipTrigger\n render={\n <span\n ref={labelRef}\n className={cn('flex-1 min-w-[60px] truncate', !expanded && 'sr-only')}\n />\n }\n >\n {children}\n </TooltipTrigger>\n <TooltipContent anchor={buttonRef} side={dir === 'rtl' ? 'left' : 'right'}>\n {children}\n </TooltipContent>\n </Tooltip>\n {extras}\n </button>\n );\n\n return (\n <li className=\"contents\">\n <Tooltip disabled={expanded}>\n <TooltipTrigger render={button} />\n <TooltipContent side={dir === 'rtl' ? 'left' : 'right'}>\n {expandTooltip}\n </TooltipContent>\n </Tooltip>\n </li>\n );\n }\n);\nSidebarSecondaryCollapseTrigger.displayName = 'SidebarSecondaryCollapseTrigger';\n\nexport {\n SidebarSecondary,\n SidebarSecondaryHeader,\n SidebarSecondaryContent,\n SidebarSecondaryCollapsedBreadcrumb,\n SidebarSecondaryFooter,\n SidebarSecondarySection,\n SidebarSecondarySectionLabel,\n SidebarSecondaryMenu,\n SidebarSecondaryMenuItem,\n SidebarSecondaryMenuItemExtras,\n SidebarSecondaryCollapseTrigger,\n sidebarSecondaryMenuItemVariants,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"sidebar-secondary.js","names":[],"sources":["../../../../src/components/ui/sidebar-secondary/sidebar-secondary.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport { Collapsible } from '@base-ui/react/collapsible';\nimport {\n ChevronDownIcon,\n SquareArrowUpRightIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\nimport { useDocDir } from '@/lib/use-doc-dir';\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '@/components/ui/tooltip';\n\n/**\n * Tracks whether `ref`'s element is clipping its own content (`scrollWidth >\n * clientWidth`) — used to gate a tooltip so it only opens when a truncated\n * label is actually cut off. Re-measures via `ResizeObserver` (covers the\n * rail's expand/collapse width transition); `enabled` skips measurement\n * entirely (e.g. while collapsed, where the label is `sr-only`).\n */\nfunction useIsOverflowing<T extends Element>(\n ref: React.RefObject<T | null>,\n { enabled }: { enabled: boolean }\n): boolean {\n const [isOverflowing, setIsOverflowing] = React.useState(false);\n\n React.useEffect(() => {\n const element = ref.current;\n if (!enabled || !element) {\n setIsOverflowing(false);\n return;\n }\n const measure = () =>\n setIsOverflowing(element.scrollWidth > element.clientWidth);\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [ref, enabled]);\n\n return isOverflowing;\n}\n\n// Resize constraints — mirrors the design-token defaults.\n// CSS still uses `var(--ui-sidebar-secondary-expanded-container-width)` so\n// brands that override the token get the correct visual width; these JS\n// constants only govern the drag-resize clamping range.\nconst SIDEBAR_EXPANDED_WIDTH = 256; // --ui-sidebar-secondary-expanded-container-width\nconst SIDEBAR_MAX_WIDTH = SIDEBAR_EXPANDED_WIDTH * 2;\n\n// Composable SidebarSecondary primitives mirroring the Figma \"SidebarSecondary\"\n// component set (node 2468:59502, variant expanded|collapsed). Every color and\n// metric is wired to a next-gen `--ui-sidebar-secondary-*` token from\n// @acronis-platform/tokens-pd — no hex, no invented tokens.\n//\n// Like SidebarPrimary, expanded/collapsed is a width-reflow state (not a panel\n// show/hide), modelled as a controlled/uncontrolled `expanded` prop (default\n// true) that sets `data-state=\"expanded|collapsed\"` on the root and is shared to\n// descendants via context. The collapsed rail replaces the section list with a\n// vertical breadcrumb (parent → separator → current page), toggled purely by the\n// `data-[state]` selectors so it is SSR-present and needs no JS branch.\n//\n// Menu-item color wiring DIVERGES from Primary (DESIGN §6.2): Secondary recolors\n// only the CONTAINER per selected/unselected; the icon and label use the shared\n// `--ui-sidebar-secondary-menu-item-global-{icon,label}-color-color` tokens\n// across both variants and every interaction state (the next-gen token sync\n// collapsed the former per-state idle/hover/active icon+label colors into a\n// single value each). So the cva base carries the global icon/label colors and\n// the two variants only swap the container fill.\n//\n// R6 (collapsed separator icon): resolved from the Figma node metadata — the\n// collapsed `iconSeparator` instance's mainComponent is \"ChevronDown\" (updated\n// from ChevronRight), so the separator defaults to `ChevronDownIcon` (16px),\n// tinted by `--ui-sidebar-secondary-collapsed-icon-separator-color`. In the\n// vertical breadcrumb flow (writing-mode: vertical-rl) the downward chevron\n// visually points \"forward\" in the reading direction. The disclosure chevron\n// uses `ChevronDownIcon` rotated via `data-panel-open`. The focus ring reuses the\n// shared `--ui-focus-brand` (no sidebar focus token exists — R1).\n\nconst defaultResizeTooltipExpanded = (\n <>\n <span className=\"font-semibold\">Resize:</span> Drag\n <br />\n <span className=\"font-semibold\">Collapse:</span> Click\n <br />\n <span className=\"font-semibold\">Reset size:</span> Double click\n </>\n);\n\n// `collapsible={false}` + expanded: `handleClick` bails, so clicking the edge\n// can no longer collapse the panel. Drag and double-click still resize.\nconst defaultResizeTooltipExpandedNonCollapsible = (\n <>\n <span className=\"font-semibold\">Resize:</span> Drag\n <br />\n <span className=\"font-semibold\">Reset size:</span> Double click\n </>\n);\n\nconst defaultResizeTooltipCollapsed = (\n <>\n <span className=\"font-semibold\">Resize:</span> Drag\n <br />\n <span className=\"font-semibold\">Expand:</span> Click\n </>\n);\n\n// `collapsible={false}` + collapsed: double-click is the one live POINTER\n// gesture — `handleDoubleClick` resets the width unconditionally (only its\n// `toggleExpanded()` call is gated on `collapsible`), mirroring `Home` as the\n// live keyboard gesture. The other two lines would be false claims here:\n// clicking bails in `handleClick`, and the collapsed drag branch only ever\n// calls the gated `toggleExpanded()` — it never writes a width.\nconst defaultResizeTooltipCollapsedNonCollapsible = (\n <>\n <span className=\"font-semibold\">Reset size:</span> Double click\n </>\n);\n\ninterface SidebarSecondaryContextValue {\n expanded: boolean;\n /** Flip the panel width — drives the controlled/uncontrolled `expanded` state. */\n toggleExpanded: () => void;\n /**\n * Whether user-initiated collapse/expand is allowed. When `false`, drag,\n * click, keyboard and the footer trigger never flip `expanded`; resizing\n * itself stays live.\n */\n collapsible: boolean;\n /** Whether resize is enabled. */\n resizable: boolean;\n /** Current width in px (only meaningful when resizable + expanded). */\n width: number;\n /** Update the width (used by the resize edge during drag). */\n setWidth: (width: number) => void;\n /** Min resize width — derived from `--ui-sidebar-secondary-expanded-container-width`. */\n minWidth: number;\n /** Max resize width — expanded-width × RESIZE_MAX_WIDTH_FACTOR. */\n maxWidth: number;\n /** Default (reset) width — equals expanded-container-width token. */\n defaultWidth: number;\n /** Label registered by `SidebarSecondaryHeader` — consumed by the collapsed breadcrumb. */\n headerLabel: React.ReactNode;\n /** Register the header label (called by `SidebarSecondaryHeader`). */\n setHeaderLabel: (label: React.ReactNode) => void;\n /** Label of the currently selected `MenuItem` — consumed by the collapsed breadcrumb. */\n selectedLabel: React.ReactNode;\n /** Register the selected item label (called by `SidebarSecondaryMenuItem`). */\n setSelectedLabel: (label: React.ReactNode) => void;\n /** Accessible label for the resize edge separator. */\n resizeAriaLabel: string;\n /** Tooltip content shown when the sidebar is expanded. */\n resizeTooltipExpanded: React.ReactNode;\n /** Tooltip content shown when the sidebar is collapsed. */\n resizeTooltipCollapsed: React.ReactNode;\n}\n\nconst SidebarSecondaryContext =\n React.createContext<SidebarSecondaryContextValue | null>(null);\n\nfunction useSidebarSecondaryContext(): SidebarSecondaryContextValue {\n // Default to expanded so parts render standalone (in isolation tests /\n // stories) without a wrapping root; the toggle is a no-op outside a root.\n return (\n React.useContext(SidebarSecondaryContext) ?? {\n expanded: true,\n toggleExpanded: () => {},\n collapsible: true,\n resizable: false,\n width: SIDEBAR_EXPANDED_WIDTH,\n setWidth: () => {},\n minWidth: SIDEBAR_EXPANDED_WIDTH,\n maxWidth: SIDEBAR_MAX_WIDTH,\n defaultWidth: SIDEBAR_EXPANDED_WIDTH,\n headerLabel: undefined,\n setHeaderLabel: () => {},\n selectedLabel: undefined,\n setSelectedLabel: () => {},\n resizeAriaLabel: 'Resize sidebar',\n resizeTooltipExpanded: defaultResizeTooltipExpanded,\n resizeTooltipCollapsed: defaultResizeTooltipCollapsed,\n }\n );\n}\n\n/**\n * Controlled + uncontrolled boolean state (the Base UI idiom). When `controlled`\n * is provided it wins and the setter only emits the change callback; otherwise\n * the setter updates internal state. `onChange` is ALWAYS invoked with the next\n * value so a consumer can react in either mode.\n */\nfunction useControllableBoolean(\n controlled: boolean | undefined,\n defaultValue: boolean,\n onChange?: (next: boolean) => void\n): [boolean, (next: boolean) => void] {\n const [uncontrolled, setUncontrolled] = React.useState(defaultValue);\n const isControlled = controlled !== undefined;\n const value = isControlled ? controlled : uncontrolled;\n const setValue = React.useCallback(\n (next: boolean) => {\n if (!isControlled) setUncontrolled(next);\n onChange?.(next);\n },\n [isControlled, onChange]\n );\n return [value, setValue];\n}\n\nexport interface SidebarSecondaryProps extends React.ComponentPropsWithoutRef<'nav'> {\n /** Controlled expanded (rail width) state. */\n expanded?: boolean;\n /** Uncontrolled initial expanded state. Defaults to `true` (full width). */\n defaultExpanded?: boolean;\n /** Fires when the expanded state changes (e.g. a consumer toggle). */\n onExpandedChange?: (expanded: boolean) => void;\n /**\n * Allow the user to collapse/expand the panel (resize-edge click, drag past\n * the collapse threshold, keyboard, and the footer collapse trigger).\n * When `false` those interactions never change `expanded` and the footer\n * trigger renders `disabled`; dragging still resizes the panel, clamped to\n * the minimum width. Defaults to `true`.\n */\n collapsible?: boolean;\n /**\n * Enable the draggable resize edge on the right border.\n * When `true`, the sidebar can be resized between the expanded-width token\n * and twice that value.\n */\n resizable?: boolean;\n /** Controlled width in px (only used when `resizable`). */\n width?: number;\n /** Fires when the width changes due to a drag interaction. */\n onWidthChange?: (width: number) => void;\n /** Accessible label for the resize edge (`role=\"separator\"`). Defaults to `'Resize sidebar'`. */\n resizeAriaLabel?: string;\n /**\n * Tooltip content shown when the sidebar is expanded. Pass `null` to hide\n * the tooltip entirely. The default omits the \"Collapse: Click\" line when\n * `collapsible` is `false`, since that gesture does nothing then.\n */\n resizeTooltipExpanded?: React.ReactNode;\n /**\n * Tooltip content shown when the sidebar is collapsed. Pass `null` to hide\n * the tooltip entirely. When `collapsible` is `false` the default narrows to\n * \"Reset size: Double click\" — the one gesture that still has an effect.\n */\n resizeTooltipCollapsed?: React.ReactNode;\n /**\n * Replace the rendered `<nav>` with another element or component\n * (Base UI composition). Accepts a React element or a render function.\n */\n render?: useRender.RenderProp;\n}\n\n// ---------------------------------------------------------------------------\n// SidebarSecondaryResizeEdge — internal drag/click handle on the right edge\n// ---------------------------------------------------------------------------\n// Styled after `ResizableHandle` (Figma 4649:6681): a hit area that takes up no\n// layout space around a 1px divider, idle → `--ui-border-on-surface-border`,\n// hover → `--ui-resizable-border-color-hover`,\n// drag → `--ui-resizable-border-color-active`.\n// ---------------------------------------------------------------------------\n\nfunction SidebarSecondaryResizeEdge() {\n const ctx = useSidebarSecondaryContext();\n const { expanded, toggleExpanded, resizable, collapsible } = ctx;\n const dir = useDocDir();\n\n // Mutable ref so the closure-captured pointermove handler always reads\n // the latest context without re-attaching listeners.\n const ctxRef = React.useRef(ctx);\n ctxRef.current = ctx;\n\n // Track whether a pointermove actually happened between down→up so we can\n // suppress the click that the browser fires after every pointerup.\n const didDragRef = React.useRef(false);\n\n // Hide the tooltip while dragging.\n const [tooltipOpen, setTooltipOpen] = React.useState(false);\n const [dragging, setDragging] = React.useState(false);\n\n // Delay single-click so a double-click can cancel it.\n const clickTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n\n // Clear any pending click timer on unmount.\n React.useEffect(() => {\n return () => {\n if (clickTimerRef.current) clearTimeout(clickTimerRef.current);\n };\n }, []);\n\n if (!resizable) return null;\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n e.preventDefault();\n const el = e.currentTarget;\n el.setPointerCapture(e.pointerId);\n didDragRef.current = false;\n setDragging(true);\n setTooltipOpen(false);\n\n // Disable the width transition while dragging so resize follows the\n // cursor without animation lag.\n const sidebarEl = el.closest('[data-state]') as HTMLElement | null;\n if (!sidebarEl) {\n setDragging(false);\n el.releasePointerCapture(e.pointerId);\n return;\n }\n sidebarEl.style.transitionProperty = 'none';\n const isRtl = getComputedStyle(sidebarEl).direction === 'rtl';\n const sidebarRect = sidebarEl.getBoundingClientRect();\n\n const { minWidth, maxWidth } = ctxRef.current;\n const collapseThreshold = minWidth / 2;\n\n const onPointerMove = (ev: PointerEvent) => {\n didDragRef.current = true;\n const newWidth = isRtl\n ? sidebarRect.right - ev.clientX\n : ev.clientX - sidebarRect.left;\n const { expanded: isExpanded, collapsible: canCollapse } = ctxRef.current;\n\n if (isExpanded) {\n if (newWidth < collapseThreshold && canCollapse) {\n ctxRef.current.toggleExpanded();\n } else {\n // Not collapsible: dragging below the threshold clamps to minWidth\n // instead of collapsing, so resize stays live either way.\n ctxRef.current.setWidth(\n Math.min(Math.max(newWidth, minWidth), maxWidth)\n );\n }\n } else {\n if (newWidth > collapseThreshold && canCollapse) {\n ctxRef.current.toggleExpanded();\n }\n }\n };\n\n const onPointerUp = () => {\n setDragging(false);\n // Restore transition so collapse/expand animates.\n if (sidebarEl) sidebarEl.style.transitionProperty = '';\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n };\n\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n };\n\n const handleClick = () => {\n // A click on the resize edge only ever toggles collapse — nothing to do\n // when collapsing is disabled.\n if (!collapsible) return;\n // Suppress click when the interaction was a drag.\n if (didDragRef.current) return;\n // Cancel any pending click timer (dblclick fires two clicks).\n if (clickTimerRef.current) clearTimeout(clickTimerRef.current);\n // Wait to see if a double-click follows. Re-read `collapsible` from the\n // ref when the timer fires — the render-time value captured above is stale\n // if the prop flipped during the 250ms delay.\n clickTimerRef.current = setTimeout(() => {\n if (!ctxRef.current.collapsible) return;\n ctxRef.current.toggleExpanded();\n }, 250);\n };\n\n const handleDoubleClick = () => {\n // Cancel the pending single-click toggle.\n if (clickTimerRef.current) {\n clearTimeout(clickTimerRef.current);\n clickTimerRef.current = null;\n }\n if (!expanded && collapsible) toggleExpanded();\n ctxRef.current.setWidth(ctxRef.current.defaultWidth);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const {\n minWidth,\n maxWidth,\n defaultWidth,\n width: w,\n setWidth: sw,\n expanded: exp,\n toggleExpanded: te,\n collapsible: canCollapse,\n } = ctxRef.current;\n const step = 16;\n const growKey = dir === 'rtl' ? 'ArrowLeft' : 'ArrowRight';\n const shrinkKey = dir === 'rtl' ? 'ArrowRight' : 'ArrowLeft';\n if (e.key === growKey && exp) {\n e.preventDefault();\n sw(Math.min(w + step, maxWidth));\n } else if (e.key === growKey && !exp) {\n e.preventDefault();\n if (canCollapse) te();\n } else if (e.key === shrinkKey && exp) {\n e.preventDefault();\n const next = w - step;\n if (next < minWidth) {\n // Not collapsible: clamp at the minimum instead of collapsing.\n if (canCollapse) te();\n else sw(minWidth);\n } else {\n sw(next);\n }\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (canCollapse) te();\n } else if (e.key === 'Home') {\n e.preventDefault();\n if (!exp && canCollapse) te();\n sw(defaultWidth);\n }\n };\n\n const handleTooltipOpenChange = (open: boolean) => {\n // Never open the tooltip while dragging.\n if (dragging) return;\n setTooltipOpen(open);\n };\n\n return (\n <Tooltip open={tooltipOpen} onOpenChange={handleTooltipOpenChange} trackCursorAxis=\"y\">\n <TooltipTrigger\n render={\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={ctx.resizeAriaLabel}\n className={cn(\n // 17px hit area, absolutely positioned on inline-end edge.\n // The sidebar's own border-e provides the visible 1px line; its color\n // changes via :has() on hover/active/focus-visible.\n 'absolute end-0 top-0 h-full w-[17px] ltr:translate-x-1/2 rtl:-translate-x-1/2 cursor-[var(--ui-resizable-cursor,ew-resize)] z-10',\n // On focus: 1px active-color line (after pseudo, CSS border for pixel-snap) + 3px box-shadow ring centered on it.\n 'after:absolute after:inset-y-0 after:inset-x-0 after:mx-auto after:w-0 after:pointer-events-none',\n 'after:[border-inline-start-width:var(--ui-resizable-border-width,1px)] after:border-solid after:border-transparent',\n 'focus-visible:outline-none focus-visible:after:[border-inline-start-color:var(--ui-resizable-border-color-active)] focus-visible:after:[box-shadow:0_0_0_3px_var(--ui-focus-primary)]'\n )}\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onPointerDown={handlePointerDown}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n />\n }\n />\n {(expanded ? ctx.resizeTooltipExpanded : ctx.resizeTooltipCollapsed) !=\n null && (\n <TooltipContent side={dir === 'rtl' ? 'left' : 'right'} align=\"center\">\n {expanded ? ctx.resizeTooltipExpanded : ctx.resizeTooltipCollapsed}\n </TooltipContent>\n )}\n </Tooltip>\n );\n}\n\nconst SidebarSecondary = React.forwardRef<HTMLElement, SidebarSecondaryProps>(\n (\n {\n className,\n expanded: expandedProp,\n defaultExpanded = true,\n onExpandedChange,\n collapsible: collapsibleProp = true,\n resizable: resizableProp = true,\n width: widthProp,\n onWidthChange,\n resizeAriaLabel = 'Resize sidebar',\n // Both tooltip defaults are resolved here (not at the render site) so an\n // explicit prop value — including `null` to hide the tooltip — always\n // wins regardless of `collapsible`.\n resizeTooltipExpanded = collapsibleProp\n ? defaultResizeTooltipExpanded\n : defaultResizeTooltipExpandedNonCollapsible,\n resizeTooltipCollapsed = collapsibleProp\n ? defaultResizeTooltipCollapsed\n : defaultResizeTooltipCollapsedNonCollapsible,\n 'aria-label': ariaLabel = 'Section navigation',\n render,\n children,\n ...props\n },\n ref\n ) => {\n const [expanded, setExpanded] = useControllableBoolean(\n expandedProp,\n defaultExpanded,\n onExpandedChange\n );\n\n // Width is independent of expanded/collapsed — it persists across cycles.\n const [width, setWidthState] = React.useState(SIDEBAR_EXPANDED_WIDTH);\n const isWidthControlled = widthProp !== undefined;\n const currentWidth = isWidthControlled ? widthProp : width;\n // No-op when the width is unchanged: the drag and Arrow-key clamps both\n // keep calling this with the already-current min/max value, which would\n // otherwise emit a stream of redundant `onWidthChange` events.\n const setWidth = React.useCallback(\n (next: number) => {\n if (next === currentWidth) return;\n if (!isWidthControlled) setWidthState(next);\n onWidthChange?.(next);\n },\n [isWidthControlled, onWidthChange, currentWidth]\n );\n\n // Collapse is driven by the consumer through the layout context — the\n // `SidebarSecondaryCollapseTrigger` calls `toggleExpanded`, which updates\n // uncontrolled state and always emits `onExpandedChange`. Controlled\n // consumers ignore the internal state and react to the callback.\n // Breadcrumb auto-wiring: Header and the selected MenuItem register their\n // labels so the collapsed breadcrumb can display them without manual props.\n const [headerLabel, setHeaderLabel] =\n React.useState<React.ReactNode>(undefined);\n const [selectedLabel, setSelectedLabel] =\n React.useState<React.ReactNode>(undefined);\n\n const context = React.useMemo<SidebarSecondaryContextValue>(\n () => ({\n expanded,\n toggleExpanded: () => setExpanded(!expanded),\n collapsible: collapsibleProp,\n resizable: resizableProp,\n width: currentWidth,\n setWidth,\n minWidth: SIDEBAR_EXPANDED_WIDTH,\n maxWidth: SIDEBAR_MAX_WIDTH,\n defaultWidth: SIDEBAR_EXPANDED_WIDTH,\n headerLabel,\n setHeaderLabel,\n selectedLabel,\n setSelectedLabel,\n resizeAriaLabel,\n resizeTooltipExpanded,\n resizeTooltipCollapsed,\n }),\n [\n expanded,\n setExpanded,\n collapsibleProp,\n resizableProp,\n currentWidth,\n setWidth,\n headerLabel,\n selectedLabel,\n resizeAriaLabel,\n resizeTooltipExpanded,\n resizeTooltipCollapsed,\n ]\n );\n\n // When resizable + expanded, apply inline width ONLY when the user has\n // actively resized (or width is controlled). Otherwise the CSS token\n // `--ui-sidebar-secondary-expanded-container-width` drives the width,\n // so brand overrides are honoured and no inline style wins specificity.\n const hasWidthOverride =\n isWidthControlled || currentWidth !== SIDEBAR_EXPANDED_WIDTH;\n const inlineStyle: React.CSSProperties | undefined =\n resizableProp && expanded && hasWidthOverride\n ? { width: currentWidth }\n : undefined;\n\n const element = useRender({\n render,\n ref,\n defaultTagName: 'nav',\n props: mergeProps<'nav'>(\n {\n 'aria-label': ariaLabel,\n // `data-state` drives every collapsed/expanded token switch via\n // attribute selectors; typed loosely because React's nav attribute\n // map doesn't include arbitrary data-* keys as literals.\n ...({ 'data-state': expanded ? 'expanded' : 'collapsed' } as Record<\n string,\n string\n >),\n style: inlineStyle,\n className: cn(\n 'group/sidebar relative flex h-full flex-col bg-[var(--ui-sidebar-secondary-global-container-color)] border-e border-[var(--ui-sidebar-secondary-global-container-border-color)] [border-inline-end-width:var(--ui-sidebar-secondary-global-container-border-width)] w-[var(--ui-sidebar-secondary-collapsed-container-width)] data-[state=expanded]:w-[var(--ui-sidebar-secondary-expanded-container-width)] transition-[width]',\n resizableProp &&\n 'transition-[width,border-color] has-[[role=separator]:hover]:[border-inline-end-color:var(--ui-resizable-border-color-hover)] has-[[role=separator]:active]:[border-inline-end-color:var(--ui-resizable-border-color-active)] has-[[role=separator]:focus-visible]:[border-inline-end-color:var(--ui-resizable-border-color-active)]',\n className\n ),\n children: (\n <>\n <SidebarSecondaryCollapsedBreadcrumb />\n {children}\n <SidebarSecondaryResizeEdge />\n </>\n ),\n },\n props\n ),\n });\n\n return (\n <SidebarSecondaryContext.Provider value={context}>\n {element}\n </SidebarSecondaryContext.Provider>\n );\n }\n);\nSidebarSecondary.displayName = 'SidebarSecondary';\n\nexport interface SidebarSecondaryHeaderProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Heading text (or pass as children). */\n label?: React.ReactNode;\n}\n\nconst SidebarSecondaryHeader = React.forwardRef<\n HTMLDivElement,\n SidebarSecondaryHeaderProps\n>(({ className, label, children, ...props }, ref) => {\n const { setHeaderLabel } = useSidebarSecondaryContext();\n const resolvedLabel = label ?? children;\n\n // Register the header text so the collapsed breadcrumb can auto-display it.\n React.useEffect(() => {\n setHeaderLabel(resolvedLabel);\n }, [resolvedLabel, setHeaderLabel]);\n\n return (\n <div\n ref={ref}\n className={cn(\n 'hidden items-center shrink-0',\n 'group-data-[state=expanded]/sidebar:flex',\n 'px-[var(--ui-sidebar-secondary-global-container-header-padding-x)] py-[var(--ui-sidebar-secondary-global-container-header-padding-y)]',\n className\n )}\n {...props}\n >\n <h2 className=\"ui-sidebar-secondary-global-header-label-text-style truncate text-[var(--ui-sidebar-secondary-global-header-label-color)]\">\n {resolvedLabel}\n </h2>\n </div>\n );\n});\nSidebarSecondaryHeader.displayName = 'SidebarSecondaryHeader';\n\nconst SidebarSecondaryContent = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<'div'>\n>(({ className, ...props }, ref) => (\n // Expanded: the section list. Hidden in collapsed mode, where the\n // CollapsedBreadcrumb sibling takes over.\n <div\n ref={ref}\n className={cn(\n 'flex flex-1 flex-col overflow-y-auto gap-[var(--ui-sidebar-secondary-global-section-list-gap)]',\n 'hidden group-data-[state=expanded]/sidebar:flex',\n className\n )}\n {...props}\n />\n));\nSidebarSecondaryContent.displayName = 'SidebarSecondaryContent';\n\nexport interface SidebarSecondaryCollapsedBreadcrumbProps extends React.ComponentPropsWithoutRef<'div'> {\n /**\n * The parent section label (breadcrumbLabel).\n * Auto-derived from the `SidebarSecondaryHeader` label when omitted.\n */\n parentLabel?: React.ReactNode;\n /**\n * The current page label (labelCurrentPage).\n * Auto-derived from the selected `SidebarSecondaryMenuItem` when omitted.\n */\n currentLabel?: React.ReactNode;\n /** Separator between the two; defaults to a 16px ChevronDownIcon. */\n separator?: React.ReactNode;\n}\n\nconst SidebarSecondaryCollapsedBreadcrumb = React.forwardRef<\n HTMLDivElement,\n SidebarSecondaryCollapsedBreadcrumbProps\n>(({ className, parentLabel, currentLabel, separator, ...props }, ref) => {\n const { headerLabel, selectedLabel } = useSidebarSecondaryContext();\n const resolvedParent = parentLabel ?? headerLabel;\n const resolvedCurrent = currentLabel ?? selectedLabel;\n\n return (\n // Shown only in collapsed mode — toggled by the same data-[state] selector so\n // it stays in the DOM (SSR-present) with no JS branch. Laid out vertically:\n // parent → separator → current page.\n <div\n ref={ref}\n className={cn(\n 'flex flex-1 flex-col items-center min-h-0',\n 'gap-[var(--ui-sidebar-secondary-collapsed-container-content-gap)] py-[var(--ui-sidebar-secondary-collapsed-container-content-padding-y)]',\n 'flex group-data-[state=expanded]/sidebar:hidden',\n className\n )}\n {...props}\n >\n <span className=\"[writing-mode:vertical-rl] [direction:ltr] shrink-0 ui-sidebar-secondary-collapsed-breadcrumb-label-text-style text-[var(--ui-sidebar-secondary-collapsed-breadcrumb-label-color)]\">\n {resolvedParent}\n </span>\n <span\n aria-hidden=\"true\"\n className=\"inline-flex items-center text-[var(--ui-sidebar-secondary-collapsed-icon-separator-color)] [&>svg]:size-[var(--ui-sidebar-secondary-collapsed-icon-separator-size)]\"\n >\n {separator ?? <ChevronDownIcon size={16} />}\n </span>\n <span className=\"[writing-mode:vertical-rl] [direction:ltr] flex-1 min-h-0 overflow-hidden ui-sidebar-secondary-collapsed-label-current-page-text-style text-[var(--ui-sidebar-secondary-collapsed-label-current-page-color)]\">\n {resolvedCurrent}\n </span>\n </div>\n );\n});\nSidebarSecondaryCollapsedBreadcrumb.displayName =\n 'SidebarSecondaryCollapsedBreadcrumb';\n\nconst SidebarSecondaryFooter = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<'div'>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col shrink-0',\n 'border-t border-[var(--ui-sidebar-secondary-global-container-footer-border-color)] [border-top-width:var(--ui-sidebar-secondary-global-container-footer-border-width)]',\n 'py-[var(--ui-sidebar-secondary-section-container-padding-y)]',\n className\n )}\n {...props}\n />\n));\nSidebarSecondaryFooter.displayName = 'SidebarSecondaryFooter';\n\n// A section can be a static group (label + items) or an EXPANDABLE disclosure\n// (Figma Section `expandable=yes-*`): the label becomes a chevron toggle that\n// shows/hides the whole item list. Whether a section is expandable is shared to\n// its label + menu via this context (default: static), so the same `SectionLabel`\n// / `Menu` parts adapt without a separate component set.\ninterface SidebarSecondarySectionContextValue {\n expandable: boolean;\n}\n\nconst SidebarSecondarySectionContext =\n React.createContext<SidebarSecondarySectionContextValue>({\n expandable: false,\n });\n\nconst SECTION_STATIC: SidebarSecondarySectionContextValue = {\n expandable: false,\n};\nconst SECTION_EXPANDABLE: SidebarSecondarySectionContextValue = {\n expandable: true,\n};\n\nexport interface SidebarSecondarySectionProps extends React.ComponentPropsWithoutRef<'div'> {\n /**\n * Make the section a collapsible disclosure: the `SidebarSecondarySectionLabel`\n * becomes a chevron toggle and the `SidebarSecondaryMenu` becomes its panel.\n */\n expandable?: boolean;\n /** Controlled open state (expandable sections only). */\n open?: boolean;\n /** Uncontrolled initial open state (expandable sections only). Defaults to open. */\n defaultOpen?: boolean;\n /** Fires with the next open value when an expandable section toggles. */\n onOpenChange?: (open: boolean) => void;\n}\n\nconst SidebarSecondarySection = React.forwardRef<\n HTMLDivElement,\n SidebarSecondarySectionProps\n>(\n (\n {\n className,\n expandable = false,\n open,\n defaultOpen = true,\n onOpenChange,\n children,\n ...props\n },\n ref\n ) => {\n // Sections are separated by vertical padding + the section label; the next-gen\n // token sync removed the inter-section divider (no\n // `--ui-sidebar-secondary-section-container-border-*` token survives).\n const sectionClass = cn(\n 'flex flex-col py-[var(--ui-sidebar-secondary-section-container-padding-y)]',\n className\n );\n\n if (!expandable) {\n return (\n <SidebarSecondarySectionContext.Provider value={SECTION_STATIC}>\n <div ref={ref} className={sectionClass} {...props}>\n {children}\n </div>\n </SidebarSecondarySectionContext.Provider>\n );\n }\n\n // Expandable: Base UI Collapsible owns the open state (controlled or\n // uncontrolled) + the aria-expanded/aria-controls wiring on the trigger.\n return (\n <SidebarSecondarySectionContext.Provider value={SECTION_EXPANDABLE}>\n <Collapsible.Root\n ref={ref}\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n render={<div className={sectionClass} />}\n {...props}\n >\n {children}\n </Collapsible.Root>\n </SidebarSecondarySectionContext.Provider>\n );\n }\n);\nSidebarSecondarySection.displayName = 'SidebarSecondarySection';\n\nexport interface SidebarSecondarySectionLabelProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Trailing header actions (e.g. a ghost `ButtonIcon`). Rendered outside the toggle. */\n actions?: React.ReactNode;\n /**\n * A rollup badge (e.g. a `Tag` with an unread count) shown in the header only\n * when an expandable section is collapsed. Ignored for static sections.\n */\n unreadRollup?: React.ReactNode;\n}\n\nconst sectionLabelTextClass =\n 'ui-sidebar-secondary-section-label-section-text-style text-[var(--ui-sidebar-secondary-section-label-section-color)]';\nconst sectionHeaderPadClass =\n 'min-h-[var(--ui-sidebar-secondary-menu-item-global-container-height-min)] py-[var(--ui-sidebar-secondary-section-container-header-padding-y)] px-[var(--ui-sidebar-secondary-section-container-header-padding-x)]';\n\nconst SidebarSecondarySectionLabel = React.forwardRef<\n HTMLDivElement,\n SidebarSecondarySectionLabelProps\n>(({ className, actions, unreadRollup, children, ...props }, ref) => {\n const { expandable } = React.useContext(SidebarSecondarySectionContext);\n const dir = useDocDir();\n const rowRef = React.useRef<HTMLDivElement>(null);\n const labelRef = React.useRef<HTMLSpanElement>(null);\n const isOverflowing = useIsOverflowing(labelRef, { enabled: true });\n const setRowRef = (node: HTMLDivElement | null) => {\n rowRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n };\n\n // Anchored to the row (not the label span) so it lines up with the\n // sidebar's right edge regardless of how much the label shrinks for\n // trailing actions/rollup.\n const labelTooltip = (\n <Tooltip disabled={!isOverflowing}>\n <TooltipTrigger\n render={\n <span\n ref={labelRef}\n className=\"min-w-0 flex-1 truncate\"\n />\n }\n >\n {children}\n </TooltipTrigger>\n <TooltipContent anchor={rowRef} side={dir === 'rtl' ? 'left' : 'right'}>\n {children}\n </TooltipContent>\n </Tooltip>\n );\n\n if (!expandable) {\n // Static header: preserve the original markup when there are no actions so\n // existing layouts/baselines are unchanged.\n const base = cn(sectionLabelTextClass, sectionHeaderPadClass, className);\n if (actions == null) {\n return (\n <div\n ref={setRowRef}\n className={cn(\n base,\n 'flex items-center'\n )}\n {...props}\n >\n {labelTooltip}\n </div>\n );\n }\n return (\n <div\n ref={setRowRef}\n className={cn(\n base,\n 'flex items-center gap-[var(--ui-sidebar-secondary-section-container-header-gap)]'\n )}\n {...props}\n >\n {labelTooltip}\n <span className=\"flex shrink-0 items-center\">{actions}</span>\n </div>\n );\n }\n\n // Expandable header: a chevron toggle (the Collapsible trigger) plus optional\n // trailing actions kept OUTSIDE the trigger button (no nested buttons). The\n // unread-rollup badge sits inside the trigger and shows only while collapsed.\n return (\n <div\n ref={setRowRef}\n className={cn(\n 'flex items-center gap-[var(--ui-sidebar-secondary-section-container-header-gap)]',\n sectionHeaderPadClass,\n className\n )}\n {...props}\n >\n <Collapsible.Trigger\n className={cn(\n 'group/section flex min-w-0 flex-1 items-center gap-[var(--ui-sidebar-secondary-section-container-header-gap)] text-start cursor-pointer',\n sectionLabelTextClass,\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-inset'\n )}\n >\n <ChevronDownIcon\n size={16}\n aria-hidden=\"true\"\n className=\"shrink-0 ltr:-rotate-90 rtl:rotate-90 transition-transform group-data-[panel-open]/section:rotate-0 text-[var(--ui-sidebar-secondary-section-icon-arrow-color)]\"\n />\n {labelTooltip}\n {unreadRollup != null && (\n <span className=\"flex shrink-0 items-center group-data-[panel-open]/section:hidden\">\n {unreadRollup}\n </span>\n )}\n </Collapsible.Trigger>\n {actions != null && (\n <span className=\"flex shrink-0 items-center\">{actions}</span>\n )}\n </div>\n );\n});\nSidebarSecondarySectionLabel.displayName = 'SidebarSecondarySectionLabel';\n\nconst SidebarSecondaryMenu = React.forwardRef<\n HTMLUListElement,\n React.ComponentPropsWithoutRef<'ul'>\n>(({ className, ...props }, ref) => {\n const { expandable } = React.useContext(SidebarSecondarySectionContext);\n const list = (\n <ul\n ref={ref}\n className={cn(\n 'flex flex-col gap-[var(--ui-sidebar-secondary-section-menu-item-list-gap)]',\n className\n )}\n {...props}\n />\n );\n // Inside an expandable section the item list IS the collapsible panel, so it\n // mounts/unmounts with the section's open state.\n return expandable ? <Collapsible.Panel>{list}</Collapsible.Panel> : list;\n});\nSidebarSecondaryMenu.displayName = 'SidebarSecondaryMenu';\n\n// Shared row geometry + the GLOBAL icon/label state colors (shared across\n// selected/unselected — DESIGN §6.2). The cva `variant` only swaps the container\n// fill. Each interaction state is wired to its own token even where acronis's\n// value is unchanged (runtime var() references honor brand overrides only on the\n// referenced token).\nconst sidebarSecondaryRowClasses =\n 'group/row flex w-full items-start gap-[var(--ui-sidebar-secondary-menu-item-global-container-gap)] min-h-[var(--ui-sidebar-secondary-menu-item-global-container-height-min)] px-[var(--ui-sidebar-secondary-menu-item-global-container-padding-x)] py-[var(--ui-sidebar-secondary-menu-item-global-container-padding-y)] no-underline ui-sidebar-secondary-menu-item-global-label-text-style transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-brand)] focus-visible:ring-inset text-[var(--ui-sidebar-secondary-menu-item-global-label-color-color)] [&_svg]:shrink-0 [&_svg]:size-[var(--ui-sidebar-secondary-menu-item-global-icon-size)] [&_svg]:text-[var(--ui-sidebar-secondary-menu-item-global-icon-color-color)]';\n\nconst sidebarSecondaryMenuItemVariants = cva(sidebarSecondaryRowClasses, {\n variants: {\n variant: {\n unselected:\n 'bg-[var(--ui-sidebar-secondary-menu-item-unselected-container-color-idle)] hover:bg-[var(--ui-sidebar-secondary-menu-item-unselected-container-color-hover)] active:bg-[var(--ui-sidebar-secondary-menu-item-unselected-container-color-active)]',\n selected:\n 'bg-[var(--ui-sidebar-secondary-menu-item-selected-container-color-idle)] hover:bg-[var(--ui-sidebar-secondary-menu-item-selected-container-color-hover)] active:bg-[var(--ui-sidebar-secondary-menu-item-selected-container-color-active)]',\n },\n },\n defaultVariants: {\n variant: 'unselected',\n },\n});\n\nexport interface SidebarSecondaryMenuItemProps\n extends\n Omit<React.ComponentPropsWithoutRef<'a'>, 'children'>,\n Omit<VariantProps<typeof sidebarSecondaryMenuItemVariants>, 'variant'> {\n /** Marks the current route: sets the `selected` variant + `aria-current=\"page\"`. */\n selected?: boolean;\n /** Optional leading 16px icon (`hasIcon` in Figma). */\n icon?: React.ReactNode;\n /** Trailing extras (tag, shortcut, external-link icon — `hasExtras` in Figma). */\n extras?: React.ReactNode;\n children?: React.ReactNode;\n /** Replace the rendered `<a>` (e.g. a router `Link` or a `<button>`). */\n render?: useRender.RenderProp;\n}\n\nconst SidebarSecondaryMenuItem = React.forwardRef<\n HTMLAnchorElement,\n SidebarSecondaryMenuItemProps\n>(\n (\n { className, selected = false, icon, extras, render, children, ...props },\n ref\n ) => {\n const { expanded, setSelectedLabel } = useSidebarSecondaryContext();\n const { expandable } = React.useContext(SidebarSecondarySectionContext);\n const dir = useDocDir();\n const rowRef = React.useRef<HTMLAnchorElement>(null);\n const labelRef = React.useRef<HTMLSpanElement>(null);\n const isOverflowing = useIsOverflowing(labelRef, { enabled: expanded });\n\n // Register this item's label when selected so the collapsed breadcrumb\n // auto-displays the current page without manual props.\n React.useEffect(() => {\n if (selected) setSelectedLabel(children);\n }, [selected, children, setSelectedLabel]);\n\n const inner = useRender({\n render,\n ref: [ref, rowRef],\n defaultTagName: 'a',\n props: mergeProps<'a'>(\n {\n className: cn(\n sidebarSecondaryMenuItemVariants({\n variant: selected ? 'selected' : 'unselected',\n }),\n // Inside an expandable section, increase start padding so the\n // label aligns with the section header text (after chevron + gap)\n // while keeping the container full-width for hover/active fills.\n expandable &&\n 'ps-[calc(var(--ui-sidebar-secondary-menu-item-global-container-padding-x)+var(--ui-sidebar-secondary-section-container-header-gap)+16px)]',\n className\n ),\n 'aria-current': selected ? 'page' : undefined,\n onKeyDown: (e: React.KeyboardEvent<HTMLAnchorElement>) => {\n if (e.key === ' ') {\n e.preventDefault();\n e.currentTarget.click();\n }\n },\n children: (\n <>\n {icon != null && (\n <span className=\"flex shrink-0 items-center self-start mt-[var(--ui-sidebar-secondary-menu-item-global-icon-margin-t)]\">\n {icon}\n </span>\n )}\n {/* Keep the label in the DOM as `sr-only` in collapsed/rail mode so\n an icon-only row keeps an accessible name (a11y §7). The tooltip\n trigger is the label span itself — it only opens when the label\n is actually clipped. It's anchored to the row (not the label\n span) so it lines up with the sidebar's right edge regardless\n of how much the label shrinks for extras. */}\n <Tooltip disabled={!isOverflowing}>\n <TooltipTrigger\n render={\n <span\n ref={labelRef}\n className={cn(\n 'flex-1 min-w-[60px] truncate text-start',\n !expanded && 'sr-only'\n )}\n />\n }\n >\n {children}\n </TooltipTrigger>\n <TooltipContent\n anchor={rowRef}\n side={dir === 'rtl' ? 'left' : 'right'}\n >\n {children}\n </TooltipContent>\n </Tooltip>\n {extras}\n </>\n ),\n },\n props\n ),\n });\n\n return (\n <li className=\"contents\">\n {/* In collapsed/rail mode the label above is `sr-only` (zero-size), so\n it never receives the hover that would open its tooltip — wrap the\n whole row so the icon itself is hoverable and always shows the\n item's label as a tooltip while collapsed. */}\n <Tooltip disabled={expanded}>\n <TooltipTrigger render={inner} />\n <TooltipContent side={dir === 'rtl' ? 'left' : 'right'}>\n {children}\n </TooltipContent>\n </Tooltip>\n </li>\n );\n }\n);\nSidebarSecondaryMenuItem.displayName = 'SidebarSecondaryMenuItem';\n\nexport interface SidebarSecondaryMenuItemExtrasProps extends React.ComponentPropsWithoutRef<'span'> {\n /** Which trailing affordance to render. */\n variant: 'tag' | 'externalLink' | 'shortcut' | 'tag-externalLink';\n /** Shortcut text for the `shortcut` variant. */\n shortcut?: string;\n /** Tag content for the `tag` / `tag-externalLink` variants. */\n tag?: React.ReactNode;\n}\n\nconst SidebarSecondaryMenuItemExtras = React.forwardRef<\n HTMLSpanElement,\n SidebarSecondaryMenuItemExtrasProps\n>(({ className, variant, shortcut, tag, children, ...props }, ref) => {\n const { expanded } = useSidebarSecondaryContext();\n const showTag = variant === 'tag' || variant === 'tag-externalLink';\n const showExternal =\n variant === 'externalLink' || variant === 'tag-externalLink';\n const showShortcut = variant === 'shortcut';\n\n return (\n <span\n ref={ref}\n className={cn(\n 'inline-flex items-center shrink-0 min-h-6 overflow-clip gap-[var(--ui-sidebar-secondary-menu-item-extras-global-container-gap)]',\n !expanded && 'hidden',\n className\n )}\n {...props}\n >\n {showTag && (tag ?? children)}\n {showShortcut && (\n <span className=\"ui-sidebar-secondary-menu-item-extras-global-shortcut-text-style text-[var(--ui-sidebar-secondary-menu-item-extras-global-shortcut-color)]\">\n {shortcut ?? children}\n </span>\n )}\n {showExternal && (\n <SquareArrowUpRightIcon\n size={16}\n className=\"text-[var(--ui-sidebar-secondary-menu-item-extras-global-external-icon-color)] size-[var(--ui-sidebar-secondary-menu-item-extras-global-external-icon-size)]\"\n />\n )}\n </span>\n );\n});\nSidebarSecondaryMenuItemExtras.displayName = 'SidebarSecondaryMenuItemExtras';\n\nexport interface SidebarSecondaryCollapseTriggerProps extends Omit<\n React.ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n /** Leading 16px icon (e.g. a panel-left glyph). Rotates 180° between expanded/collapsed — same as `SidebarPrimaryCollapseTrigger`. */\n icon?: React.ReactNode;\n /**\n * Tooltip text shown when the sidebar is collapsed. Defaults to `'Expand'`.\n * Not shown when the panel is `collapsible={false}` — the trigger is\n * disabled then, so the copy would advertise an action that can't run.\n */\n expandTooltip?: React.ReactNode;\n /** Trailing extras (e.g. a keyboard shortcut hint), same slot as `SidebarSecondaryMenuItem`. */\n extras?: React.ReactNode;\n children?: React.ReactNode;\n}\n\n// The footer \"Collapse menu\" affordance. A row-styled `<button>` that flips the\n// panel width via the layout context — the live wiring for the controllable\n// `expanded` state (B1). Keeps its label as `sr-only` in collapsed mode.\n// When collapsed, wraps the button in a Tooltip showing \"Expand\".\nconst SidebarSecondaryCollapseTrigger = React.forwardRef<\n HTMLButtonElement,\n SidebarSecondaryCollapseTriggerProps\n>(\n (\n {\n className,\n icon,\n expandTooltip = 'Expand',\n extras,\n children,\n onClick,\n disabled,\n ...props\n },\n ref\n ) => {\n const { expanded, toggleExpanded, collapsible } =\n useSidebarSecondaryContext();\n const dir = useDocDir();\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const labelRef = React.useRef<HTMLSpanElement>(null);\n const isOverflowing = useIsOverflowing(labelRef, { enabled: expanded });\n\n const button = (\n <button\n ref={(node) => {\n buttonRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }}\n type=\"button\"\n // A non-collapsible panel's trigger has no state to expose or flip:\n // native `disabled` gives the a11y + styling semantics for free.\n aria-expanded={collapsible ? expanded : undefined}\n disabled={disabled || !collapsible}\n className={cn(\n sidebarSecondaryMenuItemVariants({ variant: 'unselected' }),\n 'text-start',\n // The row classes are written for an interactive item; a\n // non-collapsible (or explicitly disabled) trigger must not keep the\n // pointer cursor or the hover/active fill it can no longer act on.\n 'disabled:cursor-not-allowed disabled:text-[var(--ui-text-on-surface-disabled)] disabled:[&_svg]:text-[var(--ui-text-on-surface-disabled)] disabled:hover:bg-[var(--ui-sidebar-secondary-menu-item-unselected-container-color-idle)] disabled:active:bg-[var(--ui-sidebar-secondary-menu-item-unselected-container-color-idle)]',\n className\n )}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented && collapsible) toggleExpanded();\n }}\n {...props}\n >\n {icon != null && (\n <span\n className={cn(\n 'flex shrink-0 items-center self-start mt-[var(--ui-sidebar-secondary-menu-item-global-icon-margin-t)] transition-transform',\n expanded ? 'rtl:rotate-180' : 'ltr:rotate-180'\n )}\n >\n {icon}\n </span>\n )}\n <Tooltip disabled={!isOverflowing}>\n <TooltipTrigger\n render={\n <span\n ref={labelRef}\n className={cn('flex-1 min-w-[60px] truncate', !expanded && 'sr-only')}\n />\n }\n >\n {children}\n </TooltipTrigger>\n <TooltipContent anchor={buttonRef} side={dir === 'rtl' ? 'left' : 'right'}>\n {children}\n </TooltipContent>\n </Tooltip>\n {extras}\n </button>\n );\n\n return (\n <li className=\"contents\">\n {/* The collapsed-mode tooltip advertises an action; a non-collapsible\n trigger can't perform it, so suppress the copy there too. */}\n <Tooltip disabled={expanded || !collapsible}>\n <TooltipTrigger render={button} />\n <TooltipContent side={dir === 'rtl' ? 'left' : 'right'}>\n {expandTooltip}\n </TooltipContent>\n </Tooltip>\n </li>\n );\n }\n);\nSidebarSecondaryCollapseTrigger.displayName = 'SidebarSecondaryCollapseTrigger';\n\nexport {\n SidebarSecondary,\n SidebarSecondaryHeader,\n SidebarSecondaryContent,\n SidebarSecondaryCollapsedBreadcrumb,\n SidebarSecondaryFooter,\n SidebarSecondarySection,\n SidebarSecondarySectionLabel,\n SidebarSecondaryMenu,\n SidebarSecondaryMenuItem,\n SidebarSecondaryMenuItemExtras,\n SidebarSecondaryCollapseTrigger,\n sidebarSecondaryMenuItemVariants,\n};\n"],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ "use client";
2
+ import { cn as e } from "../../../lib/utils.js";
3
+ import { Checkbox as t } from "../checkbox/checkbox.js";
4
+ import * as n from "react";
5
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
6
+ import { ChevronRightIcon as o, SquareDashedIcon as s } from "@acronis-platform/icons-react/stroke-mono";
7
+ import { useRender as c } from "@base-ui/react/use-render";
8
+ import { mergeProps as l } from "@base-ui/react/merge-props";
9
+ //#region src/components/ui/tree-item/tree-item.tsx
10
+ var u = [
11
+ "flex min-w-32 items-center gap-2 rounded-sm px-2 py-2 transition-colors",
12
+ "hover:bg-[var(--ui-background-surface-hover)]",
13
+ "focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ui-focus-primary)]"
14
+ ].join(" "), d = "flex shrink-0 items-center py-1", f = n.forwardRef(({ className: n, title: f = "Title", hasIcon: p = !1, icon: m, hasCheckbox: h = !1, checkboxProps: g, isExpandable: _ = !0, expanded: v = !1, hasExtras: y = !0, selected: b = !1, render: x, children: S, ...C }, w) => {
15
+ let T = {
16
+ "data-slot": "tree-item",
17
+ ...b ? { "data-selected": "true" } : {}
18
+ };
19
+ return c({
20
+ render: x,
21
+ ref: w,
22
+ defaultTagName: "div",
23
+ props: l({
24
+ ...T,
25
+ className: e(u, b && "bg-[var(--ui-background-surface-active)]", n),
26
+ children: /* @__PURE__ */ a(r, { children: [
27
+ _ && /* @__PURE__ */ i("span", {
28
+ "aria-hidden": "true",
29
+ "data-slot": "tree-item-expander",
30
+ className: e(d, "text-[var(--ui-glyph-on-surface-primary)]"),
31
+ children: /* @__PURE__ */ i(o, {
32
+ size: 16,
33
+ className: e("transition-transform", v ? "rotate-90" : "rtl:rotate-180")
34
+ })
35
+ }),
36
+ h && /* @__PURE__ */ i("span", {
37
+ "data-slot": "tree-item-checkbox",
38
+ className: d,
39
+ children: /* @__PURE__ */ i(t, {
40
+ "aria-label": f,
41
+ ...g
42
+ })
43
+ }),
44
+ p && /* @__PURE__ */ i("span", {
45
+ "data-slot": "tree-item-icon",
46
+ className: e(d, "text-[var(--ui-glyph-on-surface-primary)]"),
47
+ children: m ?? /* @__PURE__ */ i(s, { size: 16 })
48
+ }),
49
+ /* @__PURE__ */ i("span", {
50
+ "data-slot": "tree-item-title",
51
+ className: "min-w-0 flex-1 truncate text-sm leading-6 font-normal text-[var(--ui-text-on-surface-primary)]",
52
+ children: f
53
+ }),
54
+ y && /* @__PURE__ */ i("span", {
55
+ "data-slot": "tree-item-extras",
56
+ className: "flex min-w-4 shrink-0 items-center justify-end",
57
+ children: S
58
+ })
59
+ ] })
60
+ }, C)
61
+ });
62
+ });
63
+ f.displayName = "TreeItem";
64
+ //#endregion
65
+ export { f as TreeItem };
66
+
67
+ //# sourceMappingURL=tree-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-item.js","names":[],"sources":["../../../../src/components/ui/tree-item/tree-item.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport {\n ChevronRightIcon,\n SquareDashedIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\nimport { Checkbox } from '../checkbox';\n\n// A single row of a tree / nested-list UI (a file tree, a nested nav), mirroring\n// the Figma \"TreeItem\" component. It is deliberately *one row* and nothing more:\n// the Figma node renders no nested list and draws no distinct expanded variant.\n// `isExpandable` and `expanded` are therefore both purely visual — the first\n// draws the chevron, the second rotates it a quarter turn — and neither toggles\n// anything nor emits a change event. The quarter turn is this implementation's\n// own addition rather than a Figma variant: without it the affordance silently\n// contradicts the `aria-expanded` the consumer is already publishing. The\n// consumer composes several `TreeItem`s, owns the expand/collapse state, and\n// renders the nested level itself. Same scope decision as `Breadcrumb`, which\n// ships the nav/ol/li primitives without owning the trail.\n//\n// For the same reason no `role=\"treeitem\"` is forced here: a real ARIA tree\n// needs a `role=\"tree\"` owner, `aria-expanded`, `aria-level`, and roving\n// tabindex — all of which live in the composition, not in a standalone row.\n// Forcing the role on an orphan row would produce an *invalid* tree rather than\n// an accessible one. The row is a plain `<div>` (polymorphic via `render`, so a\n// consumer can make it the `<li role=\"treeitem\">` its own tree needs), and it is\n// not put in the tab order — pass `tabIndex` through if you focus it.\n//\n// ── Tokens ──\n// No `Tree` tier exists in @acronis-platform/tokens-pd, and the Figma node's own\n// spacing variables still live in the pre-next-gen `componentLegacy/tree/*` and\n// `componentLegacy/sidebar/*` namespaces (never migrated). Color therefore comes\n// from the semantic tier — `--ui-text-on-surface-primary` (title),\n// `--ui-glyph-on-surface-primary` (chevron + leading icon),\n// `--ui-background-surface-hover` / `--ui-background-surface-active` (row\n// background), `--ui-focus-primary` (focus ring) — and the *layout* numbers are\n// plain Tailwind utilities matching the design's pixel values (8px gap /\n// padding, 128px min row width, 4px slot padding, 16px minimum extras well).\n// That split is the existing convention: the no-fallback rule covers colors,\n// which must never be hand-authored, while `button.tsx` likewise writes its\n// focus ring as a literal `ring-[3px]`.\n//\n// ── States ──\n// The Figma `state` axis (idle / hover / active / focus) is not four CSS\n// pseudo-classes. Its `active` swatch renders the *same* background as\n// `variant=selected` (the generated reference code applies the selected\n// background class for it), so it previews a selected row rather than a\n// mousedown. There are consequently three real looks: transparent (idle),\n// `hover:` (pointer), and the highlighted `--ui-background-surface-active`\n// fill driven by the `selected` **prop**. No `:active` pseudo-state is invented,\n// because the design draws none distinct from `selected`.\nconst rowClasses = [\n 'flex min-w-32 items-center gap-2 rounded-sm px-2 py-2 transition-colors',\n 'hover:bg-[var(--ui-background-surface-hover)]',\n // Figma's focus state is the library-standard 3px ring, flush to the row edge\n // (`button.tsx`, `BreadcrumbLink`), on the row's own 2px `rounded-sm` corner.\n 'focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ui-focus-primary)]',\n].join(' ');\n\n/** Shared wrapper for the three fixed-size leading slots (4px vertical inset). */\nconst slotClasses = 'flex shrink-0 items-center py-1';\n\nexport interface TreeItemProps extends React.ComponentPropsWithoutRef<'div'> {\n /**\n * The row's label. Rendered as the row's own text, so it is a prop with the\n * literal only as its default (never inlined) — pass a localized string.\n *\n * Note this shadows the native `title` tooltip attribute on the underlying\n * `<div>`: the Figma component names this property `title`, and it is the\n * row's visible label, not a tooltip.\n */\n title?: string;\n /** Show the leading icon slot. */\n hasIcon?: boolean;\n /**\n * The leading icon. Only rendered when `hasIcon` is true; falls back to the\n * design's `SquareDashedIcon` placeholder, which is what the Figma node shows.\n */\n icon?: React.ReactNode;\n /** Show a leading `Checkbox`. */\n hasCheckbox?: boolean;\n /**\n * Props forwarded verbatim to the leading `Checkbox` — this row holds no\n * checked state of its own, so control it from here (`checked` /\n * `onCheckedChange`) exactly as you would a standalone `Checkbox`. Defaults\n * its `aria-label` to `title`, since the box renders without a visible label.\n */\n checkboxProps?: React.ComponentPropsWithoutRef<typeof Checkbox>;\n /**\n * Show the leading expand chevron. Purely a visual affordance: this row does\n * not implement expand/collapse and renders no nested list — the consumer owns\n * that state and composes the child rows.\n */\n isExpandable?: boolean;\n /**\n * Whether the row's nested list is currently expanded. Purely visual — like\n * `isExpandable`, this row owns no expand/collapse state and renders no\n * nested list. Rotates the leading chevron to reflect the state the consumer\n * is already tracking (and should also be reflecting via `aria-expanded` on\n * their own `render` target, e.g. `<li role=\"treeitem\" aria-expanded={open}>`).\n * Has no effect when `isExpandable` is false.\n */\n expanded?: boolean;\n /** Render the trailing extras slot (`children`) at all. */\n hasExtras?: boolean;\n /**\n * Whether the row is selected. Drives the persistent highlighted background —\n * the same fill Figma's `state=active` swatch previews.\n */\n selected?: boolean;\n /**\n * Trailing extras — action buttons, a count badge. Only rendered when\n * `hasExtras` is true.\n */\n children?: React.ReactNode;\n /**\n * Replace the rendered `<div>` with another element or component (Base UI\n * composition) — e.g. the `<li role=\"treeitem\">` of a real ARIA tree.\n */\n render?: useRender.RenderProp;\n}\n\nconst TreeItem = React.forwardRef<HTMLDivElement, TreeItemProps>(\n (\n {\n className,\n title = 'Title',\n hasIcon = false,\n icon,\n hasCheckbox = false,\n checkboxProps,\n isExpandable = true,\n expanded = false,\n hasExtras = true,\n selected = false,\n render,\n children,\n ...props\n },\n ref\n ) => {\n // Hoisted out of the `mergeProps` literal: `data-*` keys aren't part of the\n // Base UI element prop type, so they only pass the excess-property check\n // when spread in (the same shape `StepperItem` / `CardFilter` use).\n const attributes = {\n 'data-slot': 'tree-item',\n ...(selected ? { 'data-selected': 'true' } : {}),\n };\n\n return useRender({\n render,\n ref,\n defaultTagName: 'div',\n props: mergeProps<'div'>(\n {\n ...attributes,\n className: cn(\n rowClasses,\n selected && 'bg-[var(--ui-background-surface-active)]',\n className\n ),\n children: (\n <>\n {isExpandable && (\n <span\n aria-hidden=\"true\"\n data-slot=\"tree-item-expander\"\n className={cn(\n slotClasses,\n 'text-[var(--ui-glyph-on-surface-primary)]'\n )}\n >\n {/* Direction-sensitive artwork: an inline-end-pointing\n chevron has to mirror under `dir=\"rtl\"`, which logical\n layout utilities cannot do on their own. */}\n <ChevronRightIcon\n size={16}\n className={cn(\n 'transition-transform',\n expanded ? 'rotate-90' : 'rtl:rotate-180'\n )}\n />\n </span>\n )}\n {hasCheckbox && (\n <span data-slot=\"tree-item-checkbox\" className={slotClasses}>\n <Checkbox aria-label={title} {...checkboxProps} />\n </span>\n )}\n {hasIcon && (\n <span\n data-slot=\"tree-item-icon\"\n className={cn(\n slotClasses,\n 'text-[var(--ui-glyph-on-surface-primary)]'\n )}\n >\n {icon ?? <SquareDashedIcon size={16} />}\n </span>\n )}\n <span\n data-slot=\"tree-item-title\"\n className=\"min-w-0 flex-1 truncate text-sm leading-6 font-normal text-[var(--ui-text-on-surface-primary)]\"\n >\n {title}\n </span>\n {hasExtras && (\n <span\n data-slot=\"tree-item-extras\"\n className=\"flex min-w-4 shrink-0 items-center justify-end\"\n >\n {children}\n </span>\n )}\n </>\n ),\n },\n props\n ),\n });\n }\n);\nTreeItem.displayName = 'TreeItem';\n\nexport { TreeItem };\n"],"mappings":";;;;;;;;;AAwDA,IAAM,IAAa;CACjB;CACA;CAGA;AACF,CAAC,CAAC,KAAK,GAAG,GAGJ,IAAc,mCA8Dd,IAAW,EAAM,YAEnB,EACE,cACA,WAAQ,SACR,aAAU,IACV,SACA,iBAAc,IACd,kBACA,kBAAe,IACf,cAAW,IACX,eAAY,IACZ,cAAW,IACX,WACA,aACA,GAAG,KAEL,MACG;CAIH,IAAM,IAAa;EACjB,aAAa;EACb,GAAI,IAAW,EAAE,iBAAiB,OAAO,IAAI,CAAC;CAChD;CAEA,OAAO,EAAU;EACf;EACA;EACA,gBAAgB;EAChB,OAAO,EACL;GACE,GAAG;GACH,WAAW,EACT,GACA,KAAY,4CACZ,CACF;GACA,UACE,kBAAA,GAAA,EAAA,UAAA;IACG,KACC,kBAAC,QAAD;KACE,eAAY;KACZ,aAAU;KACV,WAAW,EACT,GACA,2CACF;KAKA,UAAA,kBAAC,GAAD;MACE,MAAM;MACN,WAAW,EACT,wBACA,IAAW,cAAc,gBAC3B;KACD,CAAA;IACG,CAAA;IAEP,KACC,kBAAC,QAAD;KAAM,aAAU;KAAqB,WAAW;KAC9C,UAAA,kBAAC,GAAD;MAAU,cAAY;MAAO,GAAI;KAAgB,CAAA;IAC7C,CAAA;IAEP,KACC,kBAAC,QAAD;KACE,aAAU;KACV,WAAW,EACT,GACA,2CACF;KAEC,UAAA,KAAQ,kBAAC,GAAD,EAAkB,MAAM,GAAK,CAAA;IAClC,CAAA;IAER,kBAAC,QAAD;KACE,aAAU;KACV,WAAU;KAET,UAAA;IACG,CAAA;IACL,KACC,kBAAC,QAAD;KACE,aAAU;KACV,WAAU;KAET;IACG,CAAA;GAER,EAAA,CAAA;EAEN,GACA,CACF;CACF,CAAC;AACH,CACF;AACA,EAAS,cAAc"}
@@ -1,14 +1,16 @@
1
1
  "use client";
2
2
  import { cn as e } from "../../../lib/utils.js";
3
- import { CHART_DEFAULT_PALETTE as t } from "../chart/chart-palette.js";
4
- import { ChartContainer as n, ChartLegendContent as r, ChartStyle as i, ChartTooltip as a, ChartTooltipContent as o, resolveChartColors as s } from "../chart/chart.js";
5
- import { resolveAnimation as c } from "../chart/chart-format.js";
6
- import * as l from "react";
7
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
8
- import { Treemap as f } from "recharts";
3
+ import { ChartContainer as t, ChartLegendContent as n, ChartStyle as r, ChartTooltip as i, ChartTooltipContent as a, resolveChartColors as o } from "../chart/chart.js";
4
+ import { resolveAnimation as s } from "../chart/chart-format.js";
5
+ import * as c from "react";
6
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
+ import { Treemap as d } from "recharts";
9
8
  //#region src/components/ui/treemap/treemap.tsx
10
- var p = 2, m = 6, h = 4 / 3, g = 11, _ = Math.ceil(12 * h), v = Math.ceil(g * h), y = 64, b = 24 + _, x = b + v;
11
- function S(e) {
9
+ var f = {
10
+ type: "diverging",
11
+ pair: "blue-orange"
12
+ }, p = 2, m = 0, h = 64, g = 43, _ = 58;
13
+ function v(e) {
12
14
  let { row: t, keys: n, separator: r, formatter: i } = e, a = n.flatMap((e, n) => {
13
15
  let r = t[e];
14
16
  if (r == null || r === "") return [];
@@ -17,112 +19,117 @@ function S(e) {
17
19
  });
18
20
  return a.length ? a.join(r) : void 0;
19
21
  }
20
- var C = {
22
+ var y = {
21
23
  "bottom-start": "justify-end text-start",
22
24
  "top-start": "justify-start text-start",
23
25
  center: "justify-center text-center"
24
26
  };
25
- function w({ x: t = 0, y: n = 0, width: r = 0, height: i = 0, name: a, primaryLabel: o, secondaryLabel: s, showLabels: c = !0, labelAlign: l = "bottom-start" }) {
26
- if (!a) return /* @__PURE__ */ u("g", {});
27
- let f = t + p, h = n + p, g = Math.max(0, r - 4), _ = Math.max(0, i - 4), v = c && g > y && _ >= b, S = v && s && _ >= x ? s : void 0;
28
- return /* @__PURE__ */ d("g", { children: [/* @__PURE__ */ u("rect", {
29
- x: f,
30
- y: h,
31
- width: g,
32
- height: _,
27
+ function b({ x: t = 0, y: n = 0, width: r = 0, height: i = 0, name: a, primaryLabel: o, secondaryLabel: s, showLabels: c = !0, labelAlign: d = "center", fillTone: f = "dark" }) {
28
+ if (!a) return /* @__PURE__ */ l("g", {});
29
+ let v = t + p, b = n + p, x = Math.max(0, r - 4), S = Math.max(0, i - 4), C = c && x > h && S >= g, w = C && s && S >= _ ? s : void 0;
30
+ return /* @__PURE__ */ u("g", { children: [/* @__PURE__ */ l("rect", {
31
+ x: v,
32
+ y: b,
33
+ width: x,
34
+ height: S,
33
35
  rx: m,
34
36
  style: { fill: `var(--color-${a})` }
35
- }), v && /* @__PURE__ */ u("foreignObject", {
36
- x: f,
37
- y: h,
38
- width: g,
39
- height: _,
37
+ }), C && /* @__PURE__ */ l("foreignObject", {
38
+ x: v,
39
+ y: b,
40
+ width: x,
41
+ height: S,
40
42
  className: "pointer-events-none",
41
- children: /* @__PURE__ */ d("div", {
42
- className: e("flex size-full flex-col overflow-hidden p-3", "text-[var(--ui-text-on-status-strong-neutral)]", C[l]),
43
- children: [/* @__PURE__ */ u("span", {
44
- className: "truncate text-xs font-semibold",
43
+ children: /* @__PURE__ */ u("div", {
44
+ className: e("flex size-full flex-col overflow-hidden p-3", f === "pale" ? "text-[var(--ui-text-on-surface-primary)]" : f === "inverts" ? "text-[var(--ui-text-on-status-strong-primary)]" : "text-[var(--ui-text-on-status-strong-neutral)]", y[d]),
45
+ children: [/* @__PURE__ */ l("span", {
46
+ className: "truncate text-sm",
45
47
  children: o ?? a
46
- }), S && /* @__PURE__ */ u("span", {
48
+ }), w && /* @__PURE__ */ l("span", {
47
49
  className: "truncate text-[11px]",
48
- children: S
50
+ children: w
49
51
  })]
50
52
  })
51
53
  })] });
52
54
  }
53
- var T = l.forwardRef(({ className: p, config: m, palette: h, data: g, dataKey: _, nameKey: v, aspectRatio: y = 4 / 3, showLabels: b = !0, labelAlign: x = "bottom-start", secondaryKeys: C, secondaryFormatter: T, secondarySeparator: E = " · ", showTooltip: D = !0, showLegend: O = !1, legendPos: k = "bottom", tooltipContent: A, animate: j, animationDuration: M, animationBegin: N, animationEasing: P, ...F }, I) => {
54
- let L = c({
55
+ var x = c.forwardRef(({ className: p, config: m, palette: h = f, data: g, dataKey: _, nameKey: y, aspectRatio: x = 4 / 3, showLabels: S = !0, labelAlign: C = "center", secondaryKeys: w, secondaryFormatter: T, secondarySeparator: E = " · ", showTooltip: D = !0, showLegend: O = !1, legendPos: k = "bottom", tooltipContent: A, animate: j, animationDuration: M, animationBegin: N, animationEasing: P, ...F }, I) => {
56
+ let L = s({
55
57
  animate: j,
56
58
  animationDuration: M,
57
59
  animationBegin: N,
58
60
  animationEasing: P
59
- }), R = l.useMemo(() => g.map((e) => {
60
- let t = String(e[v]), n = C?.length ? S({
61
- row: e,
62
- keys: C,
63
- separator: E,
64
- formatter: T
65
- }) : void 0, r = m[t]?.label;
66
- return {
67
- ...e,
68
- fill: `var(--color-${t})`,
69
- ...typeof r == "string" ? { primaryLabel: r } : {},
70
- ...n ? { secondaryLabel: n } : {}
71
- };
72
- }), [
61
+ }), R = c.useMemo(() => {
62
+ let e = o(m, h);
63
+ return g.map((t) => {
64
+ let n = String(t[y]), r = w?.length ? v({
65
+ row: t,
66
+ keys: w,
67
+ separator: E,
68
+ formatter: T
69
+ }) : void 0, i = m[n]?.label, a = (e[n]?.color ?? "").replace(/^var\(|\)$/g, ""), o = /-(?:a[12]|b[12]|sequential-[a-z]+-[12])$/.test(a), s = /-sequential-[a-z]+-[78]$/.test(a), c = o ? "pale" : s ? "inverts" : "dark";
70
+ return {
71
+ ...t,
72
+ fill: `var(--color-${n})`,
73
+ fillTone: c,
74
+ ...typeof i == "string" ? { primaryLabel: i } : {},
75
+ ...r ? { secondaryLabel: r } : {}
76
+ };
77
+ });
78
+ }, [
73
79
  m,
74
80
  g,
75
- v,
81
+ y,
82
+ h,
76
83
  T,
77
- C,
84
+ w,
78
85
  E
79
- ]), z = l.useMemo(() => {
86
+ ]), z = c.useMemo(() => {
80
87
  let e = /* @__PURE__ */ new Set();
81
88
  return R.flatMap((t) => {
82
- let n = String(t[v]);
89
+ let n = String(t[y]);
83
90
  return e.has(n) ? [] : (e.add(n), [{
84
91
  value: n,
85
- dataKey: v,
92
+ dataKey: y,
86
93
  type: "rect",
87
94
  color: String(t.fill),
88
95
  payload: t
89
96
  }]);
90
97
  });
91
- }, [v, R]), B = `chart-${l.useId().replace(/:/g, "")}`, V = O ? /* @__PURE__ */ d("div", {
98
+ }, [y, R]), B = `chart-${c.useId().replace(/:/g, "")}`, V = O ? /* @__PURE__ */ u("div", {
92
99
  "data-chart": B,
93
100
  className: "text-xs",
94
- children: [/* @__PURE__ */ u(i, {
101
+ children: [/* @__PURE__ */ l(r, {
95
102
  id: B,
96
- config: s(m, h ?? t)
97
- }), /* @__PURE__ */ u(r, {
103
+ config: o(m, h)
104
+ }), /* @__PURE__ */ l(n, {
98
105
  config: m,
99
106
  payload: z,
100
107
  verticalAlign: k,
101
- nameKey: v
108
+ nameKey: y
102
109
  })]
103
110
  }) : null;
104
- return /* @__PURE__ */ d("div", {
111
+ return /* @__PURE__ */ u("div", {
105
112
  ref: I,
106
113
  className: e(O && "flex flex-col", p),
107
114
  ...F,
108
115
  children: [
109
116
  k === "top" && V,
110
- /* @__PURE__ */ u(n, {
117
+ /* @__PURE__ */ l(t, {
111
118
  config: m,
112
119
  palette: h,
113
120
  className: O ? "min-h-0 w-full flex-1" : "size-full",
114
- children: /* @__PURE__ */ u(f, {
121
+ children: /* @__PURE__ */ l(d, {
115
122
  data: R,
116
123
  dataKey: _,
117
- nameKey: v,
118
- aspectRatio: y,
124
+ nameKey: y,
125
+ aspectRatio: x,
119
126
  ...L,
120
- content: /* @__PURE__ */ u(w, {
121
- showLabels: b,
122
- labelAlign: x
127
+ content: /* @__PURE__ */ l(b, {
128
+ showLabels: S,
129
+ labelAlign: C
123
130
  }),
124
- children: D && /* @__PURE__ */ u(a, { content: A ?? /* @__PURE__ */ u(o, {
125
- nameKey: v,
131
+ children: D && /* @__PURE__ */ l(i, { content: A ?? /* @__PURE__ */ l(a, {
132
+ nameKey: y,
126
133
  hideLabel: !0
127
134
  }) })
128
135
  })
@@ -131,8 +138,8 @@ var T = l.forwardRef(({ className: p, config: m, palette: h, data: g, dataKey: _
131
138
  ]
132
139
  });
133
140
  });
134
- T.displayName = "Treemap";
141
+ x.displayName = "Treemap";
135
142
  //#endregion
136
- export { T as Treemap, w as TreemapCell, S as treemapSecondaryLabel };
143
+ export { x as Treemap, b as TreemapCell, v as treemapSecondaryLabel };
137
144
 
138
145
  //# sourceMappingURL=treemap.js.map