@cloudflare/kumo 1.5.1 → 1.7.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 (171) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/ai/component-registry.json +53 -10
  3. package/ai/component-registry.md +291 -90
  4. package/ai/schemas.ts +11 -2
  5. package/dist/.build-complete +1 -1
  6. package/dist/ai/schemas.d.ts +24 -5
  7. package/dist/ai/schemas.d.ts.map +1 -1
  8. package/dist/catalog.js +1 -1
  9. package/dist/{checkbox-CWANiedi.js → checkbox-Dt8iSNOg.js} +3 -3
  10. package/dist/{checkbox-CWANiedi.js.map → checkbox-Dt8iSNOg.js.map} +1 -1
  11. package/dist/clipboard-text-CeoyR28P.js +185 -0
  12. package/dist/clipboard-text-CeoyR28P.js.map +1 -0
  13. package/dist/{combobox-C9koouxM.js → combobox-BIC-YZ2L.js} +41 -41
  14. package/dist/combobox-BIC-YZ2L.js.map +1 -0
  15. package/dist/command-line/cli.js +88 -30
  16. package/dist/command-line/commands/add.js +88 -30
  17. package/dist/{command-palette-TGXgr6Vq.js → command-palette-D3MNR7w9.js} +31 -31
  18. package/dist/{command-palette-TGXgr6Vq.js.map → command-palette-D3MNR7w9.js.map} +1 -1
  19. package/dist/components/checkbox.js +1 -1
  20. package/dist/components/clipboard-text.js +1 -1
  21. package/dist/components/combobox.js +1 -1
  22. package/dist/components/command-palette.js +1 -1
  23. package/dist/components/date-picker.js +6 -0
  24. package/dist/components/date-picker.js.map +1 -0
  25. package/dist/components/dialog.js +1 -1
  26. package/dist/components/dropdown.js +1 -1
  27. package/dist/components/field.js +1 -1
  28. package/dist/components/flow.js +5640 -0
  29. package/dist/components/flow.js.map +1 -0
  30. package/dist/components/input.js +3 -3
  31. package/dist/components/label.js +1 -1
  32. package/dist/components/link.js +1 -1
  33. package/dist/components/menubar.js +1 -1
  34. package/dist/components/meter.js +1 -1
  35. package/dist/components/pagination.js +1 -1
  36. package/dist/components/popover.js +1 -1
  37. package/dist/components/radio.js +1 -1
  38. package/dist/components/select.js +1 -1
  39. package/dist/components/sensitive-input.js +1 -1
  40. package/dist/components/switch.js +1 -1
  41. package/dist/components/table.js +1 -1
  42. package/dist/components/tabs.js +1 -1
  43. package/dist/components/toast.js +2 -2
  44. package/dist/components/tooltip.js +1 -1
  45. package/dist/date-picker-M6uNX5Ca.js +2921 -0
  46. package/dist/date-picker-M6uNX5Ca.js.map +1 -0
  47. package/dist/date-range-picker-CbKEQ9pi.js.map +1 -1
  48. package/dist/{dialog-CpCeOqSZ.js → dialog-toS9krNF.js} +17 -17
  49. package/dist/dialog-toS9krNF.js.map +1 -0
  50. package/dist/{dropdown-DFeFcKfn.js → dropdown-BquiYKKC.js} +38 -38
  51. package/dist/dropdown-BquiYKKC.js.map +1 -0
  52. package/dist/{field-Dt-XuSaQ.js → field-DCq04TgZ.js} +3 -3
  53. package/dist/{field-Dt-XuSaQ.js.map → field-DCq04TgZ.js.map} +1 -1
  54. package/dist/index.js +53 -49
  55. package/dist/index.js.map +1 -1
  56. package/dist/{input-GZAWBXYX.js → input-CCR8NGG7.js} +3 -3
  57. package/dist/{input-GZAWBXYX.js.map → input-CCR8NGG7.js.map} +1 -1
  58. package/dist/{input-area-CS1-ceY4.js → input-area-DU2Yvp_t.js} +3 -3
  59. package/dist/{input-area-CS1-ceY4.js.map → input-area-DU2Yvp_t.js.map} +1 -1
  60. package/dist/{input-group-COo-wz5O.js → input-group-C365-qBq.js} +2 -2
  61. package/dist/{input-group-COo-wz5O.js.map → input-group-C365-qBq.js.map} +1 -1
  62. package/dist/{label-ChZ2Pp5p.js → label-zjtV7oXa.js} +2 -2
  63. package/dist/{label-ChZ2Pp5p.js.map → label-zjtV7oXa.js.map} +1 -1
  64. package/dist/{link-Mj2WM1AS.js → link-C8pUZ4Q-.js} +8 -8
  65. package/dist/{link-Mj2WM1AS.js.map → link-C8pUZ4Q-.js.map} +1 -1
  66. package/dist/{menubar-CbXWXQYR.js → menubar-D7WvAf6x.js} +6 -6
  67. package/dist/menubar-D7WvAf6x.js.map +1 -0
  68. package/dist/{meter-Bu5f3mAc.js → meter-jQGKS1z4.js} +4 -4
  69. package/dist/{meter-Bu5f3mAc.js.map → meter-jQGKS1z4.js.map} +1 -1
  70. package/dist/{pagination-Cf-yRO-n.js → pagination-BN80iKY6.js} +2 -2
  71. package/dist/{pagination-Cf-yRO-n.js.map → pagination-BN80iKY6.js.map} +1 -1
  72. package/dist/{popover-D7yeRosi.js → popover-syU1104E.js} +4 -4
  73. package/dist/{popover-D7yeRosi.js.map → popover-syU1104E.js.map} +1 -1
  74. package/dist/primitives/accordion.js +1 -1
  75. package/dist/primitives/alert-dialog.js +1 -1
  76. package/dist/primitives/autocomplete.js +1 -1
  77. package/dist/primitives/avatar.js +1 -1
  78. package/dist/primitives/button.js +1 -1
  79. package/dist/primitives/checkbox-group.js +1 -1
  80. package/dist/primitives/checkbox.js +1 -1
  81. package/dist/primitives/collapsible.js +1 -1
  82. package/dist/primitives/combobox.js +1 -1
  83. package/dist/primitives/context-menu.js +1 -1
  84. package/dist/primitives/dialog.js +1 -1
  85. package/dist/primitives/direction-provider.js +1 -1
  86. package/dist/primitives/field.js +1 -1
  87. package/dist/primitives/fieldset.js +1 -1
  88. package/dist/primitives/form.js +1 -1
  89. package/dist/primitives/input.js +1 -1
  90. package/dist/primitives/menu.js +1 -1
  91. package/dist/primitives/menubar.js +1 -1
  92. package/dist/primitives/meter.js +1 -1
  93. package/dist/primitives/navigation-menu.js +1 -1
  94. package/dist/primitives/number-field.js +1 -1
  95. package/dist/primitives/popover.js +1 -1
  96. package/dist/primitives/preview-card.js +1 -1
  97. package/dist/primitives/progress.js +1 -1
  98. package/dist/primitives/radio-group.js +1 -1
  99. package/dist/primitives/radio.js +1 -1
  100. package/dist/primitives/scroll-area.js +1 -1
  101. package/dist/primitives/select.js +1 -1
  102. package/dist/primitives/separator.js +1 -1
  103. package/dist/primitives/slider.js +1 -1
  104. package/dist/primitives/switch.js +1 -1
  105. package/dist/primitives/tabs.js +1 -1
  106. package/dist/primitives/toast.js +1 -1
  107. package/dist/primitives/toggle-group.js +1 -1
  108. package/dist/primitives/toggle.js +1 -1
  109. package/dist/primitives/toolbar.js +1 -1
  110. package/dist/primitives/tooltip.js +1 -1
  111. package/dist/primitives.js +1 -1
  112. package/dist/{radio-CKn09bGo.js → radio-CWMtSx65.js} +8 -8
  113. package/dist/{radio-CKn09bGo.js.map → radio-CWMtSx65.js.map} +1 -1
  114. package/dist/{schemas-H10xB2M_.js → schemas-DbIwo0ET.js} +251 -239
  115. package/dist/{schemas-H10xB2M_.js.map → schemas-DbIwo0ET.js.map} +1 -1
  116. package/dist/{select-DvpgiOau.js → select-G6JqBVkg.js} +37 -37
  117. package/dist/{select-DvpgiOau.js.map → select-G6JqBVkg.js.map} +1 -1
  118. package/dist/{sensitive-input-BuYT6U6C.js → sensitive-input-DNFpycoy.js} +4 -4
  119. package/dist/{sensitive-input-BuYT6U6C.js.map → sensitive-input-DNFpycoy.js.map} +1 -1
  120. package/dist/src/command-line/utils/transformer.d.ts +8 -4
  121. package/dist/src/command-line/utils/transformer.d.ts.map +1 -1
  122. package/dist/src/components/clipboard-text/clipboard-text.d.ts +23 -0
  123. package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -1
  124. package/dist/src/components/date-picker/date-picker.d.ts +65 -0
  125. package/dist/src/components/date-picker/date-picker.d.ts.map +1 -0
  126. package/dist/src/components/date-picker/index.d.ts +4 -0
  127. package/dist/src/components/date-picker/index.d.ts.map +1 -0
  128. package/dist/src/components/date-range-picker/date-range-picker.d.ts +7 -0
  129. package/dist/src/components/date-range-picker/date-range-picker.d.ts.map +1 -1
  130. package/dist/src/components/date-range-picker/index.d.ts +3 -0
  131. package/dist/src/components/date-range-picker/index.d.ts.map +1 -1
  132. package/dist/src/components/dropdown/dropdown.d.ts.map +1 -1
  133. package/dist/src/components/flow/connectors.d.ts +35 -0
  134. package/dist/src/components/flow/connectors.d.ts.map +1 -0
  135. package/dist/src/components/flow/diagram.d.ts +62 -0
  136. package/dist/src/components/flow/diagram.d.ts.map +1 -0
  137. package/dist/src/components/flow/index.d.ts +26 -0
  138. package/dist/src/components/flow/index.d.ts.map +1 -0
  139. package/dist/src/components/flow/node.d.ts +52 -0
  140. package/dist/src/components/flow/node.d.ts.map +1 -0
  141. package/dist/src/components/flow/parallel.d.ts +5 -0
  142. package/dist/src/components/flow/parallel.d.ts.map +1 -0
  143. package/dist/src/components/flow/use-children.d.ts +69 -0
  144. package/dist/src/components/flow/use-children.d.ts.map +1 -0
  145. package/dist/src/index.d.ts +5 -0
  146. package/dist/src/index.d.ts.map +1 -1
  147. package/dist/styles/kumo-binding.css +0 -4
  148. package/dist/styles/kumo-standalone.css +1 -1
  149. package/dist/styles/kumo.css +541 -0
  150. package/dist/styles/theme-kumo.css +1 -1
  151. package/dist/{switch-Tu34uFoa.js → switch-CmsZ4z-g.js} +9 -9
  152. package/dist/{switch-Tu34uFoa.js.map → switch-CmsZ4z-g.js.map} +1 -1
  153. package/dist/{table-DtUrZ2Rj.js → table-Dc0AGcLV.js} +2 -2
  154. package/dist/{table-DtUrZ2Rj.js.map → table-Dc0AGcLV.js.map} +1 -1
  155. package/dist/{tabs-B7THfqHW.js → tabs-BpD1iUiz.js} +2 -2
  156. package/dist/{tabs-B7THfqHW.js.map → tabs-BpD1iUiz.js.map} +1 -1
  157. package/dist/{toast-Du4y8qng.js → toast-BrR0pjLE.js} +8 -8
  158. package/dist/{toast-Du4y8qng.js.map → toast-BrR0pjLE.js.map} +1 -1
  159. package/dist/{tooltip-BxV1H6AV.js → tooltip-daVJYtXY.js} +2 -2
  160. package/dist/{tooltip-BxV1H6AV.js.map → tooltip-daVJYtXY.js.map} +1 -1
  161. package/dist/{vendor-base-ui-CQ6wEonS.js → vendor-base-ui-9w7J6BvW.js} +7246 -7245
  162. package/dist/{vendor-base-ui-CQ6wEonS.js.map → vendor-base-ui-9w7J6BvW.js.map} +1 -1
  163. package/package.json +12 -1
  164. package/scripts/component-registry/discovery.ts +1 -7
  165. package/scripts/theme-generator/config.ts +1 -1
  166. package/dist/clipboard-text-B32_yb2r.js +0 -108
  167. package/dist/clipboard-text-B32_yb2r.js.map +0 -1
  168. package/dist/combobox-C9koouxM.js.map +0 -1
  169. package/dist/dialog-CpCeOqSZ.js.map +0 -1
  170. package/dist/dropdown-DFeFcKfn.js.map +0 -1
  171. package/dist/menubar-CbXWXQYR.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/kumo",
3
- "version": "1.5.1",
3
+ "version": "1.7.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Kumo - Cloudflare's component library for building modern web applications",
@@ -44,6 +44,10 @@
44
44
  "types": "./dist/src/components/date-range-picker/index.d.ts",
45
45
  "import": "./dist/components/date-range-picker.js"
46
46
  },
47
+ "./components/date-picker": {
48
+ "types": "./dist/src/components/date-picker/index.d.ts",
49
+ "import": "./dist/components/date-picker.js"
50
+ },
47
51
  "./components/checkbox": {
48
52
  "types": "./dist/src/components/checkbox/index.d.ts",
49
53
  "import": "./dist/components/checkbox.js"
@@ -175,6 +179,10 @@
175
179
  "types": "./dist/src/components/cloudflare-logo/index.d.ts",
176
180
  "import": "./dist/components/cloudflare-logo.js"
177
181
  },
182
+ "./components/flow": {
183
+ "types": "./dist/src/components/flow/index.d.ts",
184
+ "import": "./dist/components/flow.js"
185
+ },
178
186
  "./utils": {
179
187
  "types": "./dist/src/utils/index.d.ts",
180
188
  "import": "./dist/utils.js"
@@ -384,6 +392,8 @@
384
392
  "dependencies": {
385
393
  "@base-ui/react": "^1.0.0",
386
394
  "clsx": "^2.1.1",
395
+ "motion": "^12.34.1",
396
+ "react-day-picker": "^9.13.2",
387
397
  "tailwind-merge": "^3.4.0"
388
398
  },
389
399
  "devDependencies": {
@@ -438,6 +448,7 @@
438
448
  "test:unit": "vitest run --project=unit",
439
449
  "test:coverage": "vitest run --coverage",
440
450
  "test:exports": "vitest run --project=unit tests/imports/export-path-validation.test.ts",
451
+ "test:watch": "vitest run --project=unit --watch",
441
452
  "typecheck": "tsc --noEmit",
442
453
  "validate:build": "vitest run --project=unit tests/imports/export-path-validation.test.ts",
443
454
  "validate:changeset": "tsx ../../ci/scripts/validate-kumo-changeset.ts"
@@ -395,14 +395,8 @@ export async function discoverFromDir(
395
395
  }
396
396
 
397
397
  // Extract variants from file (may be empty for components without variant props)
398
- // Layouts and pages may not have KUMO_*_VARIANTS exports
398
+ // Some components (like DatePicker) don't have KUMO_*_VARIANTS exports
399
399
  const variantsData = extractVariantsFromFile(mainFile);
400
- if (!variantsData && type === "component") {
401
- console.warn(
402
- `Warning: Could not find KUMO_*_VARIANTS exports in ${dirName}, skipping...`,
403
- );
404
- continue;
405
- }
406
400
 
407
401
  // Determine category
408
402
  const category = override.category || CATEGORY_MAP[dirName] || "Other";
@@ -62,7 +62,7 @@ export const THEME_CONFIG: ThemeConfig = {
62
62
  theme: {
63
63
  kumo: {
64
64
  light: "var(--color-neutral-400, oklch(70.8% 0 0))",
65
- dark: "var(--color-neutral-400, oklch(70.8% 0 0))",
65
+ dark: "var(--color-neutral-600, oklch(70.8% 0 0))",
66
66
  },
67
67
  },
68
68
  },
@@ -1,108 +0,0 @@
1
- "use client";
2
- import { jsxs as g, jsx as i } from "react/jsx-runtime";
3
- import { CheckIcon as y, CopyIcon as C } from "@phosphor-icons/react";
4
- import { forwardRef as T, useState as z, useCallback as v, useEffect as h } from "react";
5
- import { B as A } from "./button-Bh96oxRL.js";
6
- import { i as S } from "./input-GZAWBXYX.js";
7
- import { c as d } from "./cn-Bhsu1vx2.js";
8
- const p = {
9
- size: {
10
- sm: {
11
- classes: "text-xs",
12
- buttonSize: "sm",
13
- description: "Small clipboard text for compact UIs"
14
- },
15
- base: {
16
- classes: "text-sm",
17
- buttonSize: "base",
18
- description: "Default clipboard text size"
19
- },
20
- lg: {
21
- classes: "text-sm",
22
- buttonSize: "lg",
23
- description: "Large clipboard text for prominent display"
24
- }
25
- }
26
- }, m = {
27
- size: "lg"
28
- };
29
- function R({
30
- size: t = m.size
31
- } = {}) {
32
- return d(
33
- // Base styles
34
- "flex items-center overflow-hidden bg-kumo-base px-0 font-mono",
35
- // Apply size styles from KUMO_CLIPBOARD_TEXT_VARIANTS
36
- p.size[t].classes
37
- );
38
- }
39
- const I = T(
40
- ({
41
- text: t,
42
- className: u,
43
- size: n = m.size,
44
- onCopy: s
45
- }, f) => {
46
- const [o, r] = z(!1), c = p.size[n], b = v(async () => {
47
- try {
48
- if (typeof navigator < "u" && navigator.clipboard && typeof navigator.clipboard.writeText == "function") {
49
- await navigator.clipboard.writeText(t), r(!0), s?.();
50
- return;
51
- }
52
- } catch {
53
- }
54
- if (typeof document < "u") {
55
- const e = document.createElement("textarea");
56
- e.value = t, e.setAttribute("readonly", ""), e.style.position = "absolute", e.style.left = "-9999px", document.body.appendChild(e);
57
- const a = document.getSelection(), l = a?.rangeCount ? a.getRangeAt(0) : null;
58
- e.select();
59
- try {
60
- document.execCommand("copy"), r(!0), s?.();
61
- } catch (x) {
62
- console.warn("Clipboard copy failed", x);
63
- } finally {
64
- document.body.removeChild(e), l && (a?.removeAllRanges(), a?.addRange(l));
65
- }
66
- }
67
- }, [t, s]);
68
- return h(() => {
69
- if (o) {
70
- const e = setTimeout(() => {
71
- r(!1);
72
- }, 2e3);
73
- return () => clearTimeout(e);
74
- }
75
- }, [o]), /* @__PURE__ */ g(
76
- "div",
77
- {
78
- ref: f,
79
- className: d(
80
- S({ size: c.buttonSize }),
81
- R({ size: n }),
82
- u
83
- ),
84
- children: [
85
- /* @__PURE__ */ i("span", { className: "grow px-4", children: t }),
86
- /* @__PURE__ */ i(
87
- A,
88
- {
89
- size: c.buttonSize,
90
- variant: "ghost",
91
- className: "rounded-none border-l! border-kumo-line! px-3",
92
- onClick: b,
93
- "aria-label": o ? "Copied" : "Copy to clipboard",
94
- "aria-pressed": o,
95
- children: o ? /* @__PURE__ */ i(y, {}) : /* @__PURE__ */ i(C, {})
96
- }
97
- ),
98
- /* @__PURE__ */ i("span", { className: "sr-only", "aria-live": "polite", children: o ? "Copied to clipboard" : "" })
99
- ]
100
- }
101
- );
102
- }
103
- );
104
- I.displayName = "ClipboardText";
105
- export {
106
- I as C
107
- };
108
- //# sourceMappingURL=clipboard-text-B32_yb2r.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"clipboard-text-B32_yb2r.js","sources":["../src/components/clipboard-text/clipboard-text.tsx"],"sourcesContent":["import { CheckIcon, CopyIcon } from \"@phosphor-icons/react\";\nimport { forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { Button } from \"../button\";\nimport { inputVariants } from \"../input\";\nimport { cn } from \"../../utils/cn\";\n\n/** ClipboardText size variant definitions mapping sizes to their Tailwind classes. */\nexport const KUMO_CLIPBOARD_TEXT_VARIANTS = {\n size: {\n sm: {\n classes: \"text-xs\",\n buttonSize: \"sm\" as const,\n description: \"Small clipboard text for compact UIs\",\n },\n base: {\n classes: \"text-sm\",\n buttonSize: \"base\" as const,\n description: \"Default clipboard text size\",\n },\n lg: {\n classes: \"text-sm\",\n buttonSize: \"lg\" as const,\n description: \"Large clipboard text for prominent display\",\n },\n },\n} as const;\n\nexport const KUMO_CLIPBOARD_TEXT_DEFAULT_VARIANTS = {\n size: \"lg\",\n} as const;\n\n// Derived types from KUMO_CLIPBOARD_TEXT_VARIANTS\nexport type KumoClipboardTextSize =\n keyof typeof KUMO_CLIPBOARD_TEXT_VARIANTS.size;\n\nexport interface KumoClipboardTextVariantsProps {\n /**\n * Size of the clipboard text field.\n * - `\"sm\"` — Small clipboard text for compact UIs\n * - `\"base\"` — Default clipboard text size\n * - `\"lg\"` — Large clipboard text for prominent display\n * @default \"lg\"\n */\n size?: KumoClipboardTextSize;\n}\n\nexport function clipboardTextVariants({\n size = KUMO_CLIPBOARD_TEXT_DEFAULT_VARIANTS.size,\n}: KumoClipboardTextVariantsProps = {}) {\n return cn(\n // Base styles\n \"flex items-center overflow-hidden bg-kumo-base px-0 font-mono\",\n // Apply size styles from KUMO_CLIPBOARD_TEXT_VARIANTS\n KUMO_CLIPBOARD_TEXT_VARIANTS.size[size].classes,\n );\n}\n\n// Legacy type alias for backwards compatibility\nexport type ClipboardTextSize = KumoClipboardTextSize;\n\n/**\n * ClipboardText component props.\n *\n * @example\n * ```tsx\n * <ClipboardText text=\"sk_live_abc123\" />\n * <ClipboardText text=\"npm install @cloudflare/kumo\" size=\"sm\" />\n * ```\n */\nexport interface ClipboardTextProps extends KumoClipboardTextVariantsProps {\n /** The text to display and copy to clipboard. */\n text: string;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Callback fired after text is copied to clipboard. */\n onCopy?: () => void;\n}\n\n/**\n * Read-only text field with a one-click copy-to-clipboard button.\n *\n * @example\n * ```tsx\n * <ClipboardText text=\"0c239dd2\" />\n * ```\n */\nexport const ClipboardText = forwardRef<HTMLDivElement, ClipboardTextProps>(\n (\n {\n text,\n className,\n size = KUMO_CLIPBOARD_TEXT_DEFAULT_VARIANTS.size,\n onCopy,\n },\n ref,\n ) => {\n const [copied, setCopied] = useState(false);\n const sizeConfig = KUMO_CLIPBOARD_TEXT_VARIANTS.size[size];\n\n const copyToClipboard = useCallback(async () => {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.clipboard &&\n typeof navigator.clipboard.writeText === \"function\"\n ) {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n onCopy?.();\n return;\n }\n } catch {\n // Fall through to manual fallback\n }\n\n if (typeof document !== \"undefined\") {\n const textarea = document.createElement(\"textarea\");\n textarea.value = text;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"absolute\";\n textarea.style.left = \"-9999px\";\n document.body.appendChild(textarea);\n const selection = document.getSelection();\n const previousRange = selection?.rangeCount\n ? selection.getRangeAt(0)\n : null;\n textarea.select();\n try {\n document.execCommand(\"copy\");\n setCopied(true);\n onCopy?.();\n } catch (error) {\n console.warn(\"Clipboard copy failed\", error);\n } finally {\n document.body.removeChild(textarea);\n if (previousRange) {\n selection?.removeAllRanges();\n selection?.addRange(previousRange);\n }\n }\n }\n }, [text, onCopy]);\n\n useEffect(() => {\n if (copied) {\n const timeoutId = setTimeout(() => {\n setCopied(false);\n }, 2000);\n\n return () => clearTimeout(timeoutId);\n }\n }, [copied]);\n\n return (\n <div\n ref={ref}\n className={cn(\n inputVariants({ size: sizeConfig.buttonSize }),\n clipboardTextVariants({ size }),\n className,\n )}\n >\n <span className=\"grow px-4\">{text}</span>\n <Button\n size={sizeConfig.buttonSize}\n variant=\"ghost\"\n className=\"rounded-none border-l! border-kumo-line! px-3\"\n onClick={copyToClipboard}\n aria-label={copied ? \"Copied\" : \"Copy to clipboard\"}\n aria-pressed={copied}\n >\n {copied ? <CheckIcon /> : <CopyIcon />}\n </Button>\n <span className=\"sr-only\" aria-live=\"polite\">\n {copied ? \"Copied to clipboard\" : \"\"}\n </span>\n </div>\n );\n },\n);\n\nClipboardText.displayName = \"ClipboardText\";\n"],"names":["KUMO_CLIPBOARD_TEXT_VARIANTS","KUMO_CLIPBOARD_TEXT_DEFAULT_VARIANTS","clipboardTextVariants","size","cn","ClipboardText","forwardRef","text","className","onCopy","ref","copied","setCopied","useState","sizeConfig","copyToClipboard","useCallback","textarea","selection","previousRange","error","useEffect","timeoutId","jsxs","inputVariants","jsx","Button","CheckIcon","CopyIcon"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"combobox-C9koouxM.js","sources":["../src/components/combobox/combobox.tsx"],"sourcesContent":["import { Combobox as ComboboxBase } from \"@base-ui/react/combobox\";\nimport { CaretDownIcon, CheckIcon, XIcon } from \"@phosphor-icons/react\";\nimport { Fragment, type PropsWithChildren, type ReactNode } from \"react\";\nimport { inputVariants } from \"../input/input\";\nimport { cn } from \"../../utils/cn\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\n\n/** Combobox input position variant definitions. */\nexport const KUMO_COMBOBOX_VARIANTS = {\n inputSide: {\n right: {\n classes: \"\",\n description: \"Input positioned inline to the right of chips\",\n },\n top: {\n classes: \"\",\n description: \"Input positioned above chips\",\n },\n },\n} as const;\n\nexport const KUMO_COMBOBOX_DEFAULT_VARIANTS = {\n inputSide: \"right\",\n} as const;\n\n// Derived types from KUMO_COMBOBOX_VARIANTS\nexport type KumoComboboxInputSide =\n keyof typeof KUMO_COMBOBOX_VARIANTS.inputSide;\n\nexport interface KumoComboboxVariantsProps {\n /**\n * Position of the text input relative to chips in multi-select mode.\n * - `\"right\"` — Input inline to the right of chips\n * - `\"top\"` — Input above chips\n * @default \"right\"\n */\n inputSide?: KumoComboboxInputSide;\n}\n\nexport function comboboxVariants({\n inputSide = KUMO_COMBOBOX_DEFAULT_VARIANTS.inputSide,\n}: KumoComboboxVariantsProps = {}) {\n return cn(KUMO_COMBOBOX_VARIANTS.inputSide[inputSide].classes);\n}\n\n// Legacy type alias for backwards compatibility\nexport type ComboboxInputSide = KumoComboboxInputSide;\n\nexport type ComboboxRootProps<\n Value = unknown,\n Multiple extends boolean | undefined = false,\n> = ComboboxBase.Root.Props<Value, Multiple>;\n\n/**\n * Combobox component props (simplified for documentation; the actual Root is generic).\n *\n * Combobox provides an autocomplete/typeahead input with a filterable dropdown.\n * Supports single-select, multi-select with chips, grouped items, and Field wrapper integration.\n *\n * @example\n * ```tsx\n * // Single-select with search input\n * <Combobox value={value} onValueChange={setValue} items={options}>\n * <Combobox.TriggerInput placeholder=\"Search…\" />\n * <Combobox.Content>\n * <Combobox.List>\n * {(item) => <Combobox.Item value={item}>{item.label}</Combobox.Item>}\n * </Combobox.List>\n * <Combobox.Empty>No results</Combobox.Empty>\n * </Combobox.Content>\n * </Combobox>\n *\n * // Multi-select with chips\n * <Combobox multiple items={options} label=\"Tags\">\n * <Combobox.TriggerMultipleWithInput\n * placeholder=\"Add tag…\"\n * renderItem={(item) => <Combobox.Chip value={item}>{item.label}</Combobox.Chip>}\n * />\n * <Combobox.Content>\n * <Combobox.List>\n * {(item) => <Combobox.Item value={item}>{item.label}</Combobox.Item>}\n * </Combobox.List>\n * </Combobox.Content>\n * </Combobox>\n * ```\n */\nexport interface ComboboxProps extends KumoComboboxVariantsProps {\n /** Array of items to display in the dropdown */\n items: unknown[];\n /** Currently selected value(s) */\n value?: unknown;\n /** Callback when selection changes */\n onValueChange?: (value: unknown) => void;\n /** Enable multi-select mode */\n multiple?: boolean;\n /** Combobox content (trigger, content, items) */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n /** Label content for the combobox (enables Field wrapper) - can be a string or any React node */\n label?: ReactNode;\n /** Whether the combobox is required */\n required?: boolean;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /** Helper text displayed below the combobox */\n description?: ReactNode;\n /** Error message or validation error object */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n}\n\nfunction Root<Value, Multiple extends boolean | undefined = false>({\n label,\n required,\n labelTooltip,\n description,\n error,\n children,\n ...props\n}: ComboboxBase.Root.Props<Value, Multiple> & {\n label?: ReactNode;\n required?: boolean;\n labelTooltip?: ReactNode;\n description?: ReactNode;\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n}) {\n const comboboxControl = (\n <ComboboxBase.Root {...props}>{children}</ComboboxBase.Root>\n );\n\n // Render with Field wrapper if label, description, or error are provided\n if (label) {\n return (\n <Field\n label={label}\n required={required}\n labelTooltip={labelTooltip}\n description={description}\n error={\n error\n ? typeof error === \"string\"\n ? { message: error, match: true }\n : error\n : undefined\n }\n >\n {comboboxControl}\n </Field>\n );\n }\n\n // Render bare combobox without Field wrapper\n return comboboxControl;\n}\n\nfunction Content({\n children,\n className,\n align = \"start\",\n sideOffset = 4,\n alignOffset,\n side,\n}: PropsWithChildren<{\n className?: string;\n align?: ComboboxBase.Positioner.Props[\"align\"];\n alignOffset?: ComboboxBase.Positioner.Props[\"alignOffset\"];\n side?: ComboboxBase.Positioner.Props[\"side\"];\n sideOffset?: ComboboxBase.Positioner.Props[\"sideOffset\"];\n}>) {\n return (\n <ComboboxBase.Portal>\n <ComboboxBase.Positioner\n className=\"z-50 outline-none\"\n align={align}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n side={side}\n >\n <ComboboxBase.Popup\n className={cn(\n \"max-h-[min(var(--available-height),24rem)] max-w-(--available-width) min-w-(--anchor-width) scroll-pt-2 scroll-pb-2 overflow-y-auto overscroll-contain p-1.5\",\n \"z-50 overflow-hidden bg-kumo-control text-kumo-default\", // background\n \"rounded-lg shadow-lg ring ring-kumo-line\", // border part\n className,\n )}\n >\n {children}\n </ComboboxBase.Popup>\n </ComboboxBase.Positioner>\n </ComboboxBase.Portal>\n );\n}\n\nfunction TriggerValue({\n className,\n ...props\n}: ComboboxBase.Value.Props & { className?: string }) {\n return (\n <ComboboxBase.Trigger\n className={cn(\n inputVariants(),\n \"relative flex items-center pr-8\",\n className,\n )}\n >\n <ComboboxBase.Value>{props.children}</ComboboxBase.Value>\n <ComboboxBase.Icon className=\"absolute top-1/2 right-2 -translate-y-1/2\">\n <CaretDownIcon className=\"fill-kumo-ring\" />\n </ComboboxBase.Icon>\n </ComboboxBase.Trigger>\n );\n}\n\nfunction TriggerInput(props: ComboboxBase.Input.Props) {\n return (\n <div\n className={cn(\"relative inline-block w-full max-w-xs\", props.className)}\n >\n <ComboboxBase.Input\n {...props}\n className={cn(inputVariants(), \"w-full pr-12\")}\n />\n\n <ComboboxBase.Clear className=\"absolute top-1/2 right-8 flex -translate-y-1/2 cursor-pointer bg-transparent p-0\">\n <XIcon />\n </ComboboxBase.Clear>\n\n <ComboboxBase.Trigger className=\"p-0\">\n <ComboboxBase.Icon className=\"absolute top-1/2 right-2 flex -translate-y-1/2 cursor-pointer\">\n <CaretDownIcon className=\"fill-kumo-ring\" />\n </ComboboxBase.Icon>\n </ComboboxBase.Trigger>\n </div>\n );\n}\n\nfunction Item({ children, ...props }: ComboboxBase.Item.Props) {\n return (\n <ComboboxBase.Item\n {...props}\n className=\"group grid cursor-pointer grid-cols-[1fr_16px] gap-2 rounded px-2 py-1.5 text-base data-highlighted:bg-kumo-overlay\"\n >\n <div className=\"col-start-1\">{children}</div>\n <ComboboxBase.ItemIndicator className=\"col-start-2 flex items-center\">\n <CheckIcon />\n </ComboboxBase.ItemIndicator>\n </ComboboxBase.Item>\n );\n}\n\nfunction Empty(props: ComboboxBase.Empty.Props) {\n return (\n <ComboboxBase.Empty\n {...props}\n className={cn(\n \"px-4 py-2 text-[0.925rem] leading-4 text-kumo-subtle empty:m-0 empty:p-0\",\n )}\n children={props.children ?? \"No labels found.\"}\n />\n );\n}\n\nfunction Input(props: ComboboxBase.Input.Props) {\n return (\n <ComboboxBase.Input\n {...props}\n className={cn(inputVariants(), \"w-full first:mb-2\", props.className)}\n />\n );\n}\n\nfunction GroupLabel(props: ComboboxBase.GroupLabel.Props) {\n return (\n <ComboboxBase.GroupLabel\n {...props}\n className=\"ml-[16px] px-4 py-1.5 text-sm font-medium\"\n />\n );\n}\n\nfunction Group(props: ComboboxBase.Group.Props) {\n return <ComboboxBase.Group {...props} className=\"mt-2 first:mt-0\" />;\n}\n\nfunction Chip(props: ComboboxBase.Chip.Props) {\n return (\n <ComboboxBase.Chip\n {...props}\n className=\"flex items-center gap-1 rounded-md bg-kumo-overlay px-2 py-1\"\n >\n {props.children}\n <ComboboxBase.ChipRemove className=\"cursor-pointer rounded-md p-1 hover:bg-kumo-fill-hover\">\n <XIcon size={12} weight=\"bold\" />\n </ComboboxBase.ChipRemove>\n </ComboboxBase.Chip>\n );\n}\n\nfunction TriggerMultipleWithInput<ValueType>({\n placeholder,\n renderItem,\n className,\n inputSide = \"right\",\n value: controlledValue,\n}: {\n placeholder?: string;\n renderItem: (value: ValueType) => React.ReactNode;\n className?: string;\n inputSide?: \"right\" | \"top\";\n /** Optional controlled value for rendering chips (use when pre-selecting values) */\n value?: ValueType[];\n}) {\n // Determine which value to use for rendering chips\n const chipsToRender = controlledValue;\n\n return (\n <ComboboxBase.Chips\n className={cn(\n inputVariants(),\n cn(\"flex flex-col\", \"gap-1 p-1\", \"min-h-9\", \"h-auto\"),\n className,\n )}\n >\n {inputSide === \"top\" && (\n <ComboboxBase.Input\n placeholder={placeholder}\n className=\"w-full px-2 py-1 outline-none\"\n />\n )}\n {/* Chips container */}\n <div className=\"flex flex-wrap gap-1\">\n {/* Render chips from controlled value if provided */}\n {chipsToRender !== undefined &&\n chipsToRender.length > 0 &&\n chipsToRender.map((item) => renderItem(item))}\n {/* Also render from BaseUI's internal value for user selections */}\n <ComboboxBase.Value>\n {(internalValue: ValueType[]) => {\n // Skip rendering if using controlled value (to avoid duplicates)\n if (chipsToRender !== undefined) return null;\n return (\n <Fragment>\n {internalValue.map((item) => renderItem(item))}\n </Fragment>\n );\n }}\n </ComboboxBase.Value>\n {inputSide === \"right\" && (\n <ComboboxBase.Input\n placeholder={placeholder}\n className=\"min-w-[100px] flex-1 px-2 py-1 outline-none\"\n />\n )}\n </div>\n </ComboboxBase.Chips>\n );\n}\n\nRoot.displayName = \"Combobox.Root\";\nContent.displayName = \"Combobox.Content\";\nTriggerValue.displayName = \"Combobox.TriggerValue\";\nTriggerInput.displayName = \"Combobox.TriggerInput\";\nItem.displayName = \"Combobox.Item\";\nChip.displayName = \"Combobox.Chip\";\nTriggerMultipleWithInput.displayName = \"Combobox.TriggerMultipleWithInput\";\n\n/**\n * Combobox — autocomplete input with filterable dropdown list.\n *\n * Compound component: `Combobox` (Root), `.TriggerInput`, `.TriggerValue`,\n * `.TriggerMultipleWithInput`, `.Content`, `.Item`, `.Chip`, `.Input`,\n * `.Empty`, `.GroupLabel`, `.Group`, `.List`, `.Collection`.\n *\n * @example\n * ```tsx\n * <Combobox items={fruits} label=\"Fruit\">\n * <Combobox.TriggerInput placeholder=\"Pick a fruit…\" />\n * <Combobox.Content>\n * <Combobox.List>\n * {(item) => <Combobox.Item value={item}>{item}</Combobox.Item>}\n * </Combobox.List>\n * </Combobox.Content>\n * </Combobox>\n * ```\n *\n * @see https://base-ui.com/react/components/combobox\n */\nexport const Combobox = Object.assign(Root, {\n // Helper components\n Content,\n TriggerValue,\n TriggerInput,\n TriggerMultipleWithInput,\n\n // Slightly modified BaseUI\n Chip,\n Item,\n\n // Styled BaseUI\n Input,\n Empty,\n GroupLabel,\n Group,\n\n // BaseUI\n List: ComboboxBase.List,\n Collection: ComboboxBase.Collection,\n});\n"],"names":["Root","label","required","labelTooltip","description","error","children","props","comboboxControl","jsx","ComboboxBase.Root","Field","Content","className","align","sideOffset","alignOffset","side","ComboboxBase.Portal","ComboboxBase.Positioner","ComboboxBase.Popup","cn","TriggerValue","jsxs","ComboboxBase.Trigger","inputVariants","ComboboxBase.Value","ComboboxBase.Icon","CaretDownIcon","TriggerInput","ComboboxBase.Input","ComboboxBase.Clear","XIcon","Item","ComboboxBase.Item","ComboboxBase.ItemIndicator","CheckIcon","Empty","ComboboxBase.Empty","Input","GroupLabel","ComboboxBase.GroupLabel","Group","ComboboxBase.Group","Chip","ComboboxBase.Chip","ComboboxBase.ChipRemove","TriggerMultipleWithInput","placeholder","renderItem","inputSide","controlledValue","chipsToRender","ComboboxBase.Chips","item","internalValue","Fragment","Combobox","ComboboxBase.List","ComboboxBase.Collection"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dialog-CpCeOqSZ.js","sources":["../src/components/dialog/dialog.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, CSSProperties, ReactNode } from \"react\";\nimport { Dialog as DialogBase } from \"@base-ui/react/dialog\";\nimport { Surface } from \"../surface\";\nimport { cn } from \"../../utils/cn\";\n\n/** Dialog size variant definitions mapping sizes to their minimum widths. */\nexport const KUMO_DIALOG_VARIANTS = {\n size: {\n base: {\n classes: \"sm:min-w-96\",\n description: \"Default dialog width\",\n },\n sm: {\n classes: \"min-w-72\",\n description: \"Small dialog for simple confirmations\",\n },\n lg: {\n classes: \"min-w-[32rem]\",\n description: \"Large dialog for complex content\",\n },\n xl: {\n classes: \"min-w-[48rem]\",\n description: \"Extra large dialog for detailed views\",\n },\n },\n} as const;\n\nexport const KUMO_DIALOG_DEFAULT_VARIANTS = {\n size: \"base\",\n} as const;\n\nexport const KUMO_DIALOG_STYLING = {\n dimensions: {\n sm: {\n width: 350,\n titleSize: 20,\n descSize: 16,\n padding: 16,\n gap: 8,\n buttonSize: \"sm\",\n },\n base: {\n width: 384,\n titleSize: 20,\n descSize: 16,\n padding: 24,\n gap: 16,\n buttonSize: \"base\",\n },\n lg: {\n width: 512,\n titleSize: 20,\n descSize: 16,\n padding: 24,\n gap: 16,\n buttonSize: \"base\",\n },\n xl: {\n width: 768,\n titleSize: 20,\n descSize: 16,\n padding: 24,\n gap: 16,\n buttonSize: \"base\",\n },\n },\n baseTokens: {\n background: \"color-surface\",\n text: \"text-color-surface\",\n borderRadius: 12,\n shadow: \"shadow-m\",\n },\n backdrop: {\n background: \"color-surface-secondary\",\n opacity: 0.8,\n },\n header: {\n title: { fontWeight: 600, color: \"text-color-surface\" },\n closeIcon: { name: \"ph-x\", size: 20, color: \"text-color-muted\" },\n },\n description: {\n fontWeight: 400,\n color: \"text-color-muted\",\n },\n buttons: {\n primary: { background: \"color-primary\", text: \"white\" },\n secondary: { ring: \"color-border\", text: \"text-color-surface\" },\n },\n} as const;\n\n// Derived types from KUMO_DIALOG_VARIANTS\nexport type KumoDialogSize = keyof typeof KUMO_DIALOG_VARIANTS.size;\n\nexport interface KumoDialogVariantsProps {\n /**\n * Dialog width.\n * - `\"sm\"` — Small (min 288px) for simple confirmations\n * - `\"base\"` — Default (min 384px)\n * - `\"lg\"` — Large (min 512px) for complex content\n * - `\"xl\"` — Extra large (min 768px) for detailed views\n * @default \"base\"\n */\n size?: KumoDialogSize;\n}\n\nexport function dialogVariants({\n size = KUMO_DIALOG_DEFAULT_VARIANTS.size,\n}: KumoDialogVariantsProps = {}) {\n return cn(\n // Base styles\n \"shadow-m z-modal fixed top-1/2 left-1/2 w-full sm:w-auto max-w-[calc(100vw-2rem)] sm:max-w-[calc(100vw-3rem)] -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-xl bg-kumo-base text-kumo-default duration-150 data-ending-style:scale-90 data-ending-style:opacity-0 data-starting-style:scale-90 data-starting-style:opacity-0\",\n // Apply size from KUMO_DIALOG_VARIANTS\n KUMO_DIALOG_VARIANTS.size[size].classes,\n );\n}\n\n/**\n * Dialog component props — the modal content panel.\n *\n * @example\n * ```tsx\n * <Dialog.Root>\n * <Dialog.Trigger render={(p) => <Button {...p}>Open</Button>} />\n * <Dialog className=\"p-8\">\n * <Dialog.Title>Confirm Action</Dialog.Title>\n * <Dialog.Description>Are you sure?</Dialog.Description>\n * <Dialog.Close render={(p) => <Button {...p}>Cancel</Button>} />\n * </Dialog>\n * </Dialog.Root>\n * ```\n */\nexport type DialogProps = KumoDialogVariantsProps & {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Dialog content (typically Title, Description, Close, and action buttons). */\n children: ReactNode;\n /** Inline styles. */\n style?: CSSProperties;\n};\n\n/**\n * Modal dialog overlay with backdrop. Compound component with `Dialog.Root`,\n * `Dialog.Trigger`, `Dialog.Title`, `Dialog.Description`, and `Dialog.Close`.\n *\n * @example\n * ```tsx\n * <Dialog.Root>\n * <Dialog.Trigger render={(p) => <Button {...p}>Delete</Button>} />\n * <Dialog className=\"p-8\">\n * <Dialog.Title>Delete Item</Dialog.Title>\n * <Dialog.Description>This action cannot be undone.</Dialog.Description>\n * <Dialog.Close render={(p) => <Button variant=\"destructive\" {...p}>Delete</Button>} />\n * </Dialog>\n * </Dialog.Root>\n * ```\n */\nfunction DialogContent({\n className,\n children,\n style,\n size = KUMO_DIALOG_DEFAULT_VARIANTS.size,\n}: DialogProps) {\n return (\n <DialogBase.Portal>\n <DialogBase.Backdrop className=\"z-modal fixed inset-0 bg-kumo-overlay opacity-80 transition-all duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0\" />\n <Surface\n as={DialogBase.Popup}\n className={cn(dialogVariants({ size }), className)}\n style={\n {\n transitionProperty: \"scale, opacity\",\n transitionTimingFunction:\n \"var(--default-transition-timing-function)\",\n \"--tw-shadow\":\n \"0 20px 25px -5px rgb(0 0 0 / 0.03), 0 8px 10px -6px rgb(0 0 0 / 0.03)\",\n ...style,\n } as CSSProperties\n }\n >\n {children}\n </Surface>\n </DialogBase.Portal>\n );\n}\n\n// ============================================================================\n// Dialog Root\n// ============================================================================\n\ntype BaseDialogRootProps = ComponentPropsWithoutRef<typeof DialogBase.Root>;\n\nexport type DialogRootProps = BaseDialogRootProps;\n\nfunction DialogRoot({ children, ...props }: DialogRootProps) {\n return <DialogBase.Root {...props}>{children}</DialogBase.Root>;\n}\n\nDialogRoot.displayName = \"Dialog.Root\";\n\n// ============================================================================\n// Dialog Trigger\n// ============================================================================\n\ntype BaseDialogTriggerProps = ComponentPropsWithoutRef<\n typeof DialogBase.Trigger\n>;\n\nexport type DialogTriggerProps = BaseDialogTriggerProps;\n\nfunction DialogTrigger({ children, ...props }: DialogTriggerProps) {\n return <DialogBase.Trigger {...props}>{children}</DialogBase.Trigger>;\n}\n\nDialogTrigger.displayName = \"Dialog.Trigger\";\n\n// ============================================================================\n// Dialog Title\n// ============================================================================\n\ntype BaseDialogTitleProps = ComponentPropsWithoutRef<typeof DialogBase.Title>;\n\nexport type DialogTitleProps = BaseDialogTitleProps;\n\nfunction DialogTitle({ className, ...props }: DialogTitleProps) {\n return <DialogBase.Title className={className} {...props} />;\n}\n\nDialogTitle.displayName = \"Dialog.Title\";\n\n// ============================================================================\n// Dialog Description\n// ============================================================================\n\ntype BaseDialogDescriptionProps = ComponentPropsWithoutRef<\n typeof DialogBase.Description\n>;\n\nexport type DialogDescriptionProps = BaseDialogDescriptionProps;\n\nfunction DialogDescription({ className, ...props }: DialogDescriptionProps) {\n return <DialogBase.Description className={className} {...props} />;\n}\n\nDialogDescription.displayName = \"Dialog.Description\";\n\n// ============================================================================\n// Dialog Close\n// ============================================================================\n\ntype BaseDialogCloseProps = ComponentPropsWithoutRef<typeof DialogBase.Close>;\n\nexport type DialogCloseProps = BaseDialogCloseProps;\n\nfunction DialogClose({ children, ...props }: DialogCloseProps) {\n return <DialogBase.Close {...props}>{children}</DialogBase.Close>;\n}\n\nDialogClose.displayName = \"Dialog.Close\";\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\nconst Dialog = Object.assign(DialogContent, {\n Root: DialogRoot,\n Trigger: DialogTrigger,\n Title: DialogTitle,\n Description: DialogDescription,\n Close: DialogClose,\n});\n\nexport {\n Dialog,\n DialogRoot,\n DialogTrigger,\n DialogTitle,\n DialogDescription,\n DialogClose,\n};\n"],"names":["KUMO_DIALOG_VARIANTS","KUMO_DIALOG_DEFAULT_VARIANTS","dialogVariants","size","cn","DialogContent","className","children","style","jsxs","DialogBase.Portal","jsx","DialogBase.Backdrop","Surface","DialogBase.Popup","DialogRoot","props","DialogBase.Root","DialogTrigger","DialogBase.Trigger","DialogTitle","DialogBase.Title","DialogDescription","DialogBase.Description","DialogClose","DialogBase.Close","Dialog"],"mappings":";;;;;AAMO,MAAMA,IAAuB;AAAA,EAClC,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,IAEf,IAAI;AAAA,MACF,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,IAEf,IAAI;AAAA,MACF,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,IAEf,IAAI;AAAA,MACF,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,EACf;AAEJ,GAEaC,IAA+B;AAAA,EAC1C,MAAM;AACR;AA4EO,SAASC,EAAe;AAAA,EAC7B,MAAAC,IAAOF,EAA6B;AACtC,IAA6B,IAAI;AAC/B,SAAOG;AAAA;AAAA,IAEL;AAAA;AAAA,IAEAJ,EAAqB,KAAKG,CAAI,EAAE;AAAA,EAAA;AAEpC;AA0CA,SAASE,EAAc;AAAA,EACrB,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAL,IAAOF,EAA6B;AACtC,GAAgB;AACd,SACE,gBAAAQ,EAACC,GAAA,EACC,UAAA;AAAA,IAAA,gBAAAC,EAACC,GAAA,EAAoB,WAAU,yIAAA,CAAyI;AAAA,IACxK,gBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,IAAIC;AAAAA,QACJ,WAAWV,EAAGF,EAAe,EAAE,MAAAC,EAAA,CAAM,GAAGG,CAAS;AAAA,QACjD,OACE;AAAA,UACE,oBAAoB;AAAA,UACpB,0BACE;AAAA,UACF,eACE;AAAA,UACF,GAAGE;AAAA,QAAA;AAAA,QAIN,UAAAD;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GACF;AAEJ;AAUA,SAASQ,EAAW,EAAE,UAAAR,GAAU,GAAGS,KAA0B;AAC3D,2BAAQC,GAAA,EAAiB,GAAGD,GAAQ,UAAAT,EAAA,CAAS;AAC/C;AAEAQ,EAAW,cAAc;AAYzB,SAASG,EAAc,EAAE,UAAAX,GAAU,GAAGS,KAA6B;AACjE,2BAAQG,GAAA,EAAoB,GAAGH,GAAQ,UAAAT,EAAA,CAAS;AAClD;AAEAW,EAAc,cAAc;AAU5B,SAASE,EAAY,EAAE,WAAAd,GAAW,GAAGU,KAA2B;AAC9D,2BAAQK,GAAA,EAAiB,WAAAf,GAAuB,GAAGU,EAAA,CAAO;AAC5D;AAEAI,EAAY,cAAc;AAY1B,SAASE,EAAkB,EAAE,WAAAhB,GAAW,GAAGU,KAAiC;AAC1E,2BAAQO,GAAA,EAAuB,WAAAjB,GAAuB,GAAGU,EAAA,CAAO;AAClE;AAEAM,EAAkB,cAAc;AAUhC,SAASE,EAAY,EAAE,UAAAjB,GAAU,GAAGS,KAA2B;AAC7D,2BAAQS,GAAA,EAAkB,GAAGT,GAAQ,UAAAT,EAAA,CAAS;AAChD;AAEAiB,EAAY,cAAc;AAM1B,MAAME,IAAS,OAAO,OAAOrB,GAAe;AAAA,EAC1C,MAAMU;AAAA,EACN,SAASG;AAAA,EACT,OAAOE;AAAA,EACP,aAAaE;AAAA,EACb,OAAOE;AACT,CAAC;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropdown-DFeFcKfn.js","sources":["../src/components/dropdown/dropdown.tsx"],"sourcesContent":["import { Menu as DropdownMenuPrimitive } from \"@base-ui/react/menu\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\nimport { Checkbox } from \"../checkbox\";\nimport {\n CaretRightIcon as CaretRight,\n CheckIcon as Check,\n type Icon,\n} from \"@phosphor-icons/react\";\n\n/** Dropdown item variant definitions (default and danger styles). */\nexport const KUMO_DROPDOWN_VARIANTS = {\n variant: {\n default: {\n classes: \"\",\n description: \"Default dropdown item appearance\",\n },\n danger: {\n classes:\n \"text-kumo-danger data-highlighted:bg-kumo-danger/5 data-highlighted:text-kumo-danger\",\n description: \"Destructive action item\",\n },\n },\n} as const;\n\nexport const KUMO_DROPDOWN_DEFAULT_VARIANTS = {\n variant: \"default\",\n} as const;\n\n// Derived types from KUMO_DROPDOWN_VARIANTS\nexport type KumoDropdownVariant = keyof typeof KUMO_DROPDOWN_VARIANTS.variant;\n\nexport interface KumoDropdownVariantsProps {\n /**\n * Visual style of the dropdown item.\n * - `\"default\"` — Standard item appearance\n * - `\"danger\"` — Destructive action with red text\n * @default \"default\"\n */\n variant?: KumoDropdownVariant;\n}\n\nexport function dropdownVariants({\n variant = KUMO_DROPDOWN_DEFAULT_VARIANTS.variant,\n}: KumoDropdownVariantsProps = {}) {\n return cn(KUMO_DROPDOWN_VARIANTS.variant[variant].classes);\n}\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubmenuTrigger>,\n React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.SubmenuTrigger\n > & {\n inset?: boolean;\n icon?: Icon;\n }\n>(({ className, inset, children, icon: IconComponent, ...props }, ref) => (\n <DropdownMenuPrimitive.SubmenuTrigger\n ref={ref}\n className={cn(\n \"flex cursor-default items-center rounded-sm text-base outline-hidden select-none\", // base styles\n \"px-2 py-1.5\", // spacing\n \"focus:bg-kumo-tint\", // focus state\n \"data-[state=open]:bg-kumo-tint\", // open state\n inset && \"pl-8\", // conditional inset\n className,\n )}\n {...props}\n >\n {IconComponent && <IconComponent className=\"mr-2 h-4 w-4\" />}\n {children}\n <CaretRight className=\"ml-auto h-4 w-4\" />\n </DropdownMenuPrimitive.SubmenuTrigger>\n));\n\nDropdownMenuSubTrigger.displayName =\n DropdownMenuPrimitive.SubmenuTrigger.displayName;\n\nconst DropdownMenuContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Positioner>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Positioner>\n>(({ className, sideOffset = 8, children, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Positioner\n ref={ref}\n sideOffset={sideOffset}\n {...props}\n >\n <DropdownMenuPrimitive.Popup\n className={cn(\n \"z-50 overflow-hidden bg-kumo-control text-kumo-default\", // background\n \"rounded-lg shadow-lg ring ring-kumo-line\", // border part\n \"min-w-36 p-1.5\", // spacing\n \"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\", // open animation\n \"data-[side=bottom]:slide-in-from-top-2\", // bottom side animation\n \"data-[side=left]:slide-in-from-right-2\", // left side animation\n \"data-[side=right]:slide-in-from-left-2\", // right side animation\n \"data-[side=top]:slide-in-from-bottom-2\", // top side animation\n \"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\", // close animation\n className,\n )}\n >\n {children}\n </DropdownMenuPrimitive.Popup>\n </DropdownMenuPrimitive.Positioner>\n </DropdownMenuPrimitive.Portal>\n));\n\nconst renderIconNode = (IconComponent?: Icon | React.ReactNode) => {\n if (!IconComponent) return null;\n if (React.isValidElement(IconComponent)) return IconComponent;\n const Comp = IconComponent as React.ComponentType<Record<string, unknown>>;\n return <Comp className=\"mr-2 h-4 w-4\" />;\n};\n\nconst DropdownMenuItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n icon?: Icon | React.ReactNode;\n selected?: boolean;\n href?: string;\n variant?: \"default\" | \"danger\";\n }\n>(\n (\n {\n className,\n inset,\n icon: IconComponent,\n children,\n selected,\n render,\n href,\n variant = \"default\",\n ...props\n },\n ref,\n ) => {\n const LinkComponent = useLinkComponent();\n const content = React.useMemo(() => {\n const innerContent = (\n <>\n {IconComponent && renderIconNode(IconComponent)}\n {children}\n {selected && (\n <span className=\"inline-flex\">\n <Check />\n </span>\n )}\n </>\n );\n\n if (!href) return innerContent;\n\n const isExternal = href.startsWith(\"https://\");\n const styles = cn(\n \"flex items-center\",\n variant === \"danger\" &&\n \"text-kumo-danger data-highlighted:bg-kumo-danger/5 data-highlighted:text-kumo-danger\",\n );\n if (isExternal) {\n return (\n <a\n className={cn(styles, \"w-full text-inherit! no-underline!\")}\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n /**\n * For some reason we need this here to prevent the outer link\n * from being clicked (thereby going to the worker details\n * instead of visiting the link)\n */\n onClick={(e) => e.stopPropagation()}\n >\n {innerContent}\n </a>\n );\n }\n return (\n <LinkComponent\n className={cn(styles, \"w-full text-inherit! no-underline!\")}\n href={href}\n to={href}\n /**\n * For some reason we need this here to prevent the outer link\n * from being clicked (thereby going to the worker details\n * instead of visiting the link)\n */\n onClick={(e) => e.stopPropagation()}\n >\n {innerContent}\n </LinkComponent>\n );\n }, [href, IconComponent, children, selected, variant, LinkComponent]);\n\n // When href is provided, content already contains children via innerContent\n // When render prop is provided, caller controls children rendering\n // Only pass children directly when neither href nor render is used\n const useRenderProp = href || render;\n\n return (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex cursor-default items-center rounded-md px-2 py-1.5 text-base outline-hidden select-none focus:text-kumo-default data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-kumo-overlay\",\n inset && \"pl-8\",\n dropdownVariants({ variant }),\n className,\n )}\n render={href ? content : render}\n {...props}\n >\n {useRenderProp ? undefined : children}\n </DropdownMenuPrimitive.Item>\n );\n },\n);\n\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n \"relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-base outline-hidden transition-colors select-none focus:bg-kumo-tint focus:text-kumo-default data-disabled:pointer-events-none data-disabled:opacity-50\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center text-inherit\">\n <Checkbox checked={checked} />\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n));\nDropdownMenuCheckboxItem.displayName =\n DropdownMenuPrimitive.CheckboxItem.displayName;\n\nconst DropdownMenuLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.GroupLabel>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.GroupLabel> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.GroupLabel\n ref={ref}\n className={cn(\n \"px-2 py-1.5 text-base font-semibold\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n />\n));\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.GroupLabel.displayName;\n\nconst DropdownMenuSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-kumo-line\", className)}\n {...props}\n />\n));\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;\n\nconst DropdownMenuShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn(\"ml-auto text-xs tracking-widest opacity-60\", className)}\n {...props}\n />\n );\n};\nDropdownMenuShortcut.displayName = \"DropdownMenuShortcut\";\n\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> & {\n inset?: boolean;\n icon?: Icon | React.ReactNode;\n }\n>(({ className, children, inset, icon: IconComponent, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n \"relative flex cursor-default items-center rounded-md px-2 py-1.5 text-base outline-hidden select-none\",\n \"data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-kumo-tint\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n >\n {IconComponent && renderIconNode(IconComponent)}\n {children}\n </DropdownMenuPrimitive.RadioItem>\n));\nDropdownMenuRadioItem.displayName = \"DropdownMenuRadioItem\";\n\nconst DropdownMenuRadioItemIndicator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItemIndicator>,\n React.ComponentPropsWithoutRef<\n typeof DropdownMenuPrimitive.RadioItemIndicator\n >\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItemIndicator\n ref={ref}\n className={cn(\"ml-auto\", className)}\n {...props}\n >\n {children ?? <Check className=\"h-4 w-4\" />}\n </DropdownMenuPrimitive.RadioItemIndicator>\n));\nDropdownMenuRadioItemIndicator.displayName = \"DropdownMenuRadioItemIndicator\";\n\n/**\n * Custom Trigger that converts a single child element to the `render` prop\n * to avoid nested button issues with base-ui's Menu.Trigger.\n */\nconst DropdownMenuTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>\n>(({ children, render, ...props }, ref) => {\n // If render prop is provided, use it directly\n // Otherwise, convert single child element to render prop\n const childElement = React.isValidElement(children) ? children : null;\n const effectiveRender = render ?? childElement;\n\n return (\n <DropdownMenuPrimitive.Trigger\n ref={ref}\n {...props}\n {...(effectiveRender && {\n render: effectiveRender as React.ReactElement<Record<string, unknown>>,\n })}\n >\n {/* Only pass children if not using as render prop */}\n {childElement ? undefined : children}\n </DropdownMenuPrimitive.Trigger>\n );\n});\nDropdownMenuTrigger.displayName = \"DropdownMenuTrigger\";\n\n/**\n * DropdownMenu — accessible dropdown menu anchored to a trigger.\n *\n * Compound component: `DropdownMenu` (Root), `.Trigger`, `.Content`, `.Item`,\n * `.CheckboxItem`, `.RadioGroup`, `.RadioItem`, `.RadioItemIndicator`,\n * `.Sub`, `.SubTrigger`, `.SubContent`, `.Label`, `.Separator`, `.Shortcut`, `.Group`.\n *\n * Built on `@base-ui/react/menu`.\n *\n * @example\n * ```tsx\n * <DropdownMenu>\n * <DropdownMenu.Trigger>\n * <Button>Actions</Button>\n * </DropdownMenu.Trigger>\n * <DropdownMenu.Content>\n * <DropdownMenu.Item>Edit</DropdownMenu.Item>\n * <DropdownMenu.Item icon={CopyIcon}>Duplicate</DropdownMenu.Item>\n * <DropdownMenu.Separator />\n * <DropdownMenu.Item variant=\"danger\">Delete</DropdownMenu.Item>\n * </DropdownMenu.Content>\n * </DropdownMenu>\n * ```\n *\n * @see https://base-ui.com/react/components/menu\n */\nexport const DropdownMenu = Object.assign(DropdownMenuPrimitive.Root, {\n Trigger: DropdownMenuTrigger,\n Portal: DropdownMenuPrimitive.Portal,\n Sub: DropdownMenuPrimitive.SubmenuRoot,\n SubTrigger: DropdownMenuSubTrigger,\n SubContent: DropdownMenuContent,\n Content: DropdownMenuContent,\n Item: DropdownMenuItem,\n CheckboxItem: DropdownMenuCheckboxItem,\n RadioGroup: DropdownMenuPrimitive.RadioGroup,\n RadioItem: DropdownMenuRadioItem,\n RadioItemIndicator: DropdownMenuRadioItemIndicator,\n Label: DropdownMenuLabel,\n Separator: DropdownMenuSeparator,\n Shortcut: DropdownMenuShortcut,\n Group: DropdownMenuPrimitive.Group,\n});\n"],"names":["KUMO_DROPDOWN_VARIANTS","KUMO_DROPDOWN_DEFAULT_VARIANTS","dropdownVariants","variant","cn","DropdownMenuSubTrigger","React","className","inset","children","IconComponent","props","ref","jsxs","DropdownMenuPrimitive.SubmenuTrigger","jsx","CaretRight","DropdownMenuContent","sideOffset","DropdownMenuPrimitive.Portal","DropdownMenuPrimitive.Positioner","DropdownMenuPrimitive.Popup","renderIconNode","DropdownMenuItem","selected","render","href","LinkComponent","useLinkComponent","content","innerContent","Fragment","Check","isExternal","styles","e","useRenderProp","DropdownMenuPrimitive.Item","DropdownMenuCheckboxItem","checked","DropdownMenuPrimitive.CheckboxItem","Checkbox","DropdownMenuLabel","DropdownMenuPrimitive.GroupLabel","DropdownMenuSeparator","DropdownMenuPrimitive.Separator","DropdownMenuShortcut","DropdownMenuRadioItem","DropdownMenuPrimitive.RadioItem","DropdownMenuRadioItemIndicator","DropdownMenuPrimitive.RadioItemIndicator","DropdownMenuTrigger","childElement","effectiveRender","DropdownMenuPrimitive.Trigger","DropdownMenu","DropdownMenuPrimitive.Root","DropdownMenuPrimitive.SubmenuRoot","DropdownMenuPrimitive.RadioGroup","DropdownMenuPrimitive.Group"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"menubar-CbXWXQYR.js","sources":["../src/components/menubar/use-menu-navigation.ts","../src/components/menubar/menubar.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\n\ntype UseMenuNavigationProps = {\n menuRef: React.RefObject<HTMLElement | null>;\n direction?: \"horizontal\" | \"vertical\"; // Default: horizontal\n};\n\nexport const useMenuNavigation = ({\n menuRef,\n direction = \"horizontal\",\n}: UseMenuNavigationProps) => {\n const activeElementRef = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!menuRef.current) return;\n\n const focusableElements = Array.from(\n menuRef.current.querySelectorAll(\n 'a, button, input, textarea, select, details, [tabindex]:not([tabindex=\"-1\"])',\n ),\n ) as HTMLElement[];\n\n if (focusableElements.length === 0) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!activeElementRef.current) return;\n\n const currentIndex = focusableElements.indexOf(activeElementRef.current);\n let nextIndex = currentIndex;\n\n const isHorizontal = direction === \"horizontal\";\n const forwardKey = isHorizontal ? \"ArrowRight\" : \"ArrowDown\";\n const backwardKey = isHorizontal ? \"ArrowLeft\" : \"ArrowUp\";\n\n if (e.key === forwardKey) {\n e.preventDefault();\n nextIndex = (currentIndex + 1) % focusableElements.length;\n } else if (e.key === backwardKey) {\n e.preventDefault();\n nextIndex =\n (currentIndex - 1 + focusableElements.length) %\n focusableElements.length;\n } else {\n return;\n }\n\n const nextElement = focusableElements[nextIndex];\n activeElementRef.current = nextElement;\n nextElement.focus();\n };\n\n const addKeyListener = () =>\n document.addEventListener(\"keydown\", handleKeyDown);\n const removeKeyListener = () =>\n document.removeEventListener(\"keydown\", handleKeyDown);\n\n const handleFocusIn = () => {\n activeElementRef.current = document.activeElement as HTMLElement;\n addKeyListener();\n };\n\n const handleFocusOut = () => {\n activeElementRef.current = null;\n removeKeyListener();\n };\n\n menuRef.current.addEventListener(\"focusin\", handleFocusIn);\n menuRef.current.addEventListener(\"focusout\", handleFocusOut);\n\n return () => {\n menuRef.current?.removeEventListener(\"focusin\", handleFocusIn);\n menuRef.current?.removeEventListener(\"focusout\", handleFocusOut);\n removeKeyListener();\n };\n }, [menuRef, direction]);\n};\n","import { Tooltip } from \"../tooltip\";\nimport { cn } from \"../../utils/cn\";\nimport { IconContext } from \"@phosphor-icons/react\";\nimport React, { useRef } from \"react\";\nimport { useMenuNavigation } from \"./use-menu-navigation\";\n\n/** MenuBar variant definitions (currently empty, reserved for future additions). */\nexport const KUMO_MENUBAR_VARIANTS = {\n // MenuBar currently has no variant options but structure is ready for future additions\n} as const;\n\nexport const KUMO_MENUBAR_DEFAULT_VARIANTS = {} as const;\n\n// Derived types from KUMO_MENUBAR_VARIANTS\nexport interface KumoMenuBarVariantsProps {}\n\nexport function menuBarVariants(_props: KumoMenuBarVariantsProps = {}) {\n return cn(\n // Base styles\n \"flex rounded-lg border border-kumo-fill bg-kumo-fill pl-px shadow-xs transition-colors\",\n );\n}\n\n/** Props for an individual menu option within a MenuBar. */\ntype MenuOptionProps = {\n /** Icon element (typically from `@phosphor-icons/react`) rendered at 18px */\n icon: React.ReactNode;\n /** Unique identifier for the option (used when `optionIds` is true) */\n id?: number | string;\n /** Currently active value from the parent MenuBar */\n isActive?: number | boolean | string | undefined;\n /** Callback when this option is clicked */\n onClick: () => void;\n /** Tooltip text shown on hover */\n tooltip: string;\n};\n\nconst MenuOption = ({\n icon,\n id,\n isActive,\n onClick,\n tooltip,\n}: MenuOptionProps) => {\n return (\n <Tooltip content={tooltip} asChild>\n <button\n className={cn(\n \"focus:inset-ring-focus relative -ml-px flex h-full w-11 cursor-pointer items-center justify-center rounded-md border-none bg-kumo-fill transition-colors focus:z-10 focus:outline-none focus-visible:z-10 focus-visible:inset-ring-[0.5]\",\n {\n \"z-20 bg-kumo-base shadow-xs transition-colors\": isActive === id,\n },\n )}\n onClick={onClick}\n >\n <IconContext.Provider value={{ size: 18 }} {...({} as any)}>\n {icon}\n </IconContext.Provider>\n </button>\n </Tooltip>\n );\n};\n\n/**\n * MenuBar component props.\n *\n * Horizontal icon-button toolbar with keyboard navigation and tooltip labels.\n *\n * @example\n * ```tsx\n * <MenuBar\n * isActive={activeIndex}\n * options={[\n * { icon: <ListIcon />, tooltip: \"List view\", onClick: () => setView(\"list\") },\n * { icon: <GridFourIcon />, tooltip: \"Grid view\", onClick: () => setView(\"grid\") },\n * ]}\n * />\n * ```\n */\ntype MenuBarProps = {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** The currently active option value — matched against option index or `id`. */\n isActive: number | boolean | string | undefined;\n /** Array of menu option configurations. */\n options: MenuOptionProps[];\n /** When true, each option's `id` field is used for matching instead of its array index. */\n optionIds?: boolean;\n};\n\n/**\n * MenuBar — horizontal icon-button toolbar with keyboard arrow-key navigation.\n *\n * Each option renders as a `<button>` with a Tooltip. The active option is\n * visually highlighted with an elevated background.\n *\n * @example\n * ```tsx\n * <MenuBar\n * isActive={0}\n * options={[\n * { icon: <ListIcon />, tooltip: \"List\", onClick: () => {} },\n * { icon: <GridFourIcon />, tooltip: \"Grid\", onClick: () => {} },\n * ]}\n * />\n * ```\n */\nexport const MenuBar = ({\n className,\n isActive,\n options,\n optionIds = false, // if option needs an extra unique ID\n}: MenuBarProps) => {\n const menuRef = useRef<HTMLElement | null>(null);\n\n useMenuNavigation({ menuRef, direction: \"horizontal\" });\n\n return (\n <nav\n className={cn(\n \"flex rounded-lg border border-kumo-fill bg-kumo-fill pl-px shadow-xs transition-colors\",\n className,\n )}\n ref={menuRef}\n >\n {options.map((option, index) => (\n <MenuOption\n key={index}\n {...option}\n isActive={isActive}\n id={optionIds ? option.id : index}\n />\n ))}\n </nav>\n );\n};\n"],"names":["useMenuNavigation","menuRef","direction","activeElementRef","useRef","useEffect","focusableElements","handleKeyDown","e","currentIndex","nextIndex","isHorizontal","forwardKey","backwardKey","nextElement","addKeyListener","removeKeyListener","handleFocusIn","handleFocusOut","MenuOption","icon","id","isActive","onClick","tooltip","jsx","Tooltip","cn","IconContext","MenuBar","className","options","optionIds","option","index"],"mappings":"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"}