@keboola/design 11.0.1 → 11.2.0

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 (153) hide show
  1. package/AGENTS.md +16 -1
  2. package/CHANGELOG.md +2138 -0
  3. package/COMPONENT-API.md +40 -1
  4. package/dist/{AIKit-Dre37SJr.js → AIKit-DiS0CVOW.js} +6 -6
  5. package/dist/{AIKit-Dre37SJr.js.map → AIKit-DiS0CVOW.js.map} +1 -1
  6. package/dist/{AlertModal-BUC4Es8o.js → AlertModal-Dp_XuJBW.js} +3 -6
  7. package/dist/{AlertModal-BUC4Es8o.js.map → AlertModal-Dp_XuJBW.js.map} +1 -1
  8. package/dist/{BrandEditor-B8o9zdZO.js → BrandEditor-DyzgfVkl.js} +6 -6
  9. package/dist/{BrandEditor-B8o9zdZO.js.map → BrandEditor-DyzgfVkl.js.map} +1 -1
  10. package/dist/{Breadcrumb-DJp7WwSv.js → Breadcrumb-Frst8MTA.js} +3 -3
  11. package/dist/{Breadcrumb-DJp7WwSv.js.map → Breadcrumb-Frst8MTA.js.map} +1 -1
  12. package/dist/{Button-nzmDNS2q.js → Button-6xBX0nNl.js} +15 -15
  13. package/dist/Button-6xBX0nNl.js.map +1 -0
  14. package/dist/{ClipboardButton-ez5V3fkk.js → ClipboardButton-ClcluT0C.js} +2 -2
  15. package/dist/{ClipboardButton-ez5V3fkk.js.map → ClipboardButton-ClcluT0C.js.map} +1 -1
  16. package/dist/{CodeEditor-BfQJfbhL.js → CodeEditor-DyaN-Ij2.js} +58 -10
  17. package/dist/CodeEditor-DyaN-Ij2.js.map +1 -0
  18. package/dist/{ColorInput-Dx8Dsv7Y.js → ColorInput-B8z4j4Y_.js} +2 -2
  19. package/dist/{ColorInput-Dx8Dsv7Y.js.map → ColorInput-B8z4j4Y_.js.map} +1 -1
  20. package/dist/{ColorModeSwitch-CCqj7tjE.js → ColorModeSwitch-dZFZyqy1.js} +3 -3
  21. package/dist/{ColorModeSwitch-CCqj7tjE.js.map → ColorModeSwitch-dZFZyqy1.js.map} +1 -1
  22. package/dist/{Combobox-c_xBjf0P.js → Combobox-Dgm6Z4ib.js} +9 -5
  23. package/dist/Combobox-Dgm6Z4ib.js.map +1 -0
  24. package/dist/{Command-CQ_bQsJp.js → Command-C0aZfVTq.js} +2 -2
  25. package/dist/{Command-CQ_bQsJp.js.map → Command-C0aZfVTq.js.map} +1 -1
  26. package/dist/{DateInput-CMD3dY-T.js → DateInput-B3UdzRfW.js} +3 -3
  27. package/dist/{DateInput-CMD3dY-T.js.map → DateInput-B3UdzRfW.js.map} +1 -1
  28. package/dist/{DatePicker-BbFbmsGl.js → DatePicker-Dw3DpbUh.js} +2 -2
  29. package/dist/{DatePicker-BbFbmsGl.js.map → DatePicker-Dw3DpbUh.js.map} +1 -1
  30. package/dist/{DateRangeInput-D3BhiKyk.js → DateRangeInput-DTuySEiq.js} +3 -3
  31. package/dist/{DateRangeInput-D3BhiKyk.js.map → DateRangeInput-DTuySEiq.js.map} +1 -1
  32. package/dist/{DateRangePicker-BiUgtt_M.js → DateRangePicker-DCmMHg4s.js} +4 -4
  33. package/dist/{DateRangePicker-BiUgtt_M.js.map → DateRangePicker-DCmMHg4s.js.map} +1 -1
  34. package/dist/{DropdownMenu-B6ZbYvaM.js → DropdownMenu-t90tVw6l.js} +8 -8
  35. package/dist/DropdownMenu-t90tVw6l.js.map +1 -0
  36. package/dist/FieldItem-CAPj9lj3.d.ts +111 -0
  37. package/dist/FieldItem-D-h1NeBo.js +108 -0
  38. package/dist/FieldItem-D-h1NeBo.js.map +1 -0
  39. package/dist/{FileUpload-sXRv7JiY.js → FileUpload-BRv0TaZk.js} +2 -2
  40. package/dist/{FileUpload-sXRv7JiY.js.map → FileUpload-BRv0TaZk.js.map} +1 -1
  41. package/dist/{Form-BDCef6O9.js → Form-DHvcFoEi.js} +18 -78
  42. package/dist/{Form-BDCef6O9.js.map → Form-DHvcFoEi.js.map} +1 -1
  43. package/dist/{FormGroup-S9mPNHKH.js → FormGroup-C41n65cE.js} +7 -7
  44. package/dist/FormGroup-C41n65cE.js.map +1 -0
  45. package/dist/{FullScreenModal-CJa2VkJ2.js → FullScreenModal-Cb3PGgh4.js} +2 -2
  46. package/dist/{FullScreenModal-CJa2VkJ2.js.map → FullScreenModal-Cb3PGgh4.js.map} +1 -1
  47. package/dist/{InputGroup-BJWsI35s.js → InputGroup-CdTq8H7c.js} +2 -2
  48. package/dist/{InputGroup-BJWsI35s.js.map → InputGroup-CdTq8H7c.js.map} +1 -1
  49. package/dist/{MermaidDiagram-BB06gymm.js → MermaidDiagram-ChL3WIQT.js} +2 -2
  50. package/dist/{MermaidDiagram-BB06gymm.js.map → MermaidDiagram-ChL3WIQT.js.map} +1 -1
  51. package/dist/{Modal-BA5Wc3sx.js → Modal-wqG8nJiK.js} +2 -2
  52. package/dist/{Modal-BA5Wc3sx.js.map → Modal-wqG8nJiK.js.map} +1 -1
  53. package/dist/{MultiActionButtonGroup-CiBHxsSk.js → MultiActionButtonGroup-BiIIubiL.js} +2 -2
  54. package/dist/{MultiActionButtonGroup-CiBHxsSk.js.map → MultiActionButtonGroup-BiIIubiL.js.map} +1 -1
  55. package/dist/{Navbar-t16usFZQ.js → Navbar-BfaPeLUL.js} +5 -2
  56. package/dist/Navbar-BfaPeLUL.js.map +1 -0
  57. package/dist/{PageToolbar-0_1OBzaZ.js → PageToolbar-OQg3mPF-.js} +4 -4
  58. package/dist/PageToolbar-OQg3mPF-.js.map +1 -0
  59. package/dist/{Pagination-CM_Rszz-.js → Pagination-Cjfda8KG.js} +2 -2
  60. package/dist/{Pagination-CM_Rszz-.js.map → Pagination-Cjfda8KG.js.map} +1 -1
  61. package/dist/{Popconfirm-BGe1jLov.js → Popconfirm-D7_vfxFd.js} +4 -7
  62. package/dist/{Popconfirm-BGe1jLov.js.map → Popconfirm-D7_vfxFd.js.map} +1 -1
  63. package/dist/{Popover-Ca0V6AD1.js → Popover-CzeHjvrB.js} +6 -13
  64. package/dist/Popover-CzeHjvrB.js.map +1 -0
  65. package/dist/{SearchInput-D2fcOv7E.js → SearchInput-C7dF_Ir-.js} +2 -2
  66. package/dist/{SearchInput-D2fcOv7E.js.map → SearchInput-C7dF_Ir-.js.map} +1 -1
  67. package/dist/{SectionNav--7bw2b6u.js → SectionNav-8NoTOKO8.js} +3 -3
  68. package/dist/{SectionNav--7bw2b6u.js.map → SectionNav-8NoTOKO8.js.map} +1 -1
  69. package/dist/{Select-4YX38G5h.js → Select-Is0VkePH.js} +2 -2
  70. package/dist/{Select-4YX38G5h.js.map → Select-Is0VkePH.js.map} +1 -1
  71. package/dist/{Sheet-BQrX8-h5.js → Sheet-Dw9BDvjI.js} +2 -2
  72. package/dist/{Sheet-BQrX8-h5.js.map → Sheet-Dw9BDvjI.js.map} +1 -1
  73. package/dist/{Sidebar-ROaR_AqC.js → Sidebar-Dcb4rinA.js} +2 -2
  74. package/dist/{Sidebar-ROaR_AqC.js.map → Sidebar-Dcb4rinA.js.map} +1 -1
  75. package/dist/{Slider-Da_3mS5v.js → Slider-BOPfMOMm.js} +2 -2
  76. package/dist/{Slider-Da_3mS5v.js.map → Slider-BOPfMOMm.js.map} +1 -1
  77. package/dist/{Tabs-EAihyqCt.js → Tabs-UMQuDoW8.js} +2 -2
  78. package/dist/{Tabs-EAihyqCt.js.map → Tabs-UMQuDoW8.js.map} +1 -1
  79. package/dist/{TextInput-BGed-V13.js → TextInput-CMuN1WfY.js} +2 -2
  80. package/dist/{TextInput-BGed-V13.js.map → TextInput-CMuN1WfY.js.map} +1 -1
  81. package/dist/{TimePicker-B_NegL-7.js → TimePicker-D9zktB8A.js} +2 -2
  82. package/dist/{TimePicker-B_NegL-7.js.map → TimePicker-D9zktB8A.js.map} +1 -1
  83. package/dist/{ZoomableSvg-DG9PnAm8.js → ZoomableSvg-CZEu6sAq.js} +3 -3
  84. package/dist/{ZoomableSvg-DG9PnAm8.js.map → ZoomableSvg-CZEu6sAq.js.map} +1 -1
  85. package/dist/editors.d.ts +71 -9
  86. package/dist/editors.js +58 -3
  87. package/dist/editors.js.map +1 -1
  88. package/dist/index.d.ts +314 -312
  89. package/dist/index.js +41 -40
  90. package/dist/internal/blocks/AIKit.js +1 -1
  91. package/dist/internal/blocks/BrandEditor.js +1 -1
  92. package/dist/internal/blocks/ClipboardButton.js +1 -1
  93. package/dist/internal/blocks/ColorInput.js +1 -1
  94. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  95. package/dist/internal/blocks/Command.js +1 -1
  96. package/dist/internal/blocks/DateInput.js +1 -1
  97. package/dist/internal/blocks/DateRangeInput.js +1 -1
  98. package/dist/internal/blocks/ExportMenu.js +2 -2
  99. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +56 -0
  100. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js.map +1 -0
  101. package/dist/internal/blocks/Form.js +1 -1
  102. package/dist/internal/blocks/FormGroup.js +1 -1
  103. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  104. package/dist/internal/blocks/MultiCombobox.js +8 -3
  105. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  106. package/dist/internal/blocks/NumberInput.js +1 -1
  107. package/dist/internal/blocks/PageToolbar.js +1 -1
  108. package/dist/internal/blocks/PasswordInput.js +1 -1
  109. package/dist/internal/blocks/SearchInput.js +1 -1
  110. package/dist/internal/blocks/SearchInputWithNavigation.js +2 -2
  111. package/dist/internal/blocks/SectionNav.js +1 -1
  112. package/dist/internal/blocks/SplitButton.js +2 -2
  113. package/dist/internal/blocks/TextInput.js +1 -1
  114. package/dist/internal/blocks/Textarea.js +1 -1
  115. package/dist/internal/blocks/TimeInput.js +2 -2
  116. package/dist/internal/components/AlertModal.js +1 -1
  117. package/dist/internal/components/Breadcrumb.js +1 -1
  118. package/dist/internal/components/Button.js +1 -1
  119. package/dist/internal/components/Combobox.js +1 -1
  120. package/dist/internal/components/DatePicker.js +1 -1
  121. package/dist/internal/components/DateRangePicker.js +1 -1
  122. package/dist/internal/components/DropdownMenu.js +1 -1
  123. package/dist/internal/components/FileUpload.js +1 -1
  124. package/dist/internal/components/FullScreenModal.js +1 -1
  125. package/dist/internal/components/InputGroup.js +1 -1
  126. package/dist/internal/components/Modal.js +1 -1
  127. package/dist/internal/components/Navbar.js +1 -1
  128. package/dist/internal/components/Pagination.js +1 -1
  129. package/dist/internal/components/Popconfirm.js +1 -1
  130. package/dist/internal/components/Popover.js +1 -1
  131. package/dist/internal/components/Select.js +1 -1
  132. package/dist/internal/components/Sheet.js +1 -1
  133. package/dist/internal/components/Sidebar.js +1 -1
  134. package/dist/internal/components/Slider.js +1 -1
  135. package/dist/internal/components/Tabs.js +1 -1
  136. package/dist/internal/components/TimePicker.js +1 -1
  137. package/dist/internal/components/ZoomableSvg.js +1 -1
  138. package/dist/markdown-editor.js +5 -5
  139. package/dist/mermaid.js +1 -1
  140. package/dist/rjsf.d.ts +13 -1
  141. package/dist/rjsf.js +233 -173
  142. package/dist/rjsf.js.map +1 -1
  143. package/dist/styles.css +1 -1
  144. package/package.json +7 -6
  145. package/dist/Button-nzmDNS2q.js.map +0 -1
  146. package/dist/CodeEditor-BfQJfbhL.js.map +0 -1
  147. package/dist/Combobox-c_xBjf0P.js.map +0 -1
  148. package/dist/DropdownMenu-B6ZbYvaM.js.map +0 -1
  149. package/dist/FormGroup-S9mPNHKH.js.map +0 -1
  150. package/dist/Navbar-t16usFZQ.js.map +0 -1
  151. package/dist/PageToolbar-0_1OBzaZ.js.map +0 -1
  152. package/dist/Popover-Ca0V6AD1.js.map +0 -1
  153. package/dist/constants-D6JcsD4_.d.ts +0 -41
@@ -1 +1 @@
1
- {"version":3,"file":"Breadcrumb-DJp7WwSv.js","names":[],"sources":["../src/components/Breadcrumb/BreadcrumbDropdownContext.ts","../src/components/Breadcrumb/BreadcrumbDropdownGroup.tsx","../src/components/Breadcrumb/BreadcrumbDropdownItem.tsx","../src/components/Breadcrumb/BreadcrumbLink.tsx","../src/components/Breadcrumb/BreadcrumbDropdown.tsx","../src/components/Breadcrumb/BreadcrumbEllipsis.tsx","../src/components/Breadcrumb/BreadcrumbItem.tsx","../src/components/Breadcrumb/BreadcrumbList.tsx","../src/components/Breadcrumb/BreadcrumbPage.tsx","../src/components/Breadcrumb/BreadcrumbSeparator.tsx","../src/components/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["import { createContext, isValidElement, useCallback, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nexport type BreadcrumbDropdownContextValue = {\n /** Current (trimmed, lowercased) filter query. Empty string = no filtering. */\n query: string;\n /** An ancestor group's label matched the query — descendants render regardless of their own match. */\n forceVisible: boolean;\n /** Filtering is off (`filter={false}` or `shouldFilter={false}`) — items never self-hide. */\n filterDisabled: boolean;\n /** Report this node's visibility to the parent scope. Returns the unregister cleanup. */\n register: (id: string, visible: boolean) => () => void;\n /** Close the panel (fired by items on select). */\n close: () => void;\n};\n\nexport const BreadcrumbDropdownContext = createContext<BreadcrumbDropdownContextValue | null>(null);\n\nexport const matchesQuery = (text: string, query: string) => text.toLowerCase().includes(query);\n\n/** Text content of a React tree — the default filter text when no `textValue` is given. */\nexport const getNodeText = (node: ReactNode): string => {\n if (typeof node === 'string' || typeof node === 'number') return String(node);\n if (Array.isArray(node)) return node.map(getNodeText).join('');\n if (isValidElement<{ children?: ReactNode }>(node)) return getNodeText(node.props.children);\n return '';\n};\n\nexport const normalizeQuery = (query: string) => query.trim().toLowerCase();\n\n/**\n * Visibility registry for one filtering scope (the panel root, or one group). Items and groups\n * report their visibility here; `anyVisible` drives the group header / empty-state rendering.\n */\nexport const useMatchRegistry = () => {\n const [matches, setMatches] = useState<ReadonlyMap<string, boolean>>(new Map());\n\n const register = useCallback((id: string, visible: boolean) => {\n setMatches((prev) => (prev.get(id) === visible ? prev : new Map(prev).set(id, visible)));\n return () => {\n setMatches((prev) => {\n if (!prev.has(id)) return prev;\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n };\n }, []);\n\n const anyVisible = useMemo(() => [...matches.values()].some(Boolean), [matches]);\n\n return { register, anyVisible };\n};\n","import { Children, use, useEffect, useId, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { ChevronDown, ChevronRight } from '../../icons';\nimport { cn } from '../../utils';\n\nimport {\n BreadcrumbDropdownContext,\n getNodeText,\n matchesQuery,\n useMatchRegistry,\n} from './BreadcrumbDropdownContext';\n\nconst headerClass = cn(\n // layout\n 'tw:flex',\n 'tw:w-full',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:box-border',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:text-left',\n\n // font — single line; wrap the label in `Truncated` (design system) for ellipsis + tooltip\n 'tw:text-sm',\n 'tw:font-medium',\n 'tw:text-foreground',\n 'tw:min-w-0',\n 'tw:overflow-hidden',\n\n // icons\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n);\n\nconst collapsibleHeaderClass = cn(\n 'tw:cursor-pointer',\n 'tw:hover:bg-accent',\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n);\n\ntype BreadcrumbDropdownGroupProps = {\n /** Group header (e.g. bucket name + stage badge). */\n label: ReactNode;\n /**\n * Text the built-in filter matches against. When the group label matches, all its items stay\n * visible. Defaults to the label's rendered text content.\n */\n textValue?: string;\n /** Render the header as a toggle that expands / collapses the group's items. Default `false`. */\n collapsible?: boolean;\n /** Initial expanded state for `collapsible` groups. Default `true`. */\n defaultExpanded?: boolean;\n className?: string;\n children: ReactNode;\n};\n\n/**\n * A labelled group of `Breadcrumb.Dropdown.Item`s (e.g. one bucket with its tables). The group\n * hides itself when neither its label nor any child matches the filter query; an active query\n * force-expands collapsible groups. Non-empty `collapsible` groups toggle their items behind the\n * header with an animated expand / collapse; a `collapsible` group with no items renders a\n * non-interactive, greyed header that can't toggle.\n */\nexport const BreadcrumbDropdownGroup = ({\n label,\n textValue,\n collapsible = false,\n defaultExpanded = true,\n className,\n children,\n}: BreadcrumbDropdownGroupProps) => {\n const parent = use(BreadcrumbDropdownContext);\n if (!parent) {\n throw new Error('Breadcrumb.Dropdown.Group must be rendered inside Breadcrumb.Dropdown');\n }\n const id = useId();\n const { register: registerChild, anyVisible } = useMatchRegistry();\n const [expanded, setExpanded] = useState(defaultExpanded);\n\n const text = textValue ?? getNodeText(label);\n const filtering = !parent.filterDisabled && !!parent.query;\n const labelMatched = filtering && matchesQuery(text, parent.query);\n const visible = !filtering || parent.forceVisible || labelMatched || anyVisible;\n\n useEffect(() => parent.register(id, visible), [parent, id, visible]);\n\n const childContext = useMemo(\n () => ({\n query: parent.query,\n forceVisible: parent.forceVisible || labelMatched,\n filterDisabled: parent.filterDisabled,\n register: registerChild,\n close: parent.close,\n }),\n [parent, labelMatched, registerChild],\n );\n\n // An active query force-expands the group so matches are never hidden behind a collapsed header.\n const isExpanded = !collapsible || expanded || filtering;\n // A collapsible group with no items has nothing to toggle — render a non-interactive header.\n // oxlint-disable-next-line react-x/no-children-count -- emptiness check, no child transformation\n const isEmpty = Children.count(children) === 0;\n\n return (\n <div\n className={cn('tw:flex tw:flex-col', className)}\n style={visible ? undefined : { display: 'none' }}\n >\n {collapsible && isEmpty ? (\n <span\n aria-disabled\n className={cn(\n headerClass,\n 'tw:text-muted-foreground',\n // Fade just the leading chevron lighter than the label text.\n 'tw:[&>svg:first-child]:opacity-50',\n )}\n >\n <ChevronRight />\n {label}\n </span>\n ) : collapsible && !isEmpty ? (\n <button\n type=\"button\"\n aria-expanded={isExpanded}\n className={cn(headerClass, collapsibleHeaderClass)}\n onClick={() => setExpanded((prev) => !prev)}\n >\n {isExpanded ? <ChevronDown /> : <ChevronRight />}\n {label}\n </button>\n ) : (\n <span className={headerClass}>{label}</span>\n )}\n <BreadcrumbDropdownContext value={childContext}>\n {collapsible && !isEmpty ? (\n // Animated expand / collapse via a CSS grid-rows transition (0fr ↔ 1fr). The children stay\n // mounted while collapsed so the filter registry keeps receiving their visibility; `inert`\n // + `aria-hidden` take the collapsed content out of the a11y tree and tab order. An active\n // filter query force-expands (`isExpanded` includes `filtering`).\n <div\n className={cn(\n 'tw:grid tw:transition-[grid-template-rows] tw:duration-200 tw:ease-out',\n 'tw:motion-reduce:transition-none',\n isExpanded ? 'tw:grid-rows-[1fr]' : 'tw:grid-rows-[0fr]',\n )}\n >\n <div\n className=\"tw:overflow-hidden\"\n inert={!isExpanded}\n aria-hidden={isExpanded ? undefined : true}\n >\n <div className=\"tw:flex tw:flex-col tw:pl-6\">{children}</div>\n </div>\n </div>\n ) : (\n <div\n className=\"tw:flex tw:flex-col tw:pl-6\"\n style={isExpanded ? undefined : { display: 'none' }}\n >\n {children}\n </div>\n )}\n </BreadcrumbDropdownContext>\n </div>\n );\n};\n","import { use, useEffect, useId } from 'react';\nimport type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\nimport { BreadcrumbDropdownContext, getNodeText, matchesQuery } from './BreadcrumbDropdownContext';\n\nconst itemClass = cn(\n // layout\n 'tw:flex',\n 'tw:w-full',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:box-border',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:cursor-pointer',\n 'tw:text-left',\n\n // font — single line; wrap the label in `Truncated` (design system) for ellipsis + tooltip\n 'tw:text-sm',\n 'tw:font-normal',\n 'tw:text-foreground',\n 'tw:no-underline',\n 'tw:min-w-0',\n 'tw:overflow-hidden',\n\n // hover / active entity\n 'tw:hover:bg-accent',\n 'tw:data-[active]:bg-accent',\n 'tw:data-[active]:font-medium',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n // icons\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n);\n\ntype BreadcrumbDropdownItemProps = ComponentProps<'button'> & {\n /** Render the consumer's element (typically a router link) instead of a `button`. */\n asChild?: boolean;\n /**\n * Text the built-in filter matches against. Defaults to the item's rendered text content\n * (extracted recursively, so `asChild` links with icons work out of the box).\n */\n textValue?: string;\n /** Marks the currently open entity (highlight + `aria-current`). */\n active?: boolean;\n /** Close the panel when the item is selected. Default `true`. */\n closeOnSelect?: boolean;\n};\n\n/**\n * One selectable entity row inside `Breadcrumb.Dropdown`. Self-hides when it doesn't match the\n * panel's filter query and closes the panel on select. Use `asChild` to render a router link.\n */\nexport const BreadcrumbDropdownItem = ({\n ref,\n asChild = false,\n textValue,\n active = false,\n closeOnSelect = true,\n className,\n children,\n onClick,\n ...props\n}: BreadcrumbDropdownItemProps) => {\n const context = use(BreadcrumbDropdownContext);\n if (!context) {\n throw new Error('Breadcrumb.Dropdown.Item must be rendered inside Breadcrumb.Dropdown');\n }\n const id = useId();\n\n const text = textValue ?? getNodeText(children);\n const visible =\n context.filterDisabled ||\n !context.query ||\n context.forceVisible ||\n matchesQuery(text, context.query);\n\n useEffect(() => context.register(id, visible), [context, id, visible]);\n\n if (!visible) return null;\n\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n ref={ref}\n {...(asChild ? {} : { type: 'button' as const })}\n data-active={active || undefined}\n aria-current={active || undefined}\n className={cn(itemClass, className)}\n onClick={(event) => {\n onClick?.(event);\n if (closeOnSelect && !event.defaultPrevented) {\n context.close();\n }\n }}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'a'> & {\n asChild?: boolean;\n};\n\nexport const BreadcrumbLink = ({ ref, asChild = false, className, ...props }: Props) => {\n const Comp = asChild ? Slot : 'a';\n return (\n <Comp\n ref={ref}\n className={cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-1.5',\n // font\n 'tw:text-muted-foreground',\n 'tw:font-normal',\n 'tw:no-underline',\n\n // hover\n 'tw:hover:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n 'tw:focus-visible:rounded-sm',\n\n // Icon\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n\n // transition\n 'tw:transition-colors',\n className,\n )}\n {...props}\n />\n );\n};\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport type { ComponentRef, ReactNode } from 'react';\n\nimport { SearchInput } from '../../blocks/SearchInput';\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\nimport { Popover } from '../Popover';\n\nimport {\n BreadcrumbDropdownContext,\n normalizeQuery,\n useMatchRegistry,\n} from './BreadcrumbDropdownContext';\nimport { BreadcrumbDropdownGroup } from './BreadcrumbDropdownGroup';\nimport { BreadcrumbDropdownItem } from './BreadcrumbDropdownItem';\nimport { BreadcrumbLink } from './BreadcrumbLink';\n\n// Chevron trigger — the only button in the crumb. It sits tight next to the label so it reads as\n// grouped with it, with no persistent outline: it's a button purely via the hover / open background\n// + colour lift. Used on its own next to a link label (`splitTrigger`) or after a plain label.\nconst chevronButtonClass = cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n // compact square hit target that stays snug against the label\n 'tw:size-5',\n 'tw:text-muted-foreground',\n 'tw:transition-colors',\n 'tw:hover:bg-accent',\n 'tw:hover:text-foreground',\n 'tw:data-[state=open]:bg-accent',\n 'tw:data-[state=open]:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n // chevron rotation while open\n 'tw:[&_svg]:transition-transform',\n 'tw:[&[data-state=open]_svg]:rotate-180',\n);\n\n// Plain (non-link) label — same typography as `BreadcrumbLink` but no hover/focus treatment, since\n// it isn't interactive: only the chevron opens the panel.\nconst plainLabelClass = cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-1.5',\n 'tw:text-muted-foreground',\n 'tw:font-normal',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n);\n\n// Fixed panel width per `size` (default `medium`). Long names truncate rather than wrap or widen\n// the panel. Width still clamps to the viewport via min(); height is clamped the same way.\nconst PANEL_BASE = 'tw:max-h-[min(640px,var(--radix-popover-content-available-height))]';\n\nconst PANEL_WIDTH = {\n small: 'tw:w-[min(360px,var(--radix-popover-content-available-width))]',\n medium: 'tw:w-[min(440px,var(--radix-popover-content-available-width))]',\n large: 'tw:w-[min(560px,var(--radix-popover-content-available-width))]',\n} as const;\n\ntype PanelSize = keyof typeof PANEL_WIDTH;\n\n/**\n * Props for `Breadcrumb.Dropdown`. The panel chrome (trigger typography, popover sizing, pinned\n * filter input) is owned by the component — consumers supply the label and the panel content,\n * composed from `Breadcrumb.Dropdown.Group` / `Breadcrumb.Dropdown.Item`.\n */\ntype BreadcrumbDropdownProps = {\n /**\n * Crumb label, shown next to the chevron button that opens the panel — the label itself is never\n * the trigger. With `splitTrigger`, pass an anchor-like element (e.g. a router link) so the label\n * also navigates; otherwise it renders as a plain, non-navigational crumb label.\n */\n label: ReactNode;\n /**\n * When `true`, the label is a navigable link (pass an anchor-like `label` element, rendered through\n * `Breadcrumb.Link asChild`). Default `false` — the label is plain text. Either way only the\n * chevron button opens the panel; it always sits grouped tight to the label.\n */\n splitTrigger?: boolean;\n /**\n * Accessible name for the chevron trigger button. Defaults to `\"${label} menu\"` when `label` is\n * a plain string, otherwise `\"Open menu\"` — pass explicitly when `label` is a non-string node.\n */\n triggerLabel?: string;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * Fixed panel width: `small` (360px), `medium` (440px, default), or `large` (560px). Names that\n * exceed the width truncate with an ellipsis (hover shows the full name). Clamps to the viewport.\n */\n size?: PanelSize;\n /**\n * Pinned filter input at the top of the panel, focused on open. On by default — items and groups\n * that don't match the query hide themselves (matched against their `textValue` / string\n * content). Set to `false` to opt out of the input entirely.\n */\n filter?: boolean;\n /**\n * Set to `false` to keep the filter input but disable the built-in matching — the consumer\n * filters the content it renders (e.g. server-side or custom matching). Default `true`.\n */\n shouldFilter?: boolean;\n /** Controlled filter value. Omit to let the component manage the query internally. */\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n searchPlaceholder?: string;\n /** Rendered when the built-in filter hides everything. Default `\"No results.\"`. */\n emptyMessage?: ReactNode;\n /** Panel content — `Breadcrumb.Dropdown.Group` / `Breadcrumb.Dropdown.Item` elements. */\n children: ReactNode;\n};\n\n/**\n * Breadcrumb segment that opens a standardized switcher panel — a filterable list / tree of\n * sibling entities the user can jump between (e.g. the Storage bucket/table tree on a table\n * detail page).\n *\n * **When to use:** on the leftmost breadcrumb segment that has siblings / children worth switching\n * between. Use at most one dropdown segment per breadcrumb.\n * **When NOT to use:** for tertiary actions on the breadcrumbs row use the `overflowActions` slot of\n * `PageHeader.Detail`; for a collapsed middle of a long breadcrumb use `Breadcrumb.Ellipsis`.\n * **Composition:** render inside `Breadcrumb.Item` in place of `Breadcrumb.Link`. Compose the panel\n * from `Breadcrumb.Dropdown.Group` and `Breadcrumb.Dropdown.Item` — the built-in filter matches\n * and hides them automatically.\n */\nexport const BreadcrumbDropdown = ({\n label,\n splitTrigger = false,\n triggerLabel,\n open,\n defaultOpen = false,\n onOpenChange,\n size = 'medium',\n filter = true,\n shouldFilter = true,\n searchValue,\n onSearchChange,\n searchPlaceholder = 'Search…',\n emptyMessage = 'No results.',\n children,\n}: BreadcrumbDropdownProps) => {\n const searchRef = useRef<ComponentRef<'input'>>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [internalQuery, setInternalQuery] = useState('');\n const { register, anyVisible } = useMatchRegistry();\n\n const isOpen = open ?? internalOpen;\n const handleOpenChange = useCallback(\n (nextOpen: boolean) => {\n setInternalOpen(nextOpen);\n if (!nextOpen) setInternalQuery('');\n onOpenChange?.(nextOpen);\n },\n [onOpenChange],\n );\n const close = useCallback(() => handleOpenChange(false), [handleOpenChange]);\n\n const effectiveTriggerLabel =\n triggerLabel ?? (typeof label === 'string' ? `${label} menu` : 'Open menu');\n\n const rawQuery = searchValue ?? internalQuery;\n const filterDisabled = !filter || !shouldFilter;\n const query = filterDisabled ? '' : normalizeQuery(rawQuery);\n\n const contextValue = useMemo(\n () => ({ query, forceVisible: false, filterDisabled, register, close }),\n [query, filterDisabled, register, close],\n );\n\n return (\n <Popover open={isOpen} onOpenChange={handleOpenChange}>\n <span className=\"tw:flex tw:items-center tw:gap-0.5\">\n {splitTrigger ? (\n <BreadcrumbLink asChild>{label}</BreadcrumbLink>\n ) : (\n <span className={plainLabelClass}>{label}</span>\n )}\n <Popover.Trigger asChild>\n <button type=\"button\" aria-label={effectiveTriggerLabel} className={chevronButtonClass}>\n <ChevronDown className=\"tw:size-3.5\" />\n </button>\n </Popover.Trigger>\n </span>\n <Popover.Content\n align=\"start\"\n sideOffset={8}\n collisionPadding={16}\n data-size={size}\n className={cn('tw:overflow-hidden tw:p-0', PANEL_BASE, PANEL_WIDTH[size])}\n onOpenAutoFocus={\n filter\n ? (event) => {\n event.preventDefault();\n searchRef.current?.focus();\n }\n : undefined\n }\n >\n {filter && (\n <div className=\"tw:shrink-0 tw:border-0 tw:border-b tw:border-solid tw:border-border tw:p-2\">\n <SearchInput\n ref={searchRef}\n value={rawQuery}\n onValueChange={(value) => {\n setInternalQuery(value);\n onSearchChange?.(value);\n }}\n placeholder={searchPlaceholder}\n allowClear\n // Built-in matching is client-side and cheap — filter on every keystroke. Keep the\n // debounce only when the consumer filters itself (shouldFilter={false}, e.g. server-side).\n disableDebounce={shouldFilter}\n />\n </div>\n )}\n <div className=\"tw:flex tw:flex-1 tw:flex-col tw:overflow-y-auto tw:p-2\">\n <BreadcrumbDropdownContext value={contextValue}>{children}</BreadcrumbDropdownContext>\n {!filterDisabled && !!query && !anyVisible && (\n <span className=\"tw:px-2 tw:py-1.5 tw:text-sm tw:text-muted-foreground\">\n {emptyMessage}\n </span>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n};\n\nBreadcrumbDropdown.Item = BreadcrumbDropdownItem;\nBreadcrumbDropdown.Group = BreadcrumbDropdownGroup;\n","import type { ComponentProps } from 'react';\n\nimport { Ellipsis } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const BreadcrumbEllipsis = ({ ref, className, ...props }: Props) => (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n 'tw:text-muted-foreground',\n 'tw:transition-colors',\n // Match the Breadcrumb.Dropdown chevron trigger: background + colour lift on hover / while the\n // menu is open, so the two interactive breadcrumb affordances read consistently.\n 'tw:hover:bg-accent',\n 'tw:hover:text-foreground',\n 'tw:data-[state=open]:bg-accent',\n 'tw:data-[state=open]:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n 'tw:p-1',\n className,\n )}\n {...props}\n >\n <Ellipsis className=\"tw:size-4\" />\n <span className=\"tw:sr-only\">More</span>\n </button>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const BreadcrumbItem = ({ className, ...props }: Props) => (\n <li className={cn('tw:inline-flex', 'tw:items-center', className)} {...props} />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'ol'>;\n\nexport const BreadcrumbList = ({ className, ...props }: Props) => (\n <ol\n className={cn(\n // layout\n 'tw:flex',\n 'tw:flex-wrap',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:m-0',\n 'tw:p-0',\n\n // font\n 'tw:break-words',\n 'tw:text-sm',\n 'tw:text-muted-foreground',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'span'>;\n\nexport const BreadcrumbPage = ({ ref, className, ...props }: Props) => (\n <span\n ref={ref}\n // Do not use the anchor, as this item is not clickable\n // oxlint-disable-next-line jsx_a11y/prefer-tag-over-role\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('tw:font-medium', 'tw:text-foreground', className)}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const BreadcrumbSeparator = ({ children, className, ...props }: Props) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:aspect-square',\n 'tw:size-[15px]',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-2.5',\n 'tw:text-muted-foreground',\n className,\n )}\n {...props}\n >\n {children ?? <span className=\"tw:select-none tw:text-sm tw:text-muted-foreground/50\">/</span>}\n </li>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { BreadcrumbDropdown } from './BreadcrumbDropdown';\nimport { BreadcrumbEllipsis } from './BreadcrumbEllipsis';\nimport { BreadcrumbItem } from './BreadcrumbItem';\nimport { BreadcrumbLink } from './BreadcrumbLink';\nimport { BreadcrumbList } from './BreadcrumbList';\nimport { BreadcrumbPage } from './BreadcrumbPage';\nimport { BreadcrumbSeparator } from './BreadcrumbSeparator';\n\ntype Props = ComponentProps<'nav'>;\n\nexport const Breadcrumb = ({ className, ...props }: Props) => (\n <nav aria-label=\"breadcrumb\" className={cn('tailwindcss-preflight', className)} {...props} />\n);\n\nBreadcrumb.List = BreadcrumbList;\nBreadcrumb.Item = BreadcrumbItem;\nBreadcrumb.Link = BreadcrumbLink;\nBreadcrumb.Page = BreadcrumbPage;\nBreadcrumb.Separator = BreadcrumbSeparator;\nBreadcrumb.Ellipsis = BreadcrumbEllipsis;\nBreadcrumb.Dropdown = BreadcrumbDropdown;\n"],"mappings":";;;;;;;;AAgBA,MAAa,4BAA4B,cAAqD,IAAI;AAElG,MAAa,gBAAgB,MAAc,UAAkB,KAAK,YAAY,CAAC,CAAC,SAAS,KAAK;;AAG9F,MAAa,eAAe,SAA4B;CACtD,IAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU,OAAO,OAAO,IAAI;CAC5E,IAAI,MAAM,QAAQ,IAAI,GAAG,OAAO,KAAK,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE;CAC7D,IAAI,eAAyC,IAAI,GAAG,OAAO,YAAY,KAAK,MAAM,QAAQ;CAC1F,OAAO;AACT;AAEA,MAAa,kBAAkB,UAAkB,MAAM,KAAK,CAAC,CAAC,YAAY;;;;;AAM1E,MAAa,yBAAyB;CACpC,MAAM,CAAC,SAAS,cAAc,yBAAuC,IAAI,IAAI,CAAC;CAgB9E,OAAO;EAAE,UAdQ,aAAa,IAAY,YAAqB;GAC7D,YAAY,SAAU,KAAK,IAAI,EAAE,MAAM,UAAU,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,CAAE;GACvF,aAAa;IACX,YAAY,SAAS;KACnB,IAAI,CAAC,KAAK,IAAI,EAAE,GAAG,OAAO;KAC1B,MAAM,OAAO,IAAI,IAAI,IAAI;KACzB,KAAK,OAAO,EAAE;KACd,OAAO;IACT,CAAC;GACH;EACF,GAAG,CAAC,CAIY;EAAG,YAFA,cAAc,CAAC,GAAG,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,CAAC,OAAO,CAElD;CAAE;AAChC;;;ACvCA,MAAM,cAAc,GAElB,WACA,aACA,mBACA,YACA,iBAEA,iBACA,kBACA,qBACA,WACA,aACA,gBAGA,cACA,kBACA,sBACA,cACA,sBAGA,8CACA,qBACF;AAEA,MAAM,yBAAyB,GAC7B,qBACA,sBACA,mCACA,2BACA,+BACF;;;;;;;;AAyBA,MAAa,2BAA2B,EACtC,OACA,WACA,cAAc,OACd,kBAAkB,MAClB,WACA,eACkC;CAClC,MAAM,SAAS,IAAI,yBAAyB;CAC5C,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,uEAAuE;CAEzF,MAAM,KAAK,MAAM;CACjB,MAAM,EAAE,UAAU,eAAe,eAAe,iBAAiB;CACjE,MAAM,CAAC,UAAU,eAAe,SAAS,eAAe;CAExD,MAAM,OAAO,aAAa,YAAY,KAAK;CAC3C,MAAM,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC,OAAO;CACrD,MAAM,eAAe,aAAa,aAAa,MAAM,OAAO,KAAK;CACjE,MAAM,UAAU,CAAC,aAAa,OAAO,gBAAgB,gBAAgB;CAErE,gBAAgB,OAAO,SAAS,IAAI,OAAO,GAAG;EAAC;EAAQ;EAAI;CAAO,CAAC;CAEnE,MAAM,eAAe,eACZ;EACL,OAAO,OAAO;EACd,cAAc,OAAO,gBAAgB;EACrC,gBAAgB,OAAO;EACvB,UAAU;EACV,OAAO,OAAO;CAChB,IACA;EAAC;EAAQ;EAAc;CAAa,CACtC;CAGA,MAAM,aAAa,CAAC,eAAe,YAAY;CAG/C,MAAM,UAAU,SAAS,MAAM,QAAQ,MAAM;CAE7C,OACE,qBAAC,OAAD;EACE,WAAW,GAAG,uBAAuB,SAAS;EAC9C,OAAO,UAAU,KAAA,IAAY,EAAE,SAAS,OAAO;EAFjD,UAAA,CAIG,eAAe,UACd,qBAAC,QAAD;GACE,iBAAA;GACA,WAAW,GACT,aACA,4BAEA,mCACF;GAPF,UAAA,CASE,oBAAC,cAAD,CAAe,CAAA,GACd,KACG;EACJ,CAAA,IAAA,eAAe,CAAC,UAClB,qBAAC,UAAD;GACE,MAAK;GACL,iBAAe;GACf,WAAW,GAAG,aAAa,sBAAsB;GACjD,eAAe,aAAa,SAAS,CAAC,IAAI;GAJ5C,UAAA,CAMG,aAAa,oBAAC,aAAD,CAAc,CAAA,IAAI,oBAAC,cAAD,CAAe,CAAA,GAC9C,KACK;EAER,CAAA,IAAA,oBAAC,QAAD;GAAM,WAAW;GAAc,UAAA;EAAY,CAAA,GAE7C,oBAAC,2BAAD;GAA2B,OAAO;GAC/B,UAAA,eAAe,CAAC,UAKf,oBAAC,OAAD;IACE,WAAW,GACT,0EACA,oCACA,aAAa,uBAAuB,oBACtC;IAEA,UAAA,oBAAC,OAAD;KACE,WAAU;KACV,OAAO,CAAC;KACR,eAAa,aAAa,KAAA,IAAY;KAEtC,UAAA,oBAAC,OAAD;MAAK,WAAU;MAA+B;KAAc,CAAA;IACzD,CAAA;GACF,CAAA,IAEL,oBAAC,OAAD;IACE,WAAU;IACV,OAAO,aAAa,KAAA,IAAY,EAAE,SAAS,OAAO;IAEjD;GACE,CAAA;EAEkB,CAAA,CACxB;;AAET;;;ACtKA,MAAM,YAAY,GAEhB,WACA,aACA,mBACA,YACA,iBAEA,iBACA,kBACA,qBACA,WACA,aACA,qBACA,gBAGA,cACA,kBACA,sBACA,mBACA,cACA,sBAGA,sBACA,8BACA,gCAGA,mCACA,2BACA,iCAGA,8CACA,qBACF;;;;;AAoBA,MAAa,0BAA0B,EACrC,KACA,UAAU,OACV,WACA,SAAS,OACT,gBAAgB,MAChB,WACA,UACA,SACA,GAAG,YAC8B;CACjC,MAAM,UAAU,IAAI,yBAAyB;CAC7C,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,sEAAsE;CAExF,MAAM,KAAK,MAAM;CAEjB,MAAM,OAAO,aAAa,YAAY,QAAQ;CAC9C,MAAM,UACJ,QAAQ,kBACR,CAAC,QAAQ,SACT,QAAQ,gBACR,aAAa,MAAM,QAAQ,KAAK;CAElC,gBAAgB,QAAQ,SAAS,IAAI,OAAO,GAAG;EAAC;EAAS;EAAI;CAAO,CAAC;CAErE,IAAI,CAAC,SAAS,OAAO;CAGrB,OACE,oBAFW,UAAU,OAAO,UAE5B;EACO;EACL,GAAK,UAAU,CAAC,IAAI,EAAE,MAAM,SAAkB;EAC9C,eAAa,UAAU,KAAA;EACvB,gBAAc,UAAU,KAAA;EACxB,WAAW,GAAG,WAAW,SAAS;EAClC,UAAU,UAAU;GAClB,UAAU,KAAK;GACf,IAAI,iBAAiB,CAAC,MAAM,kBAC1B,QAAQ,MAAM;EAElB;EACA,GAAI;EAEH;CACG,CAAA;AAEV;;;ACvGA,MAAa,kBAAkB,EAAE,KAAK,UAAU,OAAO,WAAW,GAAG,YAAmB;CAEtF,OACE,oBAFW,UAAU,OAAO,KAE5B;EACO;EACL,WAAW,GACT,WACA,mBACA,cAEA,4BACA,kBACA,mBAGA,4BAGA,mCACA,2BACA,iCACA,+BAGA,kDAGA,wBACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;;;ACtBA,MAAM,qBAAqB,GAEzB,WACA,mBACA,qBAEA,iBACA,kBACA,qBACA,qBAEA,aACA,4BACA,wBACA,sBACA,4BACA,kCACA,wCAGA,mCACA,2BACA,iCAGA,mCACA,wCACF;AAIA,MAAM,kBAAkB,GACtB,WACA,mBACA,cACA,4BACA,kBACA,gDACF;AAIA,MAAM,aAAa;AAEnB,MAAM,cAAc;CAClB,OAAO;CACP,QAAQ;CACR,OAAO;AACT;;;;;;;;;;;;;;AAqEA,MAAa,sBAAsB,EACjC,OACA,eAAe,OACf,cACA,MACA,cAAc,OACd,cACA,OAAO,UACP,SAAS,MACT,eAAe,MACf,aACA,gBACA,oBAAoB,WACpB,eAAe,eACf,eAC6B;CAC7B,MAAM,YAAY,OAA8B,IAAI;CACpD,MAAM,CAAC,cAAc,mBAAmB,SAAS,WAAW;CAC5D,MAAM,CAAC,eAAe,oBAAoB,SAAS,EAAE;CACrD,MAAM,EAAE,UAAU,eAAe,iBAAiB;CAElD,MAAM,SAAS,QAAQ;CACvB,MAAM,mBAAmB,aACtB,aAAsB;EACrB,gBAAgB,QAAQ;EACxB,IAAI,CAAC,UAAU,iBAAiB,EAAE;EAClC,eAAe,QAAQ;CACzB,GACA,CAAC,YAAY,CACf;CACA,MAAM,QAAQ,kBAAkB,iBAAiB,KAAK,GAAG,CAAC,gBAAgB,CAAC;CAE3E,MAAM,wBACJ,iBAAiB,OAAO,UAAU,WAAW,GAAG,MAAM,SAAS;CAEjE,MAAM,WAAW,eAAe;CAChC,MAAM,iBAAiB,CAAC,UAAU,CAAC;CACnC,MAAM,QAAQ,iBAAiB,KAAK,eAAe,QAAQ;CAE3D,MAAM,eAAe,eACZ;EAAE;EAAO,cAAc;EAAO;EAAgB;EAAU;CAAM,IACrE;EAAC;EAAO;EAAgB;EAAU;CAAK,CACzC;CAEA,OACE,qBAAC,SAAD;EAAS,MAAM;EAAQ,cAAc;EAArC,UAAA,CACE,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACG,eACC,oBAAC,gBAAD;IAAgB,SAAA;IAAS,UAAA;GAAsB,CAAA,IAE/C,oBAAC,QAAD;IAAM,WAAW;IAAkB,UAAA;GAAY,CAAA,GAEjD,oBAAC,QAAQ,SAAT;IAAiB,SAAA;IACf,UAAA,oBAAC,UAAD;KAAQ,MAAK;KAAS,cAAY;KAAuB,WAAW;KAClE,UAAA,oBAAC,aAAD,EAAa,WAAU,cAAe,CAAA;IAChC,CAAA;GACO,CAAA,CACb;EACN,CAAA,GAAA,qBAAC,QAAQ,SAAT;GACE,OAAM;GACN,YAAY;GACZ,kBAAkB;GAClB,aAAW;GACX,WAAW,GAAG,6BAA6B,YAAY,YAAY,KAAK;GACxE,iBACE,UACK,UAAU;IACT,MAAM,eAAe;IACrB,UAAU,SAAS,MAAM;GAC3B,IACA,KAAA;GAZR,UAAA,CAeG,UACC,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,oBAAC,aAAD;KACE,KAAK;KACL,OAAO;KACP,gBAAgB,UAAU;MACxB,iBAAiB,KAAK;MACtB,iBAAiB,KAAK;KACxB;KACA,aAAa;KACb,YAAA;KAGA,iBAAiB;IAClB,CAAA;GACE,CAAA,GAEP,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,2BAAD;KAA2B,OAAO;KAAe;IAAoC,CAAA,GACpF,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,cAC9B,oBAAC,QAAD;KAAM,WAAU;KACb,UAAA;IACG,CAAA,CAEL;GACU,CAAA,CAAA;EACV,CAAA,CAAA;;AAEb;AAEA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;;;AC1O3B,MAAa,sBAAsB,EAAE,KAAK,WAAW,GAAG,YACtD,qBAAC,UAAD;CACO;CACL,MAAK;CACL,WAAW,GAET,WACA,mBACA,qBAEA,iBACA,kBACA,qBACA,qBACA,4BACA,wBAGA,sBACA,4BACA,kCACA,wCAGA,mCACA,2BACA,iCAEA,UACA,SACF;CACA,GAAI;CA9BN,UAAA,CAgCE,oBAAC,UAAD,EAAU,WAAU,YAAa,CAAA,GACjC,oBAAC,QAAD;EAAM,WAAU;EAAa,UAAA;CAAU,CAAA,CACjC;;;;ACpCV,MAAa,kBAAkB,EAAE,WAAW,GAAG,YAC7C,oBAAC,MAAD;CAAI,WAAW,GAAG,kBAAkB,mBAAmB,SAAS;CAAG,GAAI;AAAQ,CAAA;;;ACDjF,MAAa,kBAAkB,EAAE,WAAW,GAAG,YAC7C,oBAAC,MAAD;CACE,WAAW,GAET,WACA,gBACA,mBACA,YACA,UACA,UAGA,kBACA,cACA,4BACA,SACF;CACA,GAAI;AACL,CAAA;;;AClBH,MAAa,kBAAkB,EAAE,KAAK,WAAW,GAAG,YAClD,oBAAC,QAAD;CACO;CAGL,MAAK;CACL,iBAAc;CACd,gBAAa;CACb,WAAW,GAAG,kBAAkB,sBAAsB,SAAS;CAC/D,GAAI;AACL,CAAA;;;ACVH,MAAa,uBAAuB,EAAE,UAAU,WAAW,GAAG,YAC5D,oBAAC,MAAD;CACE,MAAK;CACL,eAAY;CACZ,WAAW,GAET,WACA,mBACA,qBAEA,oBACA,kBACA,kDACA,4BACA,SACF;CACA,GAAI;CAEH,UAAA,YAAY,oBAAC,QAAD;EAAM,WAAU;EAAwD,UAAA;CAAO,CAAA;AAC1F,CAAA;;;ACXN,MAAa,cAAc,EAAE,WAAW,GAAG,YACzC,oBAAC,OAAD;CAAK,cAAW;CAAa,WAAW,GAAG,yBAAyB,SAAS;CAAG,GAAI;AAAQ,CAAA;AAG9F,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,YAAY;AACvB,WAAW,WAAW;AACtB,WAAW,WAAW"}
1
+ {"version":3,"file":"Breadcrumb-Frst8MTA.js","names":[],"sources":["../src/components/Breadcrumb/BreadcrumbDropdownContext.ts","../src/components/Breadcrumb/BreadcrumbDropdownGroup.tsx","../src/components/Breadcrumb/BreadcrumbDropdownItem.tsx","../src/components/Breadcrumb/BreadcrumbLink.tsx","../src/components/Breadcrumb/BreadcrumbDropdown.tsx","../src/components/Breadcrumb/BreadcrumbEllipsis.tsx","../src/components/Breadcrumb/BreadcrumbItem.tsx","../src/components/Breadcrumb/BreadcrumbList.tsx","../src/components/Breadcrumb/BreadcrumbPage.tsx","../src/components/Breadcrumb/BreadcrumbSeparator.tsx","../src/components/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["import { createContext, isValidElement, useCallback, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nexport type BreadcrumbDropdownContextValue = {\n /** Current (trimmed, lowercased) filter query. Empty string = no filtering. */\n query: string;\n /** An ancestor group's label matched the query — descendants render regardless of their own match. */\n forceVisible: boolean;\n /** Filtering is off (`filter={false}` or `shouldFilter={false}`) — items never self-hide. */\n filterDisabled: boolean;\n /** Report this node's visibility to the parent scope. Returns the unregister cleanup. */\n register: (id: string, visible: boolean) => () => void;\n /** Close the panel (fired by items on select). */\n close: () => void;\n};\n\nexport const BreadcrumbDropdownContext = createContext<BreadcrumbDropdownContextValue | null>(null);\n\nexport const matchesQuery = (text: string, query: string) => text.toLowerCase().includes(query);\n\n/** Text content of a React tree — the default filter text when no `textValue` is given. */\nexport const getNodeText = (node: ReactNode): string => {\n if (typeof node === 'string' || typeof node === 'number') return String(node);\n if (Array.isArray(node)) return node.map(getNodeText).join('');\n if (isValidElement<{ children?: ReactNode }>(node)) return getNodeText(node.props.children);\n return '';\n};\n\nexport const normalizeQuery = (query: string) => query.trim().toLowerCase();\n\n/**\n * Visibility registry for one filtering scope (the panel root, or one group). Items and groups\n * report their visibility here; `anyVisible` drives the group header / empty-state rendering.\n */\nexport const useMatchRegistry = () => {\n const [matches, setMatches] = useState<ReadonlyMap<string, boolean>>(new Map());\n\n const register = useCallback((id: string, visible: boolean) => {\n setMatches((prev) => (prev.get(id) === visible ? prev : new Map(prev).set(id, visible)));\n return () => {\n setMatches((prev) => {\n if (!prev.has(id)) return prev;\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n };\n }, []);\n\n const anyVisible = useMemo(() => [...matches.values()].some(Boolean), [matches]);\n\n return { register, anyVisible };\n};\n","import { Children, use, useEffect, useId, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { ChevronDown, ChevronRight } from '../../icons';\nimport { cn } from '../../utils';\n\nimport {\n BreadcrumbDropdownContext,\n getNodeText,\n matchesQuery,\n useMatchRegistry,\n} from './BreadcrumbDropdownContext';\n\nconst headerClass = cn(\n // layout\n 'tw:flex',\n 'tw:w-full',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:box-border',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:text-left',\n\n // font — single line; wrap the label in `Truncated` (design system) for ellipsis + tooltip\n 'tw:text-sm',\n 'tw:font-medium',\n 'tw:text-foreground',\n 'tw:min-w-0',\n 'tw:overflow-hidden',\n\n // icons\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n);\n\nconst collapsibleHeaderClass = cn(\n 'tw:cursor-pointer',\n 'tw:hover:bg-accent',\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n);\n\ntype BreadcrumbDropdownGroupProps = {\n /** Group header (e.g. bucket name + stage badge). */\n label: ReactNode;\n /**\n * Text the built-in filter matches against. When the group label matches, all its items stay\n * visible. Defaults to the label's rendered text content.\n */\n textValue?: string;\n /** Render the header as a toggle that expands / collapses the group's items. Default `false`. */\n collapsible?: boolean;\n /** Initial expanded state for `collapsible` groups. Default `true`. */\n defaultExpanded?: boolean;\n className?: string;\n children: ReactNode;\n};\n\n/**\n * A labelled group of `Breadcrumb.Dropdown.Item`s (e.g. one bucket with its tables). The group\n * hides itself when neither its label nor any child matches the filter query; an active query\n * force-expands collapsible groups. Non-empty `collapsible` groups toggle their items behind the\n * header with an animated expand / collapse; a `collapsible` group with no items renders a\n * non-interactive, greyed header that can't toggle.\n */\nexport const BreadcrumbDropdownGroup = ({\n label,\n textValue,\n collapsible = false,\n defaultExpanded = true,\n className,\n children,\n}: BreadcrumbDropdownGroupProps) => {\n const parent = use(BreadcrumbDropdownContext);\n if (!parent) {\n throw new Error('Breadcrumb.Dropdown.Group must be rendered inside Breadcrumb.Dropdown');\n }\n const id = useId();\n const { register: registerChild, anyVisible } = useMatchRegistry();\n const [expanded, setExpanded] = useState(defaultExpanded);\n\n const text = textValue ?? getNodeText(label);\n const filtering = !parent.filterDisabled && !!parent.query;\n const labelMatched = filtering && matchesQuery(text, parent.query);\n const visible = !filtering || parent.forceVisible || labelMatched || anyVisible;\n\n useEffect(() => parent.register(id, visible), [parent, id, visible]);\n\n const childContext = useMemo(\n () => ({\n query: parent.query,\n forceVisible: parent.forceVisible || labelMatched,\n filterDisabled: parent.filterDisabled,\n register: registerChild,\n close: parent.close,\n }),\n [parent, labelMatched, registerChild],\n );\n\n // An active query force-expands the group so matches are never hidden behind a collapsed header.\n const isExpanded = !collapsible || expanded || filtering;\n // A collapsible group with no items has nothing to toggle — render a non-interactive header.\n // oxlint-disable-next-line react-x/no-children-count -- emptiness check, no child transformation\n const isEmpty = Children.count(children) === 0;\n\n return (\n <div\n className={cn('tw:flex tw:flex-col', className)}\n style={visible ? undefined : { display: 'none' }}\n >\n {collapsible && isEmpty ? (\n <span\n aria-disabled\n className={cn(\n headerClass,\n 'tw:text-muted-foreground',\n // Fade just the leading chevron lighter than the label text.\n 'tw:[&>svg:first-child]:opacity-50',\n )}\n >\n <ChevronRight />\n {label}\n </span>\n ) : collapsible && !isEmpty ? (\n <button\n type=\"button\"\n aria-expanded={isExpanded}\n className={cn(headerClass, collapsibleHeaderClass)}\n onClick={() => setExpanded((prev) => !prev)}\n >\n {isExpanded ? <ChevronDown /> : <ChevronRight />}\n {label}\n </button>\n ) : (\n <span className={headerClass}>{label}</span>\n )}\n <BreadcrumbDropdownContext value={childContext}>\n {collapsible && !isEmpty ? (\n // Animated expand / collapse via a CSS grid-rows transition (0fr ↔ 1fr). The children stay\n // mounted while collapsed so the filter registry keeps receiving their visibility; `inert`\n // + `aria-hidden` take the collapsed content out of the a11y tree and tab order. An active\n // filter query force-expands (`isExpanded` includes `filtering`).\n <div\n className={cn(\n 'tw:grid tw:transition-[grid-template-rows] tw:duration-200 tw:ease-out',\n 'tw:motion-reduce:transition-none',\n isExpanded ? 'tw:grid-rows-[1fr]' : 'tw:grid-rows-[0fr]',\n )}\n >\n <div\n className=\"tw:overflow-hidden\"\n inert={!isExpanded}\n aria-hidden={isExpanded ? undefined : true}\n >\n <div className=\"tw:flex tw:flex-col tw:pl-6\">{children}</div>\n </div>\n </div>\n ) : (\n <div\n className=\"tw:flex tw:flex-col tw:pl-6\"\n style={isExpanded ? undefined : { display: 'none' }}\n >\n {children}\n </div>\n )}\n </BreadcrumbDropdownContext>\n </div>\n );\n};\n","import { use, useEffect, useId } from 'react';\nimport type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\nimport { BreadcrumbDropdownContext, getNodeText, matchesQuery } from './BreadcrumbDropdownContext';\n\nconst itemClass = cn(\n // layout\n 'tw:flex',\n 'tw:w-full',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:box-border',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:cursor-pointer',\n 'tw:text-left',\n\n // font — single line; wrap the label in `Truncated` (design system) for ellipsis + tooltip\n 'tw:text-sm',\n 'tw:font-normal',\n 'tw:text-foreground',\n 'tw:no-underline',\n 'tw:min-w-0',\n 'tw:overflow-hidden',\n\n // hover / active entity\n 'tw:hover:bg-accent',\n 'tw:data-[active]:bg-accent',\n 'tw:data-[active]:font-medium',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n // icons\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n);\n\ntype BreadcrumbDropdownItemProps = ComponentProps<'button'> & {\n /** Render the consumer's element (typically a router link) instead of a `button`. */\n asChild?: boolean;\n /**\n * Text the built-in filter matches against. Defaults to the item's rendered text content\n * (extracted recursively, so `asChild` links with icons work out of the box).\n */\n textValue?: string;\n /** Marks the currently open entity (highlight + `aria-current`). */\n active?: boolean;\n /** Close the panel when the item is selected. Default `true`. */\n closeOnSelect?: boolean;\n};\n\n/**\n * One selectable entity row inside `Breadcrumb.Dropdown`. Self-hides when it doesn't match the\n * panel's filter query and closes the panel on select. Use `asChild` to render a router link.\n */\nexport const BreadcrumbDropdownItem = ({\n ref,\n asChild = false,\n textValue,\n active = false,\n closeOnSelect = true,\n className,\n children,\n onClick,\n ...props\n}: BreadcrumbDropdownItemProps) => {\n const context = use(BreadcrumbDropdownContext);\n if (!context) {\n throw new Error('Breadcrumb.Dropdown.Item must be rendered inside Breadcrumb.Dropdown');\n }\n const id = useId();\n\n const text = textValue ?? getNodeText(children);\n const visible =\n context.filterDisabled ||\n !context.query ||\n context.forceVisible ||\n matchesQuery(text, context.query);\n\n useEffect(() => context.register(id, visible), [context, id, visible]);\n\n if (!visible) return null;\n\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n ref={ref}\n {...(asChild ? {} : { type: 'button' as const })}\n data-active={active || undefined}\n aria-current={active || undefined}\n className={cn(itemClass, className)}\n onClick={(event) => {\n onClick?.(event);\n if (closeOnSelect && !event.defaultPrevented) {\n context.close();\n }\n }}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'a'> & {\n asChild?: boolean;\n};\n\nexport const BreadcrumbLink = ({ ref, asChild = false, className, ...props }: Props) => {\n const Comp = asChild ? Slot : 'a';\n return (\n <Comp\n ref={ref}\n className={cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-1.5',\n // font\n 'tw:text-muted-foreground',\n 'tw:font-normal',\n 'tw:no-underline',\n\n // hover\n 'tw:hover:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n 'tw:focus-visible:rounded-sm',\n\n // Icon\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n\n // transition\n 'tw:transition-colors',\n className,\n )}\n {...props}\n />\n );\n};\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport type { ComponentRef, ReactNode } from 'react';\n\nimport { SearchInput } from '../../blocks/SearchInput';\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\nimport { Popover } from '../Popover';\n\nimport {\n BreadcrumbDropdownContext,\n normalizeQuery,\n useMatchRegistry,\n} from './BreadcrumbDropdownContext';\nimport { BreadcrumbDropdownGroup } from './BreadcrumbDropdownGroup';\nimport { BreadcrumbDropdownItem } from './BreadcrumbDropdownItem';\nimport { BreadcrumbLink } from './BreadcrumbLink';\n\n// Chevron trigger — the only button in the crumb. It sits tight next to the label so it reads as\n// grouped with it, with no persistent outline: it's a button purely via the hover / open background\n// + colour lift. Used on its own next to a link label (`splitTrigger`) or after a plain label.\nconst chevronButtonClass = cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n // compact square hit target that stays snug against the label\n 'tw:size-5',\n 'tw:text-muted-foreground',\n 'tw:transition-colors',\n 'tw:hover:bg-accent',\n 'tw:hover:text-foreground',\n 'tw:data-[state=open]:bg-accent',\n 'tw:data-[state=open]:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n // chevron rotation while open\n 'tw:[&_svg]:transition-transform',\n 'tw:[&[data-state=open]_svg]:rotate-180',\n);\n\n// Plain (non-link) label — same typography as `BreadcrumbLink` but no hover/focus treatment, since\n// it isn't interactive: only the chevron opens the panel.\nconst plainLabelClass = cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-1.5',\n 'tw:text-muted-foreground',\n 'tw:font-normal',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3.5',\n);\n\n// Fixed panel width per `size` (default `medium`). Long names truncate rather than wrap or widen\n// the panel. Width still clamps to the viewport via min(); height is clamped the same way.\nconst PANEL_BASE = 'tw:max-h-[min(640px,var(--radix-popover-content-available-height))]';\n\nconst PANEL_WIDTH = {\n small: 'tw:w-[min(360px,var(--radix-popover-content-available-width))]',\n medium: 'tw:w-[min(440px,var(--radix-popover-content-available-width))]',\n large: 'tw:w-[min(560px,var(--radix-popover-content-available-width))]',\n} as const;\n\ntype PanelSize = keyof typeof PANEL_WIDTH;\n\n/**\n * Props for `Breadcrumb.Dropdown`. The panel chrome (trigger typography, popover sizing, pinned\n * filter input) is owned by the component — consumers supply the label and the panel content,\n * composed from `Breadcrumb.Dropdown.Group` / `Breadcrumb.Dropdown.Item`.\n */\ntype BreadcrumbDropdownProps = {\n /**\n * Crumb label, shown next to the chevron button that opens the panel — the label itself is never\n * the trigger. With `splitTrigger`, pass an anchor-like element (e.g. a router link) so the label\n * also navigates; otherwise it renders as a plain, non-navigational crumb label.\n */\n label: ReactNode;\n /**\n * When `true`, the label is a navigable link (pass an anchor-like `label` element, rendered through\n * `Breadcrumb.Link asChild`). Default `false` — the label is plain text. Either way only the\n * chevron button opens the panel; it always sits grouped tight to the label.\n */\n splitTrigger?: boolean;\n /**\n * Accessible name for the chevron trigger button. Defaults to `\"${label} menu\"` when `label` is\n * a plain string, otherwise `\"Open menu\"` — pass explicitly when `label` is a non-string node.\n */\n triggerLabel?: string;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /**\n * Fixed panel width: `small` (360px), `medium` (440px, default), or `large` (560px). Names that\n * exceed the width truncate with an ellipsis (hover shows the full name). Clamps to the viewport.\n */\n size?: PanelSize;\n /**\n * Pinned filter input at the top of the panel, focused on open. On by default — items and groups\n * that don't match the query hide themselves (matched against their `textValue` / string\n * content). Set to `false` to opt out of the input entirely.\n */\n filter?: boolean;\n /**\n * Set to `false` to keep the filter input but disable the built-in matching — the consumer\n * filters the content it renders (e.g. server-side or custom matching). Default `true`.\n */\n shouldFilter?: boolean;\n /** Controlled filter value. Omit to let the component manage the query internally. */\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n searchPlaceholder?: string;\n /** Rendered when the built-in filter hides everything. Default `\"No results.\"`. */\n emptyMessage?: ReactNode;\n /** Panel content — `Breadcrumb.Dropdown.Group` / `Breadcrumb.Dropdown.Item` elements. */\n children: ReactNode;\n};\n\n/**\n * Breadcrumb segment that opens a standardized switcher panel — a filterable list / tree of\n * sibling entities the user can jump between (e.g. the Storage bucket/table tree on a table\n * detail page).\n *\n * **When to use:** on the leftmost breadcrumb segment that has siblings / children worth switching\n * between. Use at most one dropdown segment per breadcrumb.\n * **When NOT to use:** for tertiary actions on the breadcrumbs row use the `overflowActions` slot of\n * `PageHeader.Detail`; for a collapsed middle of a long breadcrumb use `Breadcrumb.Ellipsis`.\n * **Composition:** render inside `Breadcrumb.Item` in place of `Breadcrumb.Link`. Compose the panel\n * from `Breadcrumb.Dropdown.Group` and `Breadcrumb.Dropdown.Item` — the built-in filter matches\n * and hides them automatically.\n */\nexport const BreadcrumbDropdown = ({\n label,\n splitTrigger = false,\n triggerLabel,\n open,\n defaultOpen = false,\n onOpenChange,\n size = 'medium',\n filter = true,\n shouldFilter = true,\n searchValue,\n onSearchChange,\n searchPlaceholder = 'Search…',\n emptyMessage = 'No results.',\n children,\n}: BreadcrumbDropdownProps) => {\n const searchRef = useRef<ComponentRef<'input'>>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [internalQuery, setInternalQuery] = useState('');\n const { register, anyVisible } = useMatchRegistry();\n\n const isOpen = open ?? internalOpen;\n const handleOpenChange = useCallback(\n (nextOpen: boolean) => {\n setInternalOpen(nextOpen);\n if (!nextOpen) setInternalQuery('');\n onOpenChange?.(nextOpen);\n },\n [onOpenChange],\n );\n const close = useCallback(() => handleOpenChange(false), [handleOpenChange]);\n\n const effectiveTriggerLabel =\n triggerLabel ?? (typeof label === 'string' ? `${label} menu` : 'Open menu');\n\n const rawQuery = searchValue ?? internalQuery;\n const filterDisabled = !filter || !shouldFilter;\n const query = filterDisabled ? '' : normalizeQuery(rawQuery);\n\n const contextValue = useMemo(\n () => ({ query, forceVisible: false, filterDisabled, register, close }),\n [query, filterDisabled, register, close],\n );\n\n return (\n <Popover open={isOpen} onOpenChange={handleOpenChange}>\n <span className=\"tw:flex tw:items-center tw:gap-0.5\">\n {splitTrigger ? (\n <BreadcrumbLink asChild>{label}</BreadcrumbLink>\n ) : (\n <span className={plainLabelClass}>{label}</span>\n )}\n <Popover.Trigger asChild>\n <button type=\"button\" aria-label={effectiveTriggerLabel} className={chevronButtonClass}>\n <ChevronDown className=\"tw:size-3.5\" />\n </button>\n </Popover.Trigger>\n </span>\n <Popover.Content\n align=\"start\"\n sideOffset={8}\n collisionPadding={16}\n data-size={size}\n className={cn('tw:overflow-hidden tw:p-0', PANEL_BASE, PANEL_WIDTH[size])}\n onOpenAutoFocus={\n filter\n ? (event) => {\n event.preventDefault();\n searchRef.current?.focus();\n }\n : undefined\n }\n >\n {filter && (\n <div className=\"tw:shrink-0 tw:border-0 tw:border-b tw:border-solid tw:border-border tw:p-2\">\n <SearchInput\n ref={searchRef}\n value={rawQuery}\n onValueChange={(value) => {\n setInternalQuery(value);\n onSearchChange?.(value);\n }}\n placeholder={searchPlaceholder}\n allowClear\n // Built-in matching is client-side and cheap — filter on every keystroke. Keep the\n // debounce only when the consumer filters itself (shouldFilter={false}, e.g. server-side).\n disableDebounce={shouldFilter}\n />\n </div>\n )}\n <div className=\"tw:flex tw:flex-1 tw:flex-col tw:overflow-y-auto tw:p-2\">\n <BreadcrumbDropdownContext value={contextValue}>{children}</BreadcrumbDropdownContext>\n {!filterDisabled && !!query && !anyVisible && (\n <span className=\"tw:px-2 tw:py-1.5 tw:text-sm tw:text-muted-foreground\">\n {emptyMessage}\n </span>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n};\n\nBreadcrumbDropdown.Item = BreadcrumbDropdownItem;\nBreadcrumbDropdown.Group = BreadcrumbDropdownGroup;\n","import type { ComponentProps } from 'react';\n\nimport { Ellipsis } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const BreadcrumbEllipsis = ({ ref, className, ...props }: Props) => (\n <button\n ref={ref}\n type=\"button\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:rounded-md',\n 'tw:border-none',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n 'tw:text-muted-foreground',\n 'tw:transition-colors',\n // Match the Breadcrumb.Dropdown chevron trigger: background + colour lift on hover / while the\n // menu is open, so the two interactive breadcrumb affordances read consistently.\n 'tw:hover:bg-accent',\n 'tw:hover:text-foreground',\n 'tw:data-[state=open]:bg-accent',\n 'tw:data-[state=open]:text-foreground',\n\n // focus\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n\n 'tw:p-1',\n className,\n )}\n {...props}\n >\n <Ellipsis className=\"tw:size-4\" />\n <span className=\"tw:sr-only\">More</span>\n </button>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const BreadcrumbItem = ({ className, ...props }: Props) => (\n <li className={cn('tw:inline-flex', 'tw:items-center', className)} {...props} />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'ol'>;\n\nexport const BreadcrumbList = ({ className, ...props }: Props) => (\n <ol\n className={cn(\n // layout\n 'tw:flex',\n 'tw:flex-wrap',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:m-0',\n 'tw:p-0',\n\n // font\n 'tw:break-words',\n 'tw:text-sm',\n 'tw:text-muted-foreground',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'span'>;\n\nexport const BreadcrumbPage = ({ ref, className, ...props }: Props) => (\n <span\n ref={ref}\n // Do not use the anchor, as this item is not clickable\n // oxlint-disable-next-line jsx_a11y/prefer-tag-over-role\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('tw:font-medium', 'tw:text-foreground', className)}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const BreadcrumbSeparator = ({ children, className, ...props }: Props) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:aspect-square',\n 'tw:size-[15px]',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-2.5',\n 'tw:text-muted-foreground',\n className,\n )}\n {...props}\n >\n {children ?? <span className=\"tw:select-none tw:text-sm tw:text-muted-foreground/50\">/</span>}\n </li>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { BreadcrumbDropdown } from './BreadcrumbDropdown';\nimport { BreadcrumbEllipsis } from './BreadcrumbEllipsis';\nimport { BreadcrumbItem } from './BreadcrumbItem';\nimport { BreadcrumbLink } from './BreadcrumbLink';\nimport { BreadcrumbList } from './BreadcrumbList';\nimport { BreadcrumbPage } from './BreadcrumbPage';\nimport { BreadcrumbSeparator } from './BreadcrumbSeparator';\n\ntype Props = ComponentProps<'nav'>;\n\nexport const Breadcrumb = ({ className, ...props }: Props) => (\n <nav aria-label=\"breadcrumb\" className={cn('tailwindcss-preflight', className)} {...props} />\n);\n\nBreadcrumb.List = BreadcrumbList;\nBreadcrumb.Item = BreadcrumbItem;\nBreadcrumb.Link = BreadcrumbLink;\nBreadcrumb.Page = BreadcrumbPage;\nBreadcrumb.Separator = BreadcrumbSeparator;\nBreadcrumb.Ellipsis = BreadcrumbEllipsis;\nBreadcrumb.Dropdown = BreadcrumbDropdown;\n"],"mappings":"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"}
@@ -85,25 +85,25 @@ const variants = cva([
85
85
  "tw:aria-disabled:!bg-transparent"
86
86
  ],
87
87
  outline: [
88
- "tw:text-neutral-800",
89
- "tw:bg-white",
90
- "tw:!border-neutral-200",
91
- "tw:hover:text-neutral-800",
92
- "tw:focus:text-neutral-800",
93
- "tw:hover:not-disabled:!border-neutral-300",
94
- "tw:hover:not-disabled:bg-neutral-100",
95
- "tw:active:not-disabled:bg-neutral-200",
96
- "tw:[&_svg]:text-neutral-400",
88
+ "tw:text-foreground",
89
+ "tw:bg-card",
90
+ "tw:!border-input",
91
+ "tw:hover:text-foreground",
92
+ "tw:focus:text-foreground",
93
+ "tw:hover:not-disabled:!border-muted-foreground/60",
94
+ "tw:hover:not-disabled:bg-muted-foreground/15",
95
+ "tw:active:not-disabled:bg-muted-foreground/35",
96
+ "tw:[&_svg]:text-muted-foreground",
97
97
  "tw:not-disabled:hover:[&_svg]:text-secondary-600",
98
98
  "tw:active:not-disabled:[&_svg]:text-secondary-600",
99
- "tw:aria-disabled:!bg-white",
100
- "tw:aria-disabled:!border-neutral-200"
99
+ "tw:aria-disabled:!bg-card",
100
+ "tw:aria-disabled:!border-input"
101
101
  ],
102
102
  inline: [
103
- "tw:text-neutral-800",
103
+ "tw:text-foreground",
104
104
  "tw:bg-transparent",
105
105
  "tw:rounded-full",
106
- "tw:[&_svg]:text-neutral-400",
106
+ "tw:[&_svg]:text-muted-foreground",
107
107
  "tw:not-disabled:hover:[&_svg]:text-secondary-600",
108
108
  "tw:not-disabled:focus:[&_svg]:text-secondary-600"
109
109
  ]
@@ -356,7 +356,7 @@ const buttonInlineVariants = cva([
356
356
  "tw:hover:text-primary/90",
357
357
  "tw:[&_svg]:text-primary"
358
358
  ],
359
- dark: ["tw:text-neutral-800 tw:[&_svg]:text-neutral-400"],
359
+ dark: ["tw:text-foreground tw:[&_svg]:text-muted-foreground"],
360
360
  danger: ["tw:text-error-500 tw:[&_svg]:text-error-500"],
361
361
  muted: ["tw:text-muted-foreground tw:[&_svg]:text-muted-foreground"],
362
362
  custom: []
@@ -388,4 +388,4 @@ const ButtonInline = ({ ref, children, className, variant, color, type = "button
388
388
  //#endregion
389
389
  export { Button, ButtonInline, argoVariants };
390
390
 
391
- //# sourceMappingURL=Button-nzmDNS2q.js.map
391
+ //# sourceMappingURL=Button-6xBX0nNl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button-6xBX0nNl.js","names":[],"sources":["../src/components/Button/styles.ts","../src/components/Button/Button.tsx","../src/components/Button/ButtonInline.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\n\nexport const variants = cva(\n [\n 'tailwindcss-preflight',\n 'tw:group/button',\n 'tw:border-box',\n\n // layout\n 'tw:relative',\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:gap-2',\n\n // text — chrome weight/tracking are brand-overridable tokens\n // (`--font-weight-medium` / `--letter-spacing-chrome`). Casing: standard case is\n // the default; only legacy brands (`keboola-legacy-*`) uppercase the chrome, so\n // modern brands (incl. Keboola V2) read naturally. Mirrors the V2 standard-case\n // treatment shipped for Tooltip/Badge (PR 7629).\n 'tw:text-xs',\n 'tw:leading-5',\n 'tw:font-medium',\n 'tw:[[data-brand^=keboola-legacy]_&]:tracking-chrome',\n 'tw:[[data-brand^=keboola-legacy]_&]:uppercase',\n\n // border — legacy (non-argo) chrome uses a fixed radius, not the brand token.\n 'tw:rounded',\n 'tw:border',\n 'tw:border-transparent',\n\n // styling\n 'tw:shadow-none',\n 'tw:[a]:cursor-pointer', // explicitly set for anchor\n\n 'tw:focus-visible:outline',\n 'tw:focus-visible:outline-1',\n 'tw:focus-visible:-outline-offset-1',\n 'tw:focus-visible:outline-ring',\n 'tw:focus-visible:ring-4',\n 'tw:focus-visible:ring-ring/30',\n\n // disabled\n 'tw:disabled:opacity-40',\n 'tw:disabled:cursor-not-allowed',\n\n // anchor support\n 'tw:!no-underline',\n 'tw:aria-disabled:opacity-40',\n 'tw:aria-disabled:cursor-not-allowed',\n\n 'tw:[&_svg]:shrink-0',\n ],\n {\n defaultVariants: {\n size: 'medium',\n variant: 'primary',\n block: false,\n },\n variants: {\n block: {\n true: ['tw:w-full'],\n },\n variant: {\n primary: [\n 'tw:text-white',\n 'tw:bg-primary-500',\n\n 'tw:focus:text-white',\n 'tw:hover:text-white',\n 'tw:hover:not-disabled:bg-primary-600',\n 'tw:active:not-disabled:bg-primary-800',\n\n // anchor disabled override\n 'tw:aria-disabled:!bg-primary-500',\n ],\n secondary: [\n 'tw:text-white',\n 'tw:bg-secondary-500',\n\n 'tw:focus:text-white',\n 'tw:hover:text-white',\n 'tw:hover:not-disabled:bg-secondary-700',\n 'tw:active:not-disabled:bg-secondary-800',\n\n // anchor disabled override\n 'tw:aria-disabled:!bg-secondary-500',\n ],\n danger: [\n 'tw:text-white',\n 'tw:bg-error-500',\n\n 'tw:focus:text-white',\n 'tw:hover:text-white',\n 'tw:hover:not-disabled:bg-error-600',\n 'tw:active:not-disabled:bg-error-700',\n\n // anchor disabled override\n 'tw:aria-disabled:!bg-error-500',\n ],\n // The label and the hover/active fills read tokens rather than the fixed\n // neutral scale, so the variant follows the active brand and colour scheme\n // (argo's `invisible` already did). A transparent button inherits whatever\n // surface it is dropped on, so it is the one legacy variant that cannot\n // assume a light page — pinning it forced every dark-scheme call site to\n // re-declare the colour by hand.\n invisible: [\n 'tw:text-foreground',\n 'tw:bg-transparent',\n\n 'tw:focus:text-foreground',\n 'tw:hover:not-disabled:bg-muted',\n 'tw:hover:text-foreground',\n 'tw:active:not-disabled:bg-secondary',\n\n // contrasting icon on hover/active\n 'tw:[&_svg]:text-neutral-400',\n 'tw:hover:not-disabled:[&_svg]:text-secondary-600',\n 'tw:active:not-disabled:[&_svg]:text-secondary-600',\n\n // anchor disabled override\n 'tw:aria-disabled:!bg-transparent',\n ],\n outline: [\n 'tw:text-foreground',\n 'tw:bg-card',\n // border\n 'tw:!border-input',\n 'tw:hover:text-foreground',\n 'tw:focus:text-foreground',\n // Hover/pressed fills and the hover border are `muted-foreground` tints, not\n // tokens of their own: a tint composites over `bg-card` and so steps visibly in\n // either scheme, where `bg-muted` sits 4/255 from `bg-card` in the dark one.\n 'tw:hover:not-disabled:!border-muted-foreground/60',\n 'tw:hover:not-disabled:bg-muted-foreground/15',\n 'tw:active:not-disabled:bg-muted-foreground/35',\n\n // contrasting icon hover, same as invisible\n 'tw:[&_svg]:text-muted-foreground',\n 'tw:not-disabled:hover:[&_svg]:text-secondary-600',\n 'tw:active:not-disabled:[&_svg]:text-secondary-600',\n\n // anchor disabled override\n 'tw:aria-disabled:!bg-card',\n 'tw:aria-disabled:!border-input',\n ],\n\n inline: [\n 'tw:text-foreground',\n 'tw:bg-transparent',\n 'tw:rounded-full',\n\n 'tw:[&_svg]:text-muted-foreground',\n 'tw:not-disabled:hover:[&_svg]:text-secondary-600',\n 'tw:not-disabled:focus:[&_svg]:text-secondary-600',\n ],\n },\n size: {\n medium: [\n 'tw:max-h-10',\n 'tw:min-h-10',\n 'tw:px-4',\n 'tw:py-2.5',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4',\n ],\n small: [\n 'tw:max-h-8',\n 'tw:min-h-8',\n 'tw:px-4',\n 'tw:py-1.5',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4',\n ],\n large: [\n 'tw:max-h-12',\n 'tw:min-h-12',\n 'tw:px-4',\n 'tw:py-3.5',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4',\n ],\n\n 'icon-lg': ['tw:size-12', 'tw:p-0', 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-6'],\n icon: ['tw:size-10', 'tw:p-0', 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4'],\n 'icon-sm': ['tw:size-8', 'tw:p-0', 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4'],\n 'icon-xs': ['tw:size-6', 'tw:p-0', 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4'],\n 'icon-2xs': [\n 'tw:!inline-flex',\n 'tw:size-5',\n 'tw:max-h-5',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3',\n ],\n 'icon-3xs': ['tw:h-fit', 'tw:w-fit', 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4'],\n },\n },\n },\n);\n\nexport const argoVariants = cva(\n [\n 'tailwindcss-preflight',\n\n // layout\n 'tw:relative',\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:whitespace-nowrap',\n 'tw:gap-2',\n\n // border\n 'tw:border',\n 'tw:border-transparent',\n 'tw:rounded-[var(--radius-lg,0.25rem)]',\n\n // text\n 'tw:font-medium',\n 'tw:select-none',\n\n // focus visible\n 'tw:!outline-hidden',\n 'tw:focus-visible:ring-2',\n\n // disabled\n 'tw:disabled:cursor-not-allowed',\n 'tw:disabled:opacity-50',\n 'tw:active:opacity-60',\n\n 'tw:transition-all',\n 'tw:bg-clip-padding',\n\n // anchor support\n 'tw:!no-underline',\n 'tw:aria-disabled:cursor-not-allowed',\n 'tw:aria-disabled:opacity-50',\n\n // icon\n 'tw:shrink-0',\n 'tw:[&_svg]:pointer-events-none',\n 'tw:[&_svg]:shrink-0',\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n ],\n {\n defaultVariants: {\n variant: 'primary',\n size: 'medium',\n },\n variants: {\n block: {\n true: ['tw:w-full'],\n },\n variant: {\n primary: [\n 'tw:bg-primary',\n 'tw:text-primary-foreground',\n 'tw:[a]:hover:bg-primary/80',\n 'tw:hover:not-disabled:bg-primary/90',\n 'tw:hover:text-primary-foreground',\n 'tw:focus:text-primary-foreground',\n\n 'tw:focus-visible:border-primary',\n 'tw:focus-visible:ring-ring/50',\n ],\n secondary: [\n 'tw:bg-primary/10',\n 'tw:text-primary',\n 'tw:hover:not-disabled:bg-primary/20',\n\n 'tw:focus-visible:border-primary',\n 'tw:focus-visible:ring-ring/50',\n ],\n\n // should be called \"destructive\" by Figma\n danger: [\n 'tw:bg-destructive',\n 'tw:text-destructive-foreground',\n 'tw:hover:not-disabled:bg-destructive/90',\n 'tw:hover:text-destructive-foreground',\n 'tw:focus:text-destructive-foreground',\n\n 'tw:focus-visible:border-destructive',\n 'tw:focus-visible:ring-destructive/20',\n ],\n outline: [\n 'tw:!border-input',\n 'tw:bg-background',\n // Semantic base text color so the label/icon flips in dark mode\n // (matches `invisible`); previously unset → inherited a fixed dark color.\n 'tw:text-foreground',\n // Hover follows the brand primary (translucent tint), matching the\n // `secondary` variant — not the fixed `accent` blue.\n 'tw:hover:not-disabled:bg-primary/10',\n 'tw:hover:not-disabled:text-primary',\n 'tw:hover:active:bg-background',\n 'tw:focus-visible:!border-primary',\n 'tw:focus-visible:ring-ring/50',\n ],\n\n // should be called \"ghost\" by Figma\n invisible: [\n 'tw:bg-transparent',\n 'tw:text-foreground',\n 'tw:hover:not-disabled:bg-primary/10',\n 'tw:hover:not-disabled:text-primary',\n 'tw:hover:not-disabled:border-primary/10',\n\n 'tw:focus-visible:ring-ring/50',\n ],\n // should be called \"link\" by Figma\n inline: [\n 'tw:bg-transparent',\n 'tw:text-primary',\n 'tw:hover:underline',\n 'tw:hover:active:bg-transparent',\n 'tw:focus-visible:ring-ring/50',\n ],\n },\n size: {\n // should be called \"default\" by Figma\n medium: ['tw:max-h-9', 'tw:py-2', 'tw:px-4', 'tw:text-sm'],\n // should be called \"small\" by Figma\n small: ['tw:max-h-8', 'tw:py-2', 'tw:px-3', 'tw:text-xs'],\n // should be called \"large\" by Figma\n large: ['tw:max-h-10', 'tw:py-2.5', 'tw:px-6', 'tw:text-sm'],\n\n 'icon-lg': ['tw:size-10'],\n icon: ['tw:size-9'],\n 'icon-sm': ['tw:size-8'],\n 'icon-xs': ['tw:size-6'],\n // unsupported in ARGO, remove when old design is gone\n 'icon-2xs': [],\n 'icon-3xs': [],\n },\n },\n },\n);\n","import type { ComponentProps } from 'react';\nimport { Root, Slottable } from '@radix-ui/react-slot';\nimport type { VariantProps } from 'class-variance-authority';\n\nimport { Loader2 } from '../../icons';\nimport { cn } from '../../utils';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nimport { argoVariants, variants } from './styles';\n\n/**\n * Props for the `Button` component.\n *\n * Pass `variant` for primary/secondary/danger/outline/invisible looks, `size`\n * for height (including `icon-*` sizes when rendering icon-only). Icons are\n * composed as children — `<Button><Trash2 className=\"tw:size-4\" /> Delete</Button>`.\n */\ntype Props = {\n /** Replaces the leading content with a spinner and disables the button visually. The caller still controls `disabled`. */\n isLoading?: boolean;\n /** Render as a Radix `Slot` so the parent JSX (e.g. a `react-router` `<Link>`) becomes the button element. */\n asChild?: boolean;\n} & ComponentProps<'button'> &\n VariantProps<typeof variants>;\n\n/**\n * Primary action surface for the design system — covers all clickable controls except inline text links.\n *\n * **When to use:** any user-initiated action (submit, save, open modal, run job). Use `size=\"icon-*\"` with no\n * children for an icon-only button; there is no separate `IconButton` component.\n * **When NOT to use:** for inline text-link actions inside body copy use `ButtonInline`; for navigation that\n * opens a URL use `Link`; for \"primary action + dropdown of related actions\" use `SplitButton`.\n * **Composition:** wrap in `Tooltip` when icon-only or when disabled state needs an explanation; pair with\n * `Popconfirm` for destructive confirmations; pass through `Modal.Trigger` / `DropdownMenu.Trigger` via `asChild`.\n *\n * @see RECIPES.md#disabled-button-tooltip — for the disabled-button + tooltip pattern\n * @see RECIPES.md#confirm-dialog — for destructive-action confirmation\n */\nexport const Button = ({\n ref,\n children,\n disabled = false,\n className,\n type = 'button',\n isLoading = false,\n asChild = false,\n onClick,\n variant = 'primary',\n size = 'medium',\n block = false,\n ...buttonProps\n}: Props) => {\n const renderArgo = useArgoDesign();\n const Comp = asChild ? Root : 'button';\n const isIconOnly = String(size).startsWith('icon');\n const classNames = renderArgo\n ? argoVariants({ variant, size, block, className })\n : variants({ size, variant, block, className });\n\n const handleClick: ComponentProps<'button'>['onClick'] = (event) => {\n const isAnchor = event.currentTarget.tagName === 'A';\n\n // <a/> does not support disabled by default, and we cannot use pointer-events: none because cursor-not-allowed would not work.\n if (isAnchor && disabled) {\n event.preventDefault();\n return;\n }\n\n onClick?.(event);\n };\n\n return (\n <Comp\n {...buttonProps}\n ref={ref}\n disabled={disabled}\n aria-disabled={disabled}\n data-variant={variant}\n // `size=\"icon\"` / `size=\"icon-*\"` flags the button as icon-only — needed\n // by `ButtonGroup space=\"block\"` which stretches non-icon children to\n // equal width.\n data-icon-only={isIconOnly}\n type={type}\n onClick={handleClick}\n className={cn(classNames)}\n >\n {isLoading && <Loader2 className=\"tw:size-4 tw:shrink-0 tw:animate-spin\" />}\n <Slottable>{isLoading && isIconOnly ? null : children}</Slottable>\n </Comp>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Root } from '@radix-ui/react-slot';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nconst buttonInlineVariants = cva(\n [\n 'tailwindcss-preflight',\n\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:gap-2',\n\n 'tw:underline-offset-2',\n\n 'tw:disabled:opacity-40',\n 'tw:disabled:cursor-not-allowed',\n 'tw:disabled:text-neutral-500',\n 'tw:disabled:no-underline',\n 'tw:disabled:[&_svg]:text-neutral-400',\n\n // Default size for nested Lucide icons; callers can override on the icon.\n \"tw:[&_svg.lucide:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n ],\n {\n defaultVariants: {\n variant: 'link',\n color: 'link',\n },\n variants: {\n color: {\n link: ['tw:text-primary', 'tw:hover:text-primary/90', 'tw:[&_svg]:text-primary'],\n dark: ['tw:text-foreground tw:[&_svg]:text-muted-foreground'],\n danger: ['tw:text-error-500 tw:[&_svg]:text-error-500'],\n muted: ['tw:text-muted-foreground tw:[&_svg]:text-muted-foreground'],\n custom: [],\n },\n variant: {\n link: ['tw:underline', 'tw:hover:no-underline'],\n 'link-reverse': ['tw:no-underline', '', 'tw:hover:underline'],\n custom: [],\n },\n },\n },\n);\n\ntype Props = ComponentProps<'button'> &\n VariantProps<typeof buttonInlineVariants> & { asChild?: boolean };\n\nexport const ButtonInline = ({\n ref,\n children,\n className,\n variant,\n color,\n type = 'button',\n asChild = false,\n ...buttonProps\n}: Props) => {\n const Comp = asChild ? Root : 'button';\n\n return (\n <Comp\n {...buttonProps}\n ref={ref}\n type={asChild ? undefined : type}\n className={buttonInlineVariants({ variant, color, className })}\n >\n {children}\n </Comp>\n );\n};\n"],"mappings":";;;;;;;AAEA,MAAa,WAAW,IACtB;CACE;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CAOA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CAGA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CAGA;CACA;CACA;CAEA;AACF,GACA;CACE,iBAAiB;EACf,MAAM;EACN,SAAS;EACT,OAAO;CACT;CACA,UAAU;EACR,OAAO,EACL,MAAM,CAAC,WAAW,EACpB;EACA,SAAS;GACP,SAAS;IACP;IACA;IAEA;IACA;IACA;IACA;IAGA;GACF;GACA,WAAW;IACT;IACA;IAEA;IACA;IACA;IACA;IAGA;GACF;GACA,QAAQ;IACN;IACA;IAEA;IACA;IACA;IACA;IAGA;GACF;GAOA,WAAW;IACT;IACA;IAEA;IACA;IACA;IACA;IAGA;IACA;IACA;IAGA;GACF;GACA,SAAS;IACP;IACA;IAEA;IACA;IACA;IAIA;IACA;IACA;IAGA;IACA;IACA;IAGA;IACA;GACF;GAEA,QAAQ;IACN;IACA;IACA;IAEA;IACA;IACA;GACF;EACF;EACA,MAAM;GACJ,QAAQ;IACN;IACA;IACA;IACA;IACA;GACF;GACA,OAAO;IACL;IACA;IACA;IACA;IACA;GACF;GACA,OAAO;IACL;IACA;IACA;IACA;IACA;GACF;GAEA,WAAW;IAAC;IAAc;IAAU;GAA4C;GAChF,MAAM;IAAC;IAAc;IAAU;GAA4C;GAC3E,WAAW;IAAC;IAAa;IAAU;GAA4C;GAC/E,WAAW;IAAC;IAAa;IAAU;GAA4C;GAC/E,YAAY;IACV;IACA;IACA;IACA;GACF;GACA,YAAY;IAAC;IAAY;IAAY;GAA4C;EACnF;CACF;AACF,CACF;AAEA,MAAa,eAAe,IAC1B;CACE;CAGA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CAGA;CACA;CAGA;CACA;CAGA;CACA;CACA;CAEA;CACA;CAGA;CACA;CACA;CAGA;CACA;CACA;CACA;AACF,GACA;CACE,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;CACA,UAAU;EACR,OAAO,EACL,MAAM,CAAC,WAAW,EACpB;EACA,SAAS;GACP,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;GACF;GACA,WAAW;IACT;IACA;IACA;IAEA;IACA;GACF;GAGA,QAAQ;IACN;IACA;IACA;IACA;IACA;IAEA;IACA;GACF;GACA,SAAS;IACP;IACA;IAGA;IAGA;IACA;IACA;IACA;IACA;GACF;GAGA,WAAW;IACT;IACA;IACA;IACA;IACA;IAEA;GACF;GAEA,QAAQ;IACN;IACA;IACA;IACA;IACA;GACF;EACF;EACA,MAAM;GAEJ,QAAQ;IAAC;IAAc;IAAW;IAAW;GAAY;GAEzD,OAAO;IAAC;IAAc;IAAW;IAAW;GAAY;GAExD,OAAO;IAAC;IAAe;IAAa;IAAW;GAAY;GAE3D,WAAW,CAAC,YAAY;GACxB,MAAM,CAAC,WAAW;GAClB,WAAW,CAAC,WAAW;GACvB,WAAW,CAAC,WAAW;GAEvB,YAAY,CAAC;GACb,YAAY,CAAC;EACf;CACF;AACF,CACF;;;;;;;;;;;;;;;;ACvSA,MAAa,UAAU,EACrB,KACA,UACA,WAAW,OACX,WACA,OAAO,UACP,YAAY,OACZ,UAAU,OACV,SACA,UAAU,WACV,OAAO,UACP,QAAQ,OACR,GAAG,kBACQ;CACX,MAAM,aAAa,cAAc;CACjC,MAAM,OAAO,UAAU,OAAO;CAC9B,MAAM,aAAa,OAAO,IAAI,CAAC,CAAC,WAAW,MAAM;CACjD,MAAM,aAAa,aACf,aAAa;EAAE;EAAS;EAAM;EAAO;CAAU,CAAC,IAChD,SAAS;EAAE;EAAM;EAAS;EAAO;CAAU,CAAC;CAEhD,MAAM,eAAoD,UAAU;EAIlE,IAHiB,MAAM,cAAc,YAAY,OAGjC,UAAU;GACxB,MAAM,eAAe;GACrB;EACF;EAEA,UAAU,KAAK;CACjB;CAEA,OACE,qBAAC,MAAD;EACE,GAAI;EACC;EACK;EACV,iBAAe;EACf,gBAAc;EAId,kBAAgB;EACV;EACN,SAAS;EACT,WAAW,GAAG,UAAU;EAZ1B,UAAA,CAcG,aAAa,oBAAC,SAAD,EAAS,WAAU,wCAAyC,CAAA,GAC1E,oBAAC,WAAD,EAAA,UAAY,aAAa,aAAa,OAAO,SAAoB,CAAA,CAC7D;;AAEV;;;ACrFA,MAAM,uBAAuB,IAC3B;CACE;CAEA;CACA;CACA;CAEA;CAEA;CACA;CACA;CACA;CACA;CAGA;CACA;AACF,GACA;CACE,iBAAiB;EACf,SAAS;EACT,OAAO;CACT;CACA,UAAU;EACR,OAAO;GACL,MAAM;IAAC;IAAmB;IAA4B;GAAyB;GAC/E,MAAM,CAAC,qDAAqD;GAC5D,QAAQ,CAAC,6CAA6C;GACtD,OAAO,CAAC,2DAA2D;GACnE,QAAQ,CAAC;EACX;EACA,SAAS;GACP,MAAM,CAAC,gBAAgB,uBAAuB;GAC9C,gBAAgB;IAAC;IAAmB;IAAI;GAAoB;GAC5D,QAAQ,CAAC;EACX;CACF;AACF,CACF;AAKA,MAAa,gBAAgB,EAC3B,KACA,UACA,WACA,SACA,OACA,OAAO,UACP,UAAU,OACV,GAAG,kBACQ;CAGX,OACE,oBAHW,UAAU,OAAO,UAG5B;EACE,GAAI;EACC;EACL,MAAM,UAAU,KAAA,IAAY;EAC5B,WAAW,qBAAqB;GAAE;GAAS;GAAO;EAAU,CAAC;EAE5D;CACG,CAAA;AAEV"}
@@ -1,5 +1,5 @@
1
1
  import { Copy } from "./icons-Cek151jC.js";
2
- import { Button, ButtonInline } from "./Button-nzmDNS2q.js";
2
+ import { Button, ButtonInline } from "./Button-6xBX0nNl.js";
3
3
  import { Clipboard } from "./Clipboard-CBJZiviP.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/blocks/ClipboardButton/ClipboardButton.tsx
@@ -40,4 +40,4 @@ const ClipboardInline = ({ text, tooltip, tooltipPlacement, tooltipVariant, chil
40
40
  //#endregion
41
41
  export { ClipboardButton, ClipboardInline };
42
42
 
43
- //# sourceMappingURL=ClipboardButton-ez5V3fkk.js.map
43
+ //# sourceMappingURL=ClipboardButton-ClcluT0C.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClipboardButton-ez5V3fkk.js","names":[],"sources":["../src/blocks/ClipboardButton/ClipboardButton.tsx","../src/blocks/ClipboardButton/ClipboardInline.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Clipboard } from '../../components/Clipboard';\nimport { Copy } from '../../icons';\n\ntype ClipboardProps = Pick<\n ComponentProps<typeof Clipboard>,\n 'text' | 'tooltip' | 'tooltipPlacement' | 'tooltipVariant'\n>;\n\ntype ButtonProps = Omit<ComponentProps<typeof Button>, 'disabled' | 'icon'>;\n\ntype Props = ClipboardProps & ButtonProps & { icon?: ReactNode };\n\nconst DEFAULT_ICON: ReactNode = <Copy />;\nconst DEFAULT_ARIA_LABEL = 'Copy';\n\nexport const ClipboardButton = ({\n // clipboard props\n text,\n tooltip,\n tooltipPlacement,\n tooltipVariant,\n\n // button props\n icon = DEFAULT_ICON,\n variant = 'outline',\n children,\n ...rest\n}: Props) => {\n // Icon-only (no text children): the `tooltip` is visual only, not an accessible\n // name, so fall back to it (when it's a string) or a sensible default. A\n // consumer-supplied `aria-label` in `rest` still wins.\n // A non-empty string tooltip names the action; an empty/absent tooltip still\n // needs a name, so fall back to the default rather than an empty aria-label.\n const defaultAriaLabel =\n typeof tooltip === 'string' && tooltip.trim() ? tooltip : DEFAULT_ARIA_LABEL;\n const ariaLabel = rest['aria-label'] ?? (children == null ? defaultAriaLabel : undefined);\n\n return (\n <Clipboard\n asChild\n tooltip={tooltip}\n tooltipPlacement={tooltipPlacement}\n tooltipVariant={tooltipVariant}\n text={text}\n >\n <Button {...rest} aria-label={ariaLabel} variant={variant} disabled={!text}>\n {icon}\n {children}\n </Button>\n </Clipboard>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { ButtonInline } from '../../components/Button';\nimport { Clipboard } from '../../components/Clipboard';\nimport { Copy } from '../../icons';\n\ntype ClipboardProps = Pick<\n ComponentProps<typeof Clipboard>,\n 'text' | 'tooltip' | 'tooltipPlacement' | 'tooltipVariant'\n>;\n\ntype ButtonProps = Omit<ComponentProps<typeof ButtonInline>, 'disabled'>;\n\ntype Props = { hideIcon?: boolean } & ClipboardProps & ButtonProps;\n\nexport const ClipboardInline = ({\n // clipboard props\n text,\n tooltip,\n tooltipPlacement,\n tooltipVariant,\n\n // button props\n children = 'Copy To Clipboard',\n hideIcon = false,\n ...rest\n}: Props) => (\n <Clipboard\n asChild\n text={text}\n tooltip={tooltip}\n tooltipPlacement={tooltipPlacement}\n tooltipVariant={tooltipVariant}\n >\n <ButtonInline {...rest} disabled={!text}>\n {!hideIcon && <Copy className=\"tw:size-4\" />}\n {children}\n </ButtonInline>\n </Clipboard>\n);\n"],"mappings":";;;;;AAeA,MAAM,eAA0B,oBAAC,MAAD,CAAO,CAAA;AACvC,MAAM,qBAAqB;AAE3B,MAAa,mBAAmB,EAE9B,MACA,SACA,kBACA,gBAGA,OAAO,cACP,UAAU,WACV,UACA,GAAG,WACQ;CAMX,MAAM,mBACJ,OAAO,YAAY,YAAY,QAAQ,KAAK,IAAI,UAAU;CAC5D,MAAM,YAAY,KAAK,kBAAkB,YAAY,OAAO,mBAAmB,KAAA;CAE/E,OACE,oBAAC,WAAD;EACE,SAAA;EACS;EACS;EACF;EACV;EAEN,UAAA,qBAAC,QAAD;GAAQ,GAAI;GAAM,cAAY;GAAoB;GAAS,UAAU,CAAC;GAAtE,UAAA,CACG,MACA,QACK;;CACC,CAAA;AAEf;;;ACvCA,MAAa,mBAAmB,EAE9B,MACA,SACA,kBACA,gBAGA,WAAW,qBACX,WAAW,OACX,GAAG,WAEH,oBAAC,WAAD;CACE,SAAA;CACM;CACG;CACS;CACF;CAEhB,UAAA,qBAAC,cAAD;EAAc,GAAI;EAAM,UAAU,CAAC;EAAnC,UAAA,CACG,CAAC,YAAY,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA,GAC1C,QACW;;AACL,CAAA"}
1
+ {"version":3,"file":"ClipboardButton-ClcluT0C.js","names":[],"sources":["../src/blocks/ClipboardButton/ClipboardButton.tsx","../src/blocks/ClipboardButton/ClipboardInline.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Clipboard } from '../../components/Clipboard';\nimport { Copy } from '../../icons';\n\ntype ClipboardProps = Pick<\n ComponentProps<typeof Clipboard>,\n 'text' | 'tooltip' | 'tooltipPlacement' | 'tooltipVariant'\n>;\n\ntype ButtonProps = Omit<ComponentProps<typeof Button>, 'disabled' | 'icon'>;\n\ntype Props = ClipboardProps & ButtonProps & { icon?: ReactNode };\n\nconst DEFAULT_ICON: ReactNode = <Copy />;\nconst DEFAULT_ARIA_LABEL = 'Copy';\n\nexport const ClipboardButton = ({\n // clipboard props\n text,\n tooltip,\n tooltipPlacement,\n tooltipVariant,\n\n // button props\n icon = DEFAULT_ICON,\n variant = 'outline',\n children,\n ...rest\n}: Props) => {\n // Icon-only (no text children): the `tooltip` is visual only, not an accessible\n // name, so fall back to it (when it's a string) or a sensible default. A\n // consumer-supplied `aria-label` in `rest` still wins.\n // A non-empty string tooltip names the action; an empty/absent tooltip still\n // needs a name, so fall back to the default rather than an empty aria-label.\n const defaultAriaLabel =\n typeof tooltip === 'string' && tooltip.trim() ? tooltip : DEFAULT_ARIA_LABEL;\n const ariaLabel = rest['aria-label'] ?? (children == null ? defaultAriaLabel : undefined);\n\n return (\n <Clipboard\n asChild\n tooltip={tooltip}\n tooltipPlacement={tooltipPlacement}\n tooltipVariant={tooltipVariant}\n text={text}\n >\n <Button {...rest} aria-label={ariaLabel} variant={variant} disabled={!text}>\n {icon}\n {children}\n </Button>\n </Clipboard>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { ButtonInline } from '../../components/Button';\nimport { Clipboard } from '../../components/Clipboard';\nimport { Copy } from '../../icons';\n\ntype ClipboardProps = Pick<\n ComponentProps<typeof Clipboard>,\n 'text' | 'tooltip' | 'tooltipPlacement' | 'tooltipVariant'\n>;\n\ntype ButtonProps = Omit<ComponentProps<typeof ButtonInline>, 'disabled'>;\n\ntype Props = { hideIcon?: boolean } & ClipboardProps & ButtonProps;\n\nexport const ClipboardInline = ({\n // clipboard props\n text,\n tooltip,\n tooltipPlacement,\n tooltipVariant,\n\n // button props\n children = 'Copy To Clipboard',\n hideIcon = false,\n ...rest\n}: Props) => (\n <Clipboard\n asChild\n text={text}\n tooltip={tooltip}\n tooltipPlacement={tooltipPlacement}\n tooltipVariant={tooltipVariant}\n >\n <ButtonInline {...rest} disabled={!text}>\n {!hideIcon && <Copy className=\"tw:size-4\" />}\n {children}\n </ButtonInline>\n </Clipboard>\n);\n"],"mappings":";;;;;AAeA,MAAM,eAA0B,oBAAC,MAAD,CAAO,CAAA;AACvC,MAAM,qBAAqB;AAE3B,MAAa,mBAAmB,EAE9B,MACA,SACA,kBACA,gBAGA,OAAO,cACP,UAAU,WACV,UACA,GAAG,WACQ;CAMX,MAAM,mBACJ,OAAO,YAAY,YAAY,QAAQ,KAAK,IAAI,UAAU;CAC5D,MAAM,YAAY,KAAK,kBAAkB,YAAY,OAAO,mBAAmB,KAAA;CAE/E,OACE,oBAAC,WAAD;EACE,SAAA;EACS;EACS;EACF;EACV;EAEN,UAAA,qBAAC,QAAD;GAAQ,GAAI;GAAM,cAAY;GAAoB;GAAS,UAAU,CAAC;GAAtE,UAAA,CACG,MACA,QACK;;CACC,CAAA;AAEf;;;ACvCA,MAAa,mBAAmB,EAE9B,MACA,SACA,kBACA,gBAGA,WAAW,qBACX,WAAW,OACX,GAAG,WAEH,oBAAC,WAAD;CACE,SAAA;CACM;CACG;CACS;CACF;CAEhB,UAAA,qBAAC,cAAD;EAAc,GAAI;EAAM,UAAU,CAAC;EAAnC,UAAA,CACG,CAAC,YAAY,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA,GAC1C,QACW;;AACL,CAAA"}
@@ -2,7 +2,7 @@ import { cn } from "./classNames-BzrkDnOD.js";
2
2
  import { isMac, keyCodes } from "./utils-D0c5VAyF.js";
3
3
  import { useArgoDesign } from "./context-KxxeMHbR.js";
4
4
  import { escapeStringRegexp } from "./escapeStringRegexp-8MxP2knR.js";
5
- import { ClipboardButton } from "./ClipboardButton-ez5V3fkk.js";
5
+ import { ClipboardButton } from "./ClipboardButton-ClcluT0C.js";
6
6
  import { HelpBlock } from "./internal/components/HelpBlock.js";
7
7
  import { Kbd } from "./Kbd-CxHAo1oo.js";
8
8
  import { useStableCallback } from "./internal/hooks/useStableCallback.js";
@@ -10,19 +10,19 @@ import { resolveToken, useThemeAttributes } from "./themeTokens-BNg98Mu9.js";
10
10
  import { useEffect, useLayoutEffect, useMemo, useRef } from "react";
11
11
  import { jsx, jsxs } from "react/jsx-runtime";
12
12
  import { autocompletion, completeAnyWord } from "@codemirror/autocomplete";
13
- import { json, jsonParseLinter } from "@codemirror/lang-json";
14
- import { linter } from "@codemirror/lint";
15
13
  import { unifiedMergeView } from "@codemirror/merge";
16
14
  import { Decoration, EditorView, ViewPlugin, keymap, placeholder, tooltips } from "@codemirror/view";
17
15
  import CodeMirror, { EditorState } from "@uiw/react-codemirror";
18
16
  import colors from "@keboola/tailwind-config/colors";
19
17
  import { javascript } from "@codemirror/lang-javascript";
18
+ import { json, jsonParseLinter } from "@codemirror/lang-json";
20
19
  import { python } from "@codemirror/lang-python";
21
20
  import { MSSQL, MySQL, PLSQL, PostgreSQL, StandardSQL } from "@codemirror/lang-sql";
22
21
  import { StreamLanguage } from "@codemirror/language";
23
22
  import { r } from "@codemirror/legacy-modes/mode/r";
24
23
  import { shell } from "@codemirror/legacy-modes/mode/shell";
25
24
  import { toml } from "@codemirror/legacy-modes/mode/toml";
25
+ import { linter } from "@codemirror/lint";
26
26
  import { tags } from "@lezer/highlight";
27
27
  import { githubLightInit } from "@uiw/codemirror-theme-github";
28
28
  import { getSqlLanguageSupport } from "@keboola/codemirror-lang-sql";
@@ -424,8 +424,9 @@ const buildBasicSetup = (readOnly) => ({
424
424
  highlightSelectionMatches: false
425
425
  } : null
426
426
  });
427
- const buildCustomTheme = () => {
427
+ const buildCustomTheme = (scheme) => {
428
428
  const foreground = resolveToken("foreground", "30 41 59");
429
+ const dark = scheme === "dark";
429
430
  return githubLightInit({
430
431
  settings: {
431
432
  fontFamily: `'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New'`,
@@ -456,7 +457,7 @@ const buildCustomTheme = () => {
456
457
  },
457
458
  {
458
459
  tag: tags.string,
459
- color: colors.warning[700]
460
+ color: dark ? colors.warning[300] : colors.warning[800]
460
461
  }
461
462
  ]
462
463
  });
@@ -487,6 +488,32 @@ const getLanguageMode = (mode) => {
487
488
  }
488
489
  };
489
490
  const shouldLintJson = (mode, readOnly) => mode === "application/json" && !readOnly;
491
+ /**
492
+ * Wraps a lint source so a blank document produces no diagnostics.
493
+ *
494
+ * `jsonParseLinter` reports "Unexpected end of input" for empty content, which is right for a file and
495
+ * wrong for an *optional* form field: it starts empty, and clearing it is how its value is removed.
496
+ * Left unwrapped, every such field opens with a red gutter marker contradicting its own validation —
497
+ * `CodeEditorField` puts six of them on one screen.
498
+ *
499
+ * Exported for its test: the wrapper is the behaviour worth pinning, and it needs no editor to exercise.
500
+ */
501
+ const skipBlankDocument = (source) => (view) => view.state.doc.toString().trim() === "" ? [] : source(view);
502
+ /**
503
+ * The JSON linter, optionally blind to a blank document.
504
+ *
505
+ * - `allowBlankDocument` is opt-in, and only `CodeEditorField` opts in (from `!required`). Suppressing
506
+ * the marker by default would break callers that treat empty as invalid *and* say so nowhere else:
507
+ * `ex-generic/JsonConfiguration.tsx`, `flows/TaskParamsModalContent.tsx` and
508
+ * `stream/PayloadTest.tsx` all gate their button on `isValidJsonConfig`, which is `false` for `''`,
509
+ * with no `disabledReason` — so the gutter marker is the only thing explaining a dead button.
510
+ * - Not derivable from `variant`: `ex-generic/FunctionControl.tsx` is `variant="field"` and empty is
511
+ * an error there too. Whether blank is valid is the *field's* contract, not the control's shape.
512
+ */
513
+ const buildJsonLinter = (allowBlankDocument) => {
514
+ const source = jsonParseLinter();
515
+ return linter(allowBlankDocument ? skipBlankDocument(source) : source);
516
+ };
490
517
  //#endregion
491
518
  //#region src/components/CodeEditor/editorChrome.ts
492
519
  /**
@@ -817,10 +844,27 @@ const useVariableCompletion = (variables = []) => useStableCallback(completeVari
817
844
  //#endregion
818
845
  //#region src/components/CodeEditor/CodeEditor.tsx
819
846
  const emptyObject = {};
820
- const CodeEditor = ({ value, previousValue, onChange, variant = "plain", mode = "application/json", placeholder: placeholder$1 = "", ariaLabel, searchQuery, searchMatchIndex, readOnly = false, inputLocked = false, autocompletions, completionSource, variables, extraKeys = emptyObject, withToggleCommentHint = false, withAutofocus = false, withLineNumbers = true, withLineWrapping = true, withCollapseUnchanged = false, withCopyButton = false, completeAny = false, help = null, helpPostfix = null, renderAdditionalButtons, className }) => {
847
+ const CodeEditor = ({ value, previousValue, onChange, variant = "plain", mode = "application/json", placeholder: placeholder$1 = "", ariaLabel, ariaLabelledBy, ariaDescribedBy, ariaInvalid, ariaRequired, allowBlankDocument = false, onBlur, searchQuery, searchMatchIndex, readOnly = false, inputLocked = false, autocompletions, completionSource, variables, extraKeys = emptyObject, withToggleCommentHint = false, withAutofocus = false, withLineNumbers = true, withLineWrapping = true, withCollapseUnchanged = false, withCopyButton = false, completeAny = false, help = null, helpPostfix = null, renderAdditionalButtons, className }) => {
821
848
  const handleChange = useStableCallback((next) => onChange?.(next));
849
+ const handleBlur = useStableCallback(() => onBlur?.());
822
850
  const withSearch = searchQuery !== void 0;
851
+ const withBlur = onBlur !== void 0;
823
852
  const editorRef = useRef(null);
853
+ const contentAria = useMemo(() => {
854
+ const attributes = {};
855
+ if (ariaLabel !== void 0) attributes["aria-label"] = ariaLabel;
856
+ if (ariaLabelledBy !== void 0) attributes["aria-labelledby"] = ariaLabelledBy;
857
+ if (ariaDescribedBy !== void 0) attributes["aria-describedby"] = ariaDescribedBy;
858
+ if (ariaInvalid !== void 0) attributes["aria-invalid"] = String(ariaInvalid);
859
+ if (ariaRequired !== void 0) attributes["aria-required"] = String(ariaRequired);
860
+ return Object.keys(attributes).length > 0 ? attributes : null;
861
+ }, [
862
+ ariaLabel,
863
+ ariaLabelledBy,
864
+ ariaDescribedBy,
865
+ ariaInvalid,
866
+ ariaRequired
867
+ ]);
824
868
  useEffect(() => {
825
869
  const view = editorRef.current?.view;
826
870
  if (view && withSearch) updateSearch(view, searchQuery, searchMatchIndex);
@@ -852,7 +896,7 @@ const CodeEditor = ({ value, previousValue, onChange, variant = "plain", mode =
852
896
  const completionEntries = [...callerCompletions ? [{ autocomplete: callerCompletions }] : [], { autocomplete: variableCompletion }];
853
897
  return [
854
898
  getLanguageMode(mode),
855
- shouldLintJson(mode, readOnly) ? linter(jsonParseLinter()) : [],
899
+ shouldLintJson(mode, readOnly) ? buildJsonLinter(allowBlankDocument) : [],
856
900
  withLineWrapping ? EditorView.lineWrapping : [],
857
901
  EditorState.languageData.of(() => completionEntries),
858
902
  keymap.of(boundKeys.map((key) => ({
@@ -863,7 +907,8 @@ const CodeEditor = ({ value, previousValue, onChange, variant = "plain", mode =
863
907
  }
864
908
  }))),
865
909
  readOnly ? [] : [autocompletion()],
866
- ariaLabel ? EditorView.contentAttributes.of({ "aria-label": ariaLabel }) : [],
910
+ contentAria ? EditorView.contentAttributes.of(contentAria) : [],
911
+ withBlur ? EditorView.domEventHandlers({ blur: handleBlur }) : [],
867
912
  withSearch ? searchExtension() : [],
868
913
  tooltipLayer,
869
914
  baseTheme
@@ -876,9 +921,12 @@ const CodeEditor = ({ value, previousValue, onChange, variant = "plain", mode =
876
921
  boundKeys,
877
922
  mode,
878
923
  readOnly,
924
+ allowBlankDocument,
879
925
  withLineWrapping,
880
926
  baseTheme,
881
- ariaLabel,
927
+ contentAria,
928
+ withBlur,
929
+ handleBlur,
882
930
  withSearch,
883
931
  tooltipLayer
884
932
  ]);
@@ -949,4 +997,4 @@ const CodeEditor = ({ value, previousValue, onChange, variant = "plain", mode =
949
997
  //#endregion
950
998
  export { CodeEditor, LANGUAGE_MODES, buildBaseThemeStyles, buildBasicSetup, buildCanvasChrome, buildChromeStyles, buildCustomTheme, isLanguageMode, searchExtension, updateSearch, useThemedExtension, useTooltipsExtension, useVariableCompletion };
951
999
 
952
- //# sourceMappingURL=CodeEditor-BfQJfbhL.js.map
1000
+ //# sourceMappingURL=CodeEditor-DyaN-Ij2.js.map