@keboola/design 11.4.0 → 11.6.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 (184) hide show
  1. package/AGENTS.md +198 -7
  2. package/CHANGELOG.md +383 -0
  3. package/COMPONENT-API.md +73 -52
  4. package/dist/{AIKit-DDg5DBCG.js → AIKit-BExvt9pt.js} +390 -70
  5. package/dist/AIKit-BExvt9pt.js.map +1 -0
  6. package/dist/{Alert-DHJFrWnS.js → Alert-Ba5b2YPq.js} +2 -2
  7. package/dist/{Alert-DHJFrWnS.js.map → Alert-Ba5b2YPq.js.map} +1 -1
  8. package/dist/{Badge-Ch26CXoP.js → Badge-D0pXdekt.js} +2 -2
  9. package/dist/Badge-D0pXdekt.js.map +1 -0
  10. package/dist/{BrandEditor-Go7w8Zj2.js → BrandEditor-CSANsxUz.js} +6 -6
  11. package/dist/{BrandEditor-Go7w8Zj2.js.map → BrandEditor-CSANsxUz.js.map} +1 -1
  12. package/dist/{BrandLogo-Dmi7jo21.js → BrandLogo-CoKBk4MI.js} +4 -4
  13. package/dist/BrandLogo-CoKBk4MI.js.map +1 -0
  14. package/dist/{Breadcrumb-uEkM6adI.js → Breadcrumb-g_xn_-Nf.js} +2 -2
  15. package/dist/{Breadcrumb-uEkM6adI.js.map → Breadcrumb-g_xn_-Nf.js.map} +1 -1
  16. package/dist/{Checkbox-fC0BuO2B.js → Checkbox-CUIn2jap.js} +2 -2
  17. package/dist/{Checkbox-fC0BuO2B.js.map → Checkbox-CUIn2jap.js.map} +1 -1
  18. package/dist/{Clipboard-ChPdiUy3.js → Clipboard-BTW6C-b_.js} +2 -2
  19. package/dist/{Clipboard-ChPdiUy3.js.map → Clipboard-BTW6C-b_.js.map} +1 -1
  20. package/dist/{ClipboardButton-D9pDjgkB.js → ClipboardButton-CwZJdRaz.js} +2 -2
  21. package/dist/{ClipboardButton-D9pDjgkB.js.map → ClipboardButton-CwZJdRaz.js.map} +1 -1
  22. package/dist/{CodeEditor-Cxy3HnKH.js → CodeEditor-C9zy7PxK.js} +6 -6
  23. package/dist/{CodeEditor-Cxy3HnKH.js.map → CodeEditor-C9zy7PxK.js.map} +1 -1
  24. package/dist/{ColorInput-Bxj-1eLT.js → ColorInput-BZV-u_94.js} +3 -3
  25. package/dist/{ColorInput-Bxj-1eLT.js.map → ColorInput-BZV-u_94.js.map} +1 -1
  26. package/dist/{Combobox-Cs_1pj2q.js → Combobox-BfIfaVMA.js} +273 -104
  27. package/dist/Combobox-BfIfaVMA.js.map +1 -0
  28. package/dist/{Command-B7ML9YMv.js → Command-Bfa1kpbt.js} +2 -2
  29. package/dist/{Command-B7ML9YMv.js.map → Command-Bfa1kpbt.js.map} +1 -1
  30. package/dist/{CopyField-BO_sh-HO.js → CopyField-DpT0Ngz1.js} +2 -2
  31. package/dist/{CopyField-BO_sh-HO.js.map → CopyField-DpT0Ngz1.js.map} +1 -1
  32. package/dist/{DateInput-ZdaMQo5i.js → DateInput-DiEd5uCL.js} +3 -3
  33. package/dist/{DateInput-ZdaMQo5i.js.map → DateInput-DiEd5uCL.js.map} +1 -1
  34. package/dist/{DateRangeInput-DkvNh_sT.js → DateRangeInput-DPfVYchl.js} +3 -3
  35. package/dist/{DateRangeInput-DkvNh_sT.js.map → DateRangeInput-DPfVYchl.js.map} +1 -1
  36. package/dist/DiagramSource-C5_d8Gdj.js +11 -0
  37. package/dist/DiagramSource-C5_d8Gdj.js.map +1 -0
  38. package/dist/{FieldItem-CCd9-xnp.js → FieldItem-B7XMmZSz.js} +3 -3
  39. package/dist/{FieldItem-CCd9-xnp.js.map → FieldItem-B7XMmZSz.js.map} +1 -1
  40. package/dist/{Form-k6PH-em3.js → Form-CsttTHn4.js} +7 -7
  41. package/dist/Form-CsttTHn4.js.map +1 -0
  42. package/dist/{FormGroup-DbcDtrgU.js → FormGroup-DHvTFdno.js} +3 -3
  43. package/dist/{FormGroup-DbcDtrgU.js.map → FormGroup-DHvTFdno.js.map} +1 -1
  44. package/dist/{FullScreenModal-BvPuYibe.js → FullScreenModal-CN9nAs72.js} +50 -2
  45. package/dist/FullScreenModal-CN9nAs72.js.map +1 -0
  46. package/dist/{InputGroup-BnLHY0eq.js → InputGroup-DcZRlVnN.js} +22 -14
  47. package/dist/InputGroup-DcZRlVnN.js.map +1 -0
  48. package/dist/{Kbd-CvSM3D3-.js → Kbd-Cvvt91Q8.js} +14 -4
  49. package/dist/Kbd-Cvvt91Q8.js.map +1 -0
  50. package/dist/{MermaidDiagram-WkonYErO.js → MermaidDiagram-DSI7xMu2.js} +21 -19
  51. package/dist/MermaidDiagram-DSI7xMu2.js.map +1 -0
  52. package/dist/{MultiActionButtonGroup-CxWH7yWK.js → MultiActionButtonGroup-DokHbPgM.js} +2 -2
  53. package/dist/{MultiActionButtonGroup-CxWH7yWK.js.map → MultiActionButtonGroup-DokHbPgM.js.map} +1 -1
  54. package/dist/{Navbar-B2UsolVU.js → Navbar-Liy1TPI7.js} +6 -6
  55. package/dist/{Navbar-B2UsolVU.js.map → Navbar-Liy1TPI7.js.map} +1 -1
  56. package/dist/PageHeader-Q3IpCnQd.js.map +1 -1
  57. package/dist/{PageToolbar-DnbFt14Q.js → PageToolbar-DExqEYGl.js} +2 -2
  58. package/dist/{PageToolbar-DnbFt14Q.js.map → PageToolbar-DExqEYGl.js.map} +1 -1
  59. package/dist/{Popconfirm-CILjmzKI.js → Popconfirm-5pBzT_HQ.js} +10 -11
  60. package/dist/{Popconfirm-CILjmzKI.js.map → Popconfirm-5pBzT_HQ.js.map} +1 -1
  61. package/dist/{RadioGroup-XFzFd1ti.js → RadioGroup-DXPbSj8P.js} +2 -2
  62. package/dist/{RadioGroup-XFzFd1ti.js.map → RadioGroup-DXPbSj8P.js.map} +1 -1
  63. package/dist/{Search-4Bxtt8hS.js → Search-5uQAiNIP.js} +2 -2
  64. package/dist/{Search-4Bxtt8hS.js.map → Search-5uQAiNIP.js.map} +1 -1
  65. package/dist/{SearchInput-f_oY9T4Z.js → SearchInput-D4UgAXJK.js} +3 -3
  66. package/dist/{SearchInput-f_oY9T4Z.js.map → SearchInput-D4UgAXJK.js.map} +1 -1
  67. package/dist/{SectionNav-BpJlisbT.js → SectionNav-OkKCjSA-.js} +3 -3
  68. package/dist/{SectionNav-BpJlisbT.js.map → SectionNav-OkKCjSA-.js.map} +1 -1
  69. package/dist/{Select-DpcgKqKB.js → Select-DV3Hak_l.js} +3 -4
  70. package/dist/Select-DV3Hak_l.js.map +1 -0
  71. package/dist/{Sidebar-Cm6I4dE1.js → Sidebar-D3cY1kha.js} +44 -20
  72. package/dist/Sidebar-D3cY1kha.js.map +1 -0
  73. package/dist/{Slider-pPC_3gz9.js → Slider-CRf-bB4y.js} +2 -2
  74. package/dist/{Slider-pPC_3gz9.js.map → Slider-CRf-bB4y.js.map} +1 -1
  75. package/dist/{Switch-ChfPKcTE.js → Switch-B0WdGSjz.js} +7 -7
  76. package/dist/{Switch-ChfPKcTE.js.map → Switch-B0WdGSjz.js.map} +1 -1
  77. package/dist/{TextInput-DHM6dHmn.js → TextInput-DH5SkbsE.js} +3 -3
  78. package/dist/{TextInput-DHM6dHmn.js.map → TextInput-DH5SkbsE.js.map} +1 -1
  79. package/dist/{ThemeProvider-DrQJtzpd.js → ThemeProvider-2RMdVGxO.js} +17 -12
  80. package/dist/{ThemeProvider-DrQJtzpd.js.map → ThemeProvider-2RMdVGxO.js.map} +1 -1
  81. package/dist/{Timeline-6btyJl4D.js → Timeline-BG5Xogxh.js} +11 -11
  82. package/dist/{Timeline-6btyJl4D.js.map → Timeline-BG5Xogxh.js.map} +1 -1
  83. package/dist/{Workbench-BzE-Vvd9.js → Workbench-UR2FBC7I.js} +3 -1
  84. package/dist/Workbench-UR2FBC7I.js.map +1 -0
  85. package/dist/{ZoomableSvg-BWnDkR61.js → ZoomableSvg-pooPb1Cu.js} +3 -3
  86. package/dist/{ZoomableSvg-BWnDkR61.js.map → ZoomableSvg-pooPb1Cu.js.map} +1 -1
  87. package/dist/editors.js +4 -4
  88. package/dist/flint.js +136 -9
  89. package/dist/flint.js.map +1 -1
  90. package/dist/index.d.ts +801 -324
  91. package/dist/index.js +41 -40
  92. package/dist/internal/blocks/AIKit.js +2 -2
  93. package/dist/internal/blocks/AuthLayout.js +118 -0
  94. package/dist/internal/blocks/AuthLayout.js.map +1 -0
  95. package/dist/internal/blocks/BrandEditor.js +1 -1
  96. package/dist/internal/blocks/ClipboardButton.js +1 -1
  97. package/dist/internal/blocks/ColorInput.js +1 -1
  98. package/dist/internal/blocks/Command.js +1 -1
  99. package/dist/internal/blocks/CopyField.js +1 -1
  100. package/dist/internal/blocks/DateInput.js +1 -1
  101. package/dist/internal/blocks/DateRangeInput.js +1 -1
  102. package/dist/internal/blocks/ExportMenu.js +1 -1
  103. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  104. package/dist/internal/blocks/Form.js +1 -1
  105. package/dist/internal/blocks/FormGroup.js +1 -1
  106. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  107. package/dist/internal/blocks/MultiCombobox.js +107 -48
  108. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  109. package/dist/internal/blocks/NumberInput.js +1 -1
  110. package/dist/internal/blocks/PageToolbar.js +1 -1
  111. package/dist/internal/blocks/PasswordInput.js +2 -2
  112. package/dist/internal/blocks/SearchInput.js +1 -1
  113. package/dist/internal/blocks/SearchInputWithNavigation.js +2 -2
  114. package/dist/internal/blocks/SectionNav.js +1 -1
  115. package/dist/internal/blocks/TextInput.js +1 -1
  116. package/dist/internal/blocks/Textarea.js +1 -1
  117. package/dist/internal/blocks/TimeInput.js +2 -2
  118. package/dist/internal/components/Alert.js +1 -1
  119. package/dist/internal/components/Avatar.js +1 -1
  120. package/dist/internal/components/Badge.js +1 -1
  121. package/dist/internal/components/BrandLogo.js +1 -1
  122. package/dist/internal/components/Breadcrumb.js +1 -1
  123. package/dist/internal/components/Checkbox.js +1 -1
  124. package/dist/internal/components/Clipboard.js +1 -1
  125. package/dist/internal/components/CollapsiblePanel.js +1 -1
  126. package/dist/internal/components/Combobox.js +2 -2
  127. package/dist/internal/components/FullScreenModal.js +1 -1
  128. package/dist/internal/components/InputGroup.js +1 -1
  129. package/dist/internal/components/Kbd.js +1 -1
  130. package/dist/internal/components/Navbar.js +1 -1
  131. package/dist/internal/components/Popconfirm.js +1 -1
  132. package/dist/internal/components/Progress.js +3 -1
  133. package/dist/internal/components/Progress.js.map +1 -1
  134. package/dist/internal/components/RadioGroup.js +1 -1
  135. package/dist/internal/components/Search.js +1 -1
  136. package/dist/internal/components/Select.js +1 -1
  137. package/dist/internal/components/Sidebar.js +1 -1
  138. package/dist/internal/components/Slider.js +1 -1
  139. package/dist/internal/components/Switch.js +1 -1
  140. package/dist/internal/components/ThemeProvider.js +1 -1
  141. package/dist/internal/components/Timeline.js +1 -1
  142. package/dist/internal/components/Tooltip.js +1 -1
  143. package/dist/internal/components/Truncated.js +1 -1
  144. package/dist/internal/components/Workbench.js +1 -1
  145. package/dist/internal/components/ZoomableSvg.js +1 -1
  146. package/dist/internal/utils.js +2 -2
  147. package/dist/markdown-editor.js +29 -23
  148. package/dist/markdown-editor.js.map +1 -1
  149. package/dist/mermaid.js +1 -1
  150. package/dist/rjsf.js +22 -23
  151. package/dist/rjsf.js.map +1 -1
  152. package/dist/styles.css +1 -1
  153. package/dist/{svgTransforms-C9njt92h.js → svgTransforms-CJAYPk7o.js} +2 -10
  154. package/dist/svgTransforms-CJAYPk7o.js.map +1 -0
  155. package/dist/testing.js +1 -1
  156. package/dist/{useColorSchemeState-klihG9-i.js → themeScopeContext-D7fSyb06.js} +16 -3
  157. package/dist/themeScopeContext-D7fSyb06.js.map +1 -0
  158. package/dist/{themeTokens-D70HeNVF.js → themeTokens-qP1-55O7.js} +37 -10
  159. package/dist/themeTokens-qP1-55O7.js.map +1 -0
  160. package/dist/{utils-B5Z52hYs.js → utils-DSvrhU8E.js} +6 -2
  161. package/dist/{utils-B5Z52hYs.js.map → utils-DSvrhU8E.js.map} +1 -1
  162. package/dist/vega.d.ts +1 -1
  163. package/dist/vega.js +3 -3
  164. package/dist/vega.js.map +1 -1
  165. package/dist/{vegaTheme-DfoEQhOy.js → vegaTheme-CSvFEMBl.js} +6 -6
  166. package/dist/vegaTheme-CSvFEMBl.js.map +1 -0
  167. package/package.json +11 -9
  168. package/src/styles.css +3 -0
  169. package/dist/AIKit-DDg5DBCG.js.map +0 -1
  170. package/dist/Badge-Ch26CXoP.js.map +0 -1
  171. package/dist/BrandLogo-Dmi7jo21.js.map +0 -1
  172. package/dist/Combobox-Cs_1pj2q.js.map +0 -1
  173. package/dist/Form-k6PH-em3.js.map +0 -1
  174. package/dist/FullScreenModal-BvPuYibe.js.map +0 -1
  175. package/dist/InputGroup-BnLHY0eq.js.map +0 -1
  176. package/dist/Kbd-CvSM3D3-.js.map +0 -1
  177. package/dist/MermaidDiagram-WkonYErO.js.map +0 -1
  178. package/dist/Select-DpcgKqKB.js.map +0 -1
  179. package/dist/Sidebar-Cm6I4dE1.js.map +0 -1
  180. package/dist/Workbench-BzE-Vvd9.js.map +0 -1
  181. package/dist/svgTransforms-C9njt92h.js.map +0 -1
  182. package/dist/themeTokens-D70HeNVF.js.map +0 -1
  183. package/dist/useColorSchemeState-klihG9-i.js.map +0 -1
  184. package/dist/vegaTheme-DfoEQhOy.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MermaidDiagram-DSI7xMu2.js","names":[],"sources":["../src/blocks/MermaidDiagram/mermaidTheme.ts","../src/blocks/MermaidDiagram/MermaidDiagram.tsx"],"sourcesContent":["import type { RenderOptions } from 'beautiful-mermaid';\nimport type { MermaidConfig } from 'mermaid';\n\nimport type { ResolvedColorScheme } from '../../components/ThemeProvider/types';\nimport { createTokenResolver } from '../../utils/themeTokens';\n\nconst DIAGRAM_FONT = 'Inter, system-ui, sans-serif';\n\n/**\n * Fallback channels for the tokens the diagram palette reads, mirroring the\n * `:root` / `[data-theme='dark']` blocks of `styles.css`.\n *\n * `resolveToken` only reaches these when the live custom property is missing —\n * SSR, or a unit test that loads no CSS. In the browser the computed value wins,\n * which is what makes a customer brand re-skin the diagram for free.\n */\nconst FALLBACK_CHANNELS = {\n card: { light: '255 255 255', dark: '34 34 40' },\n 'card-foreground': { light: '30 41 59', dark: '229 230 236' },\n foreground: { light: '30 41 59', dark: '229 230 236' },\n muted: { light: '241 245 249', dark: '38 38 45' },\n 'muted-foreground': { light: '100 116 139', dark: '141 144 153' },\n border: { light: '229 231 235', dark: '52 53 62' },\n primary: { light: '37 99 235', dark: '31 143 255' },\n accent: { light: '224 242 254', dark: '30 58 95' },\n 'accent-foreground': { light: '13 65 127', dark: '147 197 253' },\n warning: { light: '138 82 16', dark: '255 190 92' },\n success: { light: '24 122 76', dark: '62 207 127' },\n destructive: { light: '220 38 38', dark: '229 72 77' },\n} as const;\n\ntype TokenName = keyof typeof FALLBACK_CHANNELS;\n\n/**\n * Binds a token lookup to one `getComputedStyle` snapshot for the whole palette.\n * Built per call, never hoisted: the values move with the scheme and the brand.\n */\nconst tokenReader = (scheme: ResolvedColorScheme, from?: Element | null) => {\n const resolve = createTokenResolver(from);\n return (name: TokenName, alpha?: number): string =>\n resolve(name, FALLBACK_CHANNELS[name][scheme], alpha);\n};\n\n/**\n * Palette for `beautiful-mermaid`'s synchronous renderer. It sets these as CSS\n * variables on the `<svg>` and derives everything else it needs from `bg` + `fg`\n * with `color-mix()` — which is why leaving them at the library defaults painted\n * a near-white node fill (#f8f8f8, mixed from a white `bg`) on a dark page.\n *\n * `transparent` keeps the page background showing through, so `bg` only feeds\n * those derivations; the node fill is pinned explicitly via `surface`.\n */\nexport const fastRenderOptions = (\n scheme: ResolvedColorScheme,\n from?: Element | null,\n): RenderOptions => {\n const token = tokenReader(scheme, from);\n\n return {\n bg: token('card'),\n fg: token('foreground'),\n line: token('border'),\n accent: token('primary'),\n muted: token('muted-foreground'),\n surface: token('muted'),\n border: token('border'),\n transparent: true,\n font: DIAGRAM_FONT,\n };\n};\n\n/**\n * Config for the async `mermaid` renderer (the fallback for dialects the fast\n * renderer can't parse, and for icon-pack diagrams).\n *\n * Built on the `base` theme so every colour comes from `themeVariables` rather\n * than mermaid's own light/dark palettes. Node chrome maps to the `accent` pair\n * (a tinted surface with a legible foreground in both schemes), containers to\n * `card`, and the gantt/note states to the status tokens — consumed as a low\n * alpha tint plus a solid mark, per the brand-neutrality contract, since the\n * status tokens themselves are text-legible colours rather than fills.\n */\nexport const mermaidConfig = (\n scheme: ResolvedColorScheme,\n from?: Element | null,\n): MermaidConfig => {\n const token = tokenReader(scheme, from);\n\n const surface = token('accent');\n const onSurface = token('accent-foreground');\n const container = token('card');\n const onContainer = token('card-foreground');\n const line = token('border');\n const stroke = token('primary');\n const text = token('foreground');\n\n return {\n startOnLoad: false,\n securityLevel: 'strict',\n theme: 'base',\n themeVariables: {\n darkMode: scheme === 'dark',\n background: container,\n primaryColor: surface,\n primaryTextColor: onSurface,\n primaryBorderColor: stroke,\n secondaryColor: container,\n secondaryTextColor: onContainer,\n secondaryBorderColor: line,\n tertiaryColor: token('warning', 0.15),\n tertiaryTextColor: token('warning'),\n tertiaryBorderColor: token('warning'),\n lineColor: line,\n textColor: text,\n mainBkg: surface,\n nodeBorder: stroke,\n clusterBkg: container,\n clusterBorder: line,\n titleColor: text,\n edgeLabelBackground: container,\n nodeTextColor: onSurface,\n actorBorder: stroke,\n actorBkg: surface,\n actorTextColor: onSurface,\n actorLineColor: line,\n signalColor: text,\n signalTextColor: text,\n labelBoxBkgColor: surface,\n labelBoxBorderColor: stroke,\n labelTextColor: onSurface,\n loopTextColor: text,\n noteBorderColor: token('warning'),\n noteBkgColor: token('warning', 0.15),\n noteTextColor: text,\n sectionBkgColor: surface,\n altSectionBkgColor: container,\n sectionBkgColor2: token('muted'),\n taskBorderColor: stroke,\n taskBkgColor: surface,\n taskTextColor: onSurface,\n taskTextDarkColor: text,\n taskTextLightColor: text,\n activeTaskBorderColor: stroke,\n activeTaskBkgColor: token('primary', 0.25),\n doneTaskBorderColor: token('success'),\n doneTaskBkgColor: token('success', 0.15),\n critBorderColor: token('destructive'),\n critBkgColor: token('destructive', 0.15),\n fontFamily: DIAGRAM_FONT,\n fontSize: '14px',\n },\n };\n};\n","import { useEffect, useId, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { renderMermaidSVG } from 'beautiful-mermaid';\nimport type mermaid from 'mermaid';\n\nimport type { ResolvedColorScheme } from '../../components/ThemeProvider/types';\nimport { useThemeAttributes } from '../../components/ThemeProvider/useThemeAttributes';\nimport { ZoomableSvg } from '../../components/ZoomableSvg';\nimport { DiagramSkeleton } from '../DiagramShared/DiagramSkeleton';\nimport { DiagramSource } from '../DiagramShared/DiagramSource';\nimport {\n flattenForeignObjectLabels,\n hasDrawnContent,\n makeResponsive,\n} from '../DiagramShared/svgTransforms';\n\nimport { fastRenderOptions, mermaidConfig } from './mermaidTheme';\n\ntype MermaidModule = { default: typeof mermaid };\n\nlet mermaidPromise: Promise<MermaidModule> | null = null;\n\n// Iconify icon pack registered with mermaid so `@{ icon: \"lucide:name\" }` node\n// shapes and `architecture-beta service <id>(lucide:name)` render — keeping\n// diagram glyphs consistent with the Lucide icons used across the rest of the UI.\n// The pack JSON resolves from a workspace dependency (no CDN fetch) via a dynamic\n// import, so it lands in its own lazy chunk and icons render offline / under a\n// strict CSP without weighing down the initial bundle.\nconst registerLucideIconPack = (m: typeof mermaid): void => {\n m.registerIconPacks([\n {\n name: 'lucide',\n loader: () => import('@iconify-json/lucide/icons.json').then((mod) => mod.default),\n },\n ]);\n};\n\nconst getMermaid = (): Promise<MermaidModule> => {\n if (!mermaidPromise) {\n mermaidPromise = import('mermaid')\n .then((m) => {\n registerLucideIconPack(m.default);\n return m;\n })\n .catch((err) => {\n mermaidPromise = null;\n throw err;\n });\n }\n return mermaidPromise;\n};\n\nconst stripFontImports = (svg: string): string =>\n svg.replace(/@import\\s+url\\([^)]*fonts\\.googleapis\\.com[^)]*\\);?\\s*/g, '');\n\n// beautiful-mermaid's synchronous renderer has no icon-pack support, so a diagram\n// using icon syntax must skip the fast path and take the async mermaid render\n// (which registers the pack). Matches:\n// - the flowchart / treeView icon shape `@{ icon: \"pack:name\" }`\n// - `architecture-beta` / `treeView` refs `icon|service|group <id>(pack:name)`\n// (the id between keyword and `(` is optional)\n// - legacy FontAwesome refs `fa:fa-*` / `fab:` embedded in node text\nconst hasIconSyntax = (code: string): boolean =>\n /@\\{[^}]*\\bicon\\s*:/.test(code) ||\n /\\b(?:icon|service|group)\\b[^\\n(]*\\(\\s*[\\w-]+:/.test(code) ||\n /\\bfa[bslr]?:fa-/.test(code);\n\nconst tryFastRender = (\n code: string,\n scheme: ResolvedColorScheme,\n from: Element | null,\n): string | null => {\n if (hasIconSyntax(code)) return null;\n try {\n const svg = stripFontImports(renderMermaidSVG(code, fastRenderOptions(scheme, from)));\n // A zero-sized result is a silent layout failure, not a diagram — take the\n // async fallback rather than caching an empty box. See `hasDrawnContent`.\n return hasDrawnContent(svg) ? svg : null;\n } catch (err) {\n // beautiful-mermaid can't parse every mermaid dialect; the async mermaid\n // renderer is the fallback. Log at debug so regressions are diagnosable\n // without noising up the console on the expected unsupported-syntax path.\n console.debug('[MermaidDiagram] fast render unavailable, using async fallback:', err);\n return null;\n }\n};\n\n/**\n * Whether a mermaid parse error means \"ran out of input\" rather than \"bad syntax\".\n *\n * - Mermaid's jison parsers report the end of input as token `1`, so a source\n * truncated mid-diagram — every intermediate frame of a streaming answer —\n * fails with `hash.token === 1`.\n * - Genuinely invalid syntax fails on a real token (`'ONLY_ONE'`, …) instead.\n * - Only a lower bound: some truncations do land on a real token and read as\n * invalid. Those fall through to the `<pre>` fallback for one frame and clear\n * when the next chunk arrives, which is the pre-existing behaviour.\n */\nconst isTruncatedDiagram = (err: unknown): boolean =>\n typeof err === 'object' && err !== null && 'hash' in err\n ? (err as { hash?: { token?: unknown } }).hash?.token === 1\n : false;\n\nconst RENDER_DEBOUNCE_MS = 300;\n\n// How long a truncated diagram is held as \"still arriving\" before it is shown as\n// source. Comfortably longer than the gap between streamed chunks, short enough\n// that an abandoned stream resolves while the reader is still looking at it.\nconst TRUNCATION_GRACE_MS = 2_000;\n\n// Module-level SVG cache — persists across component remounts (e.g. tab switches\n// that cause React to remount the tree). The colours are baked into the markup,\n// so the key is the code *plus* the theme key (scheme + brand): the same diagram\n// is a different SVG under a different colour scheme or brand.\nconst svgCache = new Map<string, string>();\n\nconst diagramCacheKey = (code: string, themeKey: string): string => `${themeKey}\\n${code}`;\n\n// Resolve an SVG synchronously: cache hit first, otherwise a fast synchronous\n// render. Caches the result and returns it, or null when neither is available\n// (the caller then falls back to the async mermaid render).\nconst resolveSyncSvg = (\n code: string,\n cacheKey: string,\n scheme: ResolvedColorScheme,\n from: Element | null,\n): string | null => {\n const cached = svgCache.get(cacheKey);\n if (cached) return cached;\n const fast = tryFastRender(code, scheme, from);\n if (fast) svgCache.set(cacheKey, fast);\n return fast;\n};\n\ntype Props = {\n /** Mermaid diagram source code. Supports flowchart, sequence, class, state, ER,\n * pie, gantt, and mindmap. Gantt `dateFormat HH:mm` (time-only) is not supported\n * by mermaid's dayjs parser — use `dateFormat YYYY-MM-DD HH:mm` with `axisFormat %H:%M` instead. */\n code: string;\n /** Extra toolbar controls (e.g. an `ExportMenu`), forwarded to `ZoomableSvg`.\n * Receives the sanitized SVG. Omit to keep the default toolbar. */\n renderActions?: (safeSvg: string) => ReactNode;\n};\n\nexport const MermaidDiagram = ({ code, renderActions }: Props) => {\n const id = useId();\n // Re-renders whenever the active colour scheme or brand changes, so the\n // diagram is re-rendered in the new palette instead of staying a light island\n // on a dark page. The scheme comes out of the same read as the key, so the\n // palette can never be resolved under one scheme and cached under the other —\n // see `useThemeAttributes` for why the theme context is a step ahead of the\n // CSS variables it stands for.\n // `scope` is the element the live tokens are read off — the enclosing `ThemeScope`'s own,\n // or `null` for `<html>`. It is part of `themeKey`, so a palette built before the scope\n // answered is never served afterwards.\n const { scheme, cacheKey: themeKey, scope } = useThemeAttributes();\n const cacheKey = diagramCacheKey(code, themeKey);\n\n const [svg, setSvg] = useState<string | null>(() =>\n resolveSyncSvg(code, cacheKey, scheme, scope),\n );\n const [renderFailed, setRenderFailed] = useState(false);\n const [truncated, setTruncated] = useState(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const renderIdRef = useRef(0);\n\n // Synchronously reset stale state when the code or the theme changes, to avoid\n // a one-frame flash of the previous diagram.\n const [prevKey, setPrevKey] = useState(cacheKey);\n if (cacheKey !== prevKey) {\n setPrevKey(cacheKey);\n setSvg(resolveSyncSvg(code, cacheKey, scheme, scope));\n setRenderFailed(false);\n setTruncated(false);\n }\n\n useEffect(() => {\n // Synchronous results (cache hit / fast render) are already applied and\n // cached by the useState initializer (mount) and the render-phase reset\n // (code / theme change). Only the async fallback needs an effect.\n if (svgCache.has(cacheKey)) return;\n\n const currentRenderId = ++renderIdRef.current;\n\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n debounceRef.current = setTimeout(() => {\n getMermaid()\n .then(async (mermaidModule) => {\n if (renderIdRef.current !== currentRenderId) return;\n const rendererId = `mermaid-${id.replaceAll(':', '')}`;\n const container = document.createElement('div');\n container.style.visibility = 'hidden';\n container.style.position = 'absolute';\n container.style.top = '-9999px';\n container.style.width = '900px';\n document.body.appendChild(container);\n // Re-applied per render rather than once at import: `initialize` is the\n // only way to change mermaid's palette, and the palette follows the\n // active scheme/brand.\n mermaidModule.default.initialize(mermaidConfig(scheme, scope));\n try {\n const result = await mermaidModule.default.render(rendererId, code, container);\n if (renderIdRef.current === currentRenderId && result) {\n const svgOutput = flattenForeignObjectLabels(result.svg);\n svgCache.set(cacheKey, svgOutput);\n setSvg(svgOutput);\n setRenderFailed(false);\n setTruncated(false);\n }\n } finally {\n container.remove();\n }\n })\n .catch((err: unknown) => {\n if (renderIdRef.current !== currentRenderId) return;\n setSvg(null);\n // A diagram arriving a chunk at a time is invalid at almost every\n // intermediate length, so a truncation is treated as \"not ready\" and\n // holds the skeleton instead of the raw-code `<pre>`. It is held for a\n // bounded wait, not indefinitely: a stream that dies mid-entity — or a\n // diagram a user simply left unterminated — never gets a next chunk, and\n // a skeleton that stays forever is worse than showing the source. The\n // timer is cleared by the effect teardown, so any further chunk cancels\n // it and re-renders.\n if (isTruncatedDiagram(err)) {\n console.debug('[MermaidDiagram] incomplete diagram, awaiting more input:', err);\n setTruncated(true);\n return;\n }\n console.error('[MermaidDiagram] fallback failed:', err);\n setRenderFailed(true);\n });\n }, RENDER_DEBOUNCE_MS);\n\n const timer = debounceRef.current;\n const renderId = renderIdRef;\n return () => {\n renderId.current++;\n if (timer) {\n clearTimeout(timer);\n }\n };\n }, [cacheKey, code, id, scheme, scope]);\n\n // A truncated diagram is held as \"still arriving\" for a bounded wait, not\n // indefinitely: a stream that dies mid-entity — or a diagram a user left\n // unterminated — never sends another chunk, and a skeleton that stays forever\n // is worse than showing the source. Any further chunk changes `code`, which\n // resets `truncated` and tears this timer down.\n useEffect(() => {\n if (!truncated) return;\n const timer = setTimeout(() => setRenderFailed(true), TRUNCATION_GRACE_MS);\n return () => clearTimeout(timer);\n }, [truncated, cacheKey]);\n\n const processedSvg = svg ? makeResponsive(svg) : null;\n\n if (renderFailed) {\n return <DiagramSource code={code} />;\n }\n\n if (processedSvg) {\n return (\n <ZoomableSvg\n key={code}\n html={processedSvg}\n copyText={`\\`\\`\\`mermaid\\n${code}\\n\\`\\`\\``}\n className=\"tw:my-3\"\n allowForeignObject\n renderActions={renderActions}\n />\n );\n }\n\n return <DiagramSkeleton />;\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { cn } from "./classNames-BzrkDnOD.js";
2
- import { Tooltip } from "./utils-B5Z52hYs.js";
2
+ import { Tooltip } from "./utils-DSvrhU8E.js";
3
3
  import { Button } from "./Button-DsRrU5F1.js";
4
4
  import { ButtonGroup } from "./internal/components/ButtonGroup.js";
5
5
  import { jsx } from "react/jsx-runtime";
@@ -30,4 +30,4 @@ MultiActionButtonGroup.Button = MultiActionButton;
30
30
  //#endregion
31
31
  export { MultiActionButtonGroup };
32
32
 
33
- //# sourceMappingURL=MultiActionButtonGroup-CxWH7yWK.js.map
33
+ //# sourceMappingURL=MultiActionButtonGroup-DokHbPgM.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultiActionButtonGroup-CxWH7yWK.js","names":[],"sources":["../src/blocks/MultiActionButtonGroup/MultiActionButton.tsx","../src/blocks/MultiActionButtonGroup/MultiActionButtonGroup.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Tooltip } from '../../components/Tooltip';\n\ntype Props = {\n disabled?: boolean;\n icon: ReactNode;\n isLoading?: boolean;\n label: string;\n onClick: ComponentProps<typeof Button>['onClick'];\n tooltipContent: ReactNode;\n tooltipVariant?: ComponentProps<typeof Tooltip>['variant'];\n 'data-testid'?: string;\n};\n\nexport const MultiActionButton = ({\n disabled,\n icon,\n isLoading,\n label,\n onClick,\n tooltipContent,\n tooltipVariant,\n 'data-testid': dataTestId,\n}: Props) => (\n <Tooltip placement=\"top\" tooltip={tooltipContent} triggerAsChild variant={tooltipVariant}>\n <Button\n disabled={disabled}\n isLoading={isLoading}\n aria-label={label}\n onClick={onClick}\n variant=\"invisible\"\n size=\"icon\"\n data-testid={dataTestId}\n >\n {!isLoading && icon}\n </Button>\n </Tooltip>\n);\n","import type { PropsWithChildren } from 'react';\n\nimport { ButtonGroup } from '../../components/ButtonGroup';\nimport { cn } from '../../utils';\n\nimport { MultiActionButton } from './MultiActionButton';\n\ntype Props = {\n className?: string;\n} & PropsWithChildren;\n\nexport const MultiActionButtonGroup = ({ children, className }: Props) => (\n <ButtonGroup className={cn('tw:text-nowrap', className)}>{children}</ButtonGroup>\n);\n\nMultiActionButtonGroup.Button = MultiActionButton;\n"],"mappings":";;;;;;AAgBA,MAAa,qBAAqB,EAChC,UACA,MACA,WACA,OACA,SACA,gBACA,gBACA,eAAe,iBAEf,oBAAC,SAAD;CAAS,WAAU;CAAM,SAAS;CAAgB,gBAAA;CAAe,SAAS;CACxE,UAAA,oBAAC,QAAD;EACY;EACC;EACX,cAAY;EACH;EACT,SAAQ;EACR,MAAK;EACL,eAAa;EAEZ,UAAA,CAAC,aAAa;CACT,CAAA;AACD,CAAA;;;AC3BX,MAAa,0BAA0B,EAAE,UAAU,gBACjD,oBAAC,aAAD;CAAa,WAAW,GAAG,kBAAkB,SAAS;CAAI;AAAsB,CAAA;AAGlF,uBAAuB,SAAS"}
1
+ {"version":3,"file":"MultiActionButtonGroup-DokHbPgM.js","names":[],"sources":["../src/blocks/MultiActionButtonGroup/MultiActionButton.tsx","../src/blocks/MultiActionButtonGroup/MultiActionButtonGroup.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Tooltip } from '../../components/Tooltip';\n\ntype Props = {\n disabled?: boolean;\n icon: ReactNode;\n isLoading?: boolean;\n label: string;\n onClick: ComponentProps<typeof Button>['onClick'];\n tooltipContent: ReactNode;\n tooltipVariant?: ComponentProps<typeof Tooltip>['variant'];\n 'data-testid'?: string;\n};\n\nexport const MultiActionButton = ({\n disabled,\n icon,\n isLoading,\n label,\n onClick,\n tooltipContent,\n tooltipVariant,\n 'data-testid': dataTestId,\n}: Props) => (\n <Tooltip placement=\"top\" tooltip={tooltipContent} triggerAsChild variant={tooltipVariant}>\n <Button\n disabled={disabled}\n isLoading={isLoading}\n aria-label={label}\n onClick={onClick}\n variant=\"invisible\"\n size=\"icon\"\n data-testid={dataTestId}\n >\n {!isLoading && icon}\n </Button>\n </Tooltip>\n);\n","import type { PropsWithChildren } from 'react';\n\nimport { ButtonGroup } from '../../components/ButtonGroup';\nimport { cn } from '../../utils';\n\nimport { MultiActionButton } from './MultiActionButton';\n\ntype Props = {\n className?: string;\n} & PropsWithChildren;\n\nexport const MultiActionButtonGroup = ({ children, className }: Props) => (\n <ButtonGroup className={cn('tw:text-nowrap', className)}>{children}</ButtonGroup>\n);\n\nMultiActionButtonGroup.Button = MultiActionButton;\n"],"mappings":";;;;;;AAgBA,MAAa,qBAAqB,EAChC,UACA,MACA,WACA,OACA,SACA,gBACA,gBACA,eAAe,iBAEf,oBAAC,SAAD;CAAS,WAAU;CAAM,SAAS;CAAgB,gBAAA;CAAe,SAAS;CACxE,UAAA,oBAAC,QAAD;EACY;EACC;EACX,cAAY;EACH;EACT,SAAQ;EACR,MAAK;EACL,eAAa;EAEZ,UAAA,CAAC,aAAa;CACT,CAAA;AACD,CAAA;;;AC3BX,MAAa,0BAA0B,EAAE,UAAU,gBACjD,oBAAC,aAAD;CAAa,WAAW,GAAG,kBAAkB,SAAS;CAAI;AAAsB,CAAA;AAGlF,uBAAuB,SAAS"}
@@ -1,7 +1,7 @@
1
1
  import { cn } from "./classNames-BzrkDnOD.js";
2
2
  import { Search } from "./icons-Cek151jC.js";
3
3
  import { ScrollArea } from "./internal/components/ScrollArea.js";
4
- import { BrandLogo } from "./BrandLogo-Dmi7jo21.js";
4
+ import { BrandLogo } from "./BrandLogo-CoKBk4MI.js";
5
5
  import { Root, Slot, Slottable } from "@radix-ui/react-slot";
6
6
  import { cva } from "class-variance-authority";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -280,10 +280,10 @@ const navbarClassnames = cva([
280
280
  "tw:before:absolute",
281
281
  "tw:before:left-0",
282
282
  "tw:before:top-0",
283
- "tw:before:data-[accent=blue]:bg-sidebar-primary",
284
- "tw:before:data-[accent=purple]:bg-purple-500",
285
- "tw:before:data-[accent=green]:bg-primary-500",
286
- "tw:before:data-[accent=orange]:bg-warning-500"
283
+ "tw:data-[accent=blue]:before:bg-sidebar-primary",
284
+ "tw:data-[accent=purple]:before:bg-purple-500",
285
+ "tw:data-[accent=green]:before:bg-primary-500",
286
+ "tw:data-[accent=orange]:before:bg-warning-500"
287
287
  ],
288
288
  false: ""
289
289
  } }
@@ -322,4 +322,4 @@ Navbar.MenuAvatar = NavbarMenuAvatar;
322
322
  //#endregion
323
323
  export { Navbar };
324
324
 
325
- //# sourceMappingURL=Navbar-B2UsolVU.js.map
325
+ //# sourceMappingURL=Navbar-Liy1TPI7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Navbar-B2UsolVU.js","names":["variants","variants"],"sources":["../src/components/Navbar/NavbarContent.tsx","../src/components/Navbar/NavbarFooter.tsx","../src/components/Navbar/NavbarHeader.tsx","../src/components/Navbar/NavbarMenu.tsx","../src/components/Navbar/NavbarMenuAvatar.tsx","../src/components/Navbar/NavbarMenuItemAdornment.tsx","../src/components/Navbar/NavbarMenuButton.tsx","../src/components/Navbar/NavbarMenuItem.tsx","../src/components/Navbar/Navbar.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\nimport { ScrollArea } from '../ScrollArea';\n\ntype Props = {\n className?: string;\n children?: ReactNode;\n};\n\nexport const NavbarContent = ({ children, className }: Props) => (\n <ScrollArea\n type=\"auto\"\n orientation=\"horizontal\"\n className=\"tw:flex-1\"\n scrollBarClassName=\"tw:h-1.5\"\n >\n <div className={cn('tw:flex', 'tw:py-1.5', className)}>{children}</div>\n </ScrollArea>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\n// `flex items-center`, not a bare block: this slot is documented to hold several\n// items (search, notifications, avatar). As a block they are inline-level boxes\n// aligned on a text baseline, so a button carrying an icon and a text-only button\n// sit at different heights — visibly off-centre against the bar. Centring them is\n// a no-op for the common single-`Navbar.Menu` child, and `gap` only applies\n// between siblings, so existing compositions keep their spacing.\nexport const NavbarFooter = ({ children, className, ...rest }: Props) => (\n <div {...rest} className={cn('tw:flex tw:items-center tw:gap-2 tw:py-1.5', className)}>\n {children}\n </div>\n);\n","import { type ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\nimport { BrandLogo } from '../BrandLogo';\n\ntype Props = ComponentProps<'div'>;\n\nexport const NavbarHeader = ({ children, className, ...rest }: Props) => (\n // BrandLogo reads the nearest ThemeProvider (or the default context) and\n // renders null when the active brand ships no logo, so no provider gate needed.\n <div {...rest} className={cn('tw:overflow-hidden', 'tw:py-1.5', className)}>\n {children ?? <BrandLogo variant=\"wordmark\" className=\"tw:h-7\" />}\n </div>\n);\n","import type { ComponentProps } from 'react';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\n// `tw:m-0` alongside `tw:p-0`: browsers give `<ul>` a default block margin. In a plain\n// app the scoped preflight resets it, but in kbc-ui the legacy Bootstrap layer (which sits\n// above the preflight so Bootstrap padding survives on its own elements) re-applies\n// `ul { margin-bottom: 10px }`, which then inflates this menu's height and pushes the whole\n// navbar row off-center. Resetting the margin explicitly (utilities beat the legacy layer)\n// keeps the row centered everywhere.\nconst variants = cva(\n ['tw:m-0', 'tw:p-0', 'tw:flex', 'tw:items-center', 'tw:justify-center', 'tw:gap-2'],\n {\n variants: {\n marker: {\n none: [],\n 'forward-slash': [\n // Style all li children with pseudo-element marker\n 'tw:[&_li]:flex',\n 'tw:[&_li]:items-center',\n 'tw:[&_li]:before:content-[\"/\"]',\n 'tw:[&_li]:before:text-border',\n 'tw:[&_li]:before:text-sm',\n 'tw:[&_li]:before:mr-0.5',\n 'tw:[&_li:not(:first-child)]:before:ml-0.5',\n ],\n },\n },\n defaultVariants: {\n marker: 'none',\n },\n },\n);\n\ntype Props = ComponentProps<'ul'> & VariantProps<typeof variants>;\n\nexport const NavbarMenu = ({ className, marker, ...rest }: Props) => (\n <ul {...rest} className={variants({ marker, className })} />\n);\n","import type { ComponentProps } from 'react';\nimport * as RadixAvatar from '@radix-ui/react-avatar';\nimport BoringAvatar from 'boring-avatars';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'> & {\n src?: string;\n alt?: string;\n};\n\nexport const NavbarMenuAvatar = ({ ref, className, type = 'button', src, alt, ...rest }: Props) => {\n const altText = alt ?? 'Avatar';\n\n return (\n <button\n {...rest}\n ref={ref}\n type={type}\n className={cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:size-8',\n\n 'tw:aspect-square',\n 'tw:overflow-hidden',\n 'tw:shrink-0',\n\n 'tw:rounded-lg',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n\n // Disabled state\n 'tw:disabled:opacity-50',\n 'tw:disabled:cursor-not-allowed',\n\n // Focus-visible (matches SidebarMenuButton exactly)\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-sidebar-ring/50',\n className,\n )}\n >\n <RadixAvatar.Root>\n <RadixAvatar.Image src={src} alt={altText} className=\"tw:size-full tw:object-cover\" />\n\n <RadixAvatar.Fallback asChild>\n <BoringAvatar\n square\n name={altText}\n variant=\"beam\"\n colors={['#1F8FFF', '#004787', '#28D8FF', '#925cff', '#A8C2E6']}\n size={32}\n />\n </RadixAvatar.Fallback>\n </RadixAvatar.Root>\n </button>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nconst variants = cva(\n [\n 'tw:flex',\n 'tw:justify-center',\n 'tw:items-center',\n\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3',\n 'tw:[&:not(svg)]:h-5',\n 'tw:[&:not(svg)]:min-w-5',\n\n 'tw:p-1',\n 'tw:aspect-square',\n 'tw:rounded-md',\n ],\n {\n defaultVariants: { variant: 'icon-accent' },\n variants: {\n variant: {\n icon: ['tw:text-sidebar-foreground', 'tw:[&_svg]:text-sidebar-foreground'],\n 'icon-emphasized': ['tw:text-white', 'tw:[&_svg]:text-white'],\n 'icon-accent': [\n // color-aware accent styling\n 'tw:group-data-[accent=blue]/navbar:text-sidebar-primary',\n 'tw:group-data-[accent=blue]/navbar:[&_svg]:text-sidebar-primary',\n 'tw:group-data-[accent=purple]/navbar:text-purple-500',\n 'tw:group-data-[accent=purple]/navbar:[&_svg]:text-purple-500',\n 'tw:group-data-[accent=orange]/navbar:text-warning-500',\n 'tw:group-data-[accent=orange]/navbar:[&_svg]:text-warning-500',\n 'tw:group-data-[accent=green]/navbar:text-primary-500',\n 'tw:group-data-[accent=green]/navbar:[&_svg]:text-primary-500',\n ],\n 'icon-accent-emphasized': [\n 'tw:text-white',\n 'tw:[&_svg]:text-white',\n\n 'tw:group-data-[accent=blue]/navbar:bg-sidebar-primary',\n 'tw:group-data-[accent=purple]/navbar:bg-purple-500',\n 'tw:group-data-[accent=orange]/navbar:bg-warning-500',\n 'tw:group-data-[accent=green]/navbar:bg-primary-500',\n ],\n 'icon-button': ['tw:size-4', 'tw:!p-0', 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4'],\n shortcut: ['tw:bg-muted', 'tw:text-sidebar-foreground', 'tw:ml-auto'],\n },\n },\n },\n);\n\ntype Props = { asChild?: boolean } & ComponentProps<'span'> & VariantProps<typeof variants>;\n\nexport const NavbarMenuItemAdornment = ({\n ref,\n asChild = false,\n className,\n variant = 'icon-accent',\n ...props\n}: Props) => {\n const Comp = asChild ? Slot : 'span';\n\n return <Comp {...props} ref={ref} className={variants({ variant, className })} />;\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Root, Slottable } from '@radix-ui/react-slot';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nimport { Search } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { NavbarMenuItemAdornment } from './NavbarMenuItemAdornment';\n\nconst variants = cva(\n [\n 'tw:group/navbar-menu-button',\n 'tw:box-border',\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:bg-transparent',\n\n 'tw:leading-9',\n\n 'tw:border',\n 'tw:rounded-lg',\n 'tw:whitespace-nowrap',\n 'tw:select-none',\n\n // focus-visible\n 'tw:!outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-sidebar-ring/50',\n\n // disabled\n 'tw:disabled:opacity-50',\n 'tw:disabled:hover:bg-transparent',\n 'tw:disabled:cursor-not-allowed',\n ],\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: [\n 'tw:max-h-9',\n 'tw:border-transparent',\n 'tw:py-2',\n 'tw:px-1.5',\n 'tw:text-sidebar-foreground',\n 'tw:hover:bg-sidebar-accent',\n 'tw:aria-expanded:bg-sidebar-accent',\n\n // Active page. Mirrors `Sidebar.MenuButton`, which styles `aria-current=\"page\"` — a top nav\n // needs the same affordance, and without it a Navbar-shelled app cannot show where you are.\n // `aria-current` rather than a prop: with `asChild` the slot is an <a>, and that is the\n // attribute a router sets on an active link (TanStack's `Link` does it for free).\n 'tw:aria-[current=page]:bg-sidebar-accent',\n 'tw:aria-[current=page]:font-medium',\n ],\n emphasized: [\n 'tw:max-h-9',\n 'tw:border-transparent',\n 'tw:py-2',\n 'tw:px-1.5',\n\n 'tw:text-sidebar-foreground',\n 'tw:hover:bg-sidebar-accent',\n 'tw:aria-expanded:bg-sidebar-accent',\n\n 'tw:aria-[current=page]:bg-sidebar-accent',\n\n 'tw:font-semibold',\n ],\n icon: [\n 'tw:size-8',\n 'tw:aspect-square',\n 'tw:justify-center',\n 'tw:font-normal',\n 'tw:border-transparent',\n 'tw:text-primary',\n 'tw:[&_svg]:!text-primary',\n 'tw:hover:bg-sidebar-accent',\n 'tw:aria-expanded:bg-sidebar-accent',\n ],\n search: [\n 'tw:max-h-8',\n 'tw:min-w-52',\n 'tw:px-3',\n 'tw:py-1',\n 'tw:font-normal',\n 'tw:border-input',\n 'tw:text-muted-foreground',\n 'tw:[&_svg]:!text-muted-foreground',\n ],\n },\n },\n },\n);\n\ntype Props = ComponentProps<'button'> & {\n /** Optional leading-icon slot. Pass a Lucide icon node to render an adornment before children. */\n icon?: ReactNode;\n asChild?: boolean;\n} & VariantProps<typeof variants>;\n\nexport const NavbarMenuButton = ({\n ref,\n className,\n type = 'button',\n children,\n icon,\n asChild = false,\n variant = 'default',\n ...rest\n}: Props) => {\n const Comp = asChild ? Root : 'button';\n const isSearchVariant = variant === 'search';\n const isEmphasizedVariant = variant === 'emphasized';\n const adornment = isSearchVariant ? <Search /> : icon;\n\n const adornmentVariant: ComponentProps<typeof NavbarMenuItemAdornment>['variant'] = (() => {\n if (isSearchVariant || variant === 'icon') return 'icon-button';\n if (isEmphasizedVariant) return 'icon-accent-emphasized';\n return 'icon-accent';\n })();\n\n return (\n <Comp\n {...rest}\n ref={ref}\n type={type}\n data-variant={variant}\n className={cn(variants({ className, variant }))}\n >\n {adornment && (\n <NavbarMenuItemAdornment variant={adornmentVariant}>{adornment}</NavbarMenuItemAdornment>\n )}\n\n <Slottable>{children}</Slottable>\n </Comp>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const NavbarMenuItem = ({ className, ...rest }: Props) => (\n <li {...rest} className={cn('tw:flex', 'tw:items-center', 'tw:gap-2', className)} />\n);\n","import type { ComponentProps } from 'react';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nimport { NavbarContent } from './NavbarContent';\nimport { NavbarFooter } from './NavbarFooter';\nimport { NavbarHeader } from './NavbarHeader';\nimport { NavbarMenu } from './NavbarMenu';\nimport { NavbarMenuAvatar } from './NavbarMenuAvatar';\nimport { NavbarMenuButton } from './NavbarMenuButton';\nimport { NavbarMenuItem } from './NavbarMenuItem';\nimport { NavbarMenuItemAdornment } from './NavbarMenuItemAdornment';\n\nconst navbarClassnames = cva(\n [\n 'tailwindcss-preflight',\n 'tw:group/navbar',\n 'tw:sticky',\n 'tw:top-0',\n 'tw:z-50',\n 'tw:flex',\n 'tw:gap-2',\n 'tw:items-center',\n\n // The left side is intentionally smaller to align the logo with the sidebar icons.\n 'tw:pl-2',\n 'tw:pr-3',\n\n 'tw:bg-sidebar',\n // Pairs with `bg-sidebar` — required, not cosmetic.\n // - Without it `currentColor` inside the bar resolves to the UA's black, invisible\n // on the dark scheme's sidebar surface.\n // - Content inheriting it: plain text, and a `BrandLogo` whose SVG fills with\n // `currentColor`.\n 'tw:text-sidebar-foreground',\n 'tw:text-xs',\n 'tw:leading-4',\n ],\n {\n defaultVariants: {\n bordered: false,\n },\n variants: {\n bordered: {\n true: [\n 'tw:before:content',\n 'tw:before:h-0.5',\n 'tw:before:w-full',\n 'tw:before:absolute',\n 'tw:before:left-0',\n 'tw:before:top-0',\n 'tw:before:data-[accent=blue]:bg-sidebar-primary',\n 'tw:before:data-[accent=purple]:bg-purple-500',\n 'tw:before:data-[accent=green]:bg-primary-500',\n 'tw:before:data-[accent=orange]:bg-warning-500',\n ],\n false: '',\n },\n },\n },\n);\n\ntype Props = ComponentProps<'nav'> &\n VariantProps<typeof navbarClassnames> & {\n accent?: 'blue' | 'purple' | 'green' | 'orange';\n };\n\n/**\n * Top navigation bar for the app shell. Host inside `<AppShell.Header>` to give a\n * top-nav (or `keboola-legacy` top-bar) layout its primary navigation, brand mark,\n * and account/actions area.\n *\n * **Composition:** `Navbar.Header` (left — brand / logo), `Navbar.Content` (center —\n * primary `Navbar.Menu` of `Navbar.MenuItem` + `Navbar.MenuButton`, horizontally\n * scrollable), and `Navbar.Footer` (right — search, notifications, `Navbar.MenuAvatar`).\n * `bordered` renders a top accent hairline whose color follows `accent`. Renders a\n * `<nav>` landmark with a default `aria-label` — override it via `aria-label` /\n * `aria-labelledby` when a page has more than one nav.\n *\n * @see AppShell — pair with `AppShell.Header`; the sidebar rail uses `Sidebar` instead.\n */\nexport const Navbar = ({ className, accent = 'blue', bordered = false, ...rest }: Props) => (\n // A `<nav>` (not `<header>`): it's hosted inside `AppShell.Header`, which is\n // already the `<header>` landmark — nesting a second `<header>` is invalid and\n // muddies landmark navigation. `aria-label` comes first so a caller-supplied\n // label in `...rest` overrides the default.\n <nav\n aria-label=\"Main navigation\"\n {...rest}\n data-accent={accent}\n className={navbarClassnames({ bordered, className })}\n />\n);\n\nNavbar.Header = NavbarHeader;\nNavbar.Footer = NavbarFooter;\nNavbar.Content = NavbarContent;\n\nNavbar.Menu = NavbarMenu;\nNavbar.MenuItem = NavbarMenuItem;\nNavbar.MenuButton = NavbarMenuButton;\nNavbar.MenuItemAdornment = NavbarMenuItemAdornment;\nNavbar.MenuAvatar = NavbarMenuAvatar;\n"],"mappings":";;;;;;;;;;AAUA,MAAa,iBAAiB,EAAE,UAAU,gBACxC,oBAAC,YAAD;CACE,MAAK;CACL,aAAY;CACZ,WAAU;CACV,oBAAmB;CAEnB,UAAA,oBAAC,OAAD;EAAK,WAAW,GAAG,WAAW,aAAa,SAAS;EAAI;CAAc,CAAA;AAC5D,CAAA;;;ACNd,MAAa,gBAAgB,EAAE,UAAU,WAAW,GAAG,WACrD,oBAAC,OAAD;CAAK,GAAI;CAAM,WAAW,GAAG,8CAA8C,SAAS;CACjF;AACE,CAAA;;;ACRP,MAAa,gBAAgB,EAAE,UAAU,WAAW,GAAG,WAGrD,oBAAC,OAAD;CAAK,GAAI;CAAM,WAAW,GAAG,sBAAsB,aAAa,SAAS;CACtE,UAAA,YAAY,oBAAC,WAAD;EAAW,SAAQ;EAAW,WAAU;CAAU,CAAA;AAC5D,CAAA;;;ACFP,MAAMA,aAAW,IACf;CAAC;CAAU;CAAU;CAAW;CAAmB;CAAqB;AAAU,GAClF;CACE,UAAU,EACR,QAAQ;EACN,MAAM,CAAC;EACP,iBAAiB;GAEf;GACA;GACA;GACA;GACA;GACA;GACA;EACF;CACF,EACF;CACA,iBAAiB,EACf,QAAQ,OACV;AACF,CACF;AAIA,MAAa,cAAc,EAAE,WAAW,QAAQ,GAAG,WACjD,oBAAC,MAAD;CAAI,GAAI;CAAM,WAAWA,WAAS;EAAE;EAAQ;CAAU,CAAC;AAAI,CAAA;;;AC1B7D,MAAa,oBAAoB,EAAE,KAAK,WAAW,OAAO,UAAU,KAAK,KAAK,GAAG,WAAkB;CACjG,MAAM,UAAU,OAAO;CAEvB,OACE,oBAAC,UAAD;EACE,GAAI;EACC;EACC;EACN,WAAW,GACT,WACA,mBACA,qBACA,aAEA,oBACA,sBACA,eAEA,iBACA,qBACA,qBAGA,0BACA,kCAGA,mCACA,2BACA,yCACA,SACF;EAEA,UAAA,qBAAC,YAAY,MAAb,EAAA,UAAA,CACE,oBAAC,YAAY,OAAb;GAAwB;GAAK,KAAK;GAAS,WAAU;EAAgC,CAAA,GAErF,oBAAC,YAAY,UAAb;GAAsB,SAAA;GACpB,UAAA,oBAAC,cAAD;IACE,QAAA;IACA,MAAM;IACN,SAAQ;IACR,QAAQ;KAAC;KAAW;KAAW;KAAW;KAAW;IAAS;IAC9D,MAAM;GACP,CAAA;EACmB,CAAA,CACN,EAAA,CAAA;CACZ,CAAA;AAEZ;;;ACtDA,MAAMC,aAAW,IACf;CACE;CACA;CACA;CAEA;CACA;CACA;CAEA;CACA;CACA;AACF,GACA;CACE,iBAAiB,EAAE,SAAS,cAAc;CAC1C,UAAU,EACR,SAAS;EACP,MAAM,CAAC,8BAA8B,oCAAoC;EACzE,mBAAmB,CAAC,iBAAiB,uBAAuB;EAC5D,eAAe;GAEb;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,0BAA0B;GACxB;GACA;GAEA;GACA;GACA;GACA;EACF;EACA,eAAe;GAAC;GAAa;GAAW;EAA4C;EACpF,UAAU;GAAC;GAAe;GAA8B;EAAY;CACtE,EACF;AACF,CACF;AAIA,MAAa,2BAA2B,EACtC,KACA,UAAU,OACV,WACA,UAAU,eACV,GAAG,YACQ;CAGX,OAAO,oBAFM,UAAU,OAAO,QAEvB;EAAM,GAAI;EAAY;EAAK,WAAWA,WAAS;GAAE;GAAS;EAAU,CAAC;CAAI,CAAA;AAClF;;;ACtDA,MAAM,WAAW,IACf;CACE;CACA;CACA;CACA;CACA;CACA;CAEA;CAEA;CACA;CACA;CACA;CAGA;CACA;CACA;CAGA;CACA;CACA;AACF,GACA;CACE,iBAAiB,EACf,SAAS,UACX;CACA,UAAU,EACR,SAAS;EACP,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GAMA;GACA;EACF;EACA,YAAY;GACV;GACA;GACA;GACA;GAEA;GACA;GACA;GAEA;GAEA;EACF;EACA,MAAM;GACJ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,QAAQ;GACN;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;CACF,EACF;AACF,CACF;AAQA,MAAa,oBAAoB,EAC/B,KACA,WACA,OAAO,UACP,UACA,MACA,UAAU,OACV,UAAU,WACV,GAAG,WACQ;CACX,MAAM,OAAO,UAAU,OAAO;CAC9B,MAAM,kBAAkB,YAAY;CACpC,MAAM,sBAAsB,YAAY;CACxC,MAAM,YAAY,kBAAkB,oBAAC,QAAD,CAAS,CAAA,IAAI;CAEjD,MAAM,0BAAqF;EACzF,IAAI,mBAAmB,YAAY,QAAQ,OAAO;EAClD,IAAI,qBAAqB,OAAO;EAChC,OAAO;CACT,EAAA,CAAG;CAEH,OACE,qBAAC,MAAD;EACE,GAAI;EACC;EACC;EACN,gBAAc;EACd,WAAW,GAAG,SAAS;GAAE;GAAW;EAAQ,CAAC,CAAC;EALhD,UAAA,CAOG,aACC,oBAAC,yBAAD;GAAyB,SAAS;GAAmB,UAAA;EAAmC,CAAA,GAG1F,oBAAC,WAAD,EAAY,SAAoB,CAAA,CAC5B;;AAEV;;;ACtIA,MAAa,kBAAkB,EAAE,WAAW,GAAG,WAC7C,oBAAC,MAAD;CAAI,GAAI;CAAM,WAAW,GAAG,WAAW,mBAAmB,YAAY,SAAS;AAAI,CAAA;;;ACMrF,MAAM,mBAAmB,IACvB;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CAEA;CAMA;CACA;CACA;AACF,GACA;CACE,iBAAiB,EACf,UAAU,MACZ;CACA,UAAU,EACR,UAAU;EACR,MAAM;GACJ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,OAAO;CACT,EACF;AACF,CACF;;;;;;;;;;;;;;;AAqBA,MAAa,UAAU,EAAE,WAAW,SAAS,QAAQ,WAAW,OAAO,GAAG,WAKxE,oBAAC,OAAD;CACE,cAAW;CACX,GAAI;CACJ,eAAa;CACb,WAAW,iBAAiB;EAAE;EAAU;CAAU,CAAC;AACpD,CAAA;AAGH,OAAO,SAAS;AAChB,OAAO,SAAS;AAChB,OAAO,UAAU;AAEjB,OAAO,OAAO;AACd,OAAO,WAAW;AAClB,OAAO,aAAa;AACpB,OAAO,oBAAoB;AAC3B,OAAO,aAAa"}
1
+ {"version":3,"file":"Navbar-Liy1TPI7.js","names":["variants","variants"],"sources":["../src/components/Navbar/NavbarContent.tsx","../src/components/Navbar/NavbarFooter.tsx","../src/components/Navbar/NavbarHeader.tsx","../src/components/Navbar/NavbarMenu.tsx","../src/components/Navbar/NavbarMenuAvatar.tsx","../src/components/Navbar/NavbarMenuItemAdornment.tsx","../src/components/Navbar/NavbarMenuButton.tsx","../src/components/Navbar/NavbarMenuItem.tsx","../src/components/Navbar/Navbar.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\nimport { ScrollArea } from '../ScrollArea';\n\ntype Props = {\n className?: string;\n children?: ReactNode;\n};\n\nexport const NavbarContent = ({ children, className }: Props) => (\n <ScrollArea\n type=\"auto\"\n orientation=\"horizontal\"\n className=\"tw:flex-1\"\n scrollBarClassName=\"tw:h-1.5\"\n >\n <div className={cn('tw:flex', 'tw:py-1.5', className)}>{children}</div>\n </ScrollArea>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\n// `flex items-center`, not a bare block: this slot is documented to hold several\n// items (search, notifications, avatar). As a block they are inline-level boxes\n// aligned on a text baseline, so a button carrying an icon and a text-only button\n// sit at different heights — visibly off-centre against the bar. Centring them is\n// a no-op for the common single-`Navbar.Menu` child, and `gap` only applies\n// between siblings, so existing compositions keep their spacing.\nexport const NavbarFooter = ({ children, className, ...rest }: Props) => (\n <div {...rest} className={cn('tw:flex tw:items-center tw:gap-2 tw:py-1.5', className)}>\n {children}\n </div>\n);\n","import { type ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\nimport { BrandLogo } from '../BrandLogo';\n\ntype Props = ComponentProps<'div'>;\n\nexport const NavbarHeader = ({ children, className, ...rest }: Props) => (\n // BrandLogo reads the nearest ThemeProvider (or the default context) and\n // renders null when the active brand ships no logo, so no provider gate needed.\n <div {...rest} className={cn('tw:overflow-hidden', 'tw:py-1.5', className)}>\n {children ?? <BrandLogo variant=\"wordmark\" className=\"tw:h-7\" />}\n </div>\n);\n","import type { ComponentProps } from 'react';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\n// `tw:m-0` alongside `tw:p-0`: browsers give `<ul>` a default block margin. In a plain\n// app the scoped preflight resets it, but in kbc-ui the legacy Bootstrap layer (which sits\n// above the preflight so Bootstrap padding survives on its own elements) re-applies\n// `ul { margin-bottom: 10px }`, which then inflates this menu's height and pushes the whole\n// navbar row off-center. Resetting the margin explicitly (utilities beat the legacy layer)\n// keeps the row centered everywhere.\nconst variants = cva(\n ['tw:m-0', 'tw:p-0', 'tw:flex', 'tw:items-center', 'tw:justify-center', 'tw:gap-2'],\n {\n variants: {\n marker: {\n none: [],\n 'forward-slash': [\n // Style all li children with pseudo-element marker\n 'tw:[&_li]:flex',\n 'tw:[&_li]:items-center',\n 'tw:[&_li]:before:content-[\"/\"]',\n 'tw:[&_li]:before:text-border',\n 'tw:[&_li]:before:text-sm',\n 'tw:[&_li]:before:mr-0.5',\n 'tw:[&_li:not(:first-child)]:before:ml-0.5',\n ],\n },\n },\n defaultVariants: {\n marker: 'none',\n },\n },\n);\n\ntype Props = ComponentProps<'ul'> & VariantProps<typeof variants>;\n\nexport const NavbarMenu = ({ className, marker, ...rest }: Props) => (\n <ul {...rest} className={variants({ marker, className })} />\n);\n","import type { ComponentProps } from 'react';\nimport * as RadixAvatar from '@radix-ui/react-avatar';\nimport BoringAvatar from 'boring-avatars';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'> & {\n src?: string;\n alt?: string;\n};\n\nexport const NavbarMenuAvatar = ({ ref, className, type = 'button', src, alt, ...rest }: Props) => {\n const altText = alt ?? 'Avatar';\n\n return (\n <button\n {...rest}\n ref={ref}\n type={type}\n className={cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:size-8',\n\n 'tw:aspect-square',\n 'tw:overflow-hidden',\n 'tw:shrink-0',\n\n 'tw:rounded-lg',\n 'tw:bg-transparent',\n 'tw:cursor-pointer',\n\n // Disabled state\n 'tw:disabled:opacity-50',\n 'tw:disabled:cursor-not-allowed',\n\n // Focus-visible (matches SidebarMenuButton exactly)\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-sidebar-ring/50',\n className,\n )}\n >\n <RadixAvatar.Root>\n <RadixAvatar.Image src={src} alt={altText} className=\"tw:size-full tw:object-cover\" />\n\n <RadixAvatar.Fallback asChild>\n <BoringAvatar\n square\n name={altText}\n variant=\"beam\"\n colors={['#1F8FFF', '#004787', '#28D8FF', '#925cff', '#A8C2E6']}\n size={32}\n />\n </RadixAvatar.Fallback>\n </RadixAvatar.Root>\n </button>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nconst variants = cva(\n [\n 'tw:flex',\n 'tw:justify-center',\n 'tw:items-center',\n\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-3',\n 'tw:[&:not(svg)]:h-5',\n 'tw:[&:not(svg)]:min-w-5',\n\n 'tw:p-1',\n 'tw:aspect-square',\n 'tw:rounded-md',\n ],\n {\n defaultVariants: { variant: 'icon-accent' },\n variants: {\n variant: {\n icon: ['tw:text-sidebar-foreground', 'tw:[&_svg]:text-sidebar-foreground'],\n 'icon-emphasized': ['tw:text-white', 'tw:[&_svg]:text-white'],\n 'icon-accent': [\n // color-aware accent styling\n 'tw:group-data-[accent=blue]/navbar:text-sidebar-primary',\n 'tw:group-data-[accent=blue]/navbar:[&_svg]:text-sidebar-primary',\n 'tw:group-data-[accent=purple]/navbar:text-purple-500',\n 'tw:group-data-[accent=purple]/navbar:[&_svg]:text-purple-500',\n 'tw:group-data-[accent=orange]/navbar:text-warning-500',\n 'tw:group-data-[accent=orange]/navbar:[&_svg]:text-warning-500',\n 'tw:group-data-[accent=green]/navbar:text-primary-500',\n 'tw:group-data-[accent=green]/navbar:[&_svg]:text-primary-500',\n ],\n 'icon-accent-emphasized': [\n 'tw:text-white',\n 'tw:[&_svg]:text-white',\n\n 'tw:group-data-[accent=blue]/navbar:bg-sidebar-primary',\n 'tw:group-data-[accent=purple]/navbar:bg-purple-500',\n 'tw:group-data-[accent=orange]/navbar:bg-warning-500',\n 'tw:group-data-[accent=green]/navbar:bg-primary-500',\n ],\n 'icon-button': ['tw:size-4', 'tw:!p-0', 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4'],\n shortcut: ['tw:bg-muted', 'tw:text-sidebar-foreground', 'tw:ml-auto'],\n },\n },\n },\n);\n\ntype Props = { asChild?: boolean } & ComponentProps<'span'> & VariantProps<typeof variants>;\n\nexport const NavbarMenuItemAdornment = ({\n ref,\n asChild = false,\n className,\n variant = 'icon-accent',\n ...props\n}: Props) => {\n const Comp = asChild ? Slot : 'span';\n\n return <Comp {...props} ref={ref} className={variants({ variant, className })} />;\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Root, Slottable } from '@radix-ui/react-slot';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nimport { Search } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { NavbarMenuItemAdornment } from './NavbarMenuItemAdornment';\n\nconst variants = cva(\n [\n 'tw:group/navbar-menu-button',\n 'tw:box-border',\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:bg-transparent',\n\n 'tw:leading-9',\n\n 'tw:border',\n 'tw:rounded-lg',\n 'tw:whitespace-nowrap',\n 'tw:select-none',\n\n // focus-visible\n 'tw:!outline-hidden',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-sidebar-ring/50',\n\n // disabled\n 'tw:disabled:opacity-50',\n 'tw:disabled:hover:bg-transparent',\n 'tw:disabled:cursor-not-allowed',\n ],\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: [\n 'tw:max-h-9',\n 'tw:border-transparent',\n 'tw:py-2',\n 'tw:px-1.5',\n 'tw:text-sidebar-foreground',\n 'tw:hover:bg-sidebar-accent',\n 'tw:aria-expanded:bg-sidebar-accent',\n\n // Active page. Mirrors `Sidebar.MenuButton`, which styles `aria-current=\"page\"` — a top nav\n // needs the same affordance, and without it a Navbar-shelled app cannot show where you are.\n // `aria-current` rather than a prop: with `asChild` the slot is an <a>, and that is the\n // attribute a router sets on an active link (TanStack's `Link` does it for free).\n 'tw:aria-[current=page]:bg-sidebar-accent',\n 'tw:aria-[current=page]:font-medium',\n ],\n emphasized: [\n 'tw:max-h-9',\n 'tw:border-transparent',\n 'tw:py-2',\n 'tw:px-1.5',\n\n 'tw:text-sidebar-foreground',\n 'tw:hover:bg-sidebar-accent',\n 'tw:aria-expanded:bg-sidebar-accent',\n\n 'tw:aria-[current=page]:bg-sidebar-accent',\n\n 'tw:font-semibold',\n ],\n icon: [\n 'tw:size-8',\n 'tw:aspect-square',\n 'tw:justify-center',\n 'tw:font-normal',\n 'tw:border-transparent',\n 'tw:text-primary',\n 'tw:[&_svg]:!text-primary',\n 'tw:hover:bg-sidebar-accent',\n 'tw:aria-expanded:bg-sidebar-accent',\n ],\n search: [\n 'tw:max-h-8',\n 'tw:min-w-52',\n 'tw:px-3',\n 'tw:py-1',\n 'tw:font-normal',\n 'tw:border-input',\n 'tw:text-muted-foreground',\n 'tw:[&_svg]:!text-muted-foreground',\n ],\n },\n },\n },\n);\n\ntype Props = ComponentProps<'button'> & {\n /** Optional leading-icon slot. Pass a Lucide icon node to render an adornment before children. */\n icon?: ReactNode;\n asChild?: boolean;\n} & VariantProps<typeof variants>;\n\nexport const NavbarMenuButton = ({\n ref,\n className,\n type = 'button',\n children,\n icon,\n asChild = false,\n variant = 'default',\n ...rest\n}: Props) => {\n const Comp = asChild ? Root : 'button';\n const isSearchVariant = variant === 'search';\n const isEmphasizedVariant = variant === 'emphasized';\n const adornment = isSearchVariant ? <Search /> : icon;\n\n const adornmentVariant: ComponentProps<typeof NavbarMenuItemAdornment>['variant'] = (() => {\n if (isSearchVariant || variant === 'icon') return 'icon-button';\n if (isEmphasizedVariant) return 'icon-accent-emphasized';\n return 'icon-accent';\n })();\n\n return (\n <Comp\n {...rest}\n ref={ref}\n type={type}\n data-variant={variant}\n className={cn(variants({ className, variant }))}\n >\n {adornment && (\n <NavbarMenuItemAdornment variant={adornmentVariant}>{adornment}</NavbarMenuItemAdornment>\n )}\n\n <Slottable>{children}</Slottable>\n </Comp>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'li'>;\n\nexport const NavbarMenuItem = ({ className, ...rest }: Props) => (\n <li {...rest} className={cn('tw:flex', 'tw:items-center', 'tw:gap-2', className)} />\n);\n","import type { ComponentProps } from 'react';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nimport { NavbarContent } from './NavbarContent';\nimport { NavbarFooter } from './NavbarFooter';\nimport { NavbarHeader } from './NavbarHeader';\nimport { NavbarMenu } from './NavbarMenu';\nimport { NavbarMenuAvatar } from './NavbarMenuAvatar';\nimport { NavbarMenuButton } from './NavbarMenuButton';\nimport { NavbarMenuItem } from './NavbarMenuItem';\nimport { NavbarMenuItemAdornment } from './NavbarMenuItemAdornment';\n\nconst navbarClassnames = cva(\n [\n 'tailwindcss-preflight',\n 'tw:group/navbar',\n 'tw:sticky',\n 'tw:top-0',\n 'tw:z-50',\n 'tw:flex',\n 'tw:gap-2',\n 'tw:items-center',\n\n // The left side is intentionally smaller to align the logo with the sidebar icons.\n 'tw:pl-2',\n 'tw:pr-3',\n\n 'tw:bg-sidebar',\n // Pairs with `bg-sidebar` — required, not cosmetic.\n // - Without it `currentColor` inside the bar resolves to the UA's black, invisible\n // on the dark scheme's sidebar surface.\n // - Content inheriting it: plain text, and a `BrandLogo` whose SVG fills with\n // `currentColor`.\n 'tw:text-sidebar-foreground',\n 'tw:text-xs',\n 'tw:leading-4',\n ],\n {\n defaultVariants: {\n bordered: false,\n },\n variants: {\n bordered: {\n true: [\n 'tw:before:content',\n 'tw:before:h-0.5',\n 'tw:before:w-full',\n 'tw:before:absolute',\n 'tw:before:left-0',\n 'tw:before:top-0',\n 'tw:data-[accent=blue]:before:bg-sidebar-primary',\n 'tw:data-[accent=purple]:before:bg-purple-500',\n 'tw:data-[accent=green]:before:bg-primary-500',\n 'tw:data-[accent=orange]:before:bg-warning-500',\n ],\n false: '',\n },\n },\n },\n);\n\ntype Props = ComponentProps<'nav'> &\n VariantProps<typeof navbarClassnames> & {\n accent?: 'blue' | 'purple' | 'green' | 'orange';\n };\n\n/**\n * Top navigation bar for the app shell. Host inside `<AppShell.Header>` to give a\n * top-nav (or `keboola-legacy` top-bar) layout its primary navigation, brand mark,\n * and account/actions area.\n *\n * **Composition:** `Navbar.Header` (left — brand / logo), `Navbar.Content` (center —\n * primary `Navbar.Menu` of `Navbar.MenuItem` + `Navbar.MenuButton`, horizontally\n * scrollable), and `Navbar.Footer` (right — search, notifications, `Navbar.MenuAvatar`).\n * `bordered` renders a top accent hairline whose color follows `accent`. Renders a\n * `<nav>` landmark with a default `aria-label` — override it via `aria-label` /\n * `aria-labelledby` when a page has more than one nav.\n *\n * @see AppShell — pair with `AppShell.Header`; the sidebar rail uses `Sidebar` instead.\n */\nexport const Navbar = ({ className, accent = 'blue', bordered = false, ...rest }: Props) => (\n // A `<nav>` (not `<header>`): it's hosted inside `AppShell.Header`, which is\n // already the `<header>` landmark — nesting a second `<header>` is invalid and\n // muddies landmark navigation. `aria-label` comes first so a caller-supplied\n // label in `...rest` overrides the default.\n <nav\n aria-label=\"Main navigation\"\n {...rest}\n data-accent={accent}\n className={navbarClassnames({ bordered, className })}\n />\n);\n\nNavbar.Header = NavbarHeader;\nNavbar.Footer = NavbarFooter;\nNavbar.Content = NavbarContent;\n\nNavbar.Menu = NavbarMenu;\nNavbar.MenuItem = NavbarMenuItem;\nNavbar.MenuButton = NavbarMenuButton;\nNavbar.MenuItemAdornment = NavbarMenuItemAdornment;\nNavbar.MenuAvatar = NavbarMenuAvatar;\n"],"mappings":";;;;;;;;;;AAUA,MAAa,iBAAiB,EAAE,UAAU,gBACxC,oBAAC,YAAD;CACE,MAAK;CACL,aAAY;CACZ,WAAU;CACV,oBAAmB;CAEnB,UAAA,oBAAC,OAAD;EAAK,WAAW,GAAG,WAAW,aAAa,SAAS;EAAI;CAAc,CAAA;AAC5D,CAAA;;;ACNd,MAAa,gBAAgB,EAAE,UAAU,WAAW,GAAG,WACrD,oBAAC,OAAD;CAAK,GAAI;CAAM,WAAW,GAAG,8CAA8C,SAAS;CACjF;AACE,CAAA;;;ACRP,MAAa,gBAAgB,EAAE,UAAU,WAAW,GAAG,WAGrD,oBAAC,OAAD;CAAK,GAAI;CAAM,WAAW,GAAG,sBAAsB,aAAa,SAAS;CACtE,UAAA,YAAY,oBAAC,WAAD;EAAW,SAAQ;EAAW,WAAU;CAAU,CAAA;AAC5D,CAAA;;;ACFP,MAAMA,aAAW,IACf;CAAC;CAAU;CAAU;CAAW;CAAmB;CAAqB;AAAU,GAClF;CACE,UAAU,EACR,QAAQ;EACN,MAAM,CAAC;EACP,iBAAiB;GAEf;GACA;GACA;GACA;GACA;GACA;GACA;EACF;CACF,EACF;CACA,iBAAiB,EACf,QAAQ,OACV;AACF,CACF;AAIA,MAAa,cAAc,EAAE,WAAW,QAAQ,GAAG,WACjD,oBAAC,MAAD;CAAI,GAAI;CAAM,WAAWA,WAAS;EAAE;EAAQ;CAAU,CAAC;AAAI,CAAA;;;AC1B7D,MAAa,oBAAoB,EAAE,KAAK,WAAW,OAAO,UAAU,KAAK,KAAK,GAAG,WAAkB;CACjG,MAAM,UAAU,OAAO;CAEvB,OACE,oBAAC,UAAD;EACE,GAAI;EACC;EACC;EACN,WAAW,GACT,WACA,mBACA,qBACA,aAEA,oBACA,sBACA,eAEA,iBACA,qBACA,qBAGA,0BACA,kCAGA,mCACA,2BACA,yCACA,SACF;EAEA,UAAA,qBAAC,YAAY,MAAb,EAAA,UAAA,CACE,oBAAC,YAAY,OAAb;GAAwB;GAAK,KAAK;GAAS,WAAU;EAAgC,CAAA,GAErF,oBAAC,YAAY,UAAb;GAAsB,SAAA;GACpB,UAAA,oBAAC,cAAD;IACE,QAAA;IACA,MAAM;IACN,SAAQ;IACR,QAAQ;KAAC;KAAW;KAAW;KAAW;KAAW;IAAS;IAC9D,MAAM;GACP,CAAA;EACmB,CAAA,CACN,EAAA,CAAA;CACZ,CAAA;AAEZ;;;ACtDA,MAAMC,aAAW,IACf;CACE;CACA;CACA;CAEA;CACA;CACA;CAEA;CACA;CACA;AACF,GACA;CACE,iBAAiB,EAAE,SAAS,cAAc;CAC1C,UAAU,EACR,SAAS;EACP,MAAM,CAAC,8BAA8B,oCAAoC;EACzE,mBAAmB,CAAC,iBAAiB,uBAAuB;EAC5D,eAAe;GAEb;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,0BAA0B;GACxB;GACA;GAEA;GACA;GACA;GACA;EACF;EACA,eAAe;GAAC;GAAa;GAAW;EAA4C;EACpF,UAAU;GAAC;GAAe;GAA8B;EAAY;CACtE,EACF;AACF,CACF;AAIA,MAAa,2BAA2B,EACtC,KACA,UAAU,OACV,WACA,UAAU,eACV,GAAG,YACQ;CAGX,OAAO,oBAFM,UAAU,OAAO,QAEvB;EAAM,GAAI;EAAY;EAAK,WAAWA,WAAS;GAAE;GAAS;EAAU,CAAC;CAAI,CAAA;AAClF;;;ACtDA,MAAM,WAAW,IACf;CACE;CACA;CACA;CACA;CACA;CACA;CAEA;CAEA;CACA;CACA;CACA;CAGA;CACA;CACA;CAGA;CACA;CACA;AACF,GACA;CACE,iBAAiB,EACf,SAAS,UACX;CACA,UAAU,EACR,SAAS;EACP,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GAMA;GACA;EACF;EACA,YAAY;GACV;GACA;GACA;GACA;GAEA;GACA;GACA;GAEA;GAEA;EACF;EACA,MAAM;GACJ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,QAAQ;GACN;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;CACF,EACF;AACF,CACF;AAQA,MAAa,oBAAoB,EAC/B,KACA,WACA,OAAO,UACP,UACA,MACA,UAAU,OACV,UAAU,WACV,GAAG,WACQ;CACX,MAAM,OAAO,UAAU,OAAO;CAC9B,MAAM,kBAAkB,YAAY;CACpC,MAAM,sBAAsB,YAAY;CACxC,MAAM,YAAY,kBAAkB,oBAAC,QAAD,CAAS,CAAA,IAAI;CAEjD,MAAM,0BAAqF;EACzF,IAAI,mBAAmB,YAAY,QAAQ,OAAO;EAClD,IAAI,qBAAqB,OAAO;EAChC,OAAO;CACT,EAAA,CAAG;CAEH,OACE,qBAAC,MAAD;EACE,GAAI;EACC;EACC;EACN,gBAAc;EACd,WAAW,GAAG,SAAS;GAAE;GAAW;EAAQ,CAAC,CAAC;EALhD,UAAA,CAOG,aACC,oBAAC,yBAAD;GAAyB,SAAS;GAAmB,UAAA;EAAmC,CAAA,GAG1F,oBAAC,WAAD,EAAY,SAAoB,CAAA,CAC5B;;AAEV;;;ACtIA,MAAa,kBAAkB,EAAE,WAAW,GAAG,WAC7C,oBAAC,MAAD;CAAI,GAAI;CAAM,WAAW,GAAG,WAAW,mBAAmB,YAAY,SAAS;AAAI,CAAA;;;ACMrF,MAAM,mBAAmB,IACvB;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CAEA;CAMA;CACA;CACA;AACF,GACA;CACE,iBAAiB,EACf,UAAU,MACZ;CACA,UAAU,EACR,UAAU;EACR,MAAM;GACJ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,OAAO;CACT,EACF;AACF,CACF;;;;;;;;;;;;;;;AAqBA,MAAa,UAAU,EAAE,WAAW,SAAS,QAAQ,WAAW,OAAO,GAAG,WAKxE,oBAAC,OAAD;CACE,cAAW;CACX,GAAI;CACJ,eAAa;CACb,WAAW,iBAAiB;EAAE;EAAU;CAAU,CAAC;AACpD,CAAA;AAGH,OAAO,SAAS;AAChB,OAAO,SAAS;AAChB,OAAO,UAAU;AAEjB,OAAO,OAAO;AACd,OAAO,WAAW;AAClB,OAAO,aAAa;AACpB,OAAO,oBAAoB;AAC3B,OAAO,aAAa"}
@@ -1 +1 @@
1
- {"version":3,"file":"PageHeader-Q3IpCnQd.js","names":[],"sources":["../src/blocks/PageHeader/styles.ts","../src/blocks/PageHeader/PageHeaderDetail.tsx","../src/blocks/PageHeader/PageHeaderIndex.tsx","../src/blocks/PageHeader/PageHeader.tsx"],"sourcesContent":["export const titleRowClass = 'tw:flex tw:flex-wrap tw:items-center tw:gap-x-3 tw:gap-y-2';\nexport const titleClass =\n 'tw:m-0 tw:text-3xl tw:font-semibold tw:leading-9 tw:text-foreground tw:break-words';\nexport const titleCompactClass =\n 'tw:m-0 tw:text-xl tw:font-semibold tw:leading-7 tw:text-foreground tw:break-words';\n// Header badges always read as pills: force pill shape/case/tracking on any\n// Badge inside the slot via its `data-slot=\"badge\"` root (higher specificity\n// than the Badge's own variant classes, so it wins regardless of variant).\n// `tw:py-0` neutralises consumer-forced vertical padding (e.g. StatusLabel's\n// `tw:py-1.5`) so every header pill keeps the standard badge height.\nexport const badgesClass =\n 'tw:flex tw:flex-wrap tw:items-center tw:gap-2 tw:[&_[data-slot=badge]]:rounded-full tw:[&_[data-slot=badge]]:normal-case tw:[&_[data-slot=badge]]:tracking-normal tw:[&_[data-slot=badge]]:py-0';\nexport const descriptionClass =\n 'tw:m-0 tw:max-w-[800px] tw:break-words tw:text-sm tw:leading-5 tw:text-muted-foreground';\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport {\n badgesClass,\n descriptionClass,\n titleClass,\n titleCompactClass,\n titleRowClass,\n} from './styles';\n\n// Detail page header — single entity pages (bucket, flow, data app, …).\n// Pattern: docs/patterns/page-header/detail/detail-page-header.md\n// - Breadcrumbs are required; overflow menu sits on the breadcrumbs row.\n// - Max two visible actions: `primaryAction` + optional `secondaryAction`.\n// - All other actions belong in the breadcrumbs-row overflow menu.\n/**\n * Props for `PageHeader.Detail`. Detail pages enforce mandatory breadcrumbs, ≤ 2 visible actions, and an\n * overflow-menu slot on the breadcrumbs row.\n */\ntype PageHeaderDetailProps = Omit<ComponentProps<'header'>, 'title'> & {\n /** `Breadcrumb` chain ending in the entity name (last item is not a link). Required. */\n breadcrumbs: ReactNode;\n /** `DropdownMenu` for tertiary actions. Sits on the breadcrumbs row, not the title row. */\n overflowActions?: ReactNode;\n title: ReactNode;\n /** Optional icon rendered immediately left of the title (entity / component / type icon). */\n titleIcon?: ReactNode;\n /** Inline `Badge`s rendered next to the title (status, environment, version). Always rendered as pills. */\n badges?: ReactNode;\n description?: ReactNode;\n /** Compact title mode: renders a smaller title since the breadcrumb already shows the entity name. Default `false`. */\n compact?: boolean;\n /** Primary action (`Button`). Use the verb appropriate to the entity (Deploy / Run / Save). */\n primaryAction?: ReactNode;\n /** Optional second action (`Button variant=\"secondary\"`). Everything beyond goes in `overflowActions`. */\n secondaryAction?: ReactNode;\n /** Optional `Tabs` row below the title block. */\n headerNav?: ReactNode;\n /**\n * Opt into the responsive layout: the description spans its own full-width row below the title/actions row\n * instead of sharing the title column. Defaults to `false` (description sits inside the title column).\n * Enabled per the `sidebar-navigation` feature in kbc-ui; leaving it off keeps existing consumers\n * byte-identical.\n */\n fullWidthDescription?: boolean;\n};\n\n/**\n * Page header for single-entity pages.\n *\n * **When to use:** the page shows one entity (a bucket, flow, data app) with a parent hierarchy worth\n * breadcrumbing. Primary action is typically \"edit / deploy / run on this entity\".\n * **When NOT to use:** for top-level list pages use `PageHeader.Index`. For pages without a parent\n * hierarchy use `PageHeader.Index` even if they show one entity.\n * **Composition:** nest inside `PageLayout.Header`. Pass `Button`s for actions. Anything beyond the\n * 2-visible-actions cap belongs in `overflowActions` (a `DropdownMenu`), not in extra slots.\n *\n * @see RECIPES.md#list-detail — for the list-page → detail-page navigation pattern\n */\nexport const PageHeaderDetail = ({\n ref,\n className,\n breadcrumbs,\n overflowActions,\n title,\n titleIcon,\n badges,\n description,\n compact = false,\n primaryAction,\n secondaryAction,\n headerNav,\n fullWidthDescription = false,\n ...props\n}: PageHeaderDetailProps) => {\n const titleRow = (\n <div className={cn(titleRowClass, 'tw:min-w-64 tw:flex-1 tw:pr-2')}>\n {titleIcon && <span className=\"tw:flex tw:shrink-0 tw:items-center\">{titleIcon}</span>}\n <h1 className={compact ? titleCompactClass : titleClass}>{title}</h1>\n {badges && <div className={badgesClass}>{badges}</div>}\n </div>\n );\n const actions = (primaryAction || secondaryAction) && (\n <div className=\"tw:ml-auto tw:flex tw:flex-wrap tw:items-center tw:justify-end tw:gap-2\">\n {secondaryAction}\n {primaryAction}\n </div>\n );\n const descriptionNode = description && <p className={descriptionClass}>{description}</p>;\n return (\n <header\n ref={ref}\n className={cn('tw:flex tw:w-full tw:flex-col tw:gap-4', className)}\n {...props}\n >\n <div className=\"tw:flex tw:w-full tw:items-center tw:justify-between tw:gap-4\">\n <div className=\"tw:min-w-0 tw:flex-1\">{breadcrumbs}</div>\n {overflowActions && (\n <div className=\"tw:flex tw:shrink-0 tw:items-center tw:gap-2\">{overflowActions}</div>\n )}\n </div>\n\n {fullWidthDescription ? (\n <div className=\"tw:flex tw:w-full tw:flex-col tw:gap-2\">\n <div className=\"tw:flex tw:w-full tw:flex-wrap tw:items-start tw:justify-between tw:gap-x-4 tw:gap-y-3\">\n {titleRow}\n {actions}\n </div>\n {descriptionNode}\n </div>\n ) : (\n <div className=\"tw:flex tw:w-full tw:flex-wrap tw:items-start tw:justify-between tw:gap-x-4 tw:gap-y-3\">\n <div className=\"tw:flex tw:min-w-64 tw:flex-1 tw:flex-col tw:gap-2 tw:pr-2\">\n <div className={titleRowClass}>\n {titleIcon && (\n <span className=\"tw:flex tw:shrink-0 tw:items-center\">{titleIcon}</span>\n )}\n <h1 className={compact ? titleCompactClass : titleClass}>{title}</h1>\n {badges && <div className={badgesClass}>{badges}</div>}\n </div>\n {descriptionNode}\n </div>\n {actions}\n </div>\n )}\n\n {headerNav}\n </header>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { descriptionClass, titleClass, titleRowClass } from './styles';\n\n// Index page header — list / collection pages (Flows, Storage, Jobs, …).\n// Pattern: docs/patterns/page-header/index/index-page-header.md\n// - No breadcrumbs (top-level pages).\n// - `metadata` wins over `description` (mutually exclusive in pattern).\n// - At most one primary `action`; pair with the `documentation` icon button.\n/**\n * Props for `PageHeader.Index`. Index pages have no breadcrumbs and no overflow menu — search and filters\n * belong in `PageToolbar`, not here.\n */\ntype PageHeaderIndexProps = Omit<ComponentProps<'header'>, 'title'> & {\n title: ReactNode;\n /** Prose description shown below the title. Mutually exclusive with `metadata` in the pattern; `metadata` wins when both are passed. */\n description?: ReactNode;\n /** Count / system summary shown below the title (e.g. \"3 buckets and 39 tables\"). Wins over `description`. */\n metadata?: ReactNode;\n /** Icon-only docs button (`Button variant=\"invisible\" icon={<BookOpen />}`). Sits next to `action`. */\n documentation?: ReactNode;\n /** Primary \"create / add new X\" `Button`. */\n action?: ReactNode;\n /** Optional `Tabs` row rendered below the title block. Use only when >1 dataset / section is worth navigating to. */\n headerNav?: ReactNode;\n /**\n * Opt into the responsive layout: the description spans its own full-width row below the title, and the\n * action group wraps beneath the title (right-aligned) on narrow widths instead of shrinking. Defaults to\n * `false` (the description shares the title column and actions stay `shrink-0`). Enabled per the\n * `sidebar-navigation` feature in kbc-ui; leaving it off keeps existing consumers byte-identical.\n */\n fullWidthDescription?: boolean;\n};\n\n/**\n * Page header for top-level list / collection pages.\n *\n * **When to use:** the page is a list (Flows, Storage, Jobs, …) with no parent in the same section.\n * Primary action is typically \"create / add a new X\".\n * **When NOT to use:** for single-entity detail pages use `PageHeader.Detail`; for layouts that don't fit\n * either pattern host custom JSX in `PageLayout.Header` directly.\n * **Composition:** nest inside `PageLayout.Header`. Pass `Button`s into `action` and\n * `documentation`. Search and filter chips belong in `PageToolbar`, not here.\n */\nexport const PageHeaderIndex = ({\n ref,\n className,\n title,\n description,\n metadata,\n documentation,\n action,\n headerNav,\n fullWidthDescription = false,\n ...props\n}: PageHeaderIndexProps) => {\n const subtitle = metadata ?? description;\n const hasActions = Boolean(documentation || action);\n return (\n <header\n ref={ref}\n className={cn('tw:flex tw:w-full tw:flex-col tw:gap-4', className)}\n {...props}\n >\n {fullWidthDescription ? (\n <div className=\"tw:flex tw:w-full tw:flex-col tw:gap-2\">\n <div className=\"tw:flex tw:w-full tw:flex-wrap tw:items-start tw:justify-between tw:gap-x-4 tw:gap-y-3\">\n <div className={cn(titleRowClass, 'tw:min-w-64 tw:flex-1 tw:pr-2')}>\n <h1 className={titleClass}>{title}</h1>\n </div>\n {hasActions && (\n <div className=\"tw:ml-auto tw:flex tw:flex-wrap tw:items-center tw:justify-end tw:gap-2\">\n {documentation}\n {action}\n </div>\n )}\n </div>\n {subtitle && <p className={descriptionClass}>{subtitle}</p>}\n </div>\n ) : (\n <div className=\"tw:flex tw:w-full tw:items-start tw:justify-between tw:gap-4\">\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:gap-2 tw:pr-2\">\n <div className={titleRowClass}>\n <h1 className={titleClass}>{title}</h1>\n </div>\n {subtitle && <p className={descriptionClass}>{subtitle}</p>}\n </div>\n {hasActions && (\n <div className=\"tw:flex tw:shrink-0 tw:items-center tw:gap-2\">\n {documentation}\n {action}\n </div>\n )}\n </div>\n )}\n {headerNav}\n </header>\n );\n};\n","import { PageHeaderDetail } from './PageHeaderDetail';\nimport { PageHeaderIndex } from './PageHeaderIndex';\n\n/**\n * Structured page-header block that encodes the evviku page-header patterns 1:1 at the type level.\n *\n * **When to use:** every kbc-ui page with a structured header (title + actions + optional badges /\n * description / tabs). Choose `PageHeader.Index` for list / collection pages, `PageHeader.Detail` for\n * single-entity pages with breadcrumbs.\n * **When NOT to use:** for layouts that don't match either pattern, host custom JSX inside\n * `PageLayout.Header` directly. For routing-driven tab rows below the header use `PageLayout.Tabs`.\n * **Composition:** nest inside `PageLayout.Header`. Pass `@keboola/design` `Button`s into the header slots\n * (chrome is brand-driven). The variant types enforce pattern constraints (e.g. `Index` rejects breadcrumbs).\n *\n * @see RECIPES.md#page-header-tabs — for the canonical page-header + tabs composition\n */\nexport const PageHeader = {\n /** Index variant — top-level list / collection pages. No breadcrumbs; `metadata` wins over `description`. */\n Index: PageHeaderIndex,\n /** Detail variant — single-entity pages with required breadcrumbs and an overflow-actions slot. Max 2 visible actions. */\n Detail: PageHeaderDetail,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PageHeader-Q3IpCnQd.js","names":[],"sources":["../src/blocks/PageHeader/styles.ts","../src/blocks/PageHeader/PageHeaderDetail.tsx","../src/blocks/PageHeader/PageHeaderIndex.tsx","../src/blocks/PageHeader/PageHeader.tsx"],"sourcesContent":["export const titleRowClass = 'tw:flex tw:flex-wrap tw:items-center tw:gap-x-3 tw:gap-y-2';\nexport const titleClass =\n 'tw:m-0 tw:text-3xl tw:font-semibold tw:leading-9 tw:text-foreground tw:break-words';\nexport const titleCompactClass =\n 'tw:m-0 tw:text-xl tw:font-semibold tw:leading-7 tw:text-foreground tw:break-words';\n// Header badges always read as pills: force pill shape/case/tracking on any\n// Badge inside the slot via its `data-slot=\"badge\"` root (higher specificity\n// than the Badge's own variant classes, so it wins regardless of variant).\n// `tw:py-0` neutralises consumer-forced vertical padding (e.g. StatusLabel's\n// `tw:py-1.5`) so every header pill keeps the standard badge height.\nexport const badgesClass =\n 'tw:flex tw:flex-wrap tw:items-center tw:gap-2 tw:[&_[data-slot=badge]]:rounded-full tw:[&_[data-slot=badge]]:normal-case tw:[&_[data-slot=badge]]:tracking-normal tw:[&_[data-slot=badge]]:py-0';\nexport const descriptionClass =\n 'tw:m-0 tw:max-w-[800px] tw:break-words tw:text-sm tw:leading-5 tw:text-muted-foreground';\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport {\n badgesClass,\n descriptionClass,\n titleClass,\n titleCompactClass,\n titleRowClass,\n} from './styles';\n\n// Detail page header — single entity pages (bucket, flow, data app, …).\n// Pattern: docs/patterns/page-header/detail/detail-page-header.md\n// - Breadcrumbs are required; overflow menu sits on the breadcrumbs row.\n// - Max two visible actions: `primaryAction` + optional `secondaryAction`.\n// - All other actions belong in the breadcrumbs-row overflow menu.\n/**\n * Props for `PageHeader.Detail`. Detail pages enforce mandatory breadcrumbs, ≤ 2 visible actions, and an\n * overflow-menu slot on the breadcrumbs row.\n */\ntype PageHeaderDetailProps = Omit<ComponentProps<'header'>, 'title'> & {\n /**\n * `Breadcrumb` chain to the entity's parent list / hierarchy. Required. Never repeat the\n * entity's own name as a final, non-link item — it's already the `title` below.\n */\n breadcrumbs: ReactNode;\n /** `DropdownMenu` for tertiary actions. Sits on the breadcrumbs row, not the title row. */\n overflowActions?: ReactNode;\n title: ReactNode;\n /** Optional icon rendered immediately left of the title (entity / component / type icon). */\n titleIcon?: ReactNode;\n /** Inline `Badge`s rendered next to the title (status, environment, version). Always rendered as pills. */\n badges?: ReactNode;\n description?: ReactNode;\n /** Compact title mode: renders a smaller title for information-dense pages. Default `false`. */\n compact?: boolean;\n /** Primary action (`Button`). Use the verb appropriate to the entity (Deploy / Run / Save). */\n primaryAction?: ReactNode;\n /** Optional second action (`Button variant=\"secondary\"`). Everything beyond goes in `overflowActions`. */\n secondaryAction?: ReactNode;\n /** Optional `Tabs` row below the title block. */\n headerNav?: ReactNode;\n /**\n * Opt into the responsive layout: the description spans its own full-width row below the title/actions row\n * instead of sharing the title column. Defaults to `false` (description sits inside the title column).\n * Enabled per the `sidebar-navigation` feature in kbc-ui; leaving it off keeps existing consumers\n * byte-identical.\n */\n fullWidthDescription?: boolean;\n};\n\n/**\n * Page header for single-entity pages.\n *\n * **When to use:** the page shows one entity (a bucket, flow, data app) with a parent hierarchy worth\n * breadcrumbing. Primary action is typically \"edit / deploy / run on this entity\".\n * **When NOT to use:** for top-level list pages use `PageHeader.Index`. For pages without a parent\n * hierarchy use `PageHeader.Index` even if they show one entity.\n * **Composition:** nest inside `PageLayout.Header`. Pass `Button`s for actions. Anything beyond the\n * 2-visible-actions cap belongs in `overflowActions` (a `DropdownMenu`), not in extra slots.\n *\n * @see RECIPES.md#list-detail — for the list-page → detail-page navigation pattern\n */\nexport const PageHeaderDetail = ({\n ref,\n className,\n breadcrumbs,\n overflowActions,\n title,\n titleIcon,\n badges,\n description,\n compact = false,\n primaryAction,\n secondaryAction,\n headerNav,\n fullWidthDescription = false,\n ...props\n}: PageHeaderDetailProps) => {\n const titleRow = (\n <div className={cn(titleRowClass, 'tw:min-w-64 tw:flex-1 tw:pr-2')}>\n {titleIcon && <span className=\"tw:flex tw:shrink-0 tw:items-center\">{titleIcon}</span>}\n <h1 className={compact ? titleCompactClass : titleClass}>{title}</h1>\n {badges && <div className={badgesClass}>{badges}</div>}\n </div>\n );\n const actions = (primaryAction || secondaryAction) && (\n <div className=\"tw:ml-auto tw:flex tw:flex-wrap tw:items-center tw:justify-end tw:gap-2\">\n {secondaryAction}\n {primaryAction}\n </div>\n );\n const descriptionNode = description && <p className={descriptionClass}>{description}</p>;\n return (\n <header\n ref={ref}\n className={cn('tw:flex tw:w-full tw:flex-col tw:gap-4', className)}\n {...props}\n >\n <div className=\"tw:flex tw:w-full tw:items-center tw:justify-between tw:gap-4\">\n <div className=\"tw:min-w-0 tw:flex-1\">{breadcrumbs}</div>\n {overflowActions && (\n <div className=\"tw:flex tw:shrink-0 tw:items-center tw:gap-2\">{overflowActions}</div>\n )}\n </div>\n\n {fullWidthDescription ? (\n <div className=\"tw:flex tw:w-full tw:flex-col tw:gap-2\">\n <div className=\"tw:flex tw:w-full tw:flex-wrap tw:items-start tw:justify-between tw:gap-x-4 tw:gap-y-3\">\n {titleRow}\n {actions}\n </div>\n {descriptionNode}\n </div>\n ) : (\n <div className=\"tw:flex tw:w-full tw:flex-wrap tw:items-start tw:justify-between tw:gap-x-4 tw:gap-y-3\">\n <div className=\"tw:flex tw:min-w-64 tw:flex-1 tw:flex-col tw:gap-2 tw:pr-2\">\n <div className={titleRowClass}>\n {titleIcon && (\n <span className=\"tw:flex tw:shrink-0 tw:items-center\">{titleIcon}</span>\n )}\n <h1 className={compact ? titleCompactClass : titleClass}>{title}</h1>\n {badges && <div className={badgesClass}>{badges}</div>}\n </div>\n {descriptionNode}\n </div>\n {actions}\n </div>\n )}\n\n {headerNav}\n </header>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { descriptionClass, titleClass, titleRowClass } from './styles';\n\n// Index page header — list / collection pages (Flows, Storage, Jobs, …).\n// Pattern: docs/patterns/page-header/index/index-page-header.md\n// - No breadcrumbs (top-level pages).\n// - `metadata` wins over `description` (mutually exclusive in pattern).\n// - At most one primary `action`; pair with the `documentation` icon button.\n/**\n * Props for `PageHeader.Index`. Index pages have no breadcrumbs and no overflow menu — search and filters\n * belong in `PageToolbar`, not here.\n */\ntype PageHeaderIndexProps = Omit<ComponentProps<'header'>, 'title'> & {\n title: ReactNode;\n /** Prose description shown below the title. Mutually exclusive with `metadata` in the pattern; `metadata` wins when both are passed. */\n description?: ReactNode;\n /** Count / system summary shown below the title (e.g. \"3 buckets and 39 tables\"). Wins over `description`. */\n metadata?: ReactNode;\n /** Icon-only docs button (`Button variant=\"invisible\" icon={<BookOpen />}`). Sits next to `action`. */\n documentation?: ReactNode;\n /** Primary \"create / add new X\" `Button`. */\n action?: ReactNode;\n /** Optional `Tabs` row rendered below the title block. Use only when >1 dataset / section is worth navigating to. */\n headerNav?: ReactNode;\n /**\n * Opt into the responsive layout: the description spans its own full-width row below the title, and the\n * action group wraps beneath the title (right-aligned) on narrow widths instead of shrinking. Defaults to\n * `false` (the description shares the title column and actions stay `shrink-0`). Enabled per the\n * `sidebar-navigation` feature in kbc-ui; leaving it off keeps existing consumers byte-identical.\n */\n fullWidthDescription?: boolean;\n};\n\n/**\n * Page header for top-level list / collection pages.\n *\n * **When to use:** the page is a list (Flows, Storage, Jobs, …) with no parent in the same section.\n * Primary action is typically \"create / add a new X\".\n * **When NOT to use:** for single-entity detail pages use `PageHeader.Detail`; for layouts that don't fit\n * either pattern host custom JSX in `PageLayout.Header` directly.\n * **Composition:** nest inside `PageLayout.Header`. Pass `Button`s into `action` and\n * `documentation`. Search and filter chips belong in `PageToolbar`, not here.\n */\nexport const PageHeaderIndex = ({\n ref,\n className,\n title,\n description,\n metadata,\n documentation,\n action,\n headerNav,\n fullWidthDescription = false,\n ...props\n}: PageHeaderIndexProps) => {\n const subtitle = metadata ?? description;\n const hasActions = Boolean(documentation || action);\n return (\n <header\n ref={ref}\n className={cn('tw:flex tw:w-full tw:flex-col tw:gap-4', className)}\n {...props}\n >\n {fullWidthDescription ? (\n <div className=\"tw:flex tw:w-full tw:flex-col tw:gap-2\">\n <div className=\"tw:flex tw:w-full tw:flex-wrap tw:items-start tw:justify-between tw:gap-x-4 tw:gap-y-3\">\n <div className={cn(titleRowClass, 'tw:min-w-64 tw:flex-1 tw:pr-2')}>\n <h1 className={titleClass}>{title}</h1>\n </div>\n {hasActions && (\n <div className=\"tw:ml-auto tw:flex tw:flex-wrap tw:items-center tw:justify-end tw:gap-2\">\n {documentation}\n {action}\n </div>\n )}\n </div>\n {subtitle && <p className={descriptionClass}>{subtitle}</p>}\n </div>\n ) : (\n <div className=\"tw:flex tw:w-full tw:items-start tw:justify-between tw:gap-4\">\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:gap-2 tw:pr-2\">\n <div className={titleRowClass}>\n <h1 className={titleClass}>{title}</h1>\n </div>\n {subtitle && <p className={descriptionClass}>{subtitle}</p>}\n </div>\n {hasActions && (\n <div className=\"tw:flex tw:shrink-0 tw:items-center tw:gap-2\">\n {documentation}\n {action}\n </div>\n )}\n </div>\n )}\n {headerNav}\n </header>\n );\n};\n","import { PageHeaderDetail } from './PageHeaderDetail';\nimport { PageHeaderIndex } from './PageHeaderIndex';\n\n/**\n * Structured page-header block that encodes the evviku page-header patterns 1:1 at the type level.\n *\n * **When to use:** every kbc-ui page with a structured header (title + actions + optional badges /\n * description / tabs). Choose `PageHeader.Index` for list / collection pages, `PageHeader.Detail` for\n * single-entity pages with breadcrumbs.\n * **When NOT to use:** for layouts that don't match either pattern, host custom JSX inside\n * `PageLayout.Header` directly. For routing-driven tab rows below the header use `PageLayout.Tabs`.\n * **Composition:** nest inside `PageLayout.Header`. Pass `@keboola/design` `Button`s into the header slots\n * (chrome is brand-driven). The variant types enforce pattern constraints (e.g. `Index` rejects breadcrumbs).\n *\n * @see RECIPES.md#page-header-tabs — for the canonical page-header + tabs composition\n */\nexport const PageHeader = {\n /** Index variant — top-level list / collection pages. No breadcrumbs; `metadata` wins over `description`. */\n Index: PageHeaderIndex,\n /** Detail variant — single-entity pages with required breadcrumbs and an overflow-actions slot. Max 2 visible actions. */\n Detail: PageHeaderDetail,\n};\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { cn } from "./classNames-BzrkDnOD.js";
2
2
  import { ChevronDown, Plus, X } from "./icons-Cek151jC.js";
3
3
  import { Button } from "./Button-DsRrU5F1.js";
4
4
  import { Popover } from "./Popover-BEbQrC_P.js";
5
- import { Badge } from "./Badge-Ch26CXoP.js";
5
+ import { Badge } from "./Badge-D0pXdekt.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/blocks/PageToolbar/PageToolbarToken.tsx
8
8
  /**
@@ -150,4 +150,4 @@ const PageToolbar = Object.assign(Root, {
150
150
  //#endregion
151
151
  export { PageToolbar };
152
152
 
153
- //# sourceMappingURL=PageToolbar-DnbFt14Q.js.map
153
+ //# sourceMappingURL=PageToolbar-DExqEYGl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageToolbar-DnbFt14Q.js","names":[],"sources":["../src/blocks/PageToolbar/PageToolbarToken.tsx","../src/blocks/PageToolbar/PageToolbar.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ReactNode } from 'react';\n\nimport { Badge } from '../../components/Badge';\nimport { Button } from '../../components/Button';\nimport { Popover } from '../../components/Popover';\nimport { ChevronDown, X } from '../../icons';\n\ntype PageToolbarTokenProps = Omit<\n ComponentPropsWithoutRef<typeof Badge>,\n 'variant' | 'color' | 'suffix' | 'children' | 'asChild' | 'popover'\n> & {\n children: ReactNode;\n /** Popover content rendered when the chevron-down trigger is clicked — typically a value editor. */\n popover: ReactNode;\n onRemove: () => void;\n removeAriaLabel: string;\n};\n\n/**\n * Editable filter token (Query Builder variant) — `Badge` pill with a `chevron-down`\n * popover trigger for editing values and an `×` dismiss button. The popover content\n * is supplied by the caller via the `popover` slot (typically a `Combobox` or option list).\n */\nexport const PageToolbarToken = ({\n children,\n popover,\n onRemove,\n removeAriaLabel,\n ...props\n}: PageToolbarTokenProps) => (\n <Popover>\n <Badge\n {...props}\n asChild\n variant=\"pill\"\n color=\"blue-inverse\"\n suffix={\n <Button\n type=\"button\"\n variant=\"inline\"\n size=\"icon-2xs\"\n aria-label={removeAriaLabel}\n onClick={onRemove}\n >\n <X className=\"tw:size-3\" />\n </Button>\n }\n >\n <Popover.Trigger\n type=\"button\"\n className=\"tw:inline-flex tw:cursor-pointer tw:items-center tw:gap-1 tw:bg-inherit tw:text-inherit tailwindcss-preflight\"\n >\n {children}\n <ChevronDown className=\"tw:size-3\" />\n </Popover.Trigger>\n </Badge>\n <Popover.Content align=\"start\">{popover}</Popover.Content>\n </Popover>\n);\n","import type { ComponentProps, ComponentPropsWithoutRef, ReactNode } from 'react';\n\nimport { Badge } from '../../components/Badge';\nimport { Button } from '../../components/Button';\nimport { Plus, X } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { PageToolbarToken } from './PageToolbarToken';\n\ntype DivProps = ComponentProps<'div'>;\n\nconst Root = ({ ref, className, children, ...props }: DivProps) => (\n <div\n ref={ref}\n className={cn('tw:flex tw:flex-wrap tw:items-center tw:gap-3 tw:w-full', className)}\n {...props}\n >\n {children}\n </div>\n);\n\nconst Search = ({ ref, className, children, ...props }: DivProps) => (\n <div\n ref={ref}\n className={cn(\n 'tw:mr-auto tw:flex tw:items-center tw:gap-2 tw:w-full tw:sm:w-auto tw:sm:min-w-64 tw:sm:max-w-md',\n // The slot sizes itself between `min-w-64` and `max-w-md`, so the search field has to fill it —\n // without this the input stays content-width (≈224px inside a 448px slot) and truncates its own\n // placeholder, and every caller ends up hand-picking a width class to compensate.\n //\n // - First child only. The documented composition is the search field followed by filter pills;\n // stretching every child would size the pills to match the input.\n // - `min-w-0` so a long value shrinks the input rather than overflowing the toolbar.\n 'tw:*:first:min-w-0 tw:*:first:flex-1',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nconst Right = ({ ref, className, children, ...props }: DivProps) => (\n <div\n ref={ref}\n className={cn('tw:flex tw:flex-wrap tw:items-center tw:gap-2', className)}\n {...props}\n >\n {children}\n </div>\n);\n\nconst ControlGroup = ({ ref, className, children, ...props }: DivProps) => (\n <div ref={ref} className={cn('tw:flex tw:items-center tw:gap-2', className)} {...props}>\n {children}\n </div>\n);\n\nconst ActiveFilters = ({ ref, className, children, ...props }: DivProps) => (\n <div\n ref={ref}\n className={cn('tw:flex tw:flex-wrap tw:items-center tw:gap-2 tw:basis-full', className)}\n {...props}\n >\n {children}\n </div>\n);\n\ntype ChipProps = Omit<\n ComponentPropsWithoutRef<typeof Badge>,\n 'variant' | 'color' | 'suffix' | 'children'\n> & {\n children: ReactNode;\n onRemove: () => void;\n removeAriaLabel: string;\n};\n\nconst Chip = ({ children, onRemove, removeAriaLabel, ...props }: ChipProps) => (\n <Badge\n {...props}\n variant=\"pill\"\n color=\"blue-inverse\"\n suffix={\n <Button\n type=\"button\"\n variant=\"inline\"\n size=\"icon-2xs\"\n aria-label={removeAriaLabel}\n onClick={onRemove}\n >\n <X className=\"tw:size-3\" />\n </Button>\n }\n >\n {children}\n </Badge>\n);\n\ntype ActionProps = ComponentPropsWithoutRef<typeof Button>;\n\nconst AddFilter = ({ className, children, ...props }: ActionProps) => (\n <Button variant=\"invisible\" size=\"small\" className={cn('tw:gap-1.5', className)} {...props}>\n <Plus className=\"tw:size-4\" />\n {children ?? 'Add filter'}\n </Button>\n);\n\nconst Clear = ({ className, children, ...props }: ActionProps) => (\n <Button variant=\"invisible\" size=\"small\" className={cn('tw:ml-auto', className)} {...props}>\n {children ?? 'Clear all'}\n </Button>\n);\n\n/**\n * Two-row toolbar for index pages — search on the left, filter / sort / utility / view\n * controls on the right, an optional Active Filters row below for filter chips or tokens.\n *\n * **When to use:** every index page that supports search or filtering. Hosts inside\n * `PageLayout` as the search / filter row, between `PageLayout.Header` and `PageLayout.Content`.\n * **When NOT to use:** detail pages, form pages, or anywhere there is no search / filter\n * surface. For routing-based tab rows reach for `PageLayout.Tabs`.\n *\n * **Recommended composition (enforced at the call site):**\n *\n * - `Search` sits on the left; the right cluster auto-aligns via flex.\n * - Right cluster order: `Filters` → `Sort` → `Actions` → `View`. View controls are always\n * the final control group — do not render any control after `View`.\n * - `ActiveFilters` is the second row. Render it only when one or more filters are active.\n * - `Clear` self-aligns to the far right of `ActiveFilters`.\n *\n * The block is variant-agnostic: render filter chips (Standard variant, non-editable) or\n * tokens (Query Builder variant, editable) into `ActiveFilters` as plain children — do not\n * mix the two in one toolbar.\n *\n * @see https://github.com/evviku/design-system-docs/blob/main/docs/patterns/toolbar/toolbar.md\n */\nexport const PageToolbar = Object.assign(Root, {\n /** Left slot — typically a `SearchInput`. */\n Search,\n /** Right cluster — host the four control groups below in the recommended order. */\n Right,\n /** Filter controls (`Combobox`, `Select`, `DatePicker`). */\n Filters: ControlGroup,\n /** Sort control. */\n Sort: ControlGroup,\n /** Utility actions (Export, Refresh, …). */\n Actions: ControlGroup,\n /** View toggle (List / Grid). Always render last in the right cluster. */\n View: ControlGroup,\n /**\n * Active filters row. Render only when one or more filters are active. Pass filter chips\n * (Standard variant) or tokens (Query Builder variant) as children, optionally followed\n * by `AddFilter` / `Clear`.\n */\n ActiveFilters,\n /** Non-editable filter chip (Standard variant) — `Badge` pill with a dismiss button. */\n Chip,\n /**\n * Editable filter token (Query Builder variant) — `Badge` pill with a `chevron-down`\n * popover trigger for editing values and an `×` dismiss button. The popover content\n * is supplied by the caller via the `popover` slot (typically a `Combobox` or option list).\n */\n Token: PageToolbarToken,\n /** \"+ Add filter\" action — typically rendered after the chips/tokens in `ActiveFilters`. */\n AddFilter,\n /** \"Clear all\" action — self-aligns to the far right of `ActiveFilters`. */\n Clear,\n});\n"],"mappings":";;;;;;;;;;;;AAuBA,MAAa,oBAAoB,EAC/B,UACA,SACA,UACA,iBACA,GAAG,YAEH,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,OAAD;CACE,GAAI;CACJ,SAAA;CACA,SAAQ;CACR,OAAM;CACN,QACE,oBAAC,QAAD;EACE,MAAK;EACL,SAAQ;EACR,MAAK;EACL,cAAY;EACZ,SAAS;EAET,UAAA,oBAAC,GAAD,EAAG,WAAU,YAAa,CAAA;CACpB,CAAA;CAGV,UAAA,qBAAC,QAAQ,SAAT;EACE,MAAK;EACL,WAAU;EAFZ,UAAA,CAIG,UACD,oBAAC,aAAD,EAAa,WAAU,YAAa,CAAA,CACrB;;AACZ,CAAA,GACP,oBAAC,QAAQ,SAAT;CAAiB,OAAM;CAAS,UAAA;AAAyB,CAAA,CAClD,EAAA,CAAA;;;AC9CX,MAAM,QAAQ,EAAE,KAAK,WAAW,UAAU,GAAG,YAC3C,oBAAC,OAAD;CACO;CACL,WAAW,GAAG,2DAA2D,SAAS;CAClF,GAAI;CAEH;AACE,CAAA;AAGP,MAAM,UAAU,EAAE,KAAK,WAAW,UAAU,GAAG,YAC7C,oBAAC,OAAD;CACO;CACL,WAAW,GACT,oGAQA,wCACA,SACF;CACA,GAAI;CAEH;AACE,CAAA;AAGP,MAAM,SAAS,EAAE,KAAK,WAAW,UAAU,GAAG,YAC5C,oBAAC,OAAD;CACO;CACL,WAAW,GAAG,iDAAiD,SAAS;CACxE,GAAI;CAEH;AACE,CAAA;AAGP,MAAM,gBAAgB,EAAE,KAAK,WAAW,UAAU,GAAG,YACnD,oBAAC,OAAD;CAAU;CAAK,WAAW,GAAG,oCAAoC,SAAS;CAAG,GAAI;CAC9E;AACE,CAAA;AAGP,MAAM,iBAAiB,EAAE,KAAK,WAAW,UAAU,GAAG,YACpD,oBAAC,OAAD;CACO;CACL,WAAW,GAAG,+DAA+D,SAAS;CACtF,GAAI;CAEH;AACE,CAAA;AAYP,MAAM,QAAQ,EAAE,UAAU,UAAU,iBAAiB,GAAG,YACtD,oBAAC,OAAD;CACE,GAAI;CACJ,SAAQ;CACR,OAAM;CACN,QACE,oBAAC,QAAD;EACE,MAAK;EACL,SAAQ;EACR,MAAK;EACL,cAAY;EACZ,SAAS;EAET,UAAA,oBAAC,GAAD,EAAG,WAAU,YAAa,CAAA;CACpB,CAAA;CAGT;AACI,CAAA;AAKT,MAAM,aAAa,EAAE,WAAW,UAAU,GAAG,YAC3C,qBAAC,QAAD;CAAQ,SAAQ;CAAY,MAAK;CAAQ,WAAW,GAAG,cAAc,SAAS;CAAG,GAAI;CAArF,UAAA,CACE,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA,GAC5B,YAAY,YACP;;AAGV,MAAM,SAAS,EAAE,WAAW,UAAU,GAAG,YACvC,oBAAC,QAAD;CAAQ,SAAQ;CAAY,MAAK;CAAQ,WAAW,GAAG,cAAc,SAAS;CAAG,GAAI;CAClF,UAAA,YAAY;AACP,CAAA;;;;;;;;;;;;;;;;;;;;;;;;AA0BV,MAAa,cAAc,OAAO,OAAO,MAAM;;CAE7C;;CAEA;;CAEA,SAAS;;CAET,MAAM;;CAEN,SAAS;;CAET,MAAM;;;;;;CAMN;;CAEA;;;;;;CAMA,OAAO;;CAEP;;CAEA;AACF,CAAC"}
1
+ {"version":3,"file":"PageToolbar-DExqEYGl.js","names":[],"sources":["../src/blocks/PageToolbar/PageToolbarToken.tsx","../src/blocks/PageToolbar/PageToolbar.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ReactNode } from 'react';\n\nimport { Badge } from '../../components/Badge';\nimport { Button } from '../../components/Button';\nimport { Popover } from '../../components/Popover';\nimport { ChevronDown, X } from '../../icons';\n\ntype PageToolbarTokenProps = Omit<\n ComponentPropsWithoutRef<typeof Badge>,\n 'variant' | 'color' | 'suffix' | 'children' | 'asChild' | 'popover'\n> & {\n children: ReactNode;\n /** Popover content rendered when the chevron-down trigger is clicked — typically a value editor. */\n popover: ReactNode;\n onRemove: () => void;\n removeAriaLabel: string;\n};\n\n/**\n * Editable filter token (Query Builder variant) — `Badge` pill with a `chevron-down`\n * popover trigger for editing values and an `×` dismiss button. The popover content\n * is supplied by the caller via the `popover` slot (typically a `Combobox` or option list).\n */\nexport const PageToolbarToken = ({\n children,\n popover,\n onRemove,\n removeAriaLabel,\n ...props\n}: PageToolbarTokenProps) => (\n <Popover>\n <Badge\n {...props}\n asChild\n variant=\"pill\"\n color=\"blue-inverse\"\n suffix={\n <Button\n type=\"button\"\n variant=\"inline\"\n size=\"icon-2xs\"\n aria-label={removeAriaLabel}\n onClick={onRemove}\n >\n <X className=\"tw:size-3\" />\n </Button>\n }\n >\n <Popover.Trigger\n type=\"button\"\n className=\"tw:inline-flex tw:cursor-pointer tw:items-center tw:gap-1 tw:bg-inherit tw:text-inherit tailwindcss-preflight\"\n >\n {children}\n <ChevronDown className=\"tw:size-3\" />\n </Popover.Trigger>\n </Badge>\n <Popover.Content align=\"start\">{popover}</Popover.Content>\n </Popover>\n);\n","import type { ComponentProps, ComponentPropsWithoutRef, ReactNode } from 'react';\n\nimport { Badge } from '../../components/Badge';\nimport { Button } from '../../components/Button';\nimport { Plus, X } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { PageToolbarToken } from './PageToolbarToken';\n\ntype DivProps = ComponentProps<'div'>;\n\nconst Root = ({ ref, className, children, ...props }: DivProps) => (\n <div\n ref={ref}\n className={cn('tw:flex tw:flex-wrap tw:items-center tw:gap-3 tw:w-full', className)}\n {...props}\n >\n {children}\n </div>\n);\n\nconst Search = ({ ref, className, children, ...props }: DivProps) => (\n <div\n ref={ref}\n className={cn(\n 'tw:mr-auto tw:flex tw:items-center tw:gap-2 tw:w-full tw:sm:w-auto tw:sm:min-w-64 tw:sm:max-w-md',\n // The slot sizes itself between `min-w-64` and `max-w-md`, so the search field has to fill it —\n // without this the input stays content-width (≈224px inside a 448px slot) and truncates its own\n // placeholder, and every caller ends up hand-picking a width class to compensate.\n //\n // - First child only. The documented composition is the search field followed by filter pills;\n // stretching every child would size the pills to match the input.\n // - `min-w-0` so a long value shrinks the input rather than overflowing the toolbar.\n 'tw:*:first:min-w-0 tw:*:first:flex-1',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nconst Right = ({ ref, className, children, ...props }: DivProps) => (\n <div\n ref={ref}\n className={cn('tw:flex tw:flex-wrap tw:items-center tw:gap-2', className)}\n {...props}\n >\n {children}\n </div>\n);\n\nconst ControlGroup = ({ ref, className, children, ...props }: DivProps) => (\n <div ref={ref} className={cn('tw:flex tw:items-center tw:gap-2', className)} {...props}>\n {children}\n </div>\n);\n\nconst ActiveFilters = ({ ref, className, children, ...props }: DivProps) => (\n <div\n ref={ref}\n className={cn('tw:flex tw:flex-wrap tw:items-center tw:gap-2 tw:basis-full', className)}\n {...props}\n >\n {children}\n </div>\n);\n\ntype ChipProps = Omit<\n ComponentPropsWithoutRef<typeof Badge>,\n 'variant' | 'color' | 'suffix' | 'children'\n> & {\n children: ReactNode;\n onRemove: () => void;\n removeAriaLabel: string;\n};\n\nconst Chip = ({ children, onRemove, removeAriaLabel, ...props }: ChipProps) => (\n <Badge\n {...props}\n variant=\"pill\"\n color=\"blue-inverse\"\n suffix={\n <Button\n type=\"button\"\n variant=\"inline\"\n size=\"icon-2xs\"\n aria-label={removeAriaLabel}\n onClick={onRemove}\n >\n <X className=\"tw:size-3\" />\n </Button>\n }\n >\n {children}\n </Badge>\n);\n\ntype ActionProps = ComponentPropsWithoutRef<typeof Button>;\n\nconst AddFilter = ({ className, children, ...props }: ActionProps) => (\n <Button variant=\"invisible\" size=\"small\" className={cn('tw:gap-1.5', className)} {...props}>\n <Plus className=\"tw:size-4\" />\n {children ?? 'Add filter'}\n </Button>\n);\n\nconst Clear = ({ className, children, ...props }: ActionProps) => (\n <Button variant=\"invisible\" size=\"small\" className={cn('tw:ml-auto', className)} {...props}>\n {children ?? 'Clear all'}\n </Button>\n);\n\n/**\n * Two-row toolbar for index pages — search on the left, filter / sort / utility / view\n * controls on the right, an optional Active Filters row below for filter chips or tokens.\n *\n * **When to use:** every index page that supports search or filtering. Hosts inside\n * `PageLayout` as the search / filter row, between `PageLayout.Header` and `PageLayout.Content`.\n * **When NOT to use:** detail pages, form pages, or anywhere there is no search / filter\n * surface. For routing-based tab rows reach for `PageLayout.Tabs`.\n *\n * **Recommended composition (enforced at the call site):**\n *\n * - `Search` sits on the left; the right cluster auto-aligns via flex.\n * - Right cluster order: `Filters` → `Sort` → `Actions` → `View`. View controls are always\n * the final control group — do not render any control after `View`.\n * - `ActiveFilters` is the second row. Render it only when one or more filters are active.\n * - `Clear` self-aligns to the far right of `ActiveFilters`.\n *\n * The block is variant-agnostic: render filter chips (Standard variant, non-editable) or\n * tokens (Query Builder variant, editable) into `ActiveFilters` as plain children — do not\n * mix the two in one toolbar.\n *\n * @see https://github.com/evviku/design-system-docs/blob/main/docs/patterns/toolbar/toolbar.md\n */\nexport const PageToolbar = Object.assign(Root, {\n /** Left slot — typically a `SearchInput`. */\n Search,\n /** Right cluster — host the four control groups below in the recommended order. */\n Right,\n /** Filter controls (`Combobox`, `Select`, `DatePicker`). */\n Filters: ControlGroup,\n /** Sort control. */\n Sort: ControlGroup,\n /** Utility actions (Export, Refresh, …). */\n Actions: ControlGroup,\n /** View toggle (List / Grid). Always render last in the right cluster. */\n View: ControlGroup,\n /**\n * Active filters row. Render only when one or more filters are active. Pass filter chips\n * (Standard variant) or tokens (Query Builder variant) as children, optionally followed\n * by `AddFilter` / `Clear`.\n */\n ActiveFilters,\n /** Non-editable filter chip (Standard variant) — `Badge` pill with a dismiss button. */\n Chip,\n /**\n * Editable filter token (Query Builder variant) — `Badge` pill with a `chevron-down`\n * popover trigger for editing values and an `×` dismiss button. The popover content\n * is supplied by the caller via the `popover` slot (typically a `Combobox` or option list).\n */\n Token: PageToolbarToken,\n /** \"+ Add filter\" action — typically rendered after the chips/tokens in `ActiveFilters`. */\n AddFilter,\n /** \"Clear all\" action — self-aligns to the far right of `ActiveFilters`. */\n Clear,\n});\n"],"mappings":";;;;;;;;;;;;AAuBA,MAAa,oBAAoB,EAC/B,UACA,SACA,UACA,iBACA,GAAG,YAEH,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,OAAD;CACE,GAAI;CACJ,SAAA;CACA,SAAQ;CACR,OAAM;CACN,QACE,oBAAC,QAAD;EACE,MAAK;EACL,SAAQ;EACR,MAAK;EACL,cAAY;EACZ,SAAS;EAET,UAAA,oBAAC,GAAD,EAAG,WAAU,YAAa,CAAA;CACpB,CAAA;CAGV,UAAA,qBAAC,QAAQ,SAAT;EACE,MAAK;EACL,WAAU;EAFZ,UAAA,CAIG,UACD,oBAAC,aAAD,EAAa,WAAU,YAAa,CAAA,CACrB;;AACZ,CAAA,GACP,oBAAC,QAAQ,SAAT;CAAiB,OAAM;CAAS,UAAA;AAAyB,CAAA,CAClD,EAAA,CAAA;;;AC9CX,MAAM,QAAQ,EAAE,KAAK,WAAW,UAAU,GAAG,YAC3C,oBAAC,OAAD;CACO;CACL,WAAW,GAAG,2DAA2D,SAAS;CAClF,GAAI;CAEH;AACE,CAAA;AAGP,MAAM,UAAU,EAAE,KAAK,WAAW,UAAU,GAAG,YAC7C,oBAAC,OAAD;CACO;CACL,WAAW,GACT,oGAQA,wCACA,SACF;CACA,GAAI;CAEH;AACE,CAAA;AAGP,MAAM,SAAS,EAAE,KAAK,WAAW,UAAU,GAAG,YAC5C,oBAAC,OAAD;CACO;CACL,WAAW,GAAG,iDAAiD,SAAS;CACxE,GAAI;CAEH;AACE,CAAA;AAGP,MAAM,gBAAgB,EAAE,KAAK,WAAW,UAAU,GAAG,YACnD,oBAAC,OAAD;CAAU;CAAK,WAAW,GAAG,oCAAoC,SAAS;CAAG,GAAI;CAC9E;AACE,CAAA;AAGP,MAAM,iBAAiB,EAAE,KAAK,WAAW,UAAU,GAAG,YACpD,oBAAC,OAAD;CACO;CACL,WAAW,GAAG,+DAA+D,SAAS;CACtF,GAAI;CAEH;AACE,CAAA;AAYP,MAAM,QAAQ,EAAE,UAAU,UAAU,iBAAiB,GAAG,YACtD,oBAAC,OAAD;CACE,GAAI;CACJ,SAAQ;CACR,OAAM;CACN,QACE,oBAAC,QAAD;EACE,MAAK;EACL,SAAQ;EACR,MAAK;EACL,cAAY;EACZ,SAAS;EAET,UAAA,oBAAC,GAAD,EAAG,WAAU,YAAa,CAAA;CACpB,CAAA;CAGT;AACI,CAAA;AAKT,MAAM,aAAa,EAAE,WAAW,UAAU,GAAG,YAC3C,qBAAC,QAAD;CAAQ,SAAQ;CAAY,MAAK;CAAQ,WAAW,GAAG,cAAc,SAAS;CAAG,GAAI;CAArF,UAAA,CACE,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA,GAC5B,YAAY,YACP;;AAGV,MAAM,SAAS,EAAE,WAAW,UAAU,GAAG,YACvC,oBAAC,QAAD;CAAQ,SAAQ;CAAY,MAAK;CAAQ,WAAW,GAAG,cAAc,SAAS;CAAG,GAAI;CAClF,UAAA,YAAY;AACP,CAAA;;;;;;;;;;;;;;;;;;;;;;;;AA0BV,MAAa,cAAc,OAAO,OAAO,MAAM;;CAE7C;;CAEA;;CAEA,SAAS;;CAET,MAAM;;CAEN,SAAS;;CAET,MAAM;;;;;;CAMN;;CAEA;;;;;;CAMA,OAAO;;CAEP;;CAEA;AACF,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import { cn } from "./classNames-BzrkDnOD.js";
2
2
  import { Button } from "./Button-DsRrU5F1.js";
3
+ import { useStableCallback } from "./internal/hooks/useStableCallback.js";
3
4
  import { Popover } from "./Popover-BEbQrC_P.js";
4
5
  import { Slot } from "@radix-ui/react-slot";
5
- import { createContext, use, useMemo, useRef, useState } from "react";
6
+ import { createContext, use, useMemo, useState } from "react";
6
7
  import { jsx } from "react/jsx-runtime";
7
8
  //#region src/components/Popconfirm/context.ts
8
9
  const PopconfirmContext = createContext(null);
@@ -117,10 +118,8 @@ const noop = () => void 0;
117
118
  const Popconfirm = ({ children, onConfirm = noop, onCancel = noop, variant = "confirm", enabled = true, onOpenChange = noop, open, skipAsyncWait = false, ...rest }) => {
118
119
  const [isLoading, setIsLoading] = useState(false);
119
120
  const [isOpen, setIsOpen] = useState(false);
120
- const confirmRef = useRef(onConfirm);
121
- const cancelRef = useRef(onCancel);
122
- confirmRef.current = onConfirm;
123
- cancelRef.current = onCancel;
121
+ const handleConfirm = useStableCallback(onConfirm);
122
+ const handleCancel = useStableCallback(onCancel);
124
123
  const handleOnOpenChange = (open) => {
125
124
  setIsOpen(open);
126
125
  onOpenChange(open);
@@ -130,20 +129,20 @@ const Popconfirm = ({ children, onConfirm = noop, onCancel = noop, variant = "co
130
129
  isLoading,
131
130
  enabled,
132
131
  onConfirm: (event) => {
133
- const result = confirmRef.current(event);
132
+ const result = handleConfirm(event);
134
133
  if (!(result instanceof Promise) || skipAsyncWait) return;
135
134
  event.preventDefault();
136
135
  setIsLoading(true);
137
136
  result.then(() => setIsOpen(false)).finally(() => setIsLoading(false));
138
137
  },
139
- onCancel: (event) => {
140
- cancelRef.current(event);
141
- }
138
+ onCancel: handleCancel
142
139
  }), [
143
140
  variant,
144
141
  isLoading,
145
142
  enabled,
146
- skipAsyncWait
143
+ skipAsyncWait,
144
+ handleConfirm,
145
+ handleCancel
147
146
  ]);
148
147
  return /* @__PURE__ */ jsx(Popover, {
149
148
  ...rest,
@@ -164,4 +163,4 @@ Popconfirm.Trigger = PopconfirmTrigger;
164
163
  //#endregion
165
164
  export { Popconfirm };
166
165
 
167
- //# sourceMappingURL=Popconfirm-CILjmzKI.js.map
166
+ //# sourceMappingURL=Popconfirm-5pBzT_HQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popconfirm-CILjmzKI.js","names":[],"sources":["../src/components/Popconfirm/context.ts","../src/components/Popconfirm/PopconfirmBody.tsx","../src/components/Popconfirm/PopconfirmCancel.tsx","../src/components/Popconfirm/PopconfirmConfirm.tsx","../src/components/Popconfirm/PopconfirmContent.tsx","../src/components/Popconfirm/PopconfirmFooter.tsx","../src/components/Popconfirm/PopconfirmTrigger.tsx","../src/components/Popconfirm/Popconfirm.tsx"],"sourcesContent":["import { createContext, type MouseEvent, use } from 'react';\n\nexport type PopconfirmContextType = {\n variant: 'confirm' | 'danger';\n onConfirm: (event: MouseEvent<HTMLButtonElement>) => void | Promise<void>;\n onCancel: (event: MouseEvent<HTMLButtonElement>) => void;\n enabled: boolean;\n isLoading: boolean;\n};\n\nconst PopconfirmContext = createContext<PopconfirmContextType | null>(null);\n\nexport const PopconfirmContextProvider = PopconfirmContext;\n\nexport const usePopconfirmContext = () => {\n const context = use(PopconfirmContext);\n if (!context) throw new Error('usePopconfirmContext must be used within a Popconfirm');\n return context;\n};\n","import type { ComponentProps } from 'react';\n\ntype Props = ComponentProps<'div'>;\n\nexport const PopconfirmBody = (props: Props) => <div {...props} />;\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { Popover } from '../Popover';\n\nimport { usePopconfirmContext } from './context';\n\ntype SlotProps = { asChild: true } & ComponentProps<'button'>;\ntype ButtonProps = { asChild?: false; children?: ReactNode } & Omit<\n ComponentProps<typeof Button>,\n 'children'\n>;\ntype Props = SlotProps | ButtonProps;\n\nexport const PopconfirmCancel = ({\n ref,\n onClick,\n children,\n asChild,\n className,\n ...props\n}: Props) => {\n const { onCancel, isLoading } = usePopconfirmContext();\n\n const handleClick: ComponentProps<'button'>['onClick'] = (event) => {\n onClick?.(event);\n onCancel(event);\n };\n\n return (\n <Popover.Close asChild onClick={handleClick} disabled={isLoading}>\n {asChild ? (\n <Slot {...props} ref={ref} className={className}>\n {children}\n </Slot>\n ) : (\n <Button variant=\"outline\" size=\"small\" {...props} ref={ref} className={cn(className)}>\n {children ?? 'Cancel'}\n </Button>\n )}\n </Popover.Close>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\nimport { Button } from '../Button/Button';\nimport { Popover } from '../Popover';\n\nimport { usePopconfirmContext } from './context';\n\ntype SlotProps = { asChild: true } & ComponentProps<'button'>;\ntype ButtonProps = { asChild?: false; children?: ReactNode } & Omit<\n ComponentProps<typeof Button>,\n 'children' | 'isLoading'\n>;\ntype Props = SlotProps | ButtonProps;\n\nexport const PopconfirmConfirm = ({\n ref,\n onClick,\n children,\n asChild,\n className,\n ...props\n}: Props) => {\n const { onConfirm, variant, isLoading } = usePopconfirmContext();\n\n const handleOnClick: ComponentProps<'button'>['onClick'] = (event) => {\n onClick?.(event);\n onConfirm(event);\n };\n\n const defaultLabel = (() => {\n if (children) return children;\n return variant === 'danger' ? 'Delete' : 'Confirm';\n })();\n\n return (\n <Popover.Close asChild onClick={handleOnClick} disabled={isLoading} data-loading={isLoading}>\n {asChild ? (\n <Slot {...props} ref={ref} className={className}>\n {children}\n </Slot>\n ) : (\n <Button\n size=\"small\"\n variant={variant === 'danger' ? 'danger' : 'primary'}\n {...props}\n ref={ref}\n className={cn('tw:flex-1', className)}\n isLoading={isLoading}\n >\n {defaultLabel}\n </Button>\n )}\n </Popover.Close>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\nimport { Popover } from '../Popover';\n\nimport { usePopconfirmContext } from './context';\n\ntype Props = Omit<ComponentProps<typeof Popover.Content>, 'showArrow'>;\n\nexport const PopconfirmContent = ({ className, onInteractOutside, ...props }: Props) => {\n const { isLoading } = usePopconfirmContext();\n\n const handleOnInteractOutside: Props['onInteractOutside'] = (event) => {\n if (isLoading) event.preventDefault();\n onInteractOutside?.(event);\n };\n\n return (\n <Popover.Content\n {...props}\n onInteractOutside={handleOnInteractOutside}\n className={cn('tw:flex', 'tw:flex-col', 'tw:gap-3', 'tw:px-4', 'tw:py-3', className)}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const PopconfirmFooter = ({ className, ...props }: Props) => (\n <div {...props} className={cn('tw:flex tw:gap-2 tw:w-full', className)} />\n);\n","import type { ComponentProps, MouseEventHandler } from 'react';\n\nimport { Popover } from '../Popover';\n\nimport { usePopconfirmContext } from './context';\n\ntype Props = ComponentProps<typeof Popover.Trigger>;\n\nexport const PopconfirmTrigger = ({ onClick, ...props }: Props) => {\n const { enabled, onConfirm } = usePopconfirmContext();\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = (event) => {\n if (!enabled) {\n event.preventDefault();\n onConfirm(event);\n }\n\n onClick?.(event);\n };\n\n return <Popover.Trigger {...props} onClick={handleClick} />;\n};\n","import { useMemo, useRef, useState } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { Popover } from '../Popover';\n\nimport { PopconfirmContextProvider, type PopconfirmContextType } from './context';\nimport { PopconfirmBody } from './PopconfirmBody';\nimport { PopconfirmCancel } from './PopconfirmCancel';\nimport { PopconfirmConfirm } from './PopconfirmConfirm';\nimport { PopconfirmContent } from './PopconfirmContent';\nimport { PopconfirmFooter } from './PopconfirmFooter';\nimport { PopconfirmTrigger } from './PopconfirmTrigger';\n\nconst noop = () => void 0;\n\ntype Props = {\n children: ReactNode;\n skipAsyncWait?: boolean;\n} & ComponentProps<typeof Popover> &\n Omit<Partial<PopconfirmContextType>, 'isLoading'>;\n\nexport const Popconfirm = ({\n children,\n onConfirm = noop,\n onCancel = noop,\n variant = 'confirm',\n enabled = true,\n onOpenChange = noop,\n open,\n skipAsyncWait = false,\n ...rest\n}: Props) => {\n const [isLoading, setIsLoading] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n\n const confirmRef = useRef(onConfirm);\n const cancelRef = useRef(onCancel);\n confirmRef.current = onConfirm;\n cancelRef.current = onCancel;\n\n const handleOnOpenChange = (open: boolean) => {\n setIsOpen(open);\n onOpenChange(open);\n };\n\n const context = useMemo<PopconfirmContextType>(\n () => ({\n variant,\n isLoading,\n enabled,\n onConfirm: (event) => {\n const result = confirmRef.current(event);\n\n if (!(result instanceof Promise) || skipAsyncWait) return;\n\n // The async confirm's outcome drives the popover.\n // - `preventDefault` stops the click closing it, so it stays up while the action runs.\n // - Resolved closes it; rejected leaves it up so the failure stays visible.\n // - The rejection is deliberately not caught — the host's global handler reports it.\n event.preventDefault();\n setIsLoading(true);\n result.then(() => setIsOpen(false)).finally(() => setIsLoading(false));\n },\n onCancel: (event) => {\n cancelRef.current(event);\n },\n }),\n [variant, isLoading, enabled, skipAsyncWait],\n );\n\n return (\n <Popover {...rest} open={open || isOpen} onOpenChange={handleOnOpenChange}>\n <PopconfirmContextProvider value={context}>{children}</PopconfirmContextProvider>\n </Popover>\n );\n};\n\nPopconfirm.Confirm = PopconfirmConfirm;\nPopconfirm.Cancel = PopconfirmCancel;\nPopconfirm.Footer = PopconfirmFooter;\nPopconfirm.Content = PopconfirmContent;\nPopconfirm.Body = PopconfirmBody;\nPopconfirm.Trigger = PopconfirmTrigger;\n"],"mappings":";;;;;;;AAUA,MAAM,oBAAoB,cAA4C,IAAI;AAE1E,MAAa,4BAA4B;AAEzC,MAAa,6BAA6B;CACxC,MAAM,UAAU,IAAI,iBAAiB;CACrC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,uDAAuD;CACrF,OAAO;AACT;;;ACdA,MAAa,kBAAkB,UAAiB,oBAAC,OAAD,EAAK,GAAI,MAAQ,CAAA;;;ACYjE,MAAa,oBAAoB,EAC/B,KACA,SACA,UACA,SACA,WACA,GAAG,YACQ;CACX,MAAM,EAAE,UAAU,cAAc,qBAAqB;CAErD,MAAM,eAAoD,UAAU;EAClE,UAAU,KAAK;EACf,SAAS,KAAK;CAChB;CAEA,OACE,oBAAC,QAAQ,OAAT;EAAe,SAAA;EAAQ,SAAS;EAAa,UAAU;EACpD,UAAA,UACC,oBAAC,MAAD;GAAM,GAAI;GAAY;GAAgB;GACnC;EACG,CAAA,IAEN,oBAAC,QAAD;GAAQ,SAAQ;GAAU,MAAK;GAAQ,GAAI;GAAY;GAAK,WAAW,GAAG,SAAS;GAChF,UAAA,YAAY;EACP,CAAA;CAEG,CAAA;AAEnB;;;AC5BA,MAAa,qBAAqB,EAChC,KACA,SACA,UACA,SACA,WACA,GAAG,YACQ;CACX,MAAM,EAAE,WAAW,SAAS,cAAc,qBAAqB;CAE/D,MAAM,iBAAsD,UAAU;EACpE,UAAU,KAAK;EACf,UAAU,KAAK;CACjB;CAEA,MAAM,sBAAsB;EAC1B,IAAI,UAAU,OAAO;EACrB,OAAO,YAAY,WAAW,WAAW;CAC3C,EAAA,CAAG;CAEH,OACE,oBAAC,QAAQ,OAAT;EAAe,SAAA;EAAQ,SAAS;EAAe,UAAU;EAAW,gBAAc;EAC/E,UAAA,UACC,oBAAC,MAAD;GAAM,GAAI;GAAY;GAAgB;GACnC;EACG,CAAA,IAEN,oBAAC,QAAD;GACE,MAAK;GACL,SAAS,YAAY,WAAW,WAAW;GAC3C,GAAI;GACC;GACL,WAAW,GAAG,aAAa,SAAS;GACzB;GAEV,UAAA;EACK,CAAA;CAEG,CAAA;AAEnB;;;AC/CA,MAAa,qBAAqB,EAAE,WAAW,mBAAmB,GAAG,YAAmB;CACtF,MAAM,EAAE,cAAc,qBAAqB;CAE3C,MAAM,2BAAuD,UAAU;EACrE,IAAI,WAAW,MAAM,eAAe;EACpC,oBAAoB,KAAK;CAC3B;CAEA,OACE,oBAAC,QAAQ,SAAT;EACE,GAAI;EACJ,mBAAmB;EACnB,WAAW,GAAG,WAAW,eAAe,YAAY,WAAW,WAAW,SAAS;CACpF,CAAA;AAEL;;;AClBA,MAAa,oBAAoB,EAAE,WAAW,GAAG,YAC/C,oBAAC,OAAD;CAAK,GAAI;CAAO,WAAW,GAAG,8BAA8B,SAAS;AAAI,CAAA;;;ACC3E,MAAa,qBAAqB,EAAE,SAAS,GAAG,YAAmB;CACjE,MAAM,EAAE,SAAS,cAAc,qBAAqB;CAEpD,MAAM,eAAqD,UAAU;EACnE,IAAI,CAAC,SAAS;GACZ,MAAM,eAAe;GACrB,UAAU,KAAK;EACjB;EAEA,UAAU,KAAK;CACjB;CAEA,OAAO,oBAAC,QAAQ,SAAT;EAAiB,GAAI;EAAO,SAAS;CAAc,CAAA;AAC5D;;;ACRA,MAAM,aAAa,KAAK;AAQxB,MAAa,cAAc,EACzB,UACA,YAAY,MACZ,WAAW,MACX,UAAU,WACV,UAAU,MACV,eAAe,MACf,MACA,gBAAgB,OAChB,GAAG,WACQ;CACX,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAE1C,MAAM,aAAa,OAAO,SAAS;CACnC,MAAM,YAAY,OAAO,QAAQ;CACjC,WAAW,UAAU;CACrB,UAAU,UAAU;CAEpB,MAAM,sBAAsB,SAAkB;EAC5C,UAAU,IAAI;EACd,aAAa,IAAI;CACnB;CAEA,MAAM,UAAU,eACP;EACL;EACA;EACA;EACA,YAAY,UAAU;GACpB,MAAM,SAAS,WAAW,QAAQ,KAAK;GAEvC,IAAI,EAAE,kBAAkB,YAAY,eAAe;GAMnD,MAAM,eAAe;GACrB,aAAa,IAAI;GACjB,OAAO,WAAW,UAAU,KAAK,CAAC,CAAC,CAAC,cAAc,aAAa,KAAK,CAAC;EACvE;EACA,WAAW,UAAU;GACnB,UAAU,QAAQ,KAAK;EACzB;CACF,IACA;EAAC;EAAS;EAAW;EAAS;CAAa,CAC7C;CAEA,OACE,oBAAC,SAAD;EAAS,GAAI;EAAM,MAAM,QAAQ;EAAQ,cAAc;EACrD,UAAA,oBAAC,2BAAD;GAA2B,OAAO;GAAU;EAAoC,CAAA;CACzE,CAAA;AAEb;AAEA,WAAW,UAAU;AACrB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,UAAU;AACrB,WAAW,OAAO;AAClB,WAAW,UAAU"}
1
+ {"version":3,"file":"Popconfirm-5pBzT_HQ.js","names":[],"sources":["../src/components/Popconfirm/context.ts","../src/components/Popconfirm/PopconfirmBody.tsx","../src/components/Popconfirm/PopconfirmCancel.tsx","../src/components/Popconfirm/PopconfirmConfirm.tsx","../src/components/Popconfirm/PopconfirmContent.tsx","../src/components/Popconfirm/PopconfirmFooter.tsx","../src/components/Popconfirm/PopconfirmTrigger.tsx","../src/components/Popconfirm/Popconfirm.tsx"],"sourcesContent":["import { createContext, type MouseEvent, use } from 'react';\n\nexport type PopconfirmContextType = {\n variant: 'confirm' | 'danger';\n onConfirm: (event: MouseEvent<HTMLButtonElement>) => void | Promise<void>;\n onCancel: (event: MouseEvent<HTMLButtonElement>) => void;\n enabled: boolean;\n isLoading: boolean;\n};\n\nconst PopconfirmContext = createContext<PopconfirmContextType | null>(null);\n\nexport const PopconfirmContextProvider = PopconfirmContext;\n\nexport const usePopconfirmContext = () => {\n const context = use(PopconfirmContext);\n if (!context) throw new Error('usePopconfirmContext must be used within a Popconfirm');\n return context;\n};\n","import type { ComponentProps } from 'react';\n\ntype Props = ComponentProps<'div'>;\n\nexport const PopconfirmBody = (props: Props) => <div {...props} />;\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { Popover } from '../Popover';\n\nimport { usePopconfirmContext } from './context';\n\ntype SlotProps = { asChild: true } & ComponentProps<'button'>;\ntype ButtonProps = { asChild?: false; children?: ReactNode } & Omit<\n ComponentProps<typeof Button>,\n 'children'\n>;\ntype Props = SlotProps | ButtonProps;\n\nexport const PopconfirmCancel = ({\n ref,\n onClick,\n children,\n asChild,\n className,\n ...props\n}: Props) => {\n const { onCancel, isLoading } = usePopconfirmContext();\n\n const handleClick: ComponentProps<'button'>['onClick'] = (event) => {\n onClick?.(event);\n onCancel(event);\n };\n\n return (\n <Popover.Close asChild onClick={handleClick} disabled={isLoading}>\n {asChild ? (\n <Slot {...props} ref={ref} className={className}>\n {children}\n </Slot>\n ) : (\n <Button variant=\"outline\" size=\"small\" {...props} ref={ref} className={cn(className)}>\n {children ?? 'Cancel'}\n </Button>\n )}\n </Popover.Close>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\nimport { Button } from '../Button/Button';\nimport { Popover } from '../Popover';\n\nimport { usePopconfirmContext } from './context';\n\ntype SlotProps = { asChild: true } & ComponentProps<'button'>;\ntype ButtonProps = { asChild?: false; children?: ReactNode } & Omit<\n ComponentProps<typeof Button>,\n 'children' | 'isLoading'\n>;\ntype Props = SlotProps | ButtonProps;\n\nexport const PopconfirmConfirm = ({\n ref,\n onClick,\n children,\n asChild,\n className,\n ...props\n}: Props) => {\n const { onConfirm, variant, isLoading } = usePopconfirmContext();\n\n const handleOnClick: ComponentProps<'button'>['onClick'] = (event) => {\n onClick?.(event);\n onConfirm(event);\n };\n\n const defaultLabel = (() => {\n if (children) return children;\n return variant === 'danger' ? 'Delete' : 'Confirm';\n })();\n\n return (\n <Popover.Close asChild onClick={handleOnClick} disabled={isLoading} data-loading={isLoading}>\n {asChild ? (\n <Slot {...props} ref={ref} className={className}>\n {children}\n </Slot>\n ) : (\n <Button\n size=\"small\"\n variant={variant === 'danger' ? 'danger' : 'primary'}\n {...props}\n ref={ref}\n className={cn('tw:flex-1', className)}\n isLoading={isLoading}\n >\n {defaultLabel}\n </Button>\n )}\n </Popover.Close>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\nimport { Popover } from '../Popover';\n\nimport { usePopconfirmContext } from './context';\n\ntype Props = Omit<ComponentProps<typeof Popover.Content>, 'showArrow'>;\n\nexport const PopconfirmContent = ({ className, onInteractOutside, ...props }: Props) => {\n const { isLoading } = usePopconfirmContext();\n\n const handleOnInteractOutside: Props['onInteractOutside'] = (event) => {\n if (isLoading) event.preventDefault();\n onInteractOutside?.(event);\n };\n\n return (\n <Popover.Content\n {...props}\n onInteractOutside={handleOnInteractOutside}\n className={cn('tw:flex', 'tw:flex-col', 'tw:gap-3', 'tw:px-4', 'tw:py-3', className)}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const PopconfirmFooter = ({ className, ...props }: Props) => (\n <div {...props} className={cn('tw:flex tw:gap-2 tw:w-full', className)} />\n);\n","import type { ComponentProps, MouseEventHandler } from 'react';\n\nimport { Popover } from '../Popover';\n\nimport { usePopconfirmContext } from './context';\n\ntype Props = ComponentProps<typeof Popover.Trigger>;\n\nexport const PopconfirmTrigger = ({ onClick, ...props }: Props) => {\n const { enabled, onConfirm } = usePopconfirmContext();\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = (event) => {\n if (!enabled) {\n event.preventDefault();\n onConfirm(event);\n }\n\n onClick?.(event);\n };\n\n return <Popover.Trigger {...props} onClick={handleClick} />;\n};\n","import { useMemo, useState } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { useStableCallback } from '../../hooks/useStableCallback';\nimport { Popover } from '../Popover';\n\nimport { PopconfirmContextProvider, type PopconfirmContextType } from './context';\nimport { PopconfirmBody } from './PopconfirmBody';\nimport { PopconfirmCancel } from './PopconfirmCancel';\nimport { PopconfirmConfirm } from './PopconfirmConfirm';\nimport { PopconfirmContent } from './PopconfirmContent';\nimport { PopconfirmFooter } from './PopconfirmFooter';\nimport { PopconfirmTrigger } from './PopconfirmTrigger';\n\nconst noop = () => void 0;\n\ntype Props = {\n children: ReactNode;\n skipAsyncWait?: boolean;\n} & ComponentProps<typeof Popover> &\n Omit<Partial<PopconfirmContextType>, 'isLoading'>;\n\nexport const Popconfirm = ({\n children,\n onConfirm = noop,\n onCancel = noop,\n variant = 'confirm',\n enabled = true,\n onOpenChange = noop,\n open,\n skipAsyncWait = false,\n ...rest\n}: Props) => {\n const [isLoading, setIsLoading] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n\n const handleConfirm = useStableCallback(onConfirm);\n const handleCancel = useStableCallback(onCancel);\n\n const handleOnOpenChange = (open: boolean) => {\n setIsOpen(open);\n onOpenChange(open);\n };\n\n const context = useMemo<PopconfirmContextType>(\n () => ({\n variant,\n isLoading,\n enabled,\n onConfirm: (event) => {\n const result = handleConfirm(event);\n\n if (!(result instanceof Promise) || skipAsyncWait) return;\n\n // The async confirm's outcome drives the popover.\n // - `preventDefault` stops the click closing it, so it stays up while the action runs.\n // - Resolved closes it; rejected leaves it up so the failure stays visible.\n // - The rejection is deliberately not caught — the host's global handler reports it.\n event.preventDefault();\n setIsLoading(true);\n result.then(() => setIsOpen(false)).finally(() => setIsLoading(false));\n },\n onCancel: handleCancel,\n }),\n [variant, isLoading, enabled, skipAsyncWait, handleConfirm, handleCancel],\n );\n\n return (\n <Popover {...rest} open={open || isOpen} onOpenChange={handleOnOpenChange}>\n <PopconfirmContextProvider value={context}>{children}</PopconfirmContextProvider>\n </Popover>\n );\n};\n\nPopconfirm.Confirm = PopconfirmConfirm;\nPopconfirm.Cancel = PopconfirmCancel;\nPopconfirm.Footer = PopconfirmFooter;\nPopconfirm.Content = PopconfirmContent;\nPopconfirm.Body = PopconfirmBody;\nPopconfirm.Trigger = PopconfirmTrigger;\n"],"mappings":";;;;;;;;AAUA,MAAM,oBAAoB,cAA4C,IAAI;AAE1E,MAAa,4BAA4B;AAEzC,MAAa,6BAA6B;CACxC,MAAM,UAAU,IAAI,iBAAiB;CACrC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,uDAAuD;CACrF,OAAO;AACT;;;ACdA,MAAa,kBAAkB,UAAiB,oBAAC,OAAD,EAAK,GAAI,MAAQ,CAAA;;;ACYjE,MAAa,oBAAoB,EAC/B,KACA,SACA,UACA,SACA,WACA,GAAG,YACQ;CACX,MAAM,EAAE,UAAU,cAAc,qBAAqB;CAErD,MAAM,eAAoD,UAAU;EAClE,UAAU,KAAK;EACf,SAAS,KAAK;CAChB;CAEA,OACE,oBAAC,QAAQ,OAAT;EAAe,SAAA;EAAQ,SAAS;EAAa,UAAU;EACpD,UAAA,UACC,oBAAC,MAAD;GAAM,GAAI;GAAY;GAAgB;GACnC;EACG,CAAA,IAEN,oBAAC,QAAD;GAAQ,SAAQ;GAAU,MAAK;GAAQ,GAAI;GAAY;GAAK,WAAW,GAAG,SAAS;GAChF,UAAA,YAAY;EACP,CAAA;CAEG,CAAA;AAEnB;;;AC5BA,MAAa,qBAAqB,EAChC,KACA,SACA,UACA,SACA,WACA,GAAG,YACQ;CACX,MAAM,EAAE,WAAW,SAAS,cAAc,qBAAqB;CAE/D,MAAM,iBAAsD,UAAU;EACpE,UAAU,KAAK;EACf,UAAU,KAAK;CACjB;CAEA,MAAM,sBAAsB;EAC1B,IAAI,UAAU,OAAO;EACrB,OAAO,YAAY,WAAW,WAAW;CAC3C,EAAA,CAAG;CAEH,OACE,oBAAC,QAAQ,OAAT;EAAe,SAAA;EAAQ,SAAS;EAAe,UAAU;EAAW,gBAAc;EAC/E,UAAA,UACC,oBAAC,MAAD;GAAM,GAAI;GAAY;GAAgB;GACnC;EACG,CAAA,IAEN,oBAAC,QAAD;GACE,MAAK;GACL,SAAS,YAAY,WAAW,WAAW;GAC3C,GAAI;GACC;GACL,WAAW,GAAG,aAAa,SAAS;GACzB;GAEV,UAAA;EACK,CAAA;CAEG,CAAA;AAEnB;;;AC/CA,MAAa,qBAAqB,EAAE,WAAW,mBAAmB,GAAG,YAAmB;CACtF,MAAM,EAAE,cAAc,qBAAqB;CAE3C,MAAM,2BAAuD,UAAU;EACrE,IAAI,WAAW,MAAM,eAAe;EACpC,oBAAoB,KAAK;CAC3B;CAEA,OACE,oBAAC,QAAQ,SAAT;EACE,GAAI;EACJ,mBAAmB;EACnB,WAAW,GAAG,WAAW,eAAe,YAAY,WAAW,WAAW,SAAS;CACpF,CAAA;AAEL;;;AClBA,MAAa,oBAAoB,EAAE,WAAW,GAAG,YAC/C,oBAAC,OAAD;CAAK,GAAI;CAAO,WAAW,GAAG,8BAA8B,SAAS;AAAI,CAAA;;;ACC3E,MAAa,qBAAqB,EAAE,SAAS,GAAG,YAAmB;CACjE,MAAM,EAAE,SAAS,cAAc,qBAAqB;CAEpD,MAAM,eAAqD,UAAU;EACnE,IAAI,CAAC,SAAS;GACZ,MAAM,eAAe;GACrB,UAAU,KAAK;EACjB;EAEA,UAAU,KAAK;CACjB;CAEA,OAAO,oBAAC,QAAQ,SAAT;EAAiB,GAAI;EAAO,SAAS;CAAc,CAAA;AAC5D;;;ACPA,MAAM,aAAa,KAAK;AAQxB,MAAa,cAAc,EACzB,UACA,YAAY,MACZ,WAAW,MACX,UAAU,WACV,UAAU,MACV,eAAe,MACf,MACA,gBAAgB,OAChB,GAAG,WACQ;CACX,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAE1C,MAAM,gBAAgB,kBAAkB,SAAS;CACjD,MAAM,eAAe,kBAAkB,QAAQ;CAE/C,MAAM,sBAAsB,SAAkB;EAC5C,UAAU,IAAI;EACd,aAAa,IAAI;CACnB;CAEA,MAAM,UAAU,eACP;EACL;EACA;EACA;EACA,YAAY,UAAU;GACpB,MAAM,SAAS,cAAc,KAAK;GAElC,IAAI,EAAE,kBAAkB,YAAY,eAAe;GAMnD,MAAM,eAAe;GACrB,aAAa,IAAI;GACjB,OAAO,WAAW,UAAU,KAAK,CAAC,CAAC,CAAC,cAAc,aAAa,KAAK,CAAC;EACvE;EACA,UAAU;CACZ,IACA;EAAC;EAAS;EAAW;EAAS;EAAe;EAAe;CAAY,CAC1E;CAEA,OACE,oBAAC,SAAD;EAAS,GAAI;EAAM,MAAM,QAAQ;EAAQ,cAAc;EACrD,UAAA,oBAAC,2BAAD;GAA2B,OAAO;GAAU;EAAoC,CAAA;CACzE,CAAA;AAEb;AAEA,WAAW,UAAU;AACrB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,UAAU;AACrB,WAAW,OAAO;AAClB,WAAW,UAAU"}
@@ -1,5 +1,5 @@
1
1
  import { cn } from "./classNames-BzrkDnOD.js";
2
- import { Tooltip } from "./utils-B5Z52hYs.js";
2
+ import { Tooltip } from "./utils-DSvrhU8E.js";
3
3
  import { useArgoDesign } from "./context-D7X470dy.js";
4
4
  import { Circle } from "./icons-Cek151jC.js";
5
5
  import { Separator } from "./internal/components/Separator.js";
@@ -230,4 +230,4 @@ RadioGroup.Separator = RadioGroupSeparator;
230
230
  //#endregion
231
231
  export { RadioGroup };
232
232
 
233
- //# sourceMappingURL=RadioGroup-XFzFd1ti.js.map
233
+ //# sourceMappingURL=RadioGroup-DXPbSj8P.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup-XFzFd1ti.js","names":[],"sources":["../src/components/RadioGroup/context.ts","../src/components/RadioGroup/styles.ts","../src/components/RadioGroup/Radio.tsx","../src/components/RadioGroup/RadioGroupItemButton.tsx","../src/components/RadioGroup/RadioGroupItem.tsx","../src/components/RadioGroup/RadioGroupSeparator.tsx","../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\nexport type Variant = 'radio' | 'button' | 'radio-block';\nexport type Orientation = 'vertical' | 'horizontal';\n\nconst RadioGroupContext = createContext<{\n variant: Variant;\n orientation: Orientation;\n}>({\n variant: 'radio',\n orientation: 'horizontal',\n});\n\nexport const RadioGroupProvider = RadioGroupContext;\n\nexport const useRadioGroupContext = () => use(RadioGroupContext);\n","import { cva } from 'class-variance-authority';\n\nexport const radioVariants = cva(\n [\n // reset\n 'tw:bg-transparent',\n 'tw:p-0',\n 'tw:peer',\n 'tw:cursor-pointer',\n 'tw:whitespace-nowrap',\n 'tw:shrink-0',\n\n // position\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:disabled:cursor-not-allowed',\n\n 'tw:size-4',\n\n // border\n 'tw:rounded-full',\n 'tw:border',\n 'tw:border-solid',\n ],\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: [\n 'tw:disabled:opacity-40',\n\n 'tw:data-[state=checked]:border-primary',\n 'tw:data-[state=unchecked]:border-neutral-200',\n 'tw:data-[state=unchecked]:hover:border-primary',\n 'tw:data-[state=unchecked]:disabled:hover:border-neutral-200',\n\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/30',\n ],\n argo: [\n 'tw:disabled:opacity-50',\n\n 'tw:border-input',\n 'tw:transition-colors',\n\n 'tw:data-[state=checked]:bg-primary',\n 'tw:data-[state=checked]:border-primary',\n\n 'tw:data-[state=unchecked]:not-disabled:hover:bg-accent',\n 'tw:data-[state=checked]:not-disabled:hover:bg-primary',\n\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:border-primary',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n ],\n },\n },\n },\n);\n\nexport const radioIndicatorVariants = cva(['tw:size-2.5', 'tw:fill-current'], {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: ['tw:text-primary'],\n argo: ['tw:text-primary-foreground'],\n },\n },\n});\n\nexport const radioItemButtonVariants = cva(\n [\n // reset\n 'tw:bg-transparent',\n 'tw:p-0',\n 'tw:peer',\n 'tw:cursor-pointer',\n 'tw:whitespace-nowrap',\n\n // position\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:disabled:cursor-not-allowed',\n\n // layouts\n 'tw:w-full',\n 'tw:px-2',\n 'tw:py-1.5',\n\n // fonts\n 'tw:uppercase',\n 'tw:font-semibold',\n 'tw:font-sans',\n 'tw:text-[11px]',\n 'tw:whitespace-nowrap',\n 'tw:tracking-widest',\n 'tw:leading-[18px]',\n\n // border\n 'tw:border',\n 'tw:border-solid',\n 'tw:rounded',\n ],\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: [\n 'tw:disabled:opacity-40',\n 'tw:text-secondary-600',\n 'tw:border-secondary-500',\n\n 'tw:data-[state=unchecked]:hover:bg-secondary-500',\n 'tw:data-[state=unchecked]:hover:text-white',\n\n 'tw:data-[state=unchecked]:disabled:hover:bg-white',\n 'tw:data-[state=unchecked]:disabled:hover:text-secondary-500',\n 'tw:data-[state=checked]:disabled:cursor-not-allowed',\n\n 'tw:data-[state=unchecked]:bg-white',\n 'tw:data-[state=checked]:bg-secondary-500',\n 'tw:data-[state=checked]:text-white',\n 'tw:data-[state=checked]:cursor-default',\n\n 'tw:focus-visible:outline',\n 'tw:focus-visible:outline-ring',\n 'tw:focus-visible:ring-4',\n 'tw:focus-visible:ring-ring/30',\n ],\n argo: [\n 'tw:disabled:opacity-50',\n 'tw:text-foreground',\n 'tw:border-input',\n 'tw:transition-colors',\n\n // muted filled control surface — gray, distinct from white containers; not the app-background token\n 'tw:data-[state=unchecked]:bg-muted',\n 'tw:data-[state=unchecked]:not-disabled:hover:bg-accent',\n 'tw:data-[state=unchecked]:not-disabled:hover:text-accent-foreground',\n\n 'tw:data-[state=checked]:bg-primary',\n 'tw:data-[state=checked]:border-primary',\n 'tw:data-[state=checked]:text-primary-foreground',\n 'tw:data-[state=checked]:not-disabled:cursor-default',\n\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:border-primary',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n ],\n },\n },\n },\n);\n\nexport type RadioStyleVariant = 'default' | 'argo';\n","import type { ComponentProps } from 'react';\nimport { Indicator, Item } from '@radix-ui/react-radio-group';\n\nimport { Circle } from '../../icons';\nimport { cn } from '../../utils';\n\nimport type { RadioStyleVariant } from './styles';\nimport { radioIndicatorVariants, radioVariants } from './styles';\n\ntype Props = ComponentProps<typeof Item> & { styleVariant?: RadioStyleVariant };\n\nexport const Radio = ({ className, styleVariant = 'default', ...props }: Props) => (\n <Item {...props} className={cn(radioVariants({ variant: styleVariant }), className)}>\n <Indicator className={cn('tw:flex', 'tw:items-center', 'tw:justify-center')}>\n {/* Lucide Circle is stroke-only — force fill to match the stroke (currentColor)\n so the indicator reads as a solid dot. */}\n <Circle className={radioIndicatorVariants({ variant: styleVariant })} />\n </Indicator>\n </Item>\n);\n","import type { ComponentProps } from 'react';\nimport { Item } from '@radix-ui/react-radio-group';\n\nimport { cn } from '../../utils';\n\nimport type { RadioStyleVariant } from './styles';\nimport { radioItemButtonVariants } from './styles';\n\ntype Props = ComponentProps<typeof Item> & { styleVariant?: RadioStyleVariant };\n\nexport const RadioGroupItemButton = ({\n ref,\n className,\n children,\n styleVariant = 'default',\n ...props\n}: Props) => (\n <Item\n ref={ref}\n {...props}\n className={cn(radioItemButtonVariants({ variant: styleVariant }), className)}\n >\n {children}\n </Item>\n);\n","import { useId } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\nimport type { Item } from '@radix-ui/react-radio-group';\n\nimport { cn } from '../../utils';\nimport { FieldBox } from '../FieldBox';\nimport { useArgoDesign } from '../ThemeProvider/context';\nimport type { Props as TooltipProps } from '../Tooltip';\nimport { Tooltip } from '../Tooltip';\n\nimport { useRadioGroupContext } from './context';\nimport { Radio } from './Radio';\nimport { RadioGroupItemButton } from './RadioGroupItemButton';\n\ntype ItemProps = Omit<ComponentProps<typeof Item>, 'asChild' | 'value'>;\n\ntype Props<T extends string = string> = ItemProps & {\n value: T;\n tooltip?: ReactNode;\n tooltipVariant?: TooltipProps['variant'];\n tooltipPlacement?: TooltipProps['placement'];\n description?: ReactNode;\n};\n\nexport const RadioGroupItem = <T extends string = string>({\n children,\n className,\n tooltip,\n tooltipVariant,\n tooltipPlacement,\n description,\n ...props\n}: Props<T>) => {\n const { variant } = useRadioGroupContext();\n const styleVariant = useArgoDesign() ? 'argo' : 'default';\n const id = useId();\n\n const item = (() => {\n if (variant === 'button')\n return (\n <RadioGroupItemButton styleVariant={styleVariant} {...props} className={className}>\n {children}\n </RadioGroupItemButton>\n );\n\n return (\n <FieldBox\n variant={variant === 'radio-block' ? 'boxed' : 'default'}\n htmlFor={id}\n control={<Radio styleVariant={styleVariant} {...props} id={id} />}\n className={cn(variant === 'radio-block' && 'tw:flex-1', className)}\n >\n <FieldBox.Title>{children}</FieldBox.Title>\n {description && <FieldBox.Description>{description}</FieldBox.Description>}\n </FieldBox>\n );\n })();\n\n if (!tooltip) {\n return item;\n }\n\n return (\n <Tooltip tooltip={tooltip} variant={tooltipVariant} placement={tooltipPlacement} triggerAsChild>\n {item}\n </Tooltip>\n );\n};\n","import { Separator } from '../Separator';\n\nimport { useRadioGroupContext } from './context';\n\nexport const RadioGroupSeparator = () => {\n const { orientation } = useRadioGroupContext();\n const invertedOrientation = orientation === 'horizontal' ? 'vertical' : 'horizontal';\n const size = orientation === 'horizontal' ? '1/2' : 'full';\n const className = orientation === 'horizontal' ? 'tw:mx-2' : 'tw:my-2';\n\n return <Separator orientation={invertedOrientation} size={size} className={className} />;\n};\n","import type { ComponentProps } from 'react';\nimport * as RRadioGroup from '@radix-ui/react-radio-group';\nimport { cva } from 'class-variance-authority';\n\nimport { cn } from '../../utils';\n\nimport type { Orientation, Variant } from './context';\nimport { RadioGroupProvider } from './context';\nimport { RadioGroupItem } from './RadioGroupItem';\nimport { RadioGroupSeparator } from './RadioGroupSeparator';\n\nconst radioGroupVariants = cva(['tw:flex'], {\n variants: {\n orientation: {\n horizontal: ['tw:gap-2'],\n vertical: ['tw:flex-col', 'tw:gap-3'],\n },\n variant: {\n button: [],\n radio: [],\n 'radio-block': ['tw:w-full'],\n },\n },\n});\n\ntype Props<Value> = {\n variant?: Variant;\n orientation?: Orientation;\n onValueChange?: (value: Value) => void;\n value?: Value | null;\n defaultValue?: Value | null;\n} & Omit<\n ComponentProps<typeof RRadioGroup.Root>,\n 'asChild' | 'orientation' | 'onValueChange' | 'onChange' | 'value' | 'defaultValue'\n>;\n\nexport const RadioGroup = <Value extends string = string>({\n variant = 'radio',\n className,\n disabled = false,\n orientation = 'horizontal',\n onValueChange,\n children,\n value,\n defaultValue,\n ...props\n}: Props<Value>) => (\n <RRadioGroup.Root\n {...props}\n onValueChange={onValueChange}\n orientation={orientation}\n className={cn(radioGroupVariants({ orientation, variant, className }))}\n disabled={disabled}\n value={value ?? void 0}\n defaultValue={defaultValue ?? void 0}\n >\n <RadioGroupProvider value={{ variant, orientation }}>{children}</RadioGroupProvider>\n </RRadioGroup.Root>\n);\n\nRadioGroup.Item = RadioGroupItem;\nRadioGroup.Separator = RadioGroupSeparator;\n"],"mappings":"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"}
1
+ {"version":3,"file":"RadioGroup-DXPbSj8P.js","names":[],"sources":["../src/components/RadioGroup/context.ts","../src/components/RadioGroup/styles.ts","../src/components/RadioGroup/Radio.tsx","../src/components/RadioGroup/RadioGroupItemButton.tsx","../src/components/RadioGroup/RadioGroupItem.tsx","../src/components/RadioGroup/RadioGroupSeparator.tsx","../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\nexport type Variant = 'radio' | 'button' | 'radio-block';\nexport type Orientation = 'vertical' | 'horizontal';\n\nconst RadioGroupContext = createContext<{\n variant: Variant;\n orientation: Orientation;\n}>({\n variant: 'radio',\n orientation: 'horizontal',\n});\n\nexport const RadioGroupProvider = RadioGroupContext;\n\nexport const useRadioGroupContext = () => use(RadioGroupContext);\n","import { cva } from 'class-variance-authority';\n\nexport const radioVariants = cva(\n [\n // reset\n 'tw:bg-transparent',\n 'tw:p-0',\n 'tw:peer',\n 'tw:cursor-pointer',\n 'tw:whitespace-nowrap',\n 'tw:shrink-0',\n\n // position\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:disabled:cursor-not-allowed',\n\n 'tw:size-4',\n\n // border\n 'tw:rounded-full',\n 'tw:border',\n 'tw:border-solid',\n ],\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: [\n 'tw:disabled:opacity-40',\n\n 'tw:data-[state=checked]:border-primary',\n 'tw:data-[state=unchecked]:border-neutral-200',\n 'tw:data-[state=unchecked]:hover:border-primary',\n 'tw:data-[state=unchecked]:disabled:hover:border-neutral-200',\n\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/30',\n ],\n argo: [\n 'tw:disabled:opacity-50',\n\n 'tw:border-input',\n 'tw:transition-colors',\n\n 'tw:data-[state=checked]:bg-primary',\n 'tw:data-[state=checked]:border-primary',\n\n 'tw:data-[state=unchecked]:not-disabled:hover:bg-accent',\n 'tw:data-[state=checked]:not-disabled:hover:bg-primary',\n\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:border-primary',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n ],\n },\n },\n },\n);\n\nexport const radioIndicatorVariants = cva(['tw:size-2.5', 'tw:fill-current'], {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: ['tw:text-primary'],\n argo: ['tw:text-primary-foreground'],\n },\n },\n});\n\nexport const radioItemButtonVariants = cva(\n [\n // reset\n 'tw:bg-transparent',\n 'tw:p-0',\n 'tw:peer',\n 'tw:cursor-pointer',\n 'tw:whitespace-nowrap',\n\n // position\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n 'tw:disabled:cursor-not-allowed',\n\n // layouts\n 'tw:w-full',\n 'tw:px-2',\n 'tw:py-1.5',\n\n // fonts\n 'tw:uppercase',\n 'tw:font-semibold',\n 'tw:font-sans',\n 'tw:text-[11px]',\n 'tw:whitespace-nowrap',\n 'tw:tracking-widest',\n 'tw:leading-[18px]',\n\n // border\n 'tw:border',\n 'tw:border-solid',\n 'tw:rounded',\n ],\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: [\n 'tw:disabled:opacity-40',\n 'tw:text-secondary-600',\n 'tw:border-secondary-500',\n\n 'tw:data-[state=unchecked]:hover:bg-secondary-500',\n 'tw:data-[state=unchecked]:hover:text-white',\n\n 'tw:data-[state=unchecked]:disabled:hover:bg-white',\n 'tw:data-[state=unchecked]:disabled:hover:text-secondary-500',\n 'tw:data-[state=checked]:disabled:cursor-not-allowed',\n\n 'tw:data-[state=unchecked]:bg-white',\n 'tw:data-[state=checked]:bg-secondary-500',\n 'tw:data-[state=checked]:text-white',\n 'tw:data-[state=checked]:cursor-default',\n\n 'tw:focus-visible:outline',\n 'tw:focus-visible:outline-ring',\n 'tw:focus-visible:ring-4',\n 'tw:focus-visible:ring-ring/30',\n ],\n argo: [\n 'tw:disabled:opacity-50',\n 'tw:text-foreground',\n 'tw:border-input',\n 'tw:transition-colors',\n\n // muted filled control surface — gray, distinct from white containers; not the app-background token\n 'tw:data-[state=unchecked]:bg-muted',\n 'tw:data-[state=unchecked]:not-disabled:hover:bg-accent',\n 'tw:data-[state=unchecked]:not-disabled:hover:text-accent-foreground',\n\n 'tw:data-[state=checked]:bg-primary',\n 'tw:data-[state=checked]:border-primary',\n 'tw:data-[state=checked]:text-primary-foreground',\n 'tw:data-[state=checked]:not-disabled:cursor-default',\n\n 'tw:focus-visible:outline-hidden',\n 'tw:focus-visible:border-primary',\n 'tw:focus-visible:ring-2',\n 'tw:focus-visible:ring-ring/50',\n ],\n },\n },\n },\n);\n\nexport type RadioStyleVariant = 'default' | 'argo';\n","import type { ComponentProps } from 'react';\nimport { Indicator, Item } from '@radix-ui/react-radio-group';\n\nimport { Circle } from '../../icons';\nimport { cn } from '../../utils';\n\nimport type { RadioStyleVariant } from './styles';\nimport { radioIndicatorVariants, radioVariants } from './styles';\n\ntype Props = ComponentProps<typeof Item> & { styleVariant?: RadioStyleVariant };\n\nexport const Radio = ({ className, styleVariant = 'default', ...props }: Props) => (\n <Item {...props} className={cn(radioVariants({ variant: styleVariant }), className)}>\n <Indicator className={cn('tw:flex', 'tw:items-center', 'tw:justify-center')}>\n {/* Lucide Circle is stroke-only — force fill to match the stroke (currentColor)\n so the indicator reads as a solid dot. */}\n <Circle className={radioIndicatorVariants({ variant: styleVariant })} />\n </Indicator>\n </Item>\n);\n","import type { ComponentProps } from 'react';\nimport { Item } from '@radix-ui/react-radio-group';\n\nimport { cn } from '../../utils';\n\nimport type { RadioStyleVariant } from './styles';\nimport { radioItemButtonVariants } from './styles';\n\ntype Props = ComponentProps<typeof Item> & { styleVariant?: RadioStyleVariant };\n\nexport const RadioGroupItemButton = ({\n ref,\n className,\n children,\n styleVariant = 'default',\n ...props\n}: Props) => (\n <Item\n ref={ref}\n {...props}\n className={cn(radioItemButtonVariants({ variant: styleVariant }), className)}\n >\n {children}\n </Item>\n);\n","import { useId } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\nimport type { Item } from '@radix-ui/react-radio-group';\n\nimport { cn } from '../../utils';\nimport { FieldBox } from '../FieldBox';\nimport { useArgoDesign } from '../ThemeProvider/context';\nimport type { Props as TooltipProps } from '../Tooltip';\nimport { Tooltip } from '../Tooltip';\n\nimport { useRadioGroupContext } from './context';\nimport { Radio } from './Radio';\nimport { RadioGroupItemButton } from './RadioGroupItemButton';\n\ntype ItemProps = Omit<ComponentProps<typeof Item>, 'asChild' | 'value'>;\n\ntype Props<T extends string = string> = ItemProps & {\n value: T;\n tooltip?: ReactNode;\n tooltipVariant?: TooltipProps['variant'];\n tooltipPlacement?: TooltipProps['placement'];\n description?: ReactNode;\n};\n\nexport const RadioGroupItem = <T extends string = string>({\n children,\n className,\n tooltip,\n tooltipVariant,\n tooltipPlacement,\n description,\n ...props\n}: Props<T>) => {\n const { variant } = useRadioGroupContext();\n const styleVariant = useArgoDesign() ? 'argo' : 'default';\n const id = useId();\n\n const item = (() => {\n if (variant === 'button')\n return (\n <RadioGroupItemButton styleVariant={styleVariant} {...props} className={className}>\n {children}\n </RadioGroupItemButton>\n );\n\n return (\n <FieldBox\n variant={variant === 'radio-block' ? 'boxed' : 'default'}\n htmlFor={id}\n control={<Radio styleVariant={styleVariant} {...props} id={id} />}\n className={cn(variant === 'radio-block' && 'tw:flex-1', className)}\n >\n <FieldBox.Title>{children}</FieldBox.Title>\n {description && <FieldBox.Description>{description}</FieldBox.Description>}\n </FieldBox>\n );\n })();\n\n if (!tooltip) {\n return item;\n }\n\n return (\n <Tooltip tooltip={tooltip} variant={tooltipVariant} placement={tooltipPlacement} triggerAsChild>\n {item}\n </Tooltip>\n );\n};\n","import { Separator } from '../Separator';\n\nimport { useRadioGroupContext } from './context';\n\nexport const RadioGroupSeparator = () => {\n const { orientation } = useRadioGroupContext();\n const invertedOrientation = orientation === 'horizontal' ? 'vertical' : 'horizontal';\n const size = orientation === 'horizontal' ? '1/2' : 'full';\n const className = orientation === 'horizontal' ? 'tw:mx-2' : 'tw:my-2';\n\n return <Separator orientation={invertedOrientation} size={size} className={className} />;\n};\n","import type { ComponentProps } from 'react';\nimport * as RRadioGroup from '@radix-ui/react-radio-group';\nimport { cva } from 'class-variance-authority';\n\nimport { cn } from '../../utils';\n\nimport type { Orientation, Variant } from './context';\nimport { RadioGroupProvider } from './context';\nimport { RadioGroupItem } from './RadioGroupItem';\nimport { RadioGroupSeparator } from './RadioGroupSeparator';\n\nconst radioGroupVariants = cva(['tw:flex'], {\n variants: {\n orientation: {\n horizontal: ['tw:gap-2'],\n vertical: ['tw:flex-col', 'tw:gap-3'],\n },\n variant: {\n button: [],\n radio: [],\n 'radio-block': ['tw:w-full'],\n },\n },\n});\n\ntype Props<Value> = {\n variant?: Variant;\n orientation?: Orientation;\n onValueChange?: (value: Value) => void;\n value?: Value | null;\n defaultValue?: Value | null;\n} & Omit<\n ComponentProps<typeof RRadioGroup.Root>,\n 'asChild' | 'orientation' | 'onValueChange' | 'onChange' | 'value' | 'defaultValue'\n>;\n\nexport const RadioGroup = <Value extends string = string>({\n variant = 'radio',\n className,\n disabled = false,\n orientation = 'horizontal',\n onValueChange,\n children,\n value,\n defaultValue,\n ...props\n}: Props<Value>) => (\n <RRadioGroup.Root\n {...props}\n onValueChange={onValueChange}\n orientation={orientation}\n className={cn(radioGroupVariants({ orientation, variant, className }))}\n disabled={disabled}\n value={value ?? void 0}\n defaultValue={defaultValue ?? void 0}\n >\n <RadioGroupProvider value={{ variant, orientation }}>{children}</RadioGroupProvider>\n </RRadioGroup.Root>\n);\n\nRadioGroup.Item = RadioGroupItem;\nRadioGroup.Separator = RadioGroupSeparator;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { cn } from "./classNames-BzrkDnOD.js";
2
- import { createPrefixedString, debounce, noop } from "./utils-B5Z52hYs.js";
2
+ import { createPrefixedString, debounce, noop } from "./utils-DSvrhU8E.js";
3
3
  import { Search as Search$1, Sparkles, X } from "./icons-Cek151jC.js";
4
4
  import { useEffect, useMemo, useState } from "react";
5
5
  import { cva } from "class-variance-authority";
@@ -181,4 +181,4 @@ const SearchForm = ({ ref, onSubmit, name = "search-field", ...props }) => {
181
181
  //#endregion
182
182
  export { Search, SearchForm };
183
183
 
184
- //# sourceMappingURL=Search-4Bxtt8hS.js.map
184
+ //# sourceMappingURL=Search-5uQAiNIP.js.map