@acronis-platform/ui-react 0.56.1 → 0.57.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 (44) hide show
  1. package/dist/components/ui/avatar/avatar.js +7 -7
  2. package/dist/components/ui/avatar/avatar.js.map +1 -1
  3. package/dist/components/ui/bar-chart/bar-chart.js +104 -0
  4. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -0
  5. package/dist/components/ui/chart/chart.js +49 -49
  6. package/dist/components/ui/chart/chart.js.map +1 -1
  7. package/dist/components/ui/checkbox/checkbox.js +1 -1
  8. package/dist/components/ui/checkbox/checkbox.js.map +1 -1
  9. package/dist/components/ui/chip/chip.js +28 -28
  10. package/dist/components/ui/chip/chip.js.map +1 -1
  11. package/dist/components/ui/data-table/data-table.js +223 -155
  12. package/dist/components/ui/data-table/data-table.js.map +1 -1
  13. package/dist/components/ui/input-text/input-text.js +8 -8
  14. package/dist/components/ui/input-text/input-text.js.map +1 -1
  15. package/dist/components/ui/link/link.js +16 -16
  16. package/dist/components/ui/link/link.js.map +1 -1
  17. package/dist/components/ui/page-header/page-header.js +159 -49
  18. package/dist/components/ui/page-header/page-header.js.map +1 -1
  19. package/dist/components/ui/search/search.js +6 -6
  20. package/dist/components/ui/search/search.js.map +1 -1
  21. package/dist/components/ui/table/table.js +32 -32
  22. package/dist/components/ui/table/table.js.map +1 -1
  23. package/dist/components/ui/toolbar/toolbar.js +214 -0
  24. package/dist/components/ui/toolbar/toolbar.js.map +1 -0
  25. package/dist/hooks/use-intersection-observer.js +26 -0
  26. package/dist/hooks/use-intersection-observer.js.map +1 -0
  27. package/dist/index.js +356 -343
  28. package/dist/index.js.map +1 -1
  29. package/dist/react.js +356 -343
  30. package/dist/react.js.map +1 -1
  31. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +28 -0
  32. package/dist/src/components/ui/bar-chart/index.d.ts +1 -0
  33. package/dist/src/components/ui/data-table/data-table.d.ts +107 -4
  34. package/dist/src/components/ui/data-table/data-table.docs.d.ts +88 -4
  35. package/dist/src/components/ui/data-table/index.d.ts +1 -1
  36. package/dist/src/components/ui/page-header/index.d.ts +1 -1
  37. package/dist/src/components/ui/page-header/page-header.d.ts +9 -3
  38. package/dist/src/components/ui/toolbar/index.d.ts +1 -0
  39. package/dist/src/components/ui/toolbar/toolbar.d.ts +23 -0
  40. package/dist/src/hooks/index.d.ts +1 -0
  41. package/dist/src/hooks/use-intersection-observer.d.ts +26 -0
  42. package/dist/src/index.d.ts +2 -0
  43. package/dist/ui-react.css +1 -1
  44. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"page-header.js","sources":["../../../../src/components/ui/page-header/page-header.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\n// The page header region from the Figma (shadcn-uikit node 2850-701): an optional\n// breadcrumb, a title row (title left, actions right), and an optional description.\n// Ported from `@acronis-platform`'s `page-header` and reconciled with the Figma —\n// the title is a moderate page title (not the legacy 2xl). Markup-only; the only\n// color is the muted breadcrumb/description (text-muted-foreground →\n// --ui-text-on-surface-secondary).\n\nconst PageHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"page-header\"\n role=\"banner\"\n className={cn('flex flex-col gap-2 pb-4', className)}\n {...props}\n />\n));\nPageHeader.displayName = 'PageHeader';\n\nconst PageHeaderBreadcrumb = React.forwardRef<\n HTMLElement,\n React.HTMLAttributes<HTMLElement>\n>(({ className, ...props }, ref) => (\n <nav\n ref={ref}\n data-slot=\"page-header-breadcrumb\"\n aria-label=\"Breadcrumb\"\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nPageHeaderBreadcrumb.displayName = 'PageHeaderBreadcrumb';\n\n// The title + actions row: title on the left, actions pushed to the right.\nconst PageHeaderRow = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"page-header-row\"\n className={cn('flex items-center justify-between gap-4', className)}\n {...props}\n />\n));\nPageHeaderRow.displayName = 'PageHeaderRow';\n\nconst PageHeaderTitle = React.forwardRef<\n HTMLHeadingElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h1\n ref={ref}\n data-slot=\"page-header-title\"\n className={cn('text-lg font-semibold leading-tight tracking-tight', className)}\n {...props}\n />\n));\nPageHeaderTitle.displayName = 'PageHeaderTitle';\n\nconst PageHeaderDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n data-slot=\"page-header-description\"\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nPageHeaderDescription.displayName = 'PageHeaderDescription';\n\nconst PageHeaderActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"page-header-actions\"\n className={cn('flex shrink-0 items-center gap-2', className)}\n {...props}\n />\n));\nPageHeaderActions.displayName = 'PageHeaderActions';\n\nexport {\n PageHeader,\n PageHeaderBreadcrumb,\n PageHeaderRow,\n PageHeaderTitle,\n PageHeaderDescription,\n PageHeaderActions,\n};\n"],"names":["PageHeader","React","className","props","ref","jsx","cn","PageHeaderBreadcrumb","PageHeaderRow","PageHeaderTitle","PageHeaderDescription","PageHeaderActions"],"mappings":";;;AAWA,MAAMA,IAAaC,EAAM,WAGvB,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,MAAK;AAAA,IACL,WAAWE,EAAG,4BAA4BJ,CAAS;AAAA,IAClD,GAAGC;AAAA,EAAA;AACN,CACD;AACDH,EAAW,cAAc;AAEzB,MAAMO,IAAuBN,EAAM,WAGjC,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,cAAW;AAAA,IACX,WAAWE,EAAG,iCAAiCJ,CAAS;AAAA,IACvD,GAAGC;AAAA,EAAA;AACN,CACD;AACDI,EAAqB,cAAc;AAGnC,MAAMC,IAAgBP,EAAM,WAG1B,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,2CAA2CJ,CAAS;AAAA,IACjE,GAAGC;AAAA,EAAA;AACN,CACD;AACDK,EAAc,cAAc;AAE5B,MAAMC,IAAkBR,EAAM,WAG5B,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,sDAAsDJ,CAAS;AAAA,IAC5E,GAAGC;AAAA,EAAA;AACN,CACD;AACDM,EAAgB,cAAc;AAE9B,MAAMC,IAAwBT,EAAM,WAGlC,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,iCAAiCJ,CAAS;AAAA,IACvD,GAAGC;AAAA,EAAA;AACN,CACD;AACDO,EAAsB,cAAc;AAEpC,MAAMC,IAAoBV,EAAM,WAG9B,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,oCAAoCJ,CAAS;AAAA,IAC1D,GAAGC;AAAA,EAAA;AACN,CACD;AACDQ,EAAkB,cAAc;"}
1
+ {"version":3,"file":"page-header.js","sources":["../../../../src/components/ui/page-header/page-header.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport { CircleInfoIcon, EllipsisIcon } from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\nimport { Button, type ButtonProps } from '../button';\nimport { ButtonIcon } from '../button-icon';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../dropdown-menu';\nimport { Tag } from '../tag';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip';\n\n// The page header region from the Figma \"PageHeader\" component (shadcn-uikit /\n// ui-react file, node 2905-7678): a title row (title left, an optional edit\n// icon-button, a tags slot, an actions slot) and an optional description row\n// (text + an optional edit icon-button), capped at 512px. The design's\n// breadcrumb is a separate sibling above PageHeader (see the \"Breakpoints\"\n// page composition), not one of its own parts — render a `Breadcrumb` next to\n// it, don't nest one inside. Title uses the design's `headings/title` style\n// (24px/32px, regular) in `--ui-text-on-surface-primary`; the description uses\n// `link/default` (14px/24px, regular) in `--ui-text-on-surface-secondary` — the\n// only two colors here. The edit affordance is a plain `ButtonIcon` the\n// consumer places as a sibling; PageHeader doesn't own a dedicated part for it\n// since it's the same atom either row.\n\n// Detects whether a row's full-width content (measured off-screen, at natural\n// size) exceeds the space actually available to it — the Figma \"Breakpoints\"\n// page requires an all-or-nothing collapse (fit everything, or collapse), not\n// a partial \"show however many fit\" reflow. Re-measures on resize and after\n// every render (children content, e.g. tag count, isn't in a dependency array).\n// Unlike `useIsOverflowing` in sidebar-primary.tsx (which measures one element\n// against itself and returns a bare boolean), this compares a hidden\n// full-size clone against the live container and returns the refs alongside\n// the collapsed flag.\nfunction useRowOverflow() {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const measureRef = React.useRef<HTMLDivElement>(null);\n const [collapsed, setCollapsed] = React.useState(false);\n\n React.useEffect(() => {\n const container = containerRef.current;\n const measure = measureRef.current;\n if (!container || !measure) return;\n\n const recalc = () =>\n setCollapsed(measure.scrollWidth > container.clientWidth);\n\n recalc();\n const observer = new ResizeObserver(recalc);\n observer.observe(container);\n return () => observer.disconnect();\n });\n\n return { containerRef, measureRef, collapsed };\n}\n\nconst PageHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"page-header\"\n role=\"banner\"\n className={cn('flex w-full flex-col items-start gap-1', className)}\n {...props}\n />\n));\nPageHeader.displayName = 'PageHeader';\n\n// The title row: title, optional edit button, tags slot, actions slot.\nconst PageHeaderRow = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"page-header-row\"\n className={cn('flex w-full items-center gap-2', className)}\n {...props}\n />\n));\nPageHeaderRow.displayName = 'PageHeaderRow';\n\nconst PageHeaderTitle = React.forwardRef<\n HTMLHeadingElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h1\n ref={ref}\n data-slot=\"page-header-title\"\n className={cn(\n 'shrink-0 whitespace-nowrap text-2xl font-normal leading-8 text-foreground',\n className\n )}\n {...props}\n />\n));\nPageHeaderTitle.displayName = 'PageHeaderTitle';\n\ntype TagElement = React.ReactElement<{ children?: React.ReactNode }>;\n\n// The tags slot: grows to share the row's remaining width with the actions\n// slot (so actions stay flush right even when tags are omitted entirely).\n// Per the Figma \"Breakpoints\" page annotation: if all tags don't fit, show\n// only the first tag and fold the rest under a \"+#\" tag whose tooltip lists\n// their labels on hover — not a partial \"show however many fit\" reflow.\nconst PageHeaderTags = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, children, ...props }, ref) => {\n const items = React.Children.toArray(children) as TagElement[];\n const { containerRef, measureRef, collapsed } = useRowOverflow();\n const showOverflow = collapsed && items.length > 1;\n const hiddenItems = showOverflow ? items.slice(1) : [];\n\n const tagsChildren = (\n <>\n {showOverflow ? (\n <>\n {items[0]}\n <Tooltip>\n <TooltipTrigger render={<Tag icon={<CircleInfoIcon size={16} />} />}>\n {`+${hiddenItems.length}`}\n </TooltipTrigger>\n <TooltipContent>\n <ul>\n {hiddenItems.map((item, index) => (\n <li key={index}>{item.props?.children}</li>\n ))}\n </ul>\n </TooltipContent>\n </Tooltip>\n </>\n ) : (\n items\n )}\n {items.length > 1 && (\n <div\n ref={measureRef}\n aria-hidden\n className=\"invisible absolute flex items-center gap-2\"\n >\n {items}\n </div>\n )}\n </>\n );\n\n return useRender({\n ref: [ref, containerRef],\n defaultTagName: 'div',\n props: {\n 'data-slot': 'page-header-tags',\n ...mergeProps<'div'>(\n {\n className: cn(\n 'flex min-w-0 flex-1 items-center gap-2 overflow-hidden',\n className\n ),\n children: tagsChildren,\n },\n props\n ),\n },\n });\n});\nPageHeaderTags.displayName = 'PageHeaderTags';\n\ntype ActionElement = React.ReactElement<\n Omit<ButtonProps, 'render'> & {\n // Only the element form is meaningful once folded — a function-form\n // render receives Button's own state shape, not the \"More\" menu item's.\n render?: React.ReactElement;\n }\n>;\n\n// Fold only reduces a secondary action to a generic \"Menu Item\" label — the\n// Figma \"Breakpoints\" page annotation and its \"More\" menu mockup only cover a\n// plain button with a single click action. A trigger-style component (e.g.\n// ButtonMenu, which opens its own menu rather than firing one action) has no\n// single action to reduce to, so it's excluded even if given `variant=\"secondary\"`.\nconst isSecondaryAction = (item: ActionElement) =>\n item.type === Button && item.props?.variant === 'secondary';\n\n// The actions slot: grows to share the row's remaining width with the tags\n// slot. Per the Figma \"Breakpoints\" page annotation: if all buttons don't\n// fit, fold all secondary buttons under a single \"More\" ButtonIcon — primary\n// buttons are never hidden.\nconst PageHeaderActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, children, ...props }, ref) => {\n const items = React.Children.toArray(children) as ActionElement[];\n const secondaryItems = items.filter(isSecondaryAction);\n const { containerRef, measureRef, collapsed } = useRowOverflow();\n const showOverflow = collapsed && secondaryItems.length > 0;\n\n // Each secondary item becomes zero or one output items: dropped, except\n // the first (in original order), which becomes the \"More\" menu holding\n // all of them — hence `flatMap` over `map`/`filter`.\n const moreButton = (\n <DropdownMenu key=\"page-header-actions-more\">\n <DropdownMenuTrigger\n render={\n <ButtonIcon variant=\"secondary\" aria-label=\"More actions\">\n <EllipsisIcon size={16} />\n </ButtonIcon>\n }\n />\n <DropdownMenuContent align=\"end\">\n {secondaryItems.map((secondaryItem, index) => {\n const { variant, children, ...rest } = secondaryItem.props;\n return (\n <DropdownMenuItem\n key={index}\n {...(rest as React.ComponentPropsWithoutRef<typeof DropdownMenuItem>)}\n >\n {children}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n\n const collapseSecondaryActions = (item: ActionElement) => {\n if (!isSecondaryAction(item)) return [item];\n const isFirstSecondaryAction = item === secondaryItems[0];\n return isFirstSecondaryAction ? [moreButton] : [];\n };\n\n const visibleItems = showOverflow\n ? items.flatMap(collapseSecondaryActions)\n : items;\n\n const actionsChildren = (\n <>\n {visibleItems}\n {secondaryItems.length > 0 && (\n <div\n ref={measureRef}\n aria-hidden\n className=\"invisible absolute flex items-center gap-4\"\n >\n {items}\n </div>\n )}\n </>\n );\n\n return useRender({\n ref: [ref, containerRef],\n defaultTagName: 'div',\n props: {\n 'data-slot': 'page-header-actions',\n ...mergeProps<'div'>(\n {\n className: cn(\n 'flex min-w-0 flex-1 items-center justify-end gap-4 overflow-hidden',\n className\n ),\n children: actionsChildren,\n },\n props\n ),\n },\n });\n});\nPageHeaderActions.displayName = 'PageHeaderActions';\n\n// The description row: caps the text (+ its optional edit button) at 512px,\n// matching the Figma's explicit \"Description max width 512px\" note.\nconst PageHeaderDescriptionRow = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"page-header-description-row\"\n className={cn('flex max-w-lg items-start gap-2', className)}\n {...props}\n />\n));\nPageHeaderDescriptionRow.displayName = 'PageHeaderDescriptionRow';\n\nconst PageHeaderDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n data-slot=\"page-header-description\"\n className={cn(\n 'min-w-0 flex-1 text-sm font-normal leading-6 text-muted-foreground',\n className\n )}\n {...props}\n />\n));\nPageHeaderDescription.displayName = 'PageHeaderDescription';\n\nexport {\n PageHeader,\n PageHeaderRow,\n PageHeaderTitle,\n PageHeaderTags,\n PageHeaderActions,\n PageHeaderDescriptionRow,\n PageHeaderDescription,\n useRowOverflow,\n};\n"],"names":["useRowOverflow","containerRef","React","measureRef","collapsed","setCollapsed","container","measure","recalc","observer","PageHeader","className","props","ref","jsx","cn","PageHeaderRow","PageHeaderTitle","PageHeaderTags","children","items","showOverflow","hiddenItems","tagsChildren","jsxs","Fragment","Tooltip","TooltipTrigger","Tag","CircleInfoIcon","TooltipContent","item","index","_a","useRender","mergeProps","isSecondaryAction","Button","PageHeaderActions","secondaryItems","moreButton","DropdownMenu","DropdownMenuTrigger","ButtonIcon","EllipsisIcon","DropdownMenuContent","secondaryItem","variant","rest","DropdownMenuItem","collapseSecondaryActions","visibleItems","actionsChildren","PageHeaderDescriptionRow","PageHeaderDescription"],"mappings":";;;;;;;;;;;AAuCA,SAASA,IAAiB;AACxB,QAAMC,IAAeC,EAAM,OAAuB,IAAI,GAChDC,IAAaD,EAAM,OAAuB,IAAI,GAC9C,CAACE,GAAWC,CAAY,IAAIH,EAAM,SAAS,EAAK;AAEtD,SAAAA,EAAM,UAAU,MAAM;AACpB,UAAMI,IAAYL,EAAa,SACzBM,IAAUJ,EAAW;AAC3B,QAAI,CAACG,KAAa,CAACC,EAAS;AAE5B,UAAMC,IAAS,MACbH,EAAaE,EAAQ,cAAcD,EAAU,WAAW;AAE1D,IAAAE,EAAA;AACA,UAAMC,IAAW,IAAI,eAAeD,CAAM;AAC1C,WAAAC,EAAS,QAAQH,CAAS,GACnB,MAAMG,EAAS,WAAA;AAAA,EACxB,CAAC,GAEM,EAAE,cAAAR,GAAc,YAAAE,GAAY,WAAAC,EAAA;AACrC;AAEA,MAAMM,IAAaR,EAAM,WAGvB,CAAC,EAAE,WAAAS,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,MAAK;AAAA,IACL,WAAWE,EAAG,0CAA0CJ,CAAS;AAAA,IAChE,GAAGC;AAAA,EAAA;AACN,CACD;AACDF,EAAW,cAAc;AAGzB,MAAMM,IAAgBd,EAAM,WAG1B,CAAC,EAAE,WAAAS,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,kCAAkCJ,CAAS;AAAA,IACxD,GAAGC;AAAA,EAAA;AACN,CACD;AACDI,EAAc,cAAc;AAE5B,MAAMC,IAAkBf,EAAM,WAG5B,CAAC,EAAE,WAAAS,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE;AAAA,MACT;AAAA,MACAJ;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN,CACD;AACDK,EAAgB,cAAc;AAS9B,MAAMC,IAAiBhB,EAAM,WAG3B,CAAC,EAAE,WAAAS,GAAW,UAAAQ,GAAU,GAAGP,EAAA,GAASC,MAAQ;AAC5C,QAAMO,IAAQlB,EAAM,SAAS,QAAQiB,CAAQ,GACvC,EAAE,cAAAlB,GAAc,YAAAE,GAAY,WAAAC,EAAA,IAAcJ,EAAA,GAC1CqB,IAAejB,KAAagB,EAAM,SAAS,GAC3CE,IAAcD,IAAeD,EAAM,MAAM,CAAC,IAAI,CAAA,GAE9CG,IACJ,gBAAAC,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAJ,IACC,gBAAAG,EAAAC,GAAA,EACG,UAAA;AAAA,MAAAL,EAAM,CAAC;AAAA,wBACPM,GAAA,EACC,UAAA;AAAA,QAAA,gBAAAZ,EAACa,GAAA,EAAe,QAAQ,gBAAAb,EAACc,GAAA,EAAI,MAAM,gBAAAd,EAACe,GAAA,EAAe,MAAM,GAAA,CAAI,EAAA,CAAI,GAC9D,UAAA,IAAIP,EAAY,MAAM,IACzB;AAAA,0BACCQ,GAAA,EACC,UAAA,gBAAAhB,EAAC,MAAA,EACE,UAAAQ,EAAY,IAAI,CAACS,GAAMC,MAAA;;AACtB,iCAAAlB,EAAC,QAAgB,WAAAmB,IAAAF,EAAK,UAAL,gBAAAE,EAAY,YAApBD,CAA6B;AAAA,SACvC,GACH,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,EAAA,CACF,IAEAZ;AAAA,IAEDA,EAAM,SAAS,KACd,gBAAAN;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKX;AAAA,QACL,eAAW;AAAA,QACX,WAAU;AAAA,QAET,UAAAiB;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GAEJ;AAGF,SAAOc,EAAU;AAAA,IACf,KAAK,CAACrB,GAAKZ,CAAY;AAAA,IACvB,gBAAgB;AAAA,IAChB,OAAO;AAAA,MACL,aAAa;AAAA,MACb,GAAGkC;AAAA,QACD;AAAA,UACE,WAAWpB;AAAA,YACT;AAAA,YACAJ;AAAA,UAAA;AAAA,UAEF,UAAUY;AAAA,QAAA;AAAA,QAEZX;AAAA,MAAA;AAAA,IACF;AAAA,EACF,CACD;AACH,CAAC;AACDM,EAAe,cAAc;AAe7B,MAAMkB,IAAoB,CAACL,MAAA;;AACzB,SAAAA,EAAK,SAASM,OAAUJ,IAAAF,EAAK,UAAL,gBAAAE,EAAY,aAAY;AAAA,GAM5CK,IAAoBpC,EAAM,WAG9B,CAAC,EAAE,WAAAS,GAAW,UAAAQ,GAAU,GAAGP,EAAA,GAASC,MAAQ;AAC5C,QAAMO,IAAQlB,EAAM,SAAS,QAAQiB,CAAQ,GACvCoB,IAAiBnB,EAAM,OAAOgB,CAAiB,GAC/C,EAAE,cAAAnC,GAAc,YAAAE,GAAY,WAAAC,EAAA,IAAcJ,EAAA,GAC1CqB,IAAejB,KAAamC,EAAe,SAAS,GAKpDC,sBACHC,GAAA,EACC,UAAA;AAAA,IAAA,gBAAA3B;AAAA,MAAC4B;AAAA,MAAA;AAAA,QACC,QACE,gBAAA5B,EAAC6B,GAAA,EAAW,SAAQ,aAAY,cAAW,gBACzC,UAAA,gBAAA7B,EAAC8B,GAAA,EAAa,MAAM,GAAA,CAAI,EAAA,CAC1B;AAAA,MAAA;AAAA,IAAA;AAAA,IAGJ,gBAAA9B,EAAC+B,KAAoB,OAAM,OACxB,YAAe,IAAI,CAACC,GAAed,MAAU;AAC5C,YAAM,EAAE,SAAAe,GAAS,UAAA5B,GAAU,GAAG6B,EAAA,IAASF,EAAc;AACrD,aACE,gBAAAhC;AAAA,QAACmC;AAAA,QAAA;AAAA,UAEE,GAAID;AAAA,UAEJ,UAAA7B;AAAAA,QAAA;AAAA,QAHIa;AAAA,MAAA;AAAA,IAMX,CAAC,EAAA,CACH;AAAA,EAAA,EAAA,GApBgB,0BAqBlB,GAGIkB,IAA2B,CAACnB,MAC3BK,EAAkBL,CAAI,IACIA,MAASQ,EAAe,CAAC,IACxB,CAACC,CAAU,IAAI,CAAA,IAFV,CAACT,CAAI,GAKtCoB,IAAe9B,IACjBD,EAAM,QAAQ8B,CAAwB,IACtC9B,GAEEgC,IACJ,gBAAA5B,EAAAC,GAAA,EACG,UAAA;AAAA,IAAA0B;AAAA,IACAZ,EAAe,SAAS,KACvB,gBAAAzB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKX;AAAA,QACL,eAAW;AAAA,QACX,WAAU;AAAA,QAET,UAAAiB;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GAEJ;AAGF,SAAOc,EAAU;AAAA,IACf,KAAK,CAACrB,GAAKZ,CAAY;AAAA,IACvB,gBAAgB;AAAA,IAChB,OAAO;AAAA,MACL,aAAa;AAAA,MACb,GAAGkC;AAAA,QACD;AAAA,UACE,WAAWpB;AAAA,YACT;AAAA,YACAJ;AAAA,UAAA;AAAA,UAEF,UAAUyC;AAAA,QAAA;AAAA,QAEZxC;AAAA,MAAA;AAAA,IACF;AAAA,EACF,CACD;AACH,CAAC;AACD0B,EAAkB,cAAc;AAIhC,MAAMe,IAA2BnD,EAAM,WAGrC,CAAC,EAAE,WAAAS,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,mCAAmCJ,CAAS;AAAA,IACzD,GAAGC;AAAA,EAAA;AACN,CACD;AACDyC,EAAyB,cAAc;AAEvC,MAAMC,IAAwBpD,EAAM,WAGlC,CAAC,EAAE,WAAAS,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE;AAAA,MACT;AAAA,MACAJ;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN,CACD;AACD0C,EAAsB,cAAc;"}
@@ -4,7 +4,7 @@ import { MagnifierIcon as S, TimesIcon as k } from "@acronis-platform/icons-reac
4
4
  import { cn as N } from "../../../lib/utils.js";
5
5
  const j = t.forwardRef(
6
6
  ({
7
- className: b,
7
+ className: p,
8
8
  type: v = "search",
9
9
  disabled: s,
10
10
  onClear: n,
@@ -27,15 +27,15 @@ const j = t.forwardRef(
27
27
  ), m = (e) => {
28
28
  l(e.target.value.length > 0), c == null || c(e);
29
29
  }, y = () => {
30
- var h, p;
30
+ var h, b;
31
31
  const e = d.current;
32
32
  if (!e) return;
33
33
  let a;
34
34
  try {
35
- a = (p = Object.getOwnPropertyDescriptor(
35
+ a = (b = Object.getOwnPropertyDescriptor(
36
36
  (h = globalThis.HTMLInputElement) == null ? void 0 : h.prototype,
37
37
  "value"
38
- )) == null ? void 0 : p.set;
38
+ )) == null ? void 0 : b.set;
39
39
  } catch {
40
40
  a = void 0;
41
41
  }
@@ -47,7 +47,7 @@ const j = t.forwardRef(
47
47
  "data-disabled": s || void 0,
48
48
  className: N(
49
49
  "group inline-flex h-[var(--ui-input-search-box-height)] w-full min-w-0 items-center gap-[var(--ui-input-search-box-gap)] rounded-[var(--ui-input-search-box-border-radius)] border bg-[var(--ui-input-search-box-color-idle)] border-[var(--ui-input-search-border-color-idle)] px-[var(--ui-input-search-box-padding-x)] text-sm leading-6 text-[var(--ui-input-search-value-color-idle)] transition-colors not-data-[disabled]:hover:bg-[var(--ui-input-search-box-color-hover)] not-data-[disabled]:hover:border-[var(--ui-input-search-border-color-hover)] focus-within:border-[var(--ui-input-search-border-color-hover)] focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] data-[disabled]:cursor-not-allowed data-[disabled]:border-[var(--ui-input-search-border-color-disabled)] data-[disabled]:bg-[var(--ui-input-search-box-color-disabled)] data-[disabled]:text-[var(--ui-input-search-value-color-disabled)]",
50
- b
50
+ p
51
51
  ),
52
52
  children: [
53
53
  /* @__PURE__ */ o(
@@ -77,7 +77,7 @@ const j = t.forwardRef(
77
77
  type: "button",
78
78
  "aria-label": "Clear search",
79
79
  onClick: y,
80
- className: "inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm text-[var(--ui-input-search-clear-icon-color)] outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&>svg]:size-4",
80
+ className: "inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm text-[var(--ui-button-icon-global-icon-color-idle)] outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&>svg]:size-4",
81
81
  children: /* @__PURE__ */ o(k, { size: 16 })
82
82
  }
83
83
  )
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sources":["../../../../src/components/ui/search/search.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n MagnifierIcon,\n TimesIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\n// Internal primitive: the bare search box behind the public `InputSearch` field\n// (which is also exported as `Search`). Not exported from the package; consumed\n// by `input-search`. A bordered box (the dedicated `--ui-input-search-*` token\n// tier) holding a leading magnifier, a borderless native input, and a trailing\n// clear button shown once there's a value. The box owns the visual state via\n// `focus-within` (the input-search tier has no focus/active border token, so the\n// focused border reuses `--ui-input-search-border-color-hover` plus a 3px\n// `--ui-focus-primary` ring) / hover / disabled; the magnifier uses\n// `--ui-input-search-icon-search-color-{idle,disabled}` (via the `group`) and the\n// clear button uses `--ui-input-search-clear-icon-color`.\n\nexport interface SearchBoxProps extends React.ComponentPropsWithoutRef<'input'> {\n /** Called when the clear (×) button is pressed, after the value is cleared. */\n onClear?: () => void;\n}\n\nconst SearchBox = React.forwardRef<HTMLInputElement, SearchBoxProps>(\n (\n {\n className,\n type = 'search',\n disabled,\n onClear,\n onChange,\n value,\n defaultValue,\n ...props\n },\n forwardedRef\n ) => {\n const innerRef = React.useRef<HTMLInputElement>(null);\n const [hasValue, setHasValue] = React.useState(\n () => String(value ?? defaultValue ?? '').length > 0\n );\n\n // Keep the clear button in sync when the value is controlled externally.\n React.useEffect(() => {\n if (value !== undefined) setHasValue(String(value).length > 0);\n }, [value]);\n\n const setRefs = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) forwardedRef.current = node;\n },\n [forwardedRef]\n );\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setHasValue(event.target.value.length > 0);\n onChange?.(event);\n };\n\n const handleClear = () => {\n const input = innerRef.current;\n if (!input) return;\n // Use the native value setter when available + dispatch a real input event\n // so React's onChange fires for both controlled and uncontrolled usage.\n let setter: ((this: HTMLInputElement, value: string) => void) | undefined;\n try {\n setter = Object.getOwnPropertyDescriptor(\n globalThis.HTMLInputElement?.prototype,\n 'value'\n )?.set;\n } catch {\n setter = undefined;\n }\n\n if (setter) setter.call(input, '');\n else input.value = '';\n\n input.dispatchEvent(new Event('input', { bubbles: true }));\n setHasValue(false);\n input.focus();\n onClear?.();\n };\n\n return (\n <div\n data-disabled={disabled || undefined}\n className={cn(\n 'group inline-flex h-[var(--ui-input-search-box-height)] w-full min-w-0 items-center gap-[var(--ui-input-search-box-gap)] rounded-[var(--ui-input-search-box-border-radius)] border bg-[var(--ui-input-search-box-color-idle)] border-[var(--ui-input-search-border-color-idle)] px-[var(--ui-input-search-box-padding-x)] text-sm leading-6 text-[var(--ui-input-search-value-color-idle)] transition-colors not-data-[disabled]:hover:bg-[var(--ui-input-search-box-color-hover)] not-data-[disabled]:hover:border-[var(--ui-input-search-border-color-hover)] focus-within:border-[var(--ui-input-search-border-color-hover)] focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] data-[disabled]:cursor-not-allowed data-[disabled]:border-[var(--ui-input-search-border-color-disabled)] data-[disabled]:bg-[var(--ui-input-search-box-color-disabled)] data-[disabled]:text-[var(--ui-input-search-value-color-disabled)]',\n className\n )}\n >\n <MagnifierIcon\n size={16}\n className=\"shrink-0 text-[var(--ui-input-search-icon-search-color-idle)] group-data-[disabled]:text-[var(--ui-input-search-icon-search-color-disabled)]\"\n />\n <input\n ref={setRefs}\n type={type}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n aria-label=\"Search\"\n className=\"h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-inherit outline-none placeholder:text-[var(--ui-input-search-placeholder-color-idle)] disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:appearance-none\"\n {...props}\n />\n {hasValue && !disabled && (\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={handleClear}\n className=\"inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm text-[var(--ui-input-search-clear-icon-color)] outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&>svg]:size-4\"\n >\n <TimesIcon size={16} />\n </button>\n )}\n </div>\n );\n }\n);\nSearchBox.displayName = 'SearchBox';\n\nexport { SearchBox };\n"],"names":["SearchBox","React","className","type","disabled","onClear","onChange","value","defaultValue","props","forwardedRef","innerRef","hasValue","setHasValue","setRefs","node","handleChange","event","handleClear","input","setter","_b","_a","jsxs","cn","jsx","MagnifierIcon","TimesIcon"],"mappings":";;;;AAwBA,MAAMA,IAAYC,EAAM;AAAA,EACtB,CACE;AAAA,IACE,WAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,UAAAC;AAAA,IACA,SAAAC;AAAA,IACA,UAAAC;AAAA,IACA,OAAAC;AAAA,IACA,cAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAAWV,EAAM,OAAyB,IAAI,GAC9C,CAACW,GAAUC,CAAW,IAAIZ,EAAM;AAAA,MACpC,MAAM,OAAOM,KAASC,KAAgB,EAAE,EAAE,SAAS;AAAA,IAAA;AAIrD,IAAAP,EAAM,UAAU,MAAM;AACpB,MAAIM,MAAU,UAAWM,EAAY,OAAON,CAAK,EAAE,SAAS,CAAC;AAAA,IAC/D,GAAG,CAACA,CAAK,CAAC;AAEV,UAAMO,IAAUb,EAAM;AAAA,MACpB,CAACc,MAAkC;AACjC,QAAAJ,EAAS,UAAUI,GACf,OAAOL,KAAiB,aAAYA,EAAaK,CAAI,IAChDL,QAA2B,UAAUK;AAAA,MAChD;AAAA,MACA,CAACL,CAAY;AAAA,IAAA,GAGTM,IAAe,CAACC,MAA+C;AACnE,MAAAJ,EAAYI,EAAM,OAAO,MAAM,SAAS,CAAC,GACzCX,KAAA,QAAAA,EAAWW;AAAA,IACb,GAEMC,IAAc,MAAM;;AACxB,YAAMC,IAAQR,EAAS;AACvB,UAAI,CAACQ,EAAO;AAGZ,UAAIC;AACJ,UAAI;AACF,QAAAA,KAASC,IAAA,OAAO;AAAA,WACdC,IAAA,WAAW,qBAAX,gBAAAA,EAA6B;AAAA,UAC7B;AAAA,QAAA,MAFO,gBAAAD,EAGN;AAAA,MACL,QAAQ;AACN,QAAAD,IAAS;AAAA,MACX;AAEA,MAAIA,IAAQA,EAAO,KAAKD,GAAO,EAAE,MACtB,QAAQ,IAEnBA,EAAM,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,GAAA,CAAM,CAAC,GACzDN,EAAY,EAAK,GACjBM,EAAM,MAAA,GACNd,KAAA,QAAAA;AAAA,IACF;AAEA,WACE,gBAAAkB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,iBAAenB,KAAY;AAAA,QAC3B,WAAWoB;AAAA,UACT;AAAA,UACAtB;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA,gBAAAuB;AAAA,YAACC;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZ,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKX;AAAA,cACL,MAAAX;AAAA,cACA,UAAAC;AAAA,cACA,OAAAG;AAAA,cACA,cAAAC;AAAA,cACA,UAAUQ;AAAA,cACV,cAAW;AAAA,cACX,WAAU;AAAA,cACT,GAAGP;AAAA,YAAA;AAAA,UAAA;AAAA,UAELG,KAAY,CAACR,KACZ,gBAAAqB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,SAASP;AAAA,cACT,WAAU;AAAA,cAEV,UAAA,gBAAAO,EAACE,GAAA,EAAU,MAAM,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QACvB;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AACA3B,EAAU,cAAc;"}
1
+ {"version":3,"file":"search.js","sources":["../../../../src/components/ui/search/search.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n MagnifierIcon,\n TimesIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\n// Internal primitive: the bare search box behind the public `InputSearch` field\n// (which is also exported as `Search`). Not exported from the package; consumed\n// by `input-search`. A bordered box (the dedicated `--ui-input-search-*` token\n// tier) holding a leading magnifier, a borderless native input, and a trailing\n// clear button shown once there's a value. The box owns the visual state via\n// `focus-within` (the input-search tier has no focus/active border token, so the\n// focused border reuses `--ui-input-search-border-color-hover` plus a 3px\n// `--ui-focus-primary` ring) / hover / disabled; the magnifier uses\n// `--ui-input-search-icon-search-color-{idle,disabled}` (via the `group`) and the\n// clear button is a ghost ButtonIcon, so its glyph uses\n// `--ui-button-icon-global-icon-color-idle` (the input-search tier dropped its own\n// clear-icon token in the Figma sync).\n\nexport interface SearchBoxProps extends React.ComponentPropsWithoutRef<'input'> {\n /** Called when the clear (×) button is pressed, after the value is cleared. */\n onClear?: () => void;\n}\n\nconst SearchBox = React.forwardRef<HTMLInputElement, SearchBoxProps>(\n (\n {\n className,\n type = 'search',\n disabled,\n onClear,\n onChange,\n value,\n defaultValue,\n ...props\n },\n forwardedRef\n ) => {\n const innerRef = React.useRef<HTMLInputElement>(null);\n const [hasValue, setHasValue] = React.useState(\n () => String(value ?? defaultValue ?? '').length > 0\n );\n\n // Keep the clear button in sync when the value is controlled externally.\n React.useEffect(() => {\n if (value !== undefined) setHasValue(String(value).length > 0);\n }, [value]);\n\n const setRefs = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) forwardedRef.current = node;\n },\n [forwardedRef]\n );\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setHasValue(event.target.value.length > 0);\n onChange?.(event);\n };\n\n const handleClear = () => {\n const input = innerRef.current;\n if (!input) return;\n // Use the native value setter when available + dispatch a real input event\n // so React's onChange fires for both controlled and uncontrolled usage.\n let setter: ((this: HTMLInputElement, value: string) => void) | undefined;\n try {\n setter = Object.getOwnPropertyDescriptor(\n globalThis.HTMLInputElement?.prototype,\n 'value'\n )?.set;\n } catch {\n setter = undefined;\n }\n\n if (setter) setter.call(input, '');\n else input.value = '';\n\n input.dispatchEvent(new Event('input', { bubbles: true }));\n setHasValue(false);\n input.focus();\n onClear?.();\n };\n\n return (\n <div\n data-disabled={disabled || undefined}\n className={cn(\n 'group inline-flex h-[var(--ui-input-search-box-height)] w-full min-w-0 items-center gap-[var(--ui-input-search-box-gap)] rounded-[var(--ui-input-search-box-border-radius)] border bg-[var(--ui-input-search-box-color-idle)] border-[var(--ui-input-search-border-color-idle)] px-[var(--ui-input-search-box-padding-x)] text-sm leading-6 text-[var(--ui-input-search-value-color-idle)] transition-colors not-data-[disabled]:hover:bg-[var(--ui-input-search-box-color-hover)] not-data-[disabled]:hover:border-[var(--ui-input-search-border-color-hover)] focus-within:border-[var(--ui-input-search-border-color-hover)] focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] data-[disabled]:cursor-not-allowed data-[disabled]:border-[var(--ui-input-search-border-color-disabled)] data-[disabled]:bg-[var(--ui-input-search-box-color-disabled)] data-[disabled]:text-[var(--ui-input-search-value-color-disabled)]',\n className\n )}\n >\n <MagnifierIcon\n size={16}\n className=\"shrink-0 text-[var(--ui-input-search-icon-search-color-idle)] group-data-[disabled]:text-[var(--ui-input-search-icon-search-color-disabled)]\"\n />\n <input\n ref={setRefs}\n type={type}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n aria-label=\"Search\"\n className=\"h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-inherit outline-none placeholder:text-[var(--ui-input-search-placeholder-color-idle)] disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:appearance-none\"\n {...props}\n />\n {hasValue && !disabled && (\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={handleClear}\n className=\"inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm text-[var(--ui-button-icon-global-icon-color-idle)] outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&>svg]:size-4\"\n >\n <TimesIcon size={16} />\n </button>\n )}\n </div>\n );\n }\n);\nSearchBox.displayName = 'SearchBox';\n\nexport { SearchBox };\n"],"names":["SearchBox","React","className","type","disabled","onClear","onChange","value","defaultValue","props","forwardedRef","innerRef","hasValue","setHasValue","setRefs","node","handleChange","event","handleClear","input","setter","_b","_a","jsxs","cn","jsx","MagnifierIcon","TimesIcon"],"mappings":";;;;AA0BA,MAAMA,IAAYC,EAAM;AAAA,EACtB,CACE;AAAA,IACE,WAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,UAAAC;AAAA,IACA,SAAAC;AAAA,IACA,UAAAC;AAAA,IACA,OAAAC;AAAA,IACA,cAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAAWV,EAAM,OAAyB,IAAI,GAC9C,CAACW,GAAUC,CAAW,IAAIZ,EAAM;AAAA,MACpC,MAAM,OAAOM,KAASC,KAAgB,EAAE,EAAE,SAAS;AAAA,IAAA;AAIrD,IAAAP,EAAM,UAAU,MAAM;AACpB,MAAIM,MAAU,UAAWM,EAAY,OAAON,CAAK,EAAE,SAAS,CAAC;AAAA,IAC/D,GAAG,CAACA,CAAK,CAAC;AAEV,UAAMO,IAAUb,EAAM;AAAA,MACpB,CAACc,MAAkC;AACjC,QAAAJ,EAAS,UAAUI,GACf,OAAOL,KAAiB,aAAYA,EAAaK,CAAI,IAChDL,QAA2B,UAAUK;AAAA,MAChD;AAAA,MACA,CAACL,CAAY;AAAA,IAAA,GAGTM,IAAe,CAACC,MAA+C;AACnE,MAAAJ,EAAYI,EAAM,OAAO,MAAM,SAAS,CAAC,GACzCX,KAAA,QAAAA,EAAWW;AAAA,IACb,GAEMC,IAAc,MAAM;;AACxB,YAAMC,IAAQR,EAAS;AACvB,UAAI,CAACQ,EAAO;AAGZ,UAAIC;AACJ,UAAI;AACF,QAAAA,KAASC,IAAA,OAAO;AAAA,WACdC,IAAA,WAAW,qBAAX,gBAAAA,EAA6B;AAAA,UAC7B;AAAA,QAAA,MAFO,gBAAAD,EAGN;AAAA,MACL,QAAQ;AACN,QAAAD,IAAS;AAAA,MACX;AAEA,MAAIA,IAAQA,EAAO,KAAKD,GAAO,EAAE,MACtB,QAAQ,IAEnBA,EAAM,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,GAAA,CAAM,CAAC,GACzDN,EAAY,EAAK,GACjBM,EAAM,MAAA,GACNd,KAAA,QAAAA;AAAA,IACF;AAEA,WACE,gBAAAkB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,iBAAenB,KAAY;AAAA,QAC3B,WAAWoB;AAAA,UACT;AAAA,UACAtB;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA,gBAAAuB;AAAA,YAACC;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZ,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKX;AAAA,cACL,MAAAX;AAAA,cACA,UAAAC;AAAA,cACA,OAAAG;AAAA,cACA,cAAAC;AAAA,cACA,UAAUQ;AAAA,cACV,cAAW;AAAA,cACX,WAAU;AAAA,cACT,GAAGP;AAAA,YAAA;AAAA,UAAA;AAAA,UAELG,KAAY,CAACR,KACZ,gBAAAqB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,SAASP;AAAA,cACT,WAAU;AAAA,cAEV,UAAA,gBAAAO,EAACE,GAAA,EAAU,MAAM,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QACvB;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AACA3B,EAAU,cAAc;"}
@@ -1,12 +1,12 @@
1
- import { jsx as l, jsxs as n } from "react/jsx-runtime";
1
+ import { jsx as r, jsxs as b } from "react/jsx-runtime";
2
2
  import * as t from "react";
3
3
  import { ArrowUpIcon as m, ArrowDownIcon as p, ArrowsDownUpIcon as u } from "@acronis-platform/icons-react/stroke-mono";
4
- import { cn as r } from "../../../lib/utils.js";
5
- const f = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ l("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ l(
4
+ import { cn as l } from "../../../lib/utils.js";
5
+ const f = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ r("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ r(
6
6
  "table",
7
7
  {
8
8
  ref: o,
9
- className: r(
9
+ className: l(
10
10
  "w-full caption-bottom border-collapse text-sm text-[var(--ui-table-data-value-color-idle)]",
11
11
  a
12
12
  ),
@@ -14,47 +14,47 @@ const f = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ l("div", {
14
14
  }
15
15
  ) }));
16
16
  f.displayName = "Table";
17
- const v = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ l("thead", { ref: o, className: r(a), ...e }));
17
+ const v = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ r("thead", { ref: o, className: l(a), ...e }));
18
18
  v.displayName = "TableHeader";
19
- const h = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ l(
19
+ const w = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ r(
20
20
  "tbody",
21
21
  {
22
22
  ref: o,
23
- className: r("[&_tr:last-child]:border-0", a),
23
+ className: l("[&_tr:last-child]:border-0", a),
24
24
  ...e
25
25
  }
26
26
  ));
27
- h.displayName = "TableBody";
28
- const g = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ l(
27
+ w.displayName = "TableBody";
28
+ const h = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ r(
29
29
  "tfoot",
30
30
  {
31
31
  ref: o,
32
- className: r(
33
- "border-t border-[color:var(--ui-table-global-cell-border-color)] font-medium [&>tr]:last:border-b-0",
32
+ className: l(
33
+ "border-t border-[color:var(--ui-table-global-row-border-color)] font-medium [&>tr]:last:border-b-0",
34
34
  a
35
35
  ),
36
36
  ...e
37
37
  }
38
38
  ));
39
- g.displayName = "TableFooter";
40
- const w = t.forwardRef(
41
- ({ className: a, selected: e, ...o }, s) => /* @__PURE__ */ l(
39
+ h.displayName = "TableFooter";
40
+ const x = t.forwardRef(
41
+ ({ className: a, selected: e, ...o }, s) => /* @__PURE__ */ r(
42
42
  "tr",
43
43
  {
44
44
  ref: s,
45
45
  "data-state": e ? "selected" : void 0,
46
- className: r(
47
- "border-b border-[color:var(--ui-table-global-cell-border-color)] bg-[var(--ui-table-global-row-color-idle)] transition-colors hover:bg-[var(--ui-table-global-row-color-hover)] data-[state=selected]:bg-[var(--ui-table-global-row-color-active)]",
46
+ className: l(
47
+ "border-b border-[color:var(--ui-table-global-row-border-color)] bg-[var(--ui-table-data-row-color-idle)] transition-colors hover:bg-[var(--ui-table-data-row-color-hover)] data-[state=selected]:bg-[var(--ui-table-data-row-color-active)]",
48
48
  a
49
49
  ),
50
50
  ...o
51
51
  }
52
52
  )
53
53
  );
54
- w.displayName = "TableRow";
55
- function x({ direction: a }) {
54
+ x.displayName = "TableRow";
55
+ function g({ direction: a }) {
56
56
  const e = "size-[var(--ui-table-header-sort-icon-size)]";
57
- return a === "asc" ? /* @__PURE__ */ l(m, { className: r(e, "text-[var(--ui-table-header-sort-icon-color-active)]") }) : a === "desc" ? /* @__PURE__ */ l(p, { className: r(e, "text-[var(--ui-table-header-sort-icon-color-active)]") }) : /* @__PURE__ */ l(u, { className: r(e, "text-[var(--ui-table-header-sort-icon-color-inactive)]") });
57
+ return a === "asc" ? /* @__PURE__ */ r(m, { className: l(e, "text-[var(--ui-table-header-sort-icon-color-active)]") }) : a === "desc" ? /* @__PURE__ */ r(p, { className: l(e, "text-[var(--ui-table-header-sort-icon-color-active)]") }) : /* @__PURE__ */ r(u, { className: l(e, "text-[var(--ui-table-header-sort-icon-color-inactive)]") });
58
58
  }
59
59
  const N = t.forwardRef(
60
60
  ({
@@ -65,18 +65,18 @@ const N = t.forwardRef(
65
65
  onSort: i,
66
66
  wrap: c,
67
67
  ...d
68
- }, b) => /* @__PURE__ */ l(
68
+ }, n) => /* @__PURE__ */ r(
69
69
  "th",
70
70
  {
71
- ref: b,
71
+ ref: n,
72
72
  "aria-sort": s === "asc" ? "ascending" : s === "desc" ? "descending" : o ? "none" : void 0,
73
- className: r(
74
- "px-[var(--ui-table-header-cell-padding-x)] text-start align-middle text-sm font-semibold text-[var(--ui-table-header-label-color)] [&:has([role=checkbox])]:pe-0",
73
+ className: l(
74
+ "px-[var(--ui-table-global-cell-padding-x)] text-start align-middle text-sm font-semibold text-[var(--ui-table-header-label-color)] [&:has([role=checkbox])]:pe-0",
75
75
  c ? "whitespace-normal" : "h-10",
76
76
  a
77
77
  ),
78
78
  ...d,
79
- children: o ? /* @__PURE__ */ n(
79
+ children: o ? /* @__PURE__ */ b(
80
80
  "button",
81
81
  {
82
82
  type: "button",
@@ -84,7 +84,7 @@ const N = t.forwardRef(
84
84
  className: "-mx-1 inline-flex cursor-pointer items-center gap-[var(--ui-table-header-gap)] rounded-sm px-1 outline-none transition-colors hover:bg-[var(--ui-table-header-cell-color-hover)] focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)]",
85
85
  children: [
86
86
  e,
87
- /* @__PURE__ */ l(x, { direction: s })
87
+ /* @__PURE__ */ r(g, { direction: s })
88
88
  ]
89
89
  }
90
90
  ) : e
@@ -93,11 +93,11 @@ const N = t.forwardRef(
93
93
  );
94
94
  N.displayName = "TableHead";
95
95
  const T = t.forwardRef(
96
- ({ className: a, wrap: e, ...o }, s) => /* @__PURE__ */ l(
96
+ ({ className: a, wrap: e, ...o }, s) => /* @__PURE__ */ r(
97
97
  "td",
98
98
  {
99
99
  ref: s,
100
- className: r(
100
+ className: l(
101
101
  "px-[var(--ui-table-global-cell-padding-x)] py-[var(--ui-table-global-cell-padding-y)] align-middle text-sm [&:has([role=checkbox])]:pe-0",
102
102
  e ? "whitespace-normal" : "h-10",
103
103
  a
@@ -107,23 +107,23 @@ const T = t.forwardRef(
107
107
  )
108
108
  );
109
109
  T.displayName = "TableCell";
110
- const y = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ l(
110
+ const y = t.forwardRef(({ className: a, ...e }, o) => /* @__PURE__ */ r(
111
111
  "caption",
112
112
  {
113
113
  ref: o,
114
- className: r("mt-4 text-sm text-muted-foreground", a),
114
+ className: l("mt-4 text-sm text-muted-foreground", a),
115
115
  ...e
116
116
  }
117
117
  ));
118
118
  y.displayName = "TableCaption";
119
119
  export {
120
120
  f as Table,
121
- h as TableBody,
121
+ w as TableBody,
122
122
  y as TableCaption,
123
123
  T as TableCell,
124
- g as TableFooter,
124
+ h as TableFooter,
125
125
  N as TableHead,
126
126
  v as TableHeader,
127
- w as TableRow
127
+ x as TableRow
128
128
  };
129
129
  //# sourceMappingURL=table.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","sources":["../../../../src/components/ui/table/table.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n ArrowDownIcon,\n ArrowUpIcon,\n ArrowsDownUpIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\n// Composable table primitives ported from `@acronis-platform/shadcn-uikit`'s\n// `table` (packages/ui-legacy/src/components/ui/table.tsx) and informed by the\n// \"pre-release\" Table design in the shadcn-uikit Figma (node 2948-2416). Unlike\n// Card/Dialog, a `--ui-table-*` token tier already exists, so these parts theme\n// directly from it (imported in styles/index.css):\n// • cell -> --ui-table-global-cell-{border-color,padding-x,padding-y,min-height}\n// • row -> --ui-table-global-row-color-{idle,hover,active} (active = selected)\n// • header -> --ui-table-header-{label-color,cell-color-hover,cell-padding-x,gap}\n// • sort -> --ui-table-header-sort-icon-{color-active,color-inactive,size}\n// • data -> --ui-table-data-value-color-{idle,disabled}\n// The design's row checkboxes, tags, links and the column-settings button are\n// consumer composition (use Checkbox / Tag / Link / ButtonIcon in cells). A\n// TanStack-backed `DataTable` (sorting/selection logic over these primitives) is\n// a planned follow-up, mirroring legacy's separate `data-table`. Reconcile with\n// `/figma-component Table <url> --update` once the design is ready for dev.\n\nconst Table = React.forwardRef<\n HTMLTableElement,\n React.HTMLAttributes<HTMLTableElement>\n>(({ className, ...props }, ref) => (\n <div className=\"relative w-full overflow-auto\">\n <table\n ref={ref}\n className={cn(\n 'w-full caption-bottom border-collapse text-sm text-[var(--ui-table-data-value-color-idle)]',\n className\n )}\n {...props}\n />\n </div>\n));\nTable.displayName = 'Table';\n\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead ref={ref} className={cn(className)} {...props} />\n));\nTableHeader.displayName = 'TableHeader';\n\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn('[&_tr:last-child]:border-0', className)}\n {...props}\n />\n));\nTableBody.displayName = 'TableBody';\n\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-[color:var(--ui-table-global-cell-border-color)] font-medium [&>tr]:last:border-b-0',\n className\n )}\n {...props}\n />\n));\nTableFooter.displayName = 'TableFooter';\n\nexport interface TableRowProps\n extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Mark the row as selected — applies the active row token + `data-state`. */\n selected?: boolean;\n}\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, selected, ...props }, ref) => (\n <tr\n ref={ref}\n data-state={selected ? 'selected' : undefined}\n className={cn(\n 'border-b border-[color:var(--ui-table-global-cell-border-color)] bg-[var(--ui-table-global-row-color-idle)] transition-colors hover:bg-[var(--ui-table-global-row-color-hover)] data-[state=selected]:bg-[var(--ui-table-global-row-color-active)]',\n className\n )}\n {...props}\n />\n )\n);\nTableRow.displayName = 'TableRow';\n\ntype SortDirection = 'asc' | 'desc' | false;\n\nexport interface TableHeadProps\n extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Render the column as sortable — adds a sort affordance and `aria-sort`. */\n sortable?: boolean;\n /** Current sort direction for this column (`false` = sortable but unsorted). */\n sortDirection?: SortDirection;\n /** Invoked when the user activates a sortable header (click / Enter / Space). */\n onSort?: () => void;\n /**\n * Allow the header to wrap onto multiple lines (`whitespace-normal`) and drop\n * the fixed row height so the cell grows to fit its content.\n */\n wrap?: boolean;\n}\n\nfunction SortIcon({ direction }: { direction: SortDirection }) {\n const size = 'size-[var(--ui-table-header-sort-icon-size)]';\n if (direction === 'asc') {\n return <ArrowUpIcon className={cn(size, 'text-[var(--ui-table-header-sort-icon-color-active)]')} />;\n }\n if (direction === 'desc') {\n return <ArrowDownIcon className={cn(size, 'text-[var(--ui-table-header-sort-icon-color-active)]')} />;\n }\n return <ArrowsDownUpIcon className={cn(size, 'text-[var(--ui-table-header-sort-icon-color-inactive)]')} />;\n}\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n (\n {\n className,\n children,\n sortable,\n sortDirection = false,\n onSort,\n wrap,\n ...props\n },\n ref\n ) => (\n <th\n ref={ref}\n aria-sort={\n sortDirection === 'asc'\n ? 'ascending'\n : sortDirection === 'desc'\n ? 'descending'\n : sortable\n ? 'none'\n : undefined\n }\n className={cn(\n 'px-[var(--ui-table-header-cell-padding-x)] text-start align-middle text-sm font-semibold text-[var(--ui-table-header-label-color)] [&:has([role=checkbox])]:pe-0',\n wrap ? 'whitespace-normal' : 'h-10',\n className\n )}\n {...props}\n >\n {sortable ? (\n <button\n type=\"button\"\n onClick={onSort}\n className=\"-mx-1 inline-flex cursor-pointer items-center gap-[var(--ui-table-header-gap)] rounded-sm px-1 outline-none transition-colors hover:bg-[var(--ui-table-header-cell-color-hover)] focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)]\"\n >\n {children}\n <SortIcon direction={sortDirection} />\n </button>\n ) : (\n children\n )}\n </th>\n )\n);\nTableHead.displayName = 'TableHead';\n\nexport interface TableCellProps\n extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /**\n * Allow the cell to wrap onto multiple lines (`whitespace-normal`) and drop\n * the fixed row height so the row grows to fit its content.\n */\n wrap?: boolean;\n}\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, wrap, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n 'px-[var(--ui-table-global-cell-padding-x)] py-[var(--ui-table-global-cell-padding-y)] align-middle text-sm [&:has([role=checkbox])]:pe-0',\n wrap ? 'whitespace-normal' : 'h-10',\n className\n )}\n {...props}\n />\n )\n);\nTableCell.displayName = 'TableCell';\n\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn('mt-4 text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nTableCaption.displayName = 'TableCaption';\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n"],"names":["Table","React","className","props","ref","jsx","cn","TableHeader","TableBody","TableFooter","TableRow","selected","SortIcon","direction","size","ArrowUpIcon","ArrowDownIcon","ArrowsDownUpIcon","TableHead","children","sortable","sortDirection","onSort","wrap","jsxs","TableCell","TableCaption"],"mappings":"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"}
1
+ {"version":3,"file":"table.js","sources":["../../../../src/components/ui/table/table.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n ArrowDownIcon,\n ArrowUpIcon,\n ArrowsDownUpIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\n// Composable table primitives ported from `@acronis-platform/shadcn-uikit`'s\n// `table` (packages/ui-legacy/src/components/ui/table.tsx) and informed by the\n// \"pre-release\" Table design in the shadcn-uikit Figma (node 2948-2416). Unlike\n// Card/Dialog, a `--ui-table-*` token tier already exists, so these parts theme\n// directly from it (imported in styles/index.css):\n// • cell -> --ui-table-global-cell-{padding-x,padding-y,min-height}\n// • row -> --ui-table-global-row-border-color, --ui-table-data-row-color-{idle,hover,active} (active = selected)\n// • header -> --ui-table-header-{label-color,cell-color-hover,gap}\n// • sort -> --ui-table-header-sort-icon-{color-active,color-inactive,size}\n// • data -> --ui-table-data-value-color-{idle,disabled}\n// The design's row checkboxes, tags, links and the column-settings button are\n// consumer composition (use Checkbox / Tag / Link / ButtonIcon in cells). A\n// TanStack-backed `DataTable` (sorting/selection logic over these primitives) is\n// a planned follow-up, mirroring legacy's separate `data-table`. Reconcile with\n// `/figma-component Table <url> --update` once the design is ready for dev.\n\nconst Table = React.forwardRef<\n HTMLTableElement,\n React.HTMLAttributes<HTMLTableElement>\n>(({ className, ...props }, ref) => (\n <div className=\"relative w-full overflow-auto\">\n <table\n ref={ref}\n className={cn(\n 'w-full caption-bottom border-collapse text-sm text-[var(--ui-table-data-value-color-idle)]',\n className\n )}\n {...props}\n />\n </div>\n));\nTable.displayName = 'Table';\n\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead ref={ref} className={cn(className)} {...props} />\n));\nTableHeader.displayName = 'TableHeader';\n\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn('[&_tr:last-child]:border-0', className)}\n {...props}\n />\n));\nTableBody.displayName = 'TableBody';\n\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n 'border-t border-[color:var(--ui-table-global-row-border-color)] font-medium [&>tr]:last:border-b-0',\n className\n )}\n {...props}\n />\n));\nTableFooter.displayName = 'TableFooter';\n\nexport interface TableRowProps\n extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Mark the row as selected — applies the active row token + `data-state`. */\n selected?: boolean;\n}\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, selected, ...props }, ref) => (\n <tr\n ref={ref}\n data-state={selected ? 'selected' : undefined}\n className={cn(\n 'border-b border-[color:var(--ui-table-global-row-border-color)] bg-[var(--ui-table-data-row-color-idle)] transition-colors hover:bg-[var(--ui-table-data-row-color-hover)] data-[state=selected]:bg-[var(--ui-table-data-row-color-active)]',\n className\n )}\n {...props}\n />\n )\n);\nTableRow.displayName = 'TableRow';\n\ntype SortDirection = 'asc' | 'desc' | false;\n\nexport interface TableHeadProps\n extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Render the column as sortable — adds a sort affordance and `aria-sort`. */\n sortable?: boolean;\n /** Current sort direction for this column (`false` = sortable but unsorted). */\n sortDirection?: SortDirection;\n /** Invoked when the user activates a sortable header (click / Enter / Space). */\n onSort?: () => void;\n /**\n * Allow the header to wrap onto multiple lines (`whitespace-normal`) and drop\n * the fixed row height so the cell grows to fit its content.\n */\n wrap?: boolean;\n}\n\nfunction SortIcon({ direction }: { direction: SortDirection }) {\n const size = 'size-[var(--ui-table-header-sort-icon-size)]';\n if (direction === 'asc') {\n return <ArrowUpIcon className={cn(size, 'text-[var(--ui-table-header-sort-icon-color-active)]')} />;\n }\n if (direction === 'desc') {\n return <ArrowDownIcon className={cn(size, 'text-[var(--ui-table-header-sort-icon-color-active)]')} />;\n }\n return <ArrowsDownUpIcon className={cn(size, 'text-[var(--ui-table-header-sort-icon-color-inactive)]')} />;\n}\n\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n (\n {\n className,\n children,\n sortable,\n sortDirection = false,\n onSort,\n wrap,\n ...props\n },\n ref\n ) => (\n <th\n ref={ref}\n aria-sort={\n sortDirection === 'asc'\n ? 'ascending'\n : sortDirection === 'desc'\n ? 'descending'\n : sortable\n ? 'none'\n : undefined\n }\n className={cn(\n 'px-[var(--ui-table-global-cell-padding-x)] text-start align-middle text-sm font-semibold text-[var(--ui-table-header-label-color)] [&:has([role=checkbox])]:pe-0',\n wrap ? 'whitespace-normal' : 'h-10',\n className\n )}\n {...props}\n >\n {sortable ? (\n <button\n type=\"button\"\n onClick={onSort}\n className=\"-mx-1 inline-flex cursor-pointer items-center gap-[var(--ui-table-header-gap)] rounded-sm px-1 outline-none transition-colors hover:bg-[var(--ui-table-header-cell-color-hover)] focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)]\"\n >\n {children}\n <SortIcon direction={sortDirection} />\n </button>\n ) : (\n children\n )}\n </th>\n )\n);\nTableHead.displayName = 'TableHead';\n\nexport interface TableCellProps\n extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /**\n * Allow the cell to wrap onto multiple lines (`whitespace-normal`) and drop\n * the fixed row height so the row grows to fit its content.\n */\n wrap?: boolean;\n}\n\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, wrap, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n 'px-[var(--ui-table-global-cell-padding-x)] py-[var(--ui-table-global-cell-padding-y)] align-middle text-sm [&:has([role=checkbox])]:pe-0',\n wrap ? 'whitespace-normal' : 'h-10',\n className\n )}\n {...props}\n />\n )\n);\nTableCell.displayName = 'TableCell';\n\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn('mt-4 text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nTableCaption.displayName = 'TableCaption';\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};\n"],"names":["Table","React","className","props","ref","jsx","cn","TableHeader","TableBody","TableFooter","TableRow","selected","SortIcon","direction","size","ArrowUpIcon","ArrowDownIcon","ArrowsDownUpIcon","TableHead","children","sortable","sortDirection","onSort","wrap","jsxs","TableCell","TableCaption"],"mappings":"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"}
@@ -0,0 +1,214 @@
1
+ import { jsx as a, jsxs as R } from "react/jsx-runtime";
2
+ import * as l from "react";
3
+ import { Toolbar as v } from "@base-ui/react/toolbar";
4
+ import { cn as T } from "../../../lib/utils.js";
5
+ import { Button as x } from "../button/button.js";
6
+ import { DropdownMenu as F, DropdownMenuTrigger as L, DropdownMenuContent as _, DropdownMenuItem as I } from "../dropdown-menu/dropdown-menu.js";
7
+ import { ButtonMenu as A } from "../button-menu/button-menu.js";
8
+ const j = l.forwardRef(
9
+ ({ className: r, ...t }, n) => /* @__PURE__ */ a(
10
+ "fieldset",
11
+ {
12
+ ref: n,
13
+ className: T(
14
+ "m-0 flex min-w-0 items-center gap-4 border-0 p-0",
15
+ r
16
+ ),
17
+ ...t
18
+ }
19
+ )
20
+ );
21
+ j.displayName = "Toolbar";
22
+ const P = l.forwardRef(
23
+ ({ className: r, ...t }, n) => /* @__PURE__ */ a(
24
+ "div",
25
+ {
26
+ ref: n,
27
+ className: T(
28
+ "flex grow shrink-0 items-center justify-end gap-2 whitespace-nowrap",
29
+ r
30
+ ),
31
+ ...t
32
+ }
33
+ )
34
+ );
35
+ P.displayName = "ToolbarActions";
36
+ const M = 16;
37
+ function X(r, t, n, m) {
38
+ const d = r.length;
39
+ if (d === 0) return 0;
40
+ if (r.reduce((c, h) => c + h, 0) + n * (d - 1) <= m) return d;
41
+ let o = t, s = 0;
42
+ for (let c = 0; c < d; c++) {
43
+ const h = o + r[c] + n;
44
+ if (h > m) break;
45
+ o = h, s++;
46
+ }
47
+ return s;
48
+ }
49
+ function G(r) {
50
+ const t = Array.from(r.childNodes).filter(
51
+ (o) => {
52
+ var s;
53
+ return o.nodeType === Node.ELEMENT_NODE || o.nodeType === Node.TEXT_NODE && !!((s = o.textContent) != null && s.trim());
54
+ }
55
+ );
56
+ if (t.length === 0) return r.getBoundingClientRect().width;
57
+ const n = getComputedStyle(r), m = parseFloat(n.columnGap) || 0, d = (parseFloat(n.paddingLeft) || 0) + (parseFloat(n.paddingRight) || 0) + (parseFloat(n.borderLeftWidth) || 0) + (parseFloat(n.borderRightWidth) || 0);
58
+ return t.map((o) => {
59
+ if (o.nodeType === Node.TEXT_NODE) {
60
+ const s = document.createRange();
61
+ return s.selectNodeContents(o), s.getBoundingClientRect().width;
62
+ }
63
+ return o.getBoundingClientRect().width;
64
+ }).reduce((o, s) => o + s, 0) + m * (t.length - 1) + d;
65
+ }
66
+ function V(...r) {
67
+ return (t) => {
68
+ for (const n of r)
69
+ n && (typeof n == "function" ? n(t) : n.current = t);
70
+ };
71
+ }
72
+ const z = l.forwardRef(
73
+ ({ className: r, actions: t, moreActionsLabel: n = "More actions", ...m }, d) => {
74
+ const u = l.useRef(null), o = l.useRef(
75
+ /* @__PURE__ */ new Map()
76
+ ), s = l.useRef(null), [c, h] = l.useState(t.length), [k, C] = l.useState(!1), [g, B] = l.useState(!1);
77
+ l.useEffect(() => {
78
+ var p;
79
+ const e = (p = u.current) == null ? void 0 : p.closest("fieldset");
80
+ if (!e) return;
81
+ const i = () => B(e.disabled);
82
+ i();
83
+ const f = new MutationObserver(i);
84
+ return f.observe(e, {
85
+ attributes: !0,
86
+ attributeFilter: ["disabled"]
87
+ }), () => f.disconnect();
88
+ }, []), l.useEffect(() => {
89
+ g && C(!1);
90
+ }, [g]);
91
+ const y = l.useCallback(() => {
92
+ var E;
93
+ const e = u.current, i = e == null ? void 0 : e.parentElement;
94
+ if (!e || !i) return;
95
+ const f = Array.from(i.children).filter((b) => b !== e).reduce((b, w) => b + G(w), 0), p = Math.max(i.children.length - 1, 0), O = i.clientWidth - f - M * p, S = t.map(
96
+ (b) => {
97
+ var w;
98
+ return ((w = o.current.get(b.key)) == null ? void 0 : w.getBoundingClientRect().width) ?? 0;
99
+ }
100
+ ), W = ((E = s.current) == null ? void 0 : E.getBoundingClientRect().width) ?? 0;
101
+ h(
102
+ X(
103
+ S,
104
+ W,
105
+ M,
106
+ O
107
+ )
108
+ );
109
+ }, [t]);
110
+ l.useLayoutEffect(() => {
111
+ var f;
112
+ y();
113
+ const e = (f = u.current) == null ? void 0 : f.parentElement;
114
+ if (!e) return;
115
+ const i = new ResizeObserver(y);
116
+ return i.observe(e), Array.from(e.children).forEach((p) => {
117
+ p !== u.current && i.observe(p);
118
+ }), () => i.disconnect();
119
+ }, [y, t]);
120
+ const D = t.slice(0, c), N = t.slice(c);
121
+ return /* @__PURE__ */ R(
122
+ v.Root,
123
+ {
124
+ ref: V(u, d),
125
+ className: T(
126
+ // `overflow-hidden` clips the invisible measurement clone below —
127
+ // it's `position: absolute` + `visibility: hidden`, which keeps
128
+ // contributing to this element's scrollable overflow (and thus a
129
+ // real horizontal scrollbar on a narrow container/page) unless
130
+ // something in the ancestor chain clips it. Visible content is
131
+ // already sized to fit `availableWidth` by the collapse math, so
132
+ // clipping never affects anything actually shown.
133
+ "relative flex min-w-0 flex-nowrap items-center gap-4 overflow-hidden",
134
+ r
135
+ ),
136
+ ...m,
137
+ children: [
138
+ D.map((e) => /* @__PURE__ */ a(
139
+ v.Button,
140
+ {
141
+ disabled: e.disabled,
142
+ focusableWhenDisabled: !e.disabled,
143
+ onClick: e.onSelect,
144
+ render: /* @__PURE__ */ a(x, { variant: "ghost", children: e.label })
145
+ },
146
+ e.key
147
+ )),
148
+ N.length > 0 && /* @__PURE__ */ R(
149
+ F,
150
+ {
151
+ open: k,
152
+ onOpenChange: C,
153
+ disabled: g,
154
+ children: [
155
+ /* @__PURE__ */ a(
156
+ v.Button,
157
+ {
158
+ render: /* @__PURE__ */ a(
159
+ L,
160
+ {
161
+ render: /* @__PURE__ */ a(A, { variant: "secondary", children: n })
162
+ }
163
+ )
164
+ }
165
+ ),
166
+ /* @__PURE__ */ a(_, { align: "start", children: N.map((e) => /* @__PURE__ */ a(
167
+ I,
168
+ {
169
+ disabled: e.disabled || g,
170
+ onClick: e.onSelect,
171
+ children: e.label
172
+ },
173
+ e.key
174
+ )) })
175
+ ]
176
+ }
177
+ ),
178
+ /* @__PURE__ */ R(
179
+ "div",
180
+ {
181
+ "aria-hidden": !0,
182
+ inert: !0,
183
+ className: "pointer-events-none invisible absolute start-0 top-0 flex items-center gap-4",
184
+ children: [
185
+ t.map((e) => /* @__PURE__ */ a(
186
+ x,
187
+ {
188
+ ref: (i) => {
189
+ o.current.set(e.key, i);
190
+ },
191
+ variant: "ghost",
192
+ tabIndex: -1,
193
+ children: e.label
194
+ },
195
+ e.key
196
+ )),
197
+ /* @__PURE__ */ a(A, { ref: s, variant: "secondary", tabIndex: -1, children: n })
198
+ ]
199
+ }
200
+ )
201
+ ]
202
+ }
203
+ );
204
+ }
205
+ );
206
+ z.displayName = "ToolbarActionList";
207
+ export {
208
+ j as Toolbar,
209
+ z as ToolbarActionList,
210
+ P as ToolbarActions,
211
+ X as computeVisibleActionCount,
212
+ G as measureNaturalWidth
213
+ };
214
+ //# sourceMappingURL=toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolbar.js","sources":["../../../../src/components/ui/toolbar/toolbar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Toolbar as ToolbarPrimitive } from '@base-ui/react/toolbar';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '../button';\nimport { ButtonMenu } from '../button-menu';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../dropdown-menu';\n\n// Mirrors the Figma \"Toolbar\" component (node 3897:7199): a horizontal action\n// row — list actions, an optional overflow control (e.g. a `ButtonMenu`), and\n// an optional trailing area (`ToolbarActions`: a status text or a selection\n// counter + action) — typically shown above/below a list or table when rows\n// are selected or bulk actions are available. Every action is an existing\n// `Button`/`ButtonMenu` instance in Figma, so this component only lays them\n// out and carries no dedicated `--ui-toolbar-*` token tier; the 16px\n// inter-item gap is the Figma `gap/gap-16` semantic token, left un-tokenized —\n// same precedent as `FilterSearch`'s identical gap.\n//\n// The Figma `state: active | disabled` variant is the native `disabled`\n// attribute here: the root renders as a `<fieldset>` (reset to look like a\n// flex row) so every nested `Button`/`ButtonMenu` disables via the platform's\n// own fieldset-disables-descendants behavior — no prop-drilling into\n// arbitrary children required.\n//\n// `min-w-0` is required, not cosmetic: browsers give `<fieldset>` an\n// intrinsic `min-width: min-content` that Tailwind's reset doesn't touch, so\n// without it the fieldset refuses to shrink below its content's natural\n// width. `ToolbarActionList`'s collapse math reads this fieldset's own\n// `clientWidth` as \"available space\" — without `min-w-0` the fieldset\n// balloons to fit every action before that measurement ever runs, so it\n// always measures \"everything fits\" and the row never collapses.\n\nexport type ToolbarProps = React.ComponentPropsWithoutRef<'fieldset'>;\n\nconst Toolbar = React.forwardRef<HTMLFieldSetElement, ToolbarProps>(\n ({ className, ...props }, ref) => (\n <fieldset\n ref={ref}\n className={cn(\n 'm-0 flex min-w-0 items-center gap-4 border-0 p-0',\n className\n )}\n {...props}\n />\n )\n);\nToolbar.displayName = 'Toolbar';\n\n// Trailing, right-aligned area — a status text (e.g. \"25 of 1250 items\n// loaded\") or a selection counter + action (e.g. \"6 items selected: Deselect\").\n// 8px inter-child gap matches the Figma Counter part's own gap. `whitespace-nowrap`\n// is required, not cosmetic: the Figma \"Counter\" part is always single-line, but a\n// plain-text child (e.g. a `<span>`) defaults to `white-space: normal` — without\n// this, the text wraps mid-phrase once the row shrinks below its content's natural\n// width (`white-space` is inherited, so it cascades to children without them\n// needing their own override).\n//\n// `grow shrink-0` (not `flex-1`, which also shrinks): this area must grow to fill\n// leftover space so `justify-end` can right-align it, but must never shrink below\n// its own content's natural width. `ToolbarActionList`'s auto-collapse math reads\n// this element's *rendered* width as the space it needs to reserve — if it could\n// shrink, that measurement would be a moving target (less room reserved than the\n// content actually needs), so the actions row would under-collapse and this area's\n// (nowrap, unshrinkable) content would overflow past its own box instead.\nexport type ToolbarActionsProps = React.ComponentPropsWithoutRef<'div'>;\n\nconst ToolbarActions = React.forwardRef<HTMLDivElement, ToolbarActionsProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex grow shrink-0 items-center justify-end gap-2 whitespace-nowrap',\n className\n )}\n {...props}\n />\n )\n);\nToolbarActions.displayName = 'ToolbarActions';\n\n// Matches the `gap-4` utility used on both this component's row and\n// Toolbar's own root — keep in sync if either class changes.\nconst ACTION_LIST_GAP_PX = 16;\n\n// Pure so the collapse math is unit-testable without mocking layout/ResizeObserver.\n// Greedily fits as many leading items as possible into `availableWidth`; the\n// instant not everything fits, reserves `moreWidth` (+ one gap) for the\n// overflow trigger before fitting items.\nexport function computeVisibleActionCount(\n itemWidths: number[],\n moreWidth: number,\n gap: number,\n availableWidth: number\n): number {\n const total = itemWidths.length;\n if (total === 0) return 0;\n\n const fullWidth =\n itemWidths.reduce((sum, width) => sum + width, 0) + gap * (total - 1);\n if (fullWidth <= availableWidth) return total;\n\n let used = moreWidth;\n let count = 0;\n for (let i = 0; i < total; i++) {\n const next = used + itemWidths[i] + gap;\n if (next > availableWidth) break;\n used = next;\n count++;\n }\n return count;\n}\n\n// A grown sibling's own `getBoundingClientRect()` reflects its flex-grown\n// box, not the space its content actually needs — reading that would make\n// `measure()`'s \"available space\" calculation self-referential (see below),\n// so this reads the sibling's *content nodes* instead: normal (non-growing)\n// flex children report their natural width regardless of how large the\n// parent's box has grown to fill leftover row space. Bare text (e.g.\n// `<ToolbarActions>25 selected</ToolbarActions>` with no wrapping element)\n// renders as a `Text` node rather than an `Element`, so `children` alone\n// would miss it and fall through to the self-referential branch this\n// function exists to avoid — a `Range` measures that text's own rendered\n// width the same way `getBoundingClientRect()` does for an element.\n//\n// The sibling's own padding/border don't grow with flex-grow (only the free\n// space between content and box edge does), so they're safe to add back on\n// top of the content sum — unlike the box's own `getBoundingClientRect()`,\n// which is self-referential.\n//\n// Exported (like `computeVisibleActionCount`) so this is unit-testable\n// without mocking layout/ResizeObserver.\nexport function measureNaturalWidth(el: Element): number {\n const nodes = Array.from(el.childNodes).filter(\n (node): node is ChildNode =>\n node.nodeType === Node.ELEMENT_NODE ||\n (node.nodeType === Node.TEXT_NODE && !!node.textContent?.trim())\n );\n if (nodes.length === 0) return el.getBoundingClientRect().width;\n\n const style = getComputedStyle(el);\n const gap = parseFloat(style.columnGap) || 0;\n const ownPaddingAndBorder =\n (parseFloat(style.paddingLeft) || 0) +\n (parseFloat(style.paddingRight) || 0) +\n (parseFloat(style.borderLeftWidth) || 0) +\n (parseFloat(style.borderRightWidth) || 0);\n const widths = nodes.map((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const range = document.createRange();\n range.selectNodeContents(node);\n return range.getBoundingClientRect().width;\n }\n return (node as Element).getBoundingClientRect().width;\n });\n\n return (\n widths.reduce((sum, width) => sum + width, 0) +\n gap * (nodes.length - 1) +\n ownPaddingAndBorder\n );\n}\n\nfunction mergeRefs<T>(\n ...refs: Array<React.Ref<T> | undefined>\n): React.RefCallback<T> {\n return (node) => {\n for (const ref of refs) {\n if (!ref) continue;\n if (typeof ref === 'function') ref(node);\n else (ref as React.RefObject<T | null>).current = node;\n }\n };\n}\n\nexport interface ToolbarActionListItem {\n /** Stable identity — used as the React key in both the row and the overflow menu. */\n key: string;\n /** Rendered as the visible ghost Button's label, and the overflow menu item's label. */\n label: React.ReactNode;\n onSelect?: () => void;\n disabled?: boolean;\n}\n\nexport interface ToolbarActionListProps\n extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {\n /** Ordered list of actions; trailing ones collapse into \"More actions\" first. */\n actions: ToolbarActionListItem[];\n /** Label for the overflow trigger. */\n moreActionsLabel?: React.ReactNode;\n}\n\n// Mirrors the Figma \"ListActions\" part, but drives its `hasMoreActions`\n// overflow menu from measured available width instead of a static boolean —\n// the breakpoints spec (node 6262:28276) requires that \"if there is no space\n// for all Toolbar actions, then last actions must be hidden under More\n// actions.\" Renders every action as a ghost Button until they no longer fit\n// the row, then moves the trailing ones into a ButtonMenu + DropdownMenu\n// (same trigger Figma's `hasMoreActions` variant shows). An invisible clone\n// of every action + the trigger is kept mounted purely to measure natural\n// widths, since a hidden item can't report its own size.\n//\n// The root and each visible action/trigger are Base UI's `Toolbar.Root`/\n// `Toolbar.Button` (`@base-ui/react/toolbar`), giving the row the WAI-ARIA\n// toolbar pattern for free: one Tab stop, arrow-key roving-tabindex between\n// actions and into the overflow trigger. Base UI's `Toolbar.Root` does not\n// forward `enableHomeAndEndKeys` to its underlying composite, so Home/End\n// are not supported here — this is a Base UI limitation, not a choice made\n// in this component. `Toolbar.Button` composes\n// via `render` the same way `DropdownMenuTrigger`/`ButtonMenu` already do\n// below — it merges its own composite/keydown/disabled props onto whatever\n// element you pass. `focusableWhenDisabled={!action.disabled}` opts a\n// disabled action out of Base UI's default APG toolbar treatment (disabled\n// items normally stay focusable via `aria-disabled`, skippable with Tab) so\n// it matches every other disabled `Button` in this library: a real native\n// `disabled` button, unreachable via Tab or arrow keys. This MUST stay\n// conditional on `action.disabled` — `Toolbar.Root` builds its\n// `disabledIndices` list from `focusableWhenDisabled` alone, regardless of\n// the item's actual disabled state, so passing a bare `false` here disables\n// every index and silently breaks arrow-key navigation for the whole row.\n//\n// The invisible measurement clones stay plain `Button`/`ButtonMenu` (not\n// `Toolbar.Button`): registering them too would double-count hidden items in\n// the roving-tabindex list. This is scoped to the action list only —\n// `Toolbar`'s own `<fieldset>` disabled-cascade (see above) is\n// intentionally untouched; Base UI's `Fieldset.Root` strips the native\n// `disabled` attribute in favor of a context other Base UI Field-aware\n// components consume, which `Button`/`ButtonMenu` don't, so it would silently\n// break the \"disabling the toolbar disables every nested control\" guarantee.\nconst ToolbarActionList = React.forwardRef<\n HTMLDivElement,\n ToolbarActionListProps\n>(\n (\n { className, actions, moreActionsLabel = 'More actions', ...props },\n forwardedRef\n ) => {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const itemRefs = React.useRef<Map<string, HTMLButtonElement | null>>(\n new Map()\n );\n const moreRef = React.useRef<HTMLButtonElement>(null);\n const [visibleCount, setVisibleCount] = React.useState(actions.length);\n const [moreMenuOpen, setMoreMenuOpen] = React.useState(false);\n // The overflow menu renders in a portal, outside the ancestor\n // `<fieldset>`'s DOM subtree, so the native disabled-cascade (see\n // `Toolbar` above) never reaches its items. Tracked separately here so a\n // menu already open when the fieldset becomes disabled gets closed, and\n // its items stay disabled even if forced open again (e.g. via a ref).\n const [ancestorDisabled, setAncestorDisabled] = React.useState(false);\n\n React.useEffect(() => {\n const fieldset = containerRef.current?.closest('fieldset');\n if (!fieldset) return;\n const sync = () => setAncestorDisabled(fieldset.disabled);\n sync();\n const observer = new MutationObserver(sync);\n observer.observe(fieldset, {\n attributes: true,\n attributeFilter: ['disabled'],\n });\n return () => observer.disconnect();\n }, []);\n\n React.useEffect(() => {\n if (ancestorDisabled) setMoreMenuOpen(false);\n }, [ancestorDisabled]);\n\n const measure = React.useCallback(() => {\n const container = containerRef.current;\n const parent = container?.parentElement;\n if (!container || !parent) return;\n\n const siblingsWidth = Array.from(parent.children)\n .filter((child) => child !== container)\n .reduce((sum, el) => sum + measureNaturalWidth(el), 0);\n const gapCount = Math.max(parent.children.length - 1, 0);\n const available =\n parent.clientWidth - siblingsWidth - ACTION_LIST_GAP_PX * gapCount;\n\n // Keyed by `action.key`, not index — an index-keyed array would keep\n // stale entries (and a stale length) when `actions` shrinks, since\n // React only nulls out the removed clones' refs without truncating it.\n const itemWidths = actions.map(\n (action) =>\n itemRefs.current.get(action.key)?.getBoundingClientRect().width ?? 0\n );\n const moreWidth = moreRef.current?.getBoundingClientRect().width ?? 0;\n\n setVisibleCount(\n computeVisibleActionCount(\n itemWidths,\n moreWidth,\n ACTION_LIST_GAP_PX,\n available\n )\n );\n }, [actions]);\n\n React.useLayoutEffect(() => {\n measure();\n const parent = containerRef.current?.parentElement;\n if (!parent) return;\n const observer = new ResizeObserver(measure);\n observer.observe(parent);\n // A sibling like `ToolbarActions` is `shrink-0`, so its own border-box\n // grows with its content (e.g. a \"6 items selected\" counter ticking\n // up) even while `parent`'s box stays fixed — a ResizeObserver bound\n // only to `parent` never fires for that case, so `measure()` goes\n // stale and the row silently overflows instead of collapsing further.\n // Observing every sibling directly catches that box-size change too.\n Array.from(parent.children).forEach((sibling) => {\n if (sibling !== containerRef.current) observer.observe(sibling);\n });\n return () => observer.disconnect();\n }, [measure, actions]);\n\n const visibleActions = actions.slice(0, visibleCount);\n const hiddenActions = actions.slice(visibleCount);\n\n return (\n <ToolbarPrimitive.Root\n ref={mergeRefs(containerRef, forwardedRef)}\n className={cn(\n // `overflow-hidden` clips the invisible measurement clone below —\n // it's `position: absolute` + `visibility: hidden`, which keeps\n // contributing to this element's scrollable overflow (and thus a\n // real horizontal scrollbar on a narrow container/page) unless\n // something in the ancestor chain clips it. Visible content is\n // already sized to fit `availableWidth` by the collapse math, so\n // clipping never affects anything actually shown.\n 'relative flex min-w-0 flex-nowrap items-center gap-4 overflow-hidden',\n className\n )}\n {...props}\n >\n {visibleActions.map((action) => (\n <ToolbarPrimitive.Button\n key={action.key}\n disabled={action.disabled}\n focusableWhenDisabled={!action.disabled}\n onClick={action.onSelect}\n render={<Button variant=\"ghost\">{action.label}</Button>}\n />\n ))}\n {hiddenActions.length > 0 && (\n <DropdownMenu\n open={moreMenuOpen}\n onOpenChange={setMoreMenuOpen}\n disabled={ancestorDisabled}\n >\n <ToolbarPrimitive.Button\n render={\n <DropdownMenuTrigger\n render={\n <ButtonMenu variant=\"secondary\">\n {moreActionsLabel}\n </ButtonMenu>\n }\n />\n }\n />\n <DropdownMenuContent align=\"start\">\n {hiddenActions.map((action) => (\n <DropdownMenuItem\n key={action.key}\n disabled={action.disabled || ancestorDisabled}\n onClick={action.onSelect}\n >\n {action.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <div\n aria-hidden\n inert\n className=\"pointer-events-none invisible absolute start-0 top-0 flex items-center gap-4\"\n >\n {actions.map((action) => (\n <Button\n key={action.key}\n ref={(el) => {\n itemRefs.current.set(action.key, el);\n }}\n variant=\"ghost\"\n tabIndex={-1}\n >\n {action.label}\n </Button>\n ))}\n <ButtonMenu ref={moreRef} variant=\"secondary\" tabIndex={-1}>\n {moreActionsLabel}\n </ButtonMenu>\n </div>\n </ToolbarPrimitive.Root>\n );\n }\n);\nToolbarActionList.displayName = 'ToolbarActionList';\n\nexport { Toolbar, ToolbarActions, ToolbarActionList };\n"],"names":["Toolbar","React","className","props","ref","jsx","cn","ToolbarActions","ACTION_LIST_GAP_PX","computeVisibleActionCount","itemWidths","moreWidth","gap","availableWidth","total","sum","width","used","count","i","next","measureNaturalWidth","el","nodes","node","_a","style","ownPaddingAndBorder","range","mergeRefs","refs","ToolbarActionList","actions","moreActionsLabel","forwardedRef","containerRef","itemRefs","moreRef","visibleCount","setVisibleCount","moreMenuOpen","setMoreMenuOpen","ancestorDisabled","setAncestorDisabled","fieldset","sync","observer","measure","container","parent","siblingsWidth","child","gapCount","available","action","sibling","visibleActions","hiddenActions","jsxs","ToolbarPrimitive","Button","DropdownMenu","DropdownMenuTrigger","ButtonMenu","DropdownMenuContent","DropdownMenuItem"],"mappings":"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"}