@cloudflare/kumo 2.0.5 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/ai/component-registry.json +25 -1
  3. package/ai/component-registry.md +100 -11
  4. package/ai/schemas.ts +3 -0
  5. package/dist/.build-complete +1 -1
  6. package/dist/ai/schemas.d.ts +12 -0
  7. package/dist/ai/schemas.d.ts.map +1 -1
  8. package/dist/ai/schemas.js +137 -131
  9. package/dist/ai/schemas.js.map +1 -1
  10. package/dist/chunks/SankeyChart-h1kzhs1tyt20luha.js +629 -0
  11. package/dist/chunks/SankeyChart-h1kzhs1tyt20luha.js.map +1 -0
  12. package/dist/chunks/{autocomplete-ka7gcirdg8wwr0jd.js → autocomplete-nw1ig02pawtj3il9.js} +4 -4
  13. package/dist/chunks/{autocomplete-ka7gcirdg8wwr0jd.js.map → autocomplete-nw1ig02pawtj3il9.js.map} +1 -1
  14. package/dist/chunks/{breadcrumbs-ce0u1l0utkuyc4o6.js → breadcrumbs-f7bi3g8tx6dfcgl6.js} +2 -2
  15. package/dist/chunks/{breadcrumbs-ce0u1l0utkuyc4o6.js.map → breadcrumbs-f7bi3g8tx6dfcgl6.js.map} +1 -1
  16. package/dist/chunks/{button-bxv4r8h0s8kmcwvz.js → button-gflkhovvkmt0ftzz.js} +2 -2
  17. package/dist/chunks/{button-bxv4r8h0s8kmcwvz.js.map → button-gflkhovvkmt0ftzz.js.map} +1 -1
  18. package/dist/chunks/{checkbox-jtpf15vjwd01ztoo.js → checkbox-imuc4c45j7sds6wk.js} +3 -3
  19. package/dist/chunks/{checkbox-jtpf15vjwd01ztoo.js.map → checkbox-imuc4c45j7sds6wk.js.map} +1 -1
  20. package/dist/chunks/{clipboard-text-ccpb091h1idsqh7e.js → clipboard-text-dp5eb2c2qudgusnc.js} +4 -4
  21. package/dist/chunks/{clipboard-text-ccpb091h1idsqh7e.js.map → clipboard-text-dp5eb2c2qudgusnc.js.map} +1 -1
  22. package/dist/chunks/{collapsible-jvebgqfqljzokj8h.js → collapsible-ej6p2bq758sw30nk.js} +2 -2
  23. package/dist/chunks/{collapsible-jvebgqfqljzokj8h.js.map → collapsible-ej6p2bq758sw30nk.js.map} +1 -1
  24. package/dist/chunks/{combobox-h6uapulwxi3tfyez.js → combobox-42i2nyvfgkqjb5a4.js} +4 -4
  25. package/dist/chunks/{combobox-h6uapulwxi3tfyez.js.map → combobox-42i2nyvfgkqjb5a4.js.map} +1 -1
  26. package/dist/chunks/{command-palette-ew2nepeukh34jcbo.js → command-palette-eep807rf6iapoz8r.js} +12 -12
  27. package/dist/chunks/command-palette-eep807rf6iapoz8r.js.map +1 -0
  28. package/dist/chunks/{dialog-paxwsab337zz9ddr.js → dialog-fo3qhv9fgiadq5gp.js} +3 -3
  29. package/dist/chunks/{dialog-paxwsab337zz9ddr.js.map → dialog-fo3qhv9fgiadq5gp.js.map} +1 -1
  30. package/dist/chunks/{dropdown-mftv4iv9nzhprg81.js → dropdown-cobpydatw4vlb3ov.js} +2 -2
  31. package/dist/chunks/{dropdown-mftv4iv9nzhprg81.js.map → dropdown-cobpydatw4vlb3ov.js.map} +1 -1
  32. package/dist/chunks/{empty-fenjhasxc9akon1j.js → empty-jwan4d5hqjocakhm.js} +2 -2
  33. package/dist/chunks/{empty-fenjhasxc9akon1j.js.map → empty-jwan4d5hqjocakhm.js.map} +1 -1
  34. package/dist/chunks/{field-k10dm32v9sm4bpn4.js → field-yhlyu6fy0qi1ewtl.js} +36 -30
  35. package/dist/chunks/field-yhlyu6fy0qi1ewtl.js.map +1 -0
  36. package/dist/chunks/input-area-d85jzxlnvx7mc3x9.js +78 -0
  37. package/dist/chunks/input-area-d85jzxlnvx7mc3x9.js.map +1 -0
  38. package/dist/chunks/{input-bns82xraggaljrsx.js → input-cyils8jxj8e0udr7.js} +61 -45
  39. package/dist/chunks/input-cyils8jxj8e0udr7.js.map +1 -0
  40. package/dist/chunks/{input-group-n8e64zvcv3c16g92.js → input-group-mu8yklweljytpt04.js} +5 -5
  41. package/dist/chunks/{input-group-n8e64zvcv3c16g92.js.map → input-group-mu8yklweljytpt04.js.map} +1 -1
  42. package/dist/chunks/{label-iq35ljob9sknckjd.js → label-kaz4uxdt1yf3i5x5.js} +3 -3
  43. package/dist/chunks/{label-iq35ljob9sknckjd.js.map → label-kaz4uxdt1yf3i5x5.js.map} +1 -1
  44. package/dist/chunks/{layer-card-kde8ys0x0civrdyj.js → layer-card-hyz8lfxceudt05pv.js} +18 -17
  45. package/dist/chunks/layer-card-hyz8lfxceudt05pv.js.map +1 -0
  46. package/dist/chunks/{link-eak1exy1di49c56p.js → link-lkzjiitte3l29q87.js} +39 -25
  47. package/dist/chunks/link-lkzjiitte3l29q87.js.map +1 -0
  48. package/dist/chunks/link-provider-mn2voeohon7cj9o4.js.map +1 -1
  49. package/dist/chunks/{menubar-j3w43me6u14s93tj.js → menubar-gk322oew1y1lr851.js} +2 -2
  50. package/dist/chunks/{menubar-j3w43me6u14s93tj.js.map → menubar-gk322oew1y1lr851.js.map} +1 -1
  51. package/dist/chunks/{meter-g1ja8cwtum0frcdj.js → meter-jbxkh6gfggx1kjna.js} +2 -2
  52. package/dist/chunks/{meter-g1ja8cwtum0frcdj.js.map → meter-jbxkh6gfggx1kjna.js.map} +1 -1
  53. package/dist/chunks/{pagination-bsicq2euubayz2tg.js → pagination-kswioh2znglyq7as.js} +3 -3
  54. package/dist/chunks/{pagination-bsicq2euubayz2tg.js.map → pagination-kswioh2znglyq7as.js.map} +1 -1
  55. package/dist/chunks/{popover-f3t99000mahsnjzc.js → popover-i4opvl9g0as52fyx.js} +2 -2
  56. package/dist/chunks/{popover-f3t99000mahsnjzc.js.map → popover-i4opvl9g0as52fyx.js.map} +1 -1
  57. package/dist/chunks/{radio-me5m5ei86beum5bo.js → radio-g56o5rftpu1qpxuv.js} +6 -6
  58. package/dist/chunks/{radio-me5m5ei86beum5bo.js.map → radio-g56o5rftpu1qpxuv.js.map} +1 -1
  59. package/dist/chunks/select-hz8wwd2msvp1u0jp.js +226 -0
  60. package/dist/chunks/select-hz8wwd2msvp1u0jp.js.map +1 -0
  61. package/dist/chunks/{sensitive-input-l8dzkd0jxcod648v.js → sensitive-input-mdtjukbb3wimz1iy.js} +4 -4
  62. package/dist/chunks/{sensitive-input-l8dzkd0jxcod648v.js.map → sensitive-input-mdtjukbb3wimz1iy.js.map} +1 -1
  63. package/dist/chunks/{sidebar-ja58ws91ox3qukus.js → sidebar-dlh79t5uliezwniq.js} +3 -3
  64. package/dist/chunks/{sidebar-ja58ws91ox3qukus.js.map → sidebar-dlh79t5uliezwniq.js.map} +1 -1
  65. package/dist/chunks/{surface-hnwqkutuhab2wbwr.js → surface-ck1nt2uqfzmod4sz.js} +2 -2
  66. package/dist/chunks/{surface-hnwqkutuhab2wbwr.js.map → surface-ck1nt2uqfzmod4sz.js.map} +1 -1
  67. package/dist/chunks/{switch-bh3wirr8q2obzgiy.js → switch-luut1d75u179g7x6.js} +3 -3
  68. package/dist/chunks/{switch-bh3wirr8q2obzgiy.js.map → switch-luut1d75u179g7x6.js.map} +1 -1
  69. package/dist/chunks/{table-pbmxg269hfspxpyl.js → table-ef63hg1r1zia9u9j.js} +2 -2
  70. package/dist/chunks/{table-pbmxg269hfspxpyl.js.map → table-ef63hg1r1zia9u9j.js.map} +1 -1
  71. package/dist/chunks/tabs-g8ier5pehjpfxauf.js +152 -0
  72. package/dist/chunks/tabs-g8ier5pehjpfxauf.js.map +1 -0
  73. package/dist/chunks/{toast-cf1lbie7p0j2qg30.js → toast-e5id2hx8pv0x3vue.js} +42 -38
  74. package/dist/chunks/{toast-cf1lbie7p0j2qg30.js.map → toast-e5id2hx8pv0x3vue.js.map} +1 -1
  75. package/dist/chunks/{tooltip-b5tgbw83mdh2dzlj.js → tooltip-caka3fmn1ogdc7q8.js} +9 -5
  76. package/dist/chunks/{tooltip-b5tgbw83mdh2dzlj.js.map → tooltip-caka3fmn1ogdc7q8.js.map} +1 -1
  77. package/dist/chunks/{vendor-base-ui-epfrwb4nfbd4btaz.js → vendor-base-ui-nbyiqqi138hcoz52.js} +30 -29
  78. package/dist/chunks/{vendor-base-ui-epfrwb4nfbd4btaz.js.map → vendor-base-ui-nbyiqqi138hcoz52.js.map} +1 -1
  79. package/dist/code.js +1 -1
  80. package/dist/components/autocomplete.js +1 -1
  81. package/dist/components/breadcrumbs.js +1 -1
  82. package/dist/components/button.js +1 -1
  83. package/dist/components/chart.js +3 -2
  84. package/dist/components/checkbox.js +1 -1
  85. package/dist/components/clipboard-text.js +1 -1
  86. package/dist/components/collapsible.js +1 -1
  87. package/dist/components/combobox.js +1 -1
  88. package/dist/components/command-palette.js +1 -1
  89. package/dist/components/dialog.js +1 -1
  90. package/dist/components/dropdown.js +1 -1
  91. package/dist/components/empty.js +1 -1
  92. package/dist/components/field.js +6 -5
  93. package/dist/components/input-group.js +1 -1
  94. package/dist/components/input.js +3 -3
  95. package/dist/components/label.js +1 -1
  96. package/dist/components/layer-card.js +1 -1
  97. package/dist/components/link.js +1 -1
  98. package/dist/components/menubar.js +1 -1
  99. package/dist/components/meter.js +1 -1
  100. package/dist/components/pagination.js +1 -1
  101. package/dist/components/popover.js +1 -1
  102. package/dist/components/radio.js +1 -1
  103. package/dist/components/select.js +1 -1
  104. package/dist/components/sensitive-input.js +1 -1
  105. package/dist/components/sidebar.js +1 -1
  106. package/dist/components/surface.js +1 -1
  107. package/dist/components/switch.js +1 -1
  108. package/dist/components/table.js +1 -1
  109. package/dist/components/tabs.js +1 -1
  110. package/dist/components/toast.js +2 -2
  111. package/dist/components/tooltip.js +1 -1
  112. package/dist/index.js +149 -147
  113. package/dist/primitives/accordion.js +1 -1
  114. package/dist/primitives/alert-dialog.js +1 -1
  115. package/dist/primitives/autocomplete.js +1 -1
  116. package/dist/primitives/avatar.js +1 -1
  117. package/dist/primitives/button.js +1 -1
  118. package/dist/primitives/checkbox-group.js +1 -1
  119. package/dist/primitives/checkbox.js +1 -1
  120. package/dist/primitives/collapsible.js +1 -1
  121. package/dist/primitives/combobox.js +1 -1
  122. package/dist/primitives/context-menu.js +1 -1
  123. package/dist/primitives/csp-provider.js +1 -1
  124. package/dist/primitives/dialog.js +1 -1
  125. package/dist/primitives/direction-provider.js +1 -1
  126. package/dist/primitives/drawer.js +1 -1
  127. package/dist/primitives/field.js +1 -1
  128. package/dist/primitives/fieldset.js +1 -1
  129. package/dist/primitives/form.js +1 -1
  130. package/dist/primitives/input.js +1 -1
  131. package/dist/primitives/menu.js +1 -1
  132. package/dist/primitives/menubar.js +1 -1
  133. package/dist/primitives/meter.js +1 -1
  134. package/dist/primitives/navigation-menu.js +1 -1
  135. package/dist/primitives/number-field.js +1 -1
  136. package/dist/primitives/otp-field.js +1 -1
  137. package/dist/primitives/popover.js +1 -1
  138. package/dist/primitives/preview-card.js +1 -1
  139. package/dist/primitives/progress.js +1 -1
  140. package/dist/primitives/radio-group.js +1 -1
  141. package/dist/primitives/radio.js +1 -1
  142. package/dist/primitives/scroll-area.js +1 -1
  143. package/dist/primitives/select.js +1 -1
  144. package/dist/primitives/separator.js +1 -1
  145. package/dist/primitives/slider.js +1 -1
  146. package/dist/primitives/switch.js +1 -1
  147. package/dist/primitives/tabs.js +1 -1
  148. package/dist/primitives/toast.js +1 -1
  149. package/dist/primitives/toggle-group.js +1 -1
  150. package/dist/primitives/toggle.js +1 -1
  151. package/dist/primitives/toolbar.js +1 -1
  152. package/dist/primitives/tooltip.js +1 -1
  153. package/dist/primitives.js +1 -1
  154. package/dist/src/components/chart/Color.d.ts +11 -0
  155. package/dist/src/components/chart/Color.d.ts.map +1 -1
  156. package/dist/src/components/chart/SankeyChart.d.ts +89 -0
  157. package/dist/src/components/chart/SankeyChart.d.ts.map +1 -0
  158. package/dist/src/components/chart/TimeseriesChart.d.ts +7 -1
  159. package/dist/src/components/chart/TimeseriesChart.d.ts.map +1 -1
  160. package/dist/src/components/chart/index.d.ts +1 -0
  161. package/dist/src/components/chart/index.d.ts.map +1 -1
  162. package/dist/src/components/field/field.d.ts +22 -1
  163. package/dist/src/components/field/field.d.ts.map +1 -1
  164. package/dist/src/components/field/index.d.ts +1 -1
  165. package/dist/src/components/field/index.d.ts.map +1 -1
  166. package/dist/src/components/input/input-area.d.ts.map +1 -1
  167. package/dist/src/components/input/input.d.ts +4 -0
  168. package/dist/src/components/input/input.d.ts.map +1 -1
  169. package/dist/src/components/layer-card/layer-card.d.ts +4 -7
  170. package/dist/src/components/layer-card/layer-card.d.ts.map +1 -1
  171. package/dist/src/components/link/link.d.ts +12 -1
  172. package/dist/src/components/link/link.d.ts.map +1 -1
  173. package/dist/src/components/select/select.d.ts.map +1 -1
  174. package/dist/src/components/tabs/tabs.d.ts +10 -1
  175. package/dist/src/components/tabs/tabs.d.ts.map +1 -1
  176. package/dist/src/components/toast/toast.d.ts +28 -1
  177. package/dist/src/components/toast/toast.d.ts.map +1 -1
  178. package/dist/src/components/tooltip/tooltip.d.ts.map +1 -1
  179. package/dist/src/index.d.ts +2 -2
  180. package/dist/src/index.d.ts.map +1 -1
  181. package/dist/src/utils/link-provider.d.ts +54 -0
  182. package/dist/src/utils/link-provider.d.ts.map +1 -1
  183. package/dist/styles/kumo-binding.css +65 -0
  184. package/dist/styles/kumo-standalone.css +1 -1
  185. package/package.json +4 -4
  186. package/dist/chunks/Legend-ibjxhfm9pn2vrb6f.js +0 -430
  187. package/dist/chunks/Legend-ibjxhfm9pn2vrb6f.js.map +0 -1
  188. package/dist/chunks/command-palette-ew2nepeukh34jcbo.js.map +0 -1
  189. package/dist/chunks/field-k10dm32v9sm4bpn4.js.map +0 -1
  190. package/dist/chunks/input-area-gz5wqofuyqnwdtqs.js +0 -78
  191. package/dist/chunks/input-area-gz5wqofuyqnwdtqs.js.map +0 -1
  192. package/dist/chunks/input-bns82xraggaljrsx.js.map +0 -1
  193. package/dist/chunks/layer-card-kde8ys0x0civrdyj.js.map +0 -1
  194. package/dist/chunks/link-eak1exy1di49c56p.js.map +0 -1
  195. package/dist/chunks/select-du1d83plcgkr1cz8.js +0 -215
  196. package/dist/chunks/select-du1d83plcgkr1cz8.js.map +0 -1
  197. package/dist/chunks/tabs-fdkhdhv8kvnpp8nt.js +0 -92
  198. package/dist/chunks/tabs-fdkhdhv8kvnpp8nt.js.map +0 -1
@@ -1,78 +0,0 @@
1
- "use client";
2
- import { jsx as e } from "react/jsx-runtime";
3
- import { i as y } from "./input-bns82xraggaljrsx.js";
4
- import { c as N } from "./cn-ct4n7r74mh8y0f48.js";
5
- import * as x from "react";
6
- import { useCallback as I } from "react";
7
- import { F as b } from "./field-k10dm32v9sm4bpn4.js";
8
- import { aT as w } from "./vendor-base-ui-epfrwb4nfbd4btaz.js";
9
- const c = x.forwardRef(
10
- (u, t) => {
11
- const {
12
- className: d,
13
- onValueChange: n,
14
- size: f = "base",
15
- variant: s,
16
- onChange: i,
17
- label: p,
18
- labelTooltip: h,
19
- description: g,
20
- error: r,
21
- ...o
22
- } = u;
23
- process.env.NODE_ENV !== "production" && s === "error" && console.warn(
24
- '[Kumo InputArea]: variant="error" is deprecated. Error styling is now automatically applied when the `error` prop is truthy. Simply remove the variant prop and pass an error message instead.'
25
- );
26
- const v = s ?? (r ? "error" : "default"), { required: C } = o, l = I(
27
- (a) => {
28
- i?.(a), n?.(a.target.value);
29
- },
30
- [i, n]
31
- ), m = N(
32
- y({ size: f, variant: v, focusIndicator: !0 }),
33
- "h-auto py-2",
34
- // Input variant always comes with size, but it does not apply for textarea
35
- d
36
- );
37
- return p ? /* @__PURE__ */ e(
38
- b,
39
- {
40
- label: p,
41
- required: C,
42
- labelTooltip: h,
43
- description: g,
44
- error: r ? typeof r == "string" ? { message: r, match: !0 } : r : void 0,
45
- children: /* @__PURE__ */ e(
46
- w,
47
- {
48
- render: (a) => /* @__PURE__ */ e(
49
- "textarea",
50
- {
51
- ...a,
52
- ref: t,
53
- className: m,
54
- onChange: l,
55
- ...o
56
- }
57
- )
58
- }
59
- )
60
- }
61
- ) : /* @__PURE__ */ e(
62
- "textarea",
63
- {
64
- ref: t,
65
- className: m,
66
- onChange: l,
67
- ...o
68
- }
69
- );
70
- }
71
- );
72
- c.displayName = "InputArea";
73
- const j = c;
74
- export {
75
- c as I,
76
- j as T
77
- };
78
- //# sourceMappingURL=input-area-gz5wqofuyqnwdtqs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"input-area-gz5wqofuyqnwdtqs.js","sources":["../../src/components/input/input-area.tsx"],"sourcesContent":["import { inputVariants } from \"./input\";\nimport { cn } from \"../../utils/cn\";\nimport { useCallback, type ReactNode } from \"react\";\nimport * as React from \"react\";\nimport { Field as FieldBase } from \"@base-ui/react/field\";\nimport { Field as KumoField, type FieldErrorMatch } from \"../field/field\";\n\nexport const InputArea = React.forwardRef<HTMLTextAreaElement, InputAreaProps>(\n (props, ref) => {\n const {\n className,\n onValueChange,\n size = \"base\",\n variant: variantProp,\n onChange,\n label,\n labelTooltip,\n description,\n error,\n ...inputProps\n } = props;\n\n // Deprecation warning for variant=\"error\"\n if (process.env.NODE_ENV !== \"production\" && variantProp === \"error\") {\n console.warn(\n '[Kumo InputArea]: variant=\"error\" is deprecated. ' +\n \"Error styling is now automatically applied when the `error` prop is truthy. \" +\n \"Simply remove the variant prop and pass an error message instead.\",\n );\n }\n\n // Auto-apply error styling when error prop is truthy\n // Explicit variant prop takes precedence for backwards compatibility\n const variant = variantProp ?? (error ? \"error\" : \"default\");\n\n // Extract required from inputProps to pass to Field for label decoration\n const { required } = inputProps;\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n onChange?.(event);\n onValueChange?.(event.target.value);\n },\n [onChange, onValueChange],\n );\n\n const textareaClassName = cn(\n inputVariants({ size, variant, focusIndicator: true }),\n \"h-auto py-2\", // Input variant always comes with size, but it does not apply for textarea\n className,\n );\n\n // Render with Field wrapper if label is provided\n // Use FieldBase.Control with render callback to ensure proper label-textarea association.\n // The render callback receives props with the correct id/aria-labelledby from Field context.\n if (label) {\n return (\n <KumoField\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 <FieldBase.Control\n render={(controlProps) => (\n <textarea\n {...controlProps}\n ref={ref}\n className={textareaClassName}\n onChange={handleChange}\n {...inputProps}\n />\n )}\n />\n </KumoField>\n );\n }\n\n // Render bare textarea without Field wrapper\n return (\n <textarea\n ref={ref}\n className={textareaClassName}\n onChange={handleChange}\n {...inputProps}\n />\n );\n },\n);\n\nInputArea.displayName = \"InputArea\";\n\n/** Alias for InputArea — provided for discoverability when migrating from other libraries */\nexport const Textarea = InputArea;\n\n/**\n * InputArea component props\n * @property {ReactNode} [label] - Label content for the textarea (enables Field wrapper)\n * @property {ReactNode} [description] - Helper text displayed below the textarea\n * @property {string | { message: ReactNode, match: FieldErrorMatch }} [error] - Error message or validation error object\n */\nexport type InputAreaProps = {\n onValueChange?: (value: string) => void;\n variant?: \"default\" | \"error\";\n size?: \"xs\" | \"sm\" | \"base\" | \"lg\";\n // Then other custom props\n children?: React.ReactNode;\n className?: string;\n /** Label content for the textarea (enables Field wrapper) - can be a string or any React node */\n label?: ReactNode;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /** Helper text displayed below the textarea */\n description?: ReactNode;\n /** Error message or validation error object */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n\n // Finally, spread the native input props (least important)\n} & Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, \"size\">;\n"],"names":["InputArea","React","props","ref","className","onValueChange","size","variantProp","onChange","label","labelTooltip","description","error","inputProps","variant","required","handleChange","useCallback","event","textareaClassName","cn","inputVariants","jsx","KumoField","FieldBase.Control","controlProps","Textarea"],"mappings":";;;;;;;;AAOO,MAAMA,IAAYC,EAAM;AAAA,EAC7B,CAACC,GAAOC,MAAQ;AACd,UAAM;AAAA,MACJ,WAAAC;AAAA,MACA,eAAAC;AAAA,MACA,MAAAC,IAAO;AAAA,MACP,SAASC;AAAA,MACT,UAAAC;AAAA,MACA,OAAAC;AAAA,MACA,cAAAC;AAAA,MACA,aAAAC;AAAA,MACA,OAAAC;AAAA,MACA,GAAGC;AAAA,IAAA,IACDX;AAGJ,IAAI,QAAQ,IAAI,aAAa,gBAAgBK,MAAgB,WAC3D,QAAQ;AAAA,MACN;AAAA,IAAA;AAQJ,UAAMO,IAAUP,MAAgBK,IAAQ,UAAU,YAG5C,EAAE,UAAAG,MAAaF,GACfG,IAAeC;AAAA,MACnB,CAACC,MAAkD;AACjD,QAAAV,IAAWU,CAAK,GAChBb,IAAgBa,EAAM,OAAO,KAAK;AAAA,MACpC;AAAA,MACA,CAACV,GAAUH,CAAa;AAAA,IAAA,GAGpBc,IAAoBC;AAAA,MACxBC,EAAc,EAAE,MAAAf,GAAM,SAAAQ,GAAS,gBAAgB,IAAM;AAAA,MACrD;AAAA;AAAA,MACAV;AAAA,IAAA;AAMF,WAAIK,IAEA,gBAAAa;AAAA,MAACC;AAAAA,MAAA;AAAA,QACC,OAAAd;AAAA,QACA,UAAAM;AAAA,QACA,cAAAL;AAAA,QACA,aAAAC;AAAA,QACA,OACEC,IACI,OAAOA,KAAU,WACf,EAAE,SAASA,GAAO,OAAO,GAAA,IACzBA,IACF;AAAA,QAGN,UAAA,gBAAAU;AAAA,UAACE;AAAAA,UAAA;AAAA,YACC,QAAQ,CAACC,MACP,gBAAAH;AAAA,cAAC;AAAA,cAAA;AAAA,gBACE,GAAGG;AAAA,gBACJ,KAAAtB;AAAA,gBACA,WAAWgB;AAAA,gBACX,UAAUH;AAAA,gBACT,GAAGH;AAAA,cAAA;AAAA,YAAA;AAAA,UACN;AAAA,QAAA;AAAA,MAEJ;AAAA,IAAA,IAOJ,gBAAAS;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAnB;AAAA,QACA,WAAWgB;AAAA,QACX,UAAUH;AAAA,QACT,GAAGH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;AAEAb,EAAU,cAAc;AAGjB,MAAM0B,IAAW1B;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"input-bns82xraggaljrsx.js","sources":["../../src/components/input/input.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn\";\nimport { resolveVariant } from \"../../utils/resolve-variant\";\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from \"react\";\nimport { Input as BaseInput } from \"@base-ui/react/input\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\n\n/** Input size and variant definitions mapping names to their Tailwind classes. */\nexport const KUMO_INPUT_VARIANTS = {\n size: {\n xs: {\n classes: \"h-5 gap-1 rounded-sm px-1.5 text-xs\",\n description: \"Extra small input for compact UIs\",\n },\n sm: {\n classes: \"h-6.5 gap-1 rounded-md px-2 text-xs\",\n description: \"Small input for secondary fields\",\n },\n base: {\n classes: \"h-9 gap-1.5 rounded-lg px-3 text-base\",\n description: \"Default input size\",\n },\n lg: {\n classes: \"h-10 gap-2 rounded-lg px-4 text-base\",\n description: \"Large input for prominent fields\",\n },\n },\n variant: {\n default: {\n classes: \"focus:ring-kumo-focus/50 focus:ring-[1.5px]\",\n description: \"Default input appearance\",\n },\n error: {\n classes: \"!ring-kumo-danger focus:ring-kumo-danger/50 focus:ring-[1.5px]\",\n description: \"Error state for validation failures\",\n },\n },\n} as const;\n\nexport const KUMO_INPUT_DEFAULT_VARIANTS = {\n size: \"base\",\n variant: \"default\",\n} as const;\n\nexport const KUMO_INPUT_STYLING = {\n dimensions: {\n xs: { height: 20, paddingX: 6, fontSize: 12, borderRadius: 2, width: 160 },\n sm: { height: 26, paddingX: 8, fontSize: 12, borderRadius: 6, width: 200 },\n base: {\n height: 36,\n paddingX: 12,\n fontSize: 16,\n borderRadius: 8,\n width: 280,\n },\n lg: { height: 40, paddingX: 16, fontSize: 16, borderRadius: 8, width: 320 },\n },\n baseTokens: {\n background: \"color-secondary\",\n text: \"text-color-surface\",\n placeholder: \"text-color-muted\",\n ring: \"color-border\",\n },\n stateTokens: {\n focus: { ring: \"color-active\" },\n error: { ring: \"color-error\" },\n disabled: { opacity: 0.5, text: \"text-color-muted\" },\n },\n} as const;\n\n// Derived types from KUMO_INPUT_VARIANTS\nexport type KumoInputSize = keyof typeof KUMO_INPUT_VARIANTS.size;\nexport type KumoInputVariant = keyof typeof KUMO_INPUT_VARIANTS.variant;\n\nexport interface KumoInputVariantsProps {\n /**\n * Input size.\n * - `\"xs\"` — Extra small for compact UIs\n * - `\"sm\"` — Small for secondary fields\n * - `\"base\"` — Default size\n * - `\"lg\"` — Large for prominent fields\n * @default \"base\"\n */\n size?: KumoInputSize;\n /**\n * Visual variant.\n * - `\"default\"` — Standard input\n * - `\"error\"` — Error state for validation failures\n * @default \"default\"\n */\n variant?: KumoInputVariant;\n parentFocusIndicator?: boolean;\n focusIndicator?: boolean;\n}\n\n// Omit native `size` attribute (number) to avoid conflict with our custom `size` variant\ntype BaseInputProps = Omit<ComponentPropsWithoutRef<typeof BaseInput>, \"size\">;\n\nexport function inputVariants({\n variant = KUMO_INPUT_DEFAULT_VARIANTS.variant,\n size = KUMO_INPUT_DEFAULT_VARIANTS.size,\n parentFocusIndicator = false,\n focusIndicator = false,\n}: KumoInputVariantsProps = {}) {\n return cn(\n // Base styles\n \"border-0 bg-kumo-control text-kumo-default ring ring-kumo-line outline-none focus:outline-none\",\n // Disabled state and placeholder styles (using vanilla CSS class for Chrome compatibility)\n \"kumo-input-placeholder disabled:text-kumo-disabled\",\n // Apply size styles from KUMO_INPUT_VARIANTS\n resolveVariant(KUMO_INPUT_VARIANTS.size, size, KUMO_INPUT_DEFAULT_VARIANTS.size).classes,\n // Apply variant styles from KUMO_INPUT_VARIANTS\n resolveVariant(KUMO_INPUT_VARIANTS.variant, variant, KUMO_INPUT_DEFAULT_VARIANTS.variant).classes,\n // Focus state handling\n parentFocusIndicator &&\n (variant === \"error\"\n ? \"focus-within:ring-kumo-danger/50 focus-within:ring-[1.5px]\"\n : \"focus-within:ring-kumo-focus/50 focus-within:ring-[1.5px]\"),\n focusIndicator &&\n (variant === \"error\"\n ? \"focus:ring-kumo-danger/50 focus:ring-[1.5px]\"\n : \"focus:ring-kumo-focus/50 focus:ring-[1.5px]\"),\n );\n}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {\n const {\n className,\n size = \"base\",\n variant: variantProp,\n label,\n labelTooltip,\n description,\n error,\n ...inputProps\n } = props;\n\n // Deprecation warning for variant=\"error\"\n if (process.env.NODE_ENV !== \"production\" && variantProp === \"error\") {\n console.warn(\n '[Kumo Input]: variant=\"error\" is deprecated. ' +\n \"Error styling is now automatically applied when the `error` prop is truthy. \" +\n \"Simply remove the variant prop and pass an error message instead.\",\n );\n }\n\n // Auto-apply error styling when error prop is truthy\n // Explicit variant prop takes precedence for backwards compatibility\n const variant = variantProp ?? (error ? \"error\" : \"default\");\n\n // Extract required from inputProps to pass to Field for label decoration\n const { required } = inputProps;\n\n // A11y enforcement: warn in dev if no accessible name provided\n if (process.env.NODE_ENV !== \"production\") {\n const hasLabel = Boolean(label);\n const hasAriaLabel = Boolean(inputProps[\"aria-label\"]);\n const hasAriaLabelledBy = Boolean(inputProps[\"aria-labelledby\"]);\n\n if (!hasLabel && !hasAriaLabel && !hasAriaLabelledBy) {\n console.warn(\n \"[Kumo Input]: Input must have an accessible name. Provide either:\\n\" +\n \" - label prop: <Input label='Email' />\\n\" +\n \" - aria-label: <Input aria-label='Email address' />\\n\" +\n \" - aria-labelledby for custom label association\",\n );\n }\n }\n\n const input = (\n <BaseInput\n ref={ref}\n className={cn(\n inputVariants({ size, variant, focusIndicator: true }),\n className,\n )}\n {...inputProps}\n />\n );\n\n // Render with Field wrapper if label is 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 {input}\n </Field>\n );\n }\n\n // Render bare input without Field wrapper\n return input;\n});\n\nInput.displayName = \"Input\";\n\n/**\n * Input component props with accessibility guidance.\n *\n * **Accessible Name Required:** Input should have one of:\n * 1. `label` prop (recommended) - enables Field wrapper with label/description/error\n * 2. `placeholder` + `aria-label` - for bare inputs with visual placeholder\n * 3. `aria-labelledby` - for custom label association\n *\n * Missing accessible names will trigger console warnings in development.\n *\n * @example\n * // Recommended: Built-in Field wrapper\n * <Input label=\"Email\" placeholder=\"you@example.com\" />\n *\n * @example\n * // Bare input with placeholder and aria-label\n * <Input placeholder=\"Search...\" aria-label=\"Search products\" />\n *\n * @example\n * // Custom label association\n * <label id=\"email-label\">Email</label>\n * <Input aria-labelledby=\"email-label\" />\n *\n * @example\n * // With description and error\n * <Input\n * label=\"Password\"\n * description=\"Must be at least 8 characters\"\n * error=\"Password is too short\"\n * />\n */\nexport type InputProps = Pick<KumoInputVariantsProps, \"size\" | \"variant\"> &\n BaseInputProps & {\n /** Label content for the input (enables Field wrapper) - can be a string or any React node */\n label?: ReactNode;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /** Helper text displayed below the input */\n description?: ReactNode;\n /** Error message or validation error object */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n };\n"],"names":["KUMO_INPUT_VARIANTS","KUMO_INPUT_DEFAULT_VARIANTS","inputVariants","variant","size","parentFocusIndicator","focusIndicator","cn","resolveVariant","Input","forwardRef","props","ref","className","variantProp","label","labelTooltip","description","error","inputProps","required","hasLabel","hasAriaLabel","hasAriaLabelledBy","input","jsx","BaseInput","Field"],"mappings":";;;;;;;AAWO,MAAMA,IAAsB;AAAA,EACjC,MAAM;AAAA,IACJ,IAAI;AAAA,MACF,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,IAEf,IAAI;AAAA,MACF,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,IAEf,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,IAEf,IAAI;AAAA,MACF,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF,SAAS;AAAA,IACP,SAAS;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,IAEf,OAAO;AAAA,MACL,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,EACf;AAEJ,GAEaC,IAA8B;AAAA,EACzC,MAAM;AAAA,EACN,SAAS;AACX;AAwDO,SAASC,EAAc;AAAA,EAC5B,SAAAC,IAAUF,EAA4B;AAAA,EACtC,MAAAG,IAAOH,EAA4B;AAAA,EACnC,sBAAAI,IAAuB;AAAA,EACvB,gBAAAC,IAAiB;AACnB,IAA4B,IAAI;AAC9B,SAAOC;AAAA;AAAA,IAEL;AAAA;AAAA,IAEA;AAAA;AAAA,IAEAC,EAAeR,EAAoB,MAAMI,GAAMH,EAA4B,IAAI,EAAE;AAAA;AAAA,IAEjFO,EAAeR,EAAoB,SAASG,GAASF,EAA4B,OAAO,EAAE;AAAA;AAAA,IAE1FI,MACGF,MAAY,UACT,+DACA;AAAA,IACNG,MACGH,MAAY,UACT,iDACA;AAAA,EAAA;AAEV;AAEO,MAAMM,IAAQC,EAAyC,CAACC,GAAOC,MAAQ;AAC5E,QAAM;AAAA,IACJ,WAAAC;AAAA,IACA,MAAAT,IAAO;AAAA,IACP,SAASU;AAAA,IACT,OAAAC;AAAA,IACA,cAAAC;AAAA,IACA,aAAAC;AAAA,IACA,OAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACDR;AAGJ,EAAI,QAAQ,IAAI,aAAa,gBAAgBG,MAAgB,WAC3D,QAAQ;AAAA,IACN;AAAA,EAAA;AAQJ,QAAMX,IAAUW,MAAgBI,IAAQ,UAAU,YAG5C,EAAE,UAAAE,MAAaD;AAGrB,MAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,UAAME,IAAW,EAAQN,GACnBO,IAAe,EAAQH,EAAW,YAAY,GAC9CI,IAAoB,EAAQJ,EAAW,iBAAiB;AAE9D,IAAI,CAACE,KAAY,CAACC,KAAgB,CAACC,KACjC,QAAQ;AAAA,MACN;AAAA;AAAA;AAAA;AAAA,IAAA;AAAA,EAMN;AAEA,QAAMC,IACJ,gBAAAC;AAAA,IAACC;AAAAA,IAAA;AAAA,MACC,KAAAd;AAAA,MACA,WAAWL;AAAA,QACTL,EAAc,EAAE,MAAAE,GAAM,SAAAD,GAAS,gBAAgB,IAAM;AAAA,QACrDU;AAAA,MAAA;AAAA,MAED,GAAGM;AAAA,IAAA;AAAA,EAAA;AAKR,SAAIJ,IAEA,gBAAAU;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,OAAAZ;AAAA,MACA,UAAAK;AAAA,MACA,cAAAJ;AAAA,MACA,aAAAC;AAAA,MACA,OACEC,IACI,OAAOA,KAAU,WACf,EAAE,SAASA,GAAO,OAAO,GAAA,IACzBA,IACF;AAAA,MAGL,UAAAM;AAAA,IAAA;AAAA,EAAA,IAMAA;AACT,CAAC;AAEDf,EAAM,cAAc;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"layer-card-kde8ys0x0civrdyj.js","sources":["../../src/components/layer-card/layer-card.tsx"],"sourcesContent":["import {\n Children,\n Fragment,\n forwardRef,\n isValidElement,\n type PropsWithChildren,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { cn } from \"../../utils/cn\";\n\nconst LAYER_CARD_SURFACE_CLASSES =\n \"overflow-hidden rounded-lg bg-kumo-base shadow-xs ring ring-kumo-line\";\nconst LAYER_CARD_LAYERED_ROOT_CLASSES =\n \"flex w-full flex-col overflow-hidden rounded-lg bg-kumo-elevated text-base ring ring-kumo-hairline\";\nconst LAYER_CARD_SECONDARY_CLASSES =\n \"-my-2 flex items-center gap-2 bg-kumo-elevated p-4 text-base font-medium text-kumo-subtle\";\nconst LAYER_CARD_PRIMARY_CLASSES =\n \"relative flex flex-col gap-2 overflow-hidden rounded-lg bg-kumo-base p-4 pr-3 text-inherit no-underline ring ring-kumo-fill\";\n\n/** LayerCard variant definitions (currently empty, reserved for future additions). */\nexport const KUMO_LAYER_CARD_VARIANTS = {\n // LayerCard currently has no variant options but structure is ready for future additions\n} as const;\n\nexport const KUMO_LAYER_CARD_DEFAULT_VARIANTS = {} as const;\n\n// Derived types from KUMO_LAYER_CARD_VARIANTS\nexport interface KumoLayerCardVariantsProps {}\n\nexport function layerCardVariants(_props: KumoLayerCardVariantsProps = {}) {\n return cn(LAYER_CARD_SURFACE_CLASSES);\n}\n\nfunction hasLayerCardSections(children: ReactNode): boolean {\n return Children.toArray(children).some((child): boolean => {\n if (!isValidElement(child)) {\n return false;\n }\n\n if (child.type === LayerCardPrimary || child.type === LayerCardSecondary) {\n return true;\n }\n\n if (child.type === Fragment) {\n const fragmentChild = child as ReactElement<{ children?: ReactNode }>;\n return hasLayerCardSections(fragmentChild.props.children);\n }\n\n return false;\n });\n}\n\n/**\n * LayerCard component props.\n *\n * @example\n * ```tsx\n * <LayerCard className=\"p-4\">\n * Get started with Kumo\n * </LayerCard>\n *\n * <LayerCard>\n * <LayerCard.Secondary>Next Steps</LayerCard.Secondary>\n * <LayerCard.Primary>Get started with Kumo</LayerCard.Primary>\n * </LayerCard>\n * ```\n */\nexport type LayerCardProps = useRender.ComponentProps<\"div\"> &\n KumoLayerCardVariantsProps;\n\nexport type LayerCardSectionProps = PropsWithChildren<{\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n}>;\n\n/**\n * Card container for both simple surfaces and layered layouts.\n *\n * Render children directly for a single-surface card, or use\n * `LayerCard.Secondary` and `LayerCard.Primary` for the layered card treatment.\n *\n * @example\n * ```tsx\n * <LayerCard className=\"rounded-lg p-4\">Card content</LayerCard>\n * ```\n *\n * @example\n * ```tsx\n * <LayerCard>\n * <LayerCard.Secondary>Getting Started</LayerCard.Secondary>\n * <LayerCard.Primary>Quick start guide</LayerCard.Primary>\n * </LayerCard>\n * ```\n */\nconst LayerCardRoot = forwardRef<HTMLDivElement, LayerCardProps>(function LayerCard(\n { children, className, render, ...props },\n ref,\n) {\n const hasStructuredLayers = hasLayerCardSections(children);\n\n const defaultProps: useRender.ElementProps<\"div\"> = {\n className: cn(\n hasStructuredLayers ? LAYER_CARD_LAYERED_ROOT_CLASSES : layerCardVariants(),\n className,\n ),\n };\n\n return useRender({\n defaultTagName: \"div\",\n render,\n ref,\n props: mergeProps<\"div\">(defaultProps, props, { children }),\n });\n});\n\nfunction LayerCardSecondary({\n children,\n className,\n}: LayerCardSectionProps) {\n return <div className={cn(LAYER_CARD_SECONDARY_CLASSES, className)}>{children}</div>;\n}\n\nfunction LayerCardPrimary({ children, className }: LayerCardSectionProps) {\n return <div className={cn(LAYER_CARD_PRIMARY_CLASSES, className)}>{children}</div>;\n}\n\nLayerCardRoot.displayName = \"LayerCard\";\nLayerCardSecondary.displayName = \"LayerCard.Secondary\";\nLayerCardPrimary.displayName = \"LayerCard.Primary\";\n\ntype LayerCardComponent = typeof LayerCardRoot & {\n Primary: typeof LayerCardPrimary;\n Secondary: typeof LayerCardSecondary;\n};\n\nconst LayerCard = Object.assign(LayerCardRoot, {\n Primary: LayerCardPrimary,\n Secondary: LayerCardSecondary,\n}) as LayerCardComponent;\n\nexport { LayerCard };\n"],"names":["LAYER_CARD_SURFACE_CLASSES","LAYER_CARD_LAYERED_ROOT_CLASSES","LAYER_CARD_SECONDARY_CLASSES","LAYER_CARD_PRIMARY_CLASSES","layerCardVariants","_props","cn","hasLayerCardSections","children","Children","child","isValidElement","LayerCardPrimary","LayerCardSecondary","Fragment","LayerCardRoot","forwardRef","className","render","props","ref","hasStructuredLayers","defaultProps","useRender","mergeProps","LayerCard"],"mappings":";;;;;AAaA,MAAMA,IACJ,yEACIC,IACJ,sGACIC,IACJ,6FACIC,IACJ;AAYK,SAASC,EAAkBC,IAAqC,IAAI;AACzE,SAAOC,EAAGN,CAA0B;AACtC;AAEA,SAASO,EAAqBC,GAA8B;AAC1D,SAAOC,EAAS,QAAQD,CAAQ,EAAE,KAAK,CAACE,MACjCC,EAAeD,CAAK,IAIrBA,EAAM,SAASE,KAAoBF,EAAM,SAASG,IAC7C,KAGLH,EAAM,SAASI,IAEVP,EADeG,EACoB,MAAM,QAAQ,IAGnD,KAZE,EAaV;AACH;AA4CA,MAAMK,IAAgBC,EAA2C,SAC/D,EAAE,UAAAR,GAAU,WAAAS,GAAW,QAAAC,GAAQ,GAAGC,EAAA,GAClCC,GACA;AACA,QAAMC,IAAsBd,EAAqBC,CAAQ,GAEnDc,IAA8C;AAAA,IAClD,WAAWhB;AAAA,MACTe,IAAsBpB,IAAkCG,EAAA;AAAA,MACxDa;AAAA,IAAA;AAAA,EACF;AAGF,SAAOM,EAAU;AAAA,IACf,gBAAgB;AAAA,IAChB,QAAAL;AAAA,IACA,KAAAE;AAAA,IACA,OAAOI,EAAkBF,GAAcH,GAAO,EAAE,UAAAX,GAAU;AAAA,EAAA,CAC3D;AACH,CAAC;AAED,SAASK,EAAmB;AAAA,EAC1B,UAAAL;AAAA,EACA,WAAAS;AACF,GAA0B;AACxB,2BAAQ,OAAA,EAAI,WAAWX,EAAGJ,GAA8Be,CAAS,GAAI,UAAAT,GAAS;AAChF;AAEA,SAASI,EAAiB,EAAE,UAAAJ,GAAU,WAAAS,KAAoC;AACxE,2BAAQ,OAAA,EAAI,WAAWX,EAAGH,GAA4Bc,CAAS,GAAI,UAAAT,GAAS;AAC9E;AAEAO,EAAc,cAAc;AAC5BF,EAAmB,cAAc;AACjCD,EAAiB,cAAc;AAO/B,MAAMa,IAAY,OAAO,OAAOV,GAAe;AAAA,EAC7C,SAASH;AAAA,EACT,WAAWC;AACb,CAAC;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"link-eak1exy1di49c56p.js","sources":["../../src/components/link/link.tsx"],"sourcesContent":["import { forwardRef, type SVGProps } from \"react\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { mergeProps } from \"@base-ui/react/merge-props\";\nimport { cn } from \"../../utils/cn\";\nimport { resolveVariant } from \"../../utils/resolve-variant\";\nimport {\n useLinkComponent,\n type LinkComponentProps,\n} from \"../../utils/link-provider\";\n\n/**\n * ExternalIcon - Visual indicator for links that open in a new tab/window.\n *\n * Use this as a child of Link to indicate external navigation:\n * ```tsx\n * <Link href=\"https://example.com\" target=\"_blank\" rel=\"noopener noreferrer\">\n * Visit Example <Link.ExternalIcon />\n * </Link>\n * ```\n */\nconst ExternalIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className=\"link-external-icon\"\n {...props}\n >\n <path d=\"M9 4H8.8C7.11984 4 6.27976 4 5.63803 4.32698C5.07354 4.6146 4.6146 5.07354 4.32698 5.63803C4 6.27976 4 7.11984 4 8.8V15.2C4 16.8802 4 17.7202 4.32698 18.362C4.6146 18.9265 5.07354 19.3854 5.63803 19.673C6.27976 20 7.11984 20 8.8 20H15.2C16.8802 20 17.7202 20 18.362 19.673C18.9265 19.3854 19.3854 18.9265 19.673 18.362C20 17.7202 20 16.8802 20 15.2V15\" />\n <path d=\"M14 4H20M20 4V10M20 4L11 13\" />\n </svg>\n);\n\nExternalIcon.displayName = \"Link.ExternalIcon\";\n\n/** Link variant definitions mapping variant names to their Tailwind classes. */\nexport const KUMO_LINK_VARIANTS = {\n variant: {\n inline: {\n classes:\n // text-kumo-link provides defensive color that won't be overridden by global `a` styles\n \"text-kumo-link underline underline-offset-[0.15em] decoration-[0.0625em] link-current transition-colors\",\n description: \"Inline text link that flows with content\",\n },\n current: {\n classes:\n \"text-current underline underline-offset-[0.15em] decoration-[0.0625em] link-current transition-colors\",\n description: \"Link that inherits color from parent text\",\n },\n plain: {\n classes:\n // text-kumo-link provides defensive color that won't be overridden by global `a` styles\n \"text-kumo-link hover:text-kumo-link/70 transition-colors\",\n description: \"Link without underline decoration\",\n },\n },\n} as const;\n\nexport const KUMO_LINK_DEFAULT_VARIANTS = {\n variant: \"inline\",\n} as const;\n\nexport type KumoLinkVariant = keyof typeof KUMO_LINK_VARIANTS.variant;\n\nexport interface KumoLinkVariantsProps {\n /**\n * Visual style of the link.\n * - `\"inline\"` — Inline text link that flows with content\n * - `\"current\"` — Link that inherits color from parent text\n * - `\"plain\"` — Link without underline decoration\n * @default \"inline\"\n */\n variant?: KumoLinkVariant;\n}\n\nexport function linkVariants({\n variant = KUMO_LINK_DEFAULT_VARIANTS.variant,\n}: KumoLinkVariantsProps = {}) {\n return cn(resolveVariant(KUMO_LINK_VARIANTS.variant, variant, KUMO_LINK_DEFAULT_VARIANTS.variant).classes);\n}\n\n/**\n * Link component props.\n *\n * @example\n * ```tsx\n * <Link href=\"/docs\">Learn more</Link>\n * <Link href=\"https://cloudflare.com\" target=\"_blank\" rel=\"noopener noreferrer\">\n * Visit Cloudflare <Link.ExternalIcon />\n * </Link>\n * <Link render={<RouterLink to=\"/dashboard\" />}>Dashboard</Link>\n * ```\n */\nexport type LinkProps = useRender.ComponentProps<\"a\"> &\n LinkComponentProps &\n KumoLinkVariantsProps;\n\n/**\n * Link component for consistent inline text links.\n *\n * Supports composition via `render` prop for framework-specific routing:\n * - Without render: renders via LinkProvider (default anchor or configured component)\n * - With render: merges props onto the provided element with proper ref/event handling\n *\n * @example Basic usage\n * ```tsx\n * <Link href=\"/docs\">Learn more</Link>\n * ```\n *\n * @example External link with icon\n * ```tsx\n * <Link href=\"https://cloudflare.com\" target=\"_blank\" rel=\"noopener noreferrer\">\n * Visit Cloudflare <Link.ExternalIcon />\n * </Link>\n * ```\n *\n * @example Composition with React Router\n * ```tsx\n * <Link render={<RouterLink to=\"/dashboard\" />} variant=\"inline\">\n * Dashboard\n * </Link>\n * ```\n */\nconst LinkBase = forwardRef<HTMLAnchorElement, LinkProps>(function Link(\n { className, variant = \"inline\", render, ...props },\n ref,\n) {\n const LinkComponent = useLinkComponent();\n\n const defaultProps: useRender.ElementProps<\"a\"> = {\n className: cn(\n linkVariants({ variant }),\n \"group/link inline-flex items-center gap-[0.1875em]\",\n ),\n };\n\n const element = useRender({\n render: render ?? <LinkComponent />,\n ref,\n props: mergeProps<\"a\">(defaultProps, props, { className }),\n });\n\n return element;\n});\n\nLinkBase.displayName = \"Link\";\n\n// Compound component with ExternalIcon subcomponent\nexport const Link = Object.assign(LinkBase, {\n ExternalIcon,\n});\n"],"names":["ExternalIcon","props","jsxs","jsx","KUMO_LINK_VARIANTS","KUMO_LINK_DEFAULT_VARIANTS","linkVariants","variant","cn","resolveVariant","LinkBase","forwardRef","className","render","ref","LinkComponent","useLinkComponent","defaultProps","useRender","mergeProps","Link"],"mappings":";;;;;;;AAoBA,MAAMA,IAAe,CAACC,MACpB,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IACZ,WAAU;AAAA,IACT,GAAGD;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAE,EAAC,QAAA,EAAK,GAAE,kWAAA,CAAkW;AAAA,MAC1W,gBAAAA,EAAC,QAAA,EAAK,GAAE,8BAAA,CAA8B;AAAA,IAAA;AAAA,EAAA;AACxC;AAGFH,EAAa,cAAc;AAGpB,MAAMI,IAAqB;AAAA,EAChC,SAAS;AAAA,IACP,QAAQ;AAAA,MACN;AAAA;AAAA,QAEE;AAAA;AAAA,MACF,aAAa;AAAA,IAAA;AAAA,IAEf,SAAS;AAAA,MACP,SACE;AAAA,MACF,aAAa;AAAA,IAAA;AAAA,IAEf,OAAO;AAAA,MACL;AAAA;AAAA,QAEE;AAAA;AAAA,MACF,aAAa;AAAA,IAAA;AAAA,EACf;AAEJ,GAEaC,IAA6B;AAAA,EACxC,SAAS;AACX;AAeO,SAASC,EAAa;AAAA,EAC3B,SAAAC,IAAUF,EAA2B;AACvC,IAA2B,IAAI;AAC7B,SAAOG,EAAGC,EAAeL,EAAmB,SAASG,GAASF,EAA2B,OAAO,EAAE,OAAO;AAC3G;AA4CA,MAAMK,IAAWC,EAAyC,SACxD,EAAE,WAAAC,GAAW,SAAAL,IAAU,UAAU,QAAAM,GAAQ,GAAGZ,EAAA,GAC5Ca,GACA;AACA,QAAMC,IAAgBC,EAAA,GAEhBC,IAA4C;AAAA,IAChD,WAAWT;AAAA,MACTF,EAAa,EAAE,SAAAC,GAAS;AAAA,MACxB;AAAA,IAAA;AAAA,EACF;AASF,SANgBW,EAAU;AAAA,IACxB,QAAQL,KAAU,gBAAAV,EAACY,GAAA,CAAA,CAAc;AAAA,IACjC,KAAAD;AAAA,IACA,OAAOK,EAAgBF,GAAchB,GAAO,EAAE,WAAAW,GAAW;AAAA,EAAA,CAC1D;AAGH,CAAC;AAEDF,EAAS,cAAc;AAGhB,MAAMU,IAAO,OAAO,OAAOV,GAAU;AAAA,EAC1C,cAAAV;AACF,CAAC;"}
@@ -1,215 +0,0 @@
1
- "use client";
2
- import { jsxs as m, jsx as a } from "react/jsx-runtime";
3
- import { CaretUpDownIcon as R, CheckIcon as B } from "@phosphor-icons/react";
4
- import { useId as W, forwardRef as p } from "react";
5
- import { c as o } from "./cn-ct4n7r74mh8y0f48.js";
6
- import { b as q } from "./button-bxv4r8h0s8kmcwvz.js";
7
- import { K as H } from "./input-bns82xraggaljrsx.js";
8
- import { S as J } from "./skeleton-line-epxenksfesr2fkcv.js";
9
- import { F as Q } from "./field-k10dm32v9sm4bpn4.js";
10
- import { u as X } from "./portal-provider-hwmkdmkpvct0cb76.js";
11
- import { a$ as Y, b0 as Z, b1 as ee, b2 as te, b3 as ae, b4 as se, b5 as le, b6 as oe, b7 as ie, b8 as ne, b9 as re, ba as ce, bb as de, S as ue } from "./vendor-base-ui-epfrwb4nfbd4btaz.js";
12
- H.size;
13
- const I = {
14
- size: "base"
15
- };
16
- function me({
17
- size: e = I.size
18
- } = {}) {
19
- return o(
20
- q({ size: e }),
21
- "justify-between font-normal",
22
- "focus:opacity-100 focus:ring-kumo-focus/50 focus-visible:ring-inset *:in-focus:opacity-100"
23
- );
24
- }
25
- const k = {
26
- xs: { iconSize: 12, className: "text-kumo-subtle" },
27
- sm: { iconSize: 14, className: "text-kumo-subtle" },
28
- base: { iconSize: 16, className: "text-kumo-subtle" },
29
- lg: { iconSize: 18, className: "text-kumo-subtle" }
30
- };
31
- function L(e) {
32
- if (e == null || typeof e != "object" || Array.isArray(e) || "$$typeof" in e || e instanceof Promise) return !1;
33
- const s = e;
34
- return "label" in s && s.label !== void 0;
35
- }
36
- function w(e) {
37
- return Array.isArray(e) ? e : Object.entries(e).map(([s, l]) => ({
38
- value: s,
39
- label: L(l) ? l.label : l
40
- }));
41
- }
42
- function be(e) {
43
- const s = w(e), l = /* @__PURE__ */ new Map();
44
- if (!Array.isArray(e))
45
- for (const [t, r] of Object.entries(e))
46
- L(r) && l.set(t, { disabled: r.disabled });
47
- return s.filter((t) => t.value !== null).map((t, r) => {
48
- const c = typeof t.value == "string" ? t.value : `option-${r}`, u = typeof t.value == "string" ? l.get(t.value) : void 0;
49
- return /* @__PURE__ */ a(z, { value: t.value, disabled: u?.disabled, children: t.label }, c);
50
- });
51
- }
52
- function d({
53
- children: e,
54
- className: s,
55
- renderValue: l,
56
- label: t,
57
- hideLabel: r,
58
- placeholder: c,
59
- loading: u,
60
- size: b = I.size,
61
- labelTooltip: F,
62
- description: f,
63
- error: i,
64
- required: G,
65
- container: j,
66
- ...n
67
- }) {
68
- const g = W(), P = X(), T = j ?? P ?? void 0, S = n, _ = S["aria-label"], E = S["aria-labelledby"], U = typeof t == "string" ? t : c;
69
- process.env.NODE_ENV !== "production" && r !== void 0 && console.warn(
70
- '[Kumo Select]: `hideLabel` is deprecated. For hidden labels, use `aria-label` instead of `label` + `hideLabel={true}`.\n Migration:\n - For visible labels: <Select label="Country" /> (hideLabel no longer needed)\n - For hidden labels: <Select aria-label="Select a country" /> (remove label and hideLabel)'
71
- );
72
- const h = t && r !== !0, y = h ? void 0 : E ?? (t ? g : void 0), V = _ ?? (y ? void 0 : U), $ = n.items ? w(n.items) : void 0, D = e || (n.items ? be(n.items) : null), K = l ? (v) => v == null ? c == null ? null : /* @__PURE__ */ a("span", { className: "text-kumo-placeholder", children: c }) : l(v) : void 0, { items: fe, ...M } = n, x = /* @__PURE__ */ m(
73
- Y,
74
- {
75
- ...M,
76
- items: $,
77
- disabled: u || n.disabled,
78
- children: [
79
- /* @__PURE__ */ m(
80
- Z,
81
- {
82
- className: o(
83
- me({ size: b }),
84
- n.disabled && "cursor-not-allowed opacity-50",
85
- s
86
- ),
87
- "aria-label": V,
88
- "aria-labelledby": y,
89
- children: [
90
- u ? /* @__PURE__ */ a(J, { className: "w-32" }) : /* @__PURE__ */ a(
91
- ee,
92
- {
93
- placeholder: c,
94
- className: "min-w-0 truncate data-[placeholder]:text-kumo-placeholder",
95
- children: K
96
- }
97
- ),
98
- /* @__PURE__ */ a(
99
- te,
100
- {
101
- className: o(
102
- "flex shrink-0 items-center",
103
- k[b].className
104
- ),
105
- children: /* @__PURE__ */ a(
106
- R,
107
- {
108
- size: k[b].iconSize,
109
- className: "fill-current"
110
- }
111
- )
112
- }
113
- )
114
- ]
115
- }
116
- ),
117
- /* @__PURE__ */ a(ae, { container: T, children: /* @__PURE__ */ a(se, { children: /* @__PURE__ */ a(
118
- le,
119
- {
120
- className: o(
121
- "flex flex-col",
122
- "max-h-[var(--available-height)] bg-kumo-base text-kumo-default",
123
- "rounded-lg shadow-lg ring ring-kumo-line",
124
- "min-w-[calc(var(--anchor-width)+3px)] py-1.5"
125
- ),
126
- children: /* @__PURE__ */ a(
127
- oe,
128
- {
129
- className: o(
130
- "min-h-0 flex-1 overflow-y-auto overscroll-none scroll-pt-2 scroll-pb-2"
131
- ),
132
- children: D
133
- }
134
- )
135
- }
136
- ) }) })
137
- ]
138
- }
139
- );
140
- if (h)
141
- return /* @__PURE__ */ a(
142
- Q,
143
- {
144
- label: t,
145
- required: G,
146
- labelTooltip: F,
147
- description: f,
148
- error: i ? typeof i == "string" ? { message: i, match: !0 } : i : void 0,
149
- children: x
150
- }
151
- );
152
- const N = i ? typeof i == "string" ? { message: i } : i : void 0;
153
- return /* @__PURE__ */ m("div", { className: "grid gap-2", children: [
154
- t && /* @__PURE__ */ a("span", { id: g, className: "sr-only", children: t }),
155
- x,
156
- N ? /* @__PURE__ */ a("span", { className: "text-sm text-kumo-danger", children: N.message }) : f && /* @__PURE__ */ a("span", { className: "text-sm leading-snug text-kumo-subtle", children: f })
157
- ] });
158
- }
159
- function z({ children: e, value: s, disabled: l, className: t }) {
160
- return /* @__PURE__ */ m(
161
- ie,
162
- {
163
- value: s,
164
- disabled: l,
165
- className: o(
166
- "group mx-1.5 flex cursor-pointer items-center justify-between gap-2 rounded px-2 py-1.5 text-base outline-none",
167
- "focus-visible:z-50 focus-visible:ring-2 focus-visible:ring-kumo-brand focus-visible:ring-inset",
168
- "data-highlighted:bg-kumo-tint",
169
- "data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
170
- t
171
- ),
172
- children: [
173
- /* @__PURE__ */ a(ne, { children: e }),
174
- /* @__PURE__ */ a(re, { children: /* @__PURE__ */ a(B, {}) })
175
- ]
176
- }
177
- );
178
- }
179
- const A = p(
180
- ({ children: e, className: s }, l) => /* @__PURE__ */ a(ce, { ref: l, className: o(s), children: e })
181
- );
182
- A.displayName = "Select.Group";
183
- const O = p(
184
- ({ children: e, className: s }, l) => /* @__PURE__ */ a(
185
- de,
186
- {
187
- ref: l,
188
- className: o(
189
- "px-3.5 py-1.5 text-sm font-semibold text-kumo-subtle",
190
- s
191
- ),
192
- children: e
193
- }
194
- )
195
- );
196
- O.displayName = "Select.GroupLabel";
197
- const C = p(
198
- ({ className: e }, s) => /* @__PURE__ */ a(
199
- ue,
200
- {
201
- ref: s,
202
- className: o("-mx-1 my-1 h-px bg-kumo-hairline", e)
203
- }
204
- )
205
- );
206
- C.displayName = "Select.Separator";
207
- d.Option = z;
208
- d.Group = A;
209
- d.GroupLabel = O;
210
- d.Separator = C;
211
- d.Option.displayName = "Select.Option";
212
- export {
213
- d as S
214
- };
215
- //# sourceMappingURL=select-du1d83plcgkr1cz8.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"select-du1d83plcgkr1cz8.js","sources":["../../src/components/select/select.tsx"],"sourcesContent":["import { Select as SelectBase } from \"@base-ui/react/select\";\nimport { CaretUpDownIcon, CheckIcon } from \"@phosphor-icons/react\";\nimport { forwardRef, useId } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { buttonVariants } from \"../button\";\nimport { KUMO_INPUT_VARIANTS, type KumoInputSize } from \"../input/input\";\nimport { SkeletonLine } from \"../loader\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\nimport {\n usePortalContainer,\n type PortalContainer,\n} from \"../../utils/portal-provider\";\n\n/** Select variant definitions. */\nexport const KUMO_SELECT_VARIANTS = {\n size: KUMO_INPUT_VARIANTS.size,\n} as const;\n\nexport const KUMO_SELECT_DEFAULT_VARIANTS = {\n size: \"base\",\n} as const;\n\n/**\n * Select component styling metadata for Figma plugin code generation\n * Extracted from select.tsx implementation (source of truth)\n */\nexport const KUMO_SELECT_STYLING = {\n trigger: {\n height: 36, // h-9\n paddingX: 12, // px-3\n borderRadius: 8, // rounded-lg\n background: \"bg-kumo-elevated\",\n text: \"text-color-surface\",\n ring: \"color-border\",\n fontSize: 16, // text-base\n fontWeight: 400, // font-normal\n },\n stateTokens: {\n focus: { ring: \"color-active\" },\n disabled: { opacity: 0.5 },\n },\n icons: {\n caret: { name: \"ph-caret-up-down\", size: 20 },\n check: { name: \"ph-check\", size: 20 },\n },\n popup: {\n background: \"bg-kumo-elevated\",\n ring: \"border-kumo-line\",\n borderRadius: 8, // rounded-lg\n padding: 6, // p-1.5\n },\n option: {\n paddingX: 8, // px-2\n paddingY: 6, // py-1.5\n borderRadius: 4, // rounded\n fontSize: 16, // text-base\n highlightBackground: \"color-surface-secondary\",\n },\n} as const;\n\n// Derived types from KUMO_SELECT_VARIANTS\nexport type KumoSelectSize = keyof typeof KUMO_SELECT_VARIANTS.size;\n\nexport interface KumoSelectVariantsProps {\n /**\n * Size of the select trigger. Matches Input component sizes.\n * - `\"xs\"` — Extra small for compact UIs (h-5 / 20px)\n * - `\"sm\"` — Small for secondary fields (h-6.5 / 26px)\n * - `\"base\"` — Default size (h-9 / 36px)\n * - `\"lg\"` — Large for prominent fields (h-10 / 40px)\n * @default \"base\"\n */\n size?: KumoSelectSize;\n}\n\nexport function selectVariants({\n size = KUMO_SELECT_DEFAULT_VARIANTS.size,\n}: KumoSelectVariantsProps = {}) {\n return cn(\n buttonVariants({ size }),\n \"justify-between font-normal\",\n \"focus:opacity-100 focus:ring-kumo-focus/50 focus-visible:ring-inset *:in-focus:opacity-100\",\n );\n}\n\nconst triggerIconStyles: Record<\n KumoInputSize,\n { iconSize: number; className: string }\n> = {\n xs: { iconSize: 12, className: \"text-kumo-subtle\" },\n sm: { iconSize: 14, className: \"text-kumo-subtle\" },\n base: { iconSize: 16, className: \"text-kumo-subtle\" },\n lg: { iconSize: 18, className: \"text-kumo-subtle\" },\n};\n\n/**\n * Shape for items that carry extra metadata (disabled state, tooltip).\n * Plain `ReactNode` values are still supported for backward compatibility.\n */\nexport interface SelectItemDescriptor {\n /** Display label for the option. */\n label: ReactNode;\n /** When `true`, the option cannot be selected. */\n disabled?: boolean;\n}\n\n/** Value type accepted by the `items` object-map prop. */\nexport type SelectItemValue = ReactNode | SelectItemDescriptor;\n\nfunction isItemDescriptor(\n value: SelectItemValue,\n): value is SelectItemDescriptor {\n if (value === null || value === undefined) return false;\n if (typeof value !== \"object\" || Array.isArray(value)) return false;\n // React elements have $$typeof — exclude them\n if (\"$$typeof\" in (value as object)) return false;\n // Promises are not descriptors\n if (value instanceof Promise) return false;\n // Must have a defined label (not just the key existing)\n const candidate = value as unknown as Record<string, unknown>;\n return \"label\" in candidate && candidate.label !== undefined;\n}\n\n/**\n * Normalizes items to array format for Base UI.\n * Object maps are converted to array format so Base UI can properly\n * handle value matching and placeholder display.\n */\nfunction normalizeItems<T>(\n items:\n | Record<string, SelectItemValue>\n | ReadonlyArray<{ label: ReactNode; value: T }>,\n): ReadonlyArray<{ label: ReactNode; value: T }> {\n if (Array.isArray(items)) {\n return items;\n }\n // Convert object map to array format\n return Object.entries(items).map(([key, entry]) => ({\n value: key as T,\n label: isItemDescriptor(entry) ? entry.label : entry,\n }));\n}\n\n/**\n * Auto-generates Select.Option elements from items prop.\n * Only used when children are not explicitly provided.\n * Filters out null values (typically used for placeholders).\n */\nfunction renderOptionsFromItems<T>(\n items:\n | Record<string, SelectItemValue>\n | ReadonlyArray<{ label: ReactNode; value: T }>,\n): ReactNode {\n const normalizedItems = normalizeItems(items);\n\n // Build a lookup for disabled metadata from object-map items.\n // Object-map keys are always strings (Record<string, ...>), so the lookup\n // uses string keys. The array form ({ label, value }[]) does not support\n // descriptors — consumers should use the children API for that case.\n const disabledLookup = new Map<string, { disabled?: boolean }>();\n if (!Array.isArray(items)) {\n for (const [key, entry] of Object.entries(items)) {\n if (isItemDescriptor(entry)) {\n disabledLookup.set(key, { disabled: entry.disabled });\n }\n }\n }\n\n // Filter out null values and render options\n return normalizedItems\n .filter((item) => item.value !== null)\n .map((item, index) => {\n const key =\n typeof item.value === \"string\" ? item.value : `option-${index}`;\n // When items is an object-map, value is always a string key from\n // Object.entries. When items is an array, disabledLookup is empty.\n const meta =\n typeof item.value === \"string\"\n ? disabledLookup.get(item.value)\n : undefined;\n\n return (\n <Option key={key} value={item.value} disabled={meta?.disabled}>\n {item.label}\n </Option>\n );\n });\n}\n\ntype SelectPropsGeneric<T, Multiple extends boolean | undefined = false> = Omit<\n SelectBase.Root.Props<T, Multiple>,\n \"items\"\n> &\n KumoSelectVariantsProps & {\n multiple?: Multiple;\n /**\n * A function that returns a `ReactNode` to format the selected value.\n * Only called when a value is selected — use `placeholder` for the empty state.\n * @example\n * ```tsx\n * <Select\n * placeholder=\"Select a user...\"\n * renderValue={(user) => user.name}\n * />\n * ```\n */\n renderValue?: (value: Multiple extends true ? T[] : T) => ReactNode;\n className?: string;\n /**\n * Data structure of items rendered in the popup.\n * Accepts a plain object map (`{ key: \"Label\" }`) or an array of `{ label, value }`.\n *\n * Object-map values can be a `ReactNode` (backward-compatible) **or** a\n * `SelectItemDescriptor` for extra metadata:\n *\n * ```tsx\n * items={{\n * apple: \"Apple\",\n * banana: { label: \"Banana\", disabled: true, disabledReason: \"Out of season\" },\n * }}\n * ```\n */\n items?:\n | Record<string, SelectItemValue>\n | ReadonlyArray<{ label: ReactNode; value: T }>;\n /**\n * Label content for the select.\n * When provided, enables the Field wrapper with a visible label.\n * For accessibility without a visible label, use `aria-label` instead.\n */\n label?: ReactNode;\n /**\n * @deprecated Use `aria-label` for hidden labels instead of `label` + `hideLabel={true}`.\n * When `label` is provided without `hideLabel`, the label is now visible by default (matching Input behavior).\n * This prop will be removed in a future version.\n */\n hideLabel?: boolean;\n placeholder?: string;\n loading?: boolean;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /** Helper text displayed below the select */\n description?: ReactNode;\n /** Error message or validation error object */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n /**\n * Container element for the portal. Use this to render the select inside\n * a Shadow DOM or custom container. Overrides `KumoPortalProvider` context.\n * @default document.body (or KumoPortalProvider container if set)\n */\n container?: PortalContainer;\n };\n\n/**\n * Select component props.\n *\n * **Accessible Name Required:** Select should have one of:\n * 1. `label` prop (recommended) - enables Field wrapper with visible label\n * 2. `aria-label` - for selects without visible label (accessibility-only)\n * 3. `aria-labelledby` - for custom label association\n *\n * @example\n * ```tsx\n * // With visible label (recommended)\n * <Select label=\"Country\" onValueChange={setValue}>\n * <Select.Option value=\"us\">United States</Select.Option>\n * <Select.Option value=\"uk\">United Kingdom</Select.Option>\n * </Select>\n *\n * // Without visible label (use aria-label for accessibility)\n * <Select aria-label=\"Select a country\" onValueChange={setValue}>\n * <Select.Option value=\"us\">United States</Select.Option>\n * </Select>\n * ```\n */\nexport interface SelectProps {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Size of the select trigger. Matches Input component sizes. */\n size?: KumoSelectSize;\n /**\n * Label content for the select.\n * When provided, enables the Field wrapper with a visible label above the select.\n * For accessibility without a visible label, use `aria-label` instead.\n */\n label?: ReactNode;\n /**\n * @deprecated Use `aria-label` for hidden labels instead of `label` + `hideLabel={true}`.\n * When `label` is provided without `hideLabel`, the label is now visible by default (matching Input behavior).\n * This prop will be removed in a future version.\n */\n hideLabel?: boolean;\n /** Placeholder text shown when no value is selected. */\n placeholder?: string;\n /** When `true`, shows a skeleton loader in place of the selected value. */\n loading?: boolean;\n /** Whether the select is disabled. */\n disabled?: boolean;\n /** Whether the select is required. When `false`, shows \"(optional)\" text. */\n required?: boolean;\n /** Tooltip content displayed next to the label via an info icon. */\n labelTooltip?: ReactNode;\n /** Currently selected value (controlled mode). */\n value?: unknown;\n /** Initial value for uncontrolled mode. */\n defaultValue?: unknown;\n /** Callback fired when the selected value changes. */\n onValueChange?: (value: unknown) => void;\n /** Enable multi-select mode. */\n multiple?: boolean;\n /** `Select.Option` elements to render in the dropdown. */\n children?: ReactNode;\n /** Helper text displayed below the select. */\n description?: ReactNode;\n /** Error message string or validation error object with `match` key. */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n}\n\n/**\n * Select.Option component props.\n */\nexport interface SelectOptionProps {\n /** The option content. */\n children: ReactNode;\n /** The value associated with this option. */\n value: unknown;\n /** When `true`, the option cannot be selected. */\n disabled?: boolean;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n}\n\n/**\n * Dropdown for selecting a value from a list of options.\n * Wraps Base UI Select with Kumo styling and optional Field integration.\n *\n * @example\n * ```tsx\n * <Select label=\"Fruit\" onValueChange={setFruit}>\n * <Select.Option value=\"apple\">Apple</Select.Option>\n * <Select.Option value=\"banana\">Banana</Select.Option>\n * </Select>\n * ```\n */\nexport function Select<T, Multiple extends boolean | undefined = false>({\n children,\n className,\n renderValue,\n label,\n hideLabel,\n placeholder,\n loading,\n size = KUMO_SELECT_DEFAULT_VARIANTS.size,\n labelTooltip,\n description,\n error,\n required,\n container: containerProp,\n ...props\n}: SelectPropsGeneric<T, Multiple> & { required?: boolean }) {\n const labelId = useId();\n const contextContainer = usePortalContainer();\n const container = containerProp ?? contextContainer ?? undefined;\n const propLookup = props as Record<string, unknown>;\n const ariaLabel = propLookup[\"aria-label\"] as string | undefined;\n const ariaLabelledby = propLookup[\"aria-labelledby\"] as string | undefined;\n // For aria-label, use string label or placeholder (ReactNode labels can't be used for aria-label)\n const fallbackLabel = typeof label === \"string\" ? label : placeholder;\n\n // Deprecation warning for hideLabel\n if (process.env.NODE_ENV !== \"production\" && hideLabel !== undefined) {\n console.warn(\n \"[Kumo Select]: `hideLabel` is deprecated. For hidden labels, use `aria-label` instead of `label` + `hideLabel={true}`.\\n\" +\n \" Migration:\\n\" +\n ' - For visible labels: <Select label=\"Country\" /> (hideLabel no longer needed)\\n' +\n ' - For hidden labels: <Select aria-label=\"Select a country\" /> (remove label and hideLabel)',\n );\n }\n\n // New behavior: label presence determines Field wrapper visibility (like Input)\n // hideLabel is only respected for backward compatibility when explicitly set to true\n const useFieldWrapper = label && hideLabel !== true;\n const triggerLabelledBy = useFieldWrapper\n ? undefined\n : (ariaLabelledby ?? (label ? labelId : undefined));\n const triggerAriaLabel =\n ariaLabel ?? (!triggerLabelledBy ? fallbackLabel : undefined);\n\n // Normalize items to array format for Base UI compatibility\n // This fixes placeholder not showing with object map items\n const normalizedItems = props.items ? normalizeItems(props.items) : undefined;\n\n // Auto-render children from items if no explicit children provided\n const renderedChildren = children\n ? children\n : props.items\n ? renderOptionsFromItems(props.items)\n : null;\n\n // Wrap renderValue to handle null values properly:\n // - When value is null, show placeholder (Base UI ignores placeholder when children fn provided)\n // - When value is non-null, call user's renderValue\n const valueChildrenFn = renderValue\n ? (value: unknown) => {\n if (value == null) {\n // If no placeholder provided, return null to show nothing (same as no renderValue)\n if (placeholder == null) {\n return null;\n }\n return <span className=\"text-kumo-placeholder\">{placeholder}</span>;\n }\n // Cast through `any` as a deliberate type boundary: Base UI passes `unknown`,\n // but our renderValue expects the generic T (or T[] for multiple)\n return renderValue(value as any);\n }\n : undefined;\n\n // Exclude Kumo-extended `items` from Base UI spread — we pass `normalizedItems` instead\n const { items: _items, ...baseProps } = props;\n\n const selectControl = (\n <SelectBase.Root\n {...baseProps}\n items={normalizedItems}\n disabled={loading || props.disabled}\n >\n <SelectBase.Trigger\n className={cn(\n selectVariants({ size }),\n props.disabled && \"cursor-not-allowed opacity-50\",\n className,\n )}\n aria-label={triggerAriaLabel}\n aria-labelledby={triggerLabelledBy}\n >\n {loading ? (\n <SkeletonLine className=\"w-32\" />\n ) : (\n <SelectBase.Value\n placeholder={placeholder}\n className=\"min-w-0 truncate data-[placeholder]:text-kumo-placeholder\"\n >\n {valueChildrenFn}\n </SelectBase.Value>\n )}\n <SelectBase.Icon\n className={cn(\n \"flex shrink-0 items-center\",\n triggerIconStyles[size].className,\n )}\n >\n <CaretUpDownIcon\n size={triggerIconStyles[size].iconSize}\n className=\"fill-current\"\n />\n </SelectBase.Icon>\n </SelectBase.Trigger>\n <SelectBase.Portal container={container}>\n <SelectBase.Positioner>\n <SelectBase.Popup\n className={cn(\n \"flex flex-col\",\n \"max-h-[var(--available-height)] bg-kumo-base text-kumo-default\",\n \"rounded-lg shadow-lg ring ring-kumo-line\",\n \"min-w-[calc(var(--anchor-width)+3px)] py-1.5\",\n )}\n >\n <SelectBase.List\n className={cn(\n \"min-h-0 flex-1 overflow-y-auto overscroll-none scroll-pt-2 scroll-pb-2\",\n )}\n >\n {renderedChildren}\n </SelectBase.List>\n </SelectBase.Popup>\n </SelectBase.Positioner>\n </SelectBase.Portal>\n </SelectBase.Root>\n );\n\n // Use Field wrapper when label is provided and not hidden\n if (useFieldWrapper) {\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 {selectControl}\n </Field>\n );\n }\n\n // Render with standalone label when label is hidden (sr-only)\n // Still show description/error for accessibility and UX\n const normalizedError = error\n ? typeof error === \"string\"\n ? { message: error, match: true as const }\n : error\n : undefined;\n\n return (\n <div className=\"grid gap-2\">\n {label && (\n <span id={labelId} className=\"sr-only\">\n {label}\n </span>\n )}\n {selectControl}\n {normalizedError ? (\n <span className=\"text-sm text-kumo-danger\">\n {normalizedError.message}\n </span>\n ) : (\n description && (\n <span className=\"text-sm leading-snug text-kumo-subtle\">\n {description}\n </span>\n )\n )}\n </div>\n );\n}\n\ntype OptionProps<T> = {\n children: ReactNode;\n value: T;\n /** When `true`, the option cannot be selected. */\n disabled?: boolean;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n};\n\nfunction Option<T>({ children, value, disabled, className }: OptionProps<T>) {\n return (\n <SelectBase.Item\n value={value}\n disabled={disabled}\n className={cn(\n \"group mx-1.5 flex cursor-pointer items-center justify-between gap-2 rounded px-2 py-1.5 text-base outline-none\",\n \"focus-visible:z-50 focus-visible:ring-2 focus-visible:ring-kumo-brand focus-visible:ring-inset\",\n \"data-highlighted:bg-kumo-tint\",\n \"data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50\",\n className,\n )}\n >\n <SelectBase.ItemText>{children}</SelectBase.ItemText>\n <SelectBase.ItemIndicator>\n <CheckIcon />\n </SelectBase.ItemIndicator>\n </SelectBase.Item>\n );\n}\n\n// --- Select.Group ---\n\ntype GroupProps = {\n children: ReactNode;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n};\n\n/**\n * Groups related options together with an accessible `role=\"group\"`.\n * Use with `Select.GroupLabel` to provide a visible heading for the group.\n *\n * @example\n * ```tsx\n * <Select.Group>\n * <Select.GroupLabel>Fruits</Select.GroupLabel>\n * <Select.Option value=\"apple\">Apple</Select.Option>\n * </Select.Group>\n * ```\n */\nconst Group = forwardRef<HTMLDivElement, GroupProps>(\n ({ children, className }, ref) => (\n <SelectBase.Group ref={ref} className={cn(className)}>\n {children}\n </SelectBase.Group>\n ),\n);\nGroup.displayName = \"Select.Group\";\n\n// --- Select.GroupLabel ---\n\ntype GroupLabelProps = {\n children: ReactNode;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n};\n\n/**\n * A visible heading for a `Select.Group`.\n * Automatically associated with its parent group for accessibility.\n *\n * @example\n * ```tsx\n * <Select.Group>\n * <Select.GroupLabel>Available</Select.GroupLabel>\n * <Select.Option value=\"a\">Option A</Select.Option>\n * </Select.Group>\n * ```\n */\nconst GroupLabel = forwardRef<HTMLDivElement, GroupLabelProps>(\n ({ children, className }, ref) => (\n <SelectBase.GroupLabel\n ref={ref}\n className={cn(\n \"px-3.5 py-1.5 text-sm font-semibold text-kumo-subtle\",\n className,\n )}\n >\n {children}\n </SelectBase.GroupLabel>\n ),\n);\nGroupLabel.displayName = \"Select.GroupLabel\";\n\n// --- Select.Separator ---\n\ntype SeparatorProps = {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n};\n\n/**\n * A visual divider between option groups.\n *\n * @example\n * ```tsx\n * <Select.Option value=\"a\">Option A</Select.Option>\n * <Select.Separator />\n * <Select.Option value=\"b\">Option B</Select.Option>\n * ```\n */\nconst Separator = forwardRef<HTMLDivElement, SeparatorProps>(\n ({ className }, ref) => (\n <SelectBase.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-kumo-hairline\", className)}\n />\n ),\n);\nSeparator.displayName = \"Select.Separator\";\n\n// --- Assign sub-components ---\n\nSelect.Option = Option;\nSelect.Group = Group;\nSelect.GroupLabel = GroupLabel;\nSelect.Separator = Separator;\n\n(Select.Option as { displayName?: string }).displayName = \"Select.Option\";\n"],"names":["KUMO_INPUT_VARIANTS","KUMO_SELECT_DEFAULT_VARIANTS","selectVariants","size","cn","buttonVariants","triggerIconStyles","isItemDescriptor","value","candidate","normalizeItems","items","key","entry","renderOptionsFromItems","normalizedItems","disabledLookup","item","index","meta","jsx","Option","Select","children","className","renderValue","label","hideLabel","placeholder","loading","labelTooltip","description","error","required","containerProp","props","labelId","useId","contextContainer","usePortalContainer","container","propLookup","ariaLabel","ariaLabelledby","fallbackLabel","useFieldWrapper","triggerLabelledBy","triggerAriaLabel","renderedChildren","valueChildrenFn","_items","baseProps","selectControl","jsxs","SelectBase.Root","SelectBase.Trigger","SkeletonLine","SelectBase.Value","SelectBase.Icon","CaretUpDownIcon","SelectBase.Portal","SelectBase.Positioner","SelectBase.Popup","SelectBase.List","Field","normalizedError","disabled","SelectBase.Item","SelectBase.ItemText","SelectBase.ItemIndicator","CheckIcon","Group","forwardRef","ref","SelectBase.Group","GroupLabel","SelectBase.GroupLabel","Separator","SelectBase.Separator"],"mappings":";;;;;;;;;;;AAgBQA,EAAoB;AAGrB,MAAMC,IAA+B;AAAA,EAC1C,MAAM;AACR;AAuDO,SAASC,GAAe;AAAA,EAC7B,MAAAC,IAAOF,EAA6B;AACtC,IAA6B,IAAI;AAC/B,SAAOG;AAAA,IACLC,EAAe,EAAE,MAAAF,GAAM;AAAA,IACvB;AAAA,IACA;AAAA,EAAA;AAEJ;AAEA,MAAMG,IAGF;AAAA,EACF,IAAI,EAAE,UAAU,IAAI,WAAW,mBAAA;AAAA,EAC/B,IAAI,EAAE,UAAU,IAAI,WAAW,mBAAA;AAAA,EAC/B,MAAM,EAAE,UAAU,IAAI,WAAW,mBAAA;AAAA,EACjC,IAAI,EAAE,UAAU,IAAI,WAAW,mBAAA;AACjC;AAgBA,SAASC,EACPC,GAC+B;AAM/B,MALIA,KAAU,QACV,OAAOA,KAAU,YAAY,MAAM,QAAQA,CAAK,KAEhD,cAAeA,KAEfA,aAAiB,QAAS,QAAO;AAErC,QAAMC,IAAYD;AAClB,SAAO,WAAWC,KAAaA,EAAU,UAAU;AACrD;AAOA,SAASC,EACPC,GAG+C;AAC/C,SAAI,MAAM,QAAQA,CAAK,IACdA,IAGF,OAAO,QAAQA,CAAK,EAAE,IAAI,CAAC,CAACC,GAAKC,CAAK,OAAO;AAAA,IAClD,OAAOD;AAAA,IACP,OAAOL,EAAiBM,CAAK,IAAIA,EAAM,QAAQA;AAAA,EAAA,EAC/C;AACJ;AAOA,SAASC,GACPH,GAGW;AACX,QAAMI,IAAkBL,EAAeC,CAAK,GAMtCK,wBAAqB,IAAA;AAC3B,MAAI,CAAC,MAAM,QAAQL,CAAK;AACtB,eAAW,CAACC,GAAKC,CAAK,KAAK,OAAO,QAAQF,CAAK;AAC7C,MAAIJ,EAAiBM,CAAK,KACxBG,EAAe,IAAIJ,GAAK,EAAE,UAAUC,EAAM,UAAU;AAM1D,SAAOE,EACJ,OAAO,CAACE,MAASA,EAAK,UAAU,IAAI,EACpC,IAAI,CAACA,GAAMC,MAAU;AACpB,UAAMN,IACJ,OAAOK,EAAK,SAAU,WAAWA,EAAK,QAAQ,UAAUC,CAAK,IAGzDC,IACJ,OAAOF,EAAK,SAAU,WAClBD,EAAe,IAAIC,EAAK,KAAK,IAC7B;AAEN,WACE,gBAAAG,EAACC,GAAA,EAAiB,OAAOJ,EAAK,OAAO,UAAUE,GAAM,UAClD,UAAAF,EAAK,MAAA,GADKL,CAEb;AAAA,EAEJ,CAAC;AACL;AA6JO,SAASU,EAAwD;AAAA,EACtE,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAA1B,IAAOF,EAA6B;AAAA,EACpC,cAAA6B;AAAA,EACA,aAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAWC;AAAA,EACX,GAAGC;AACL,GAA6D;AAC3D,QAAMC,IAAUC,EAAA,GACVC,IAAmBC,EAAA,GACnBC,IAAYN,KAAiBI,KAAoB,QACjDG,IAAaN,GACbO,IAAYD,EAAW,YAAY,GACnCE,IAAiBF,EAAW,iBAAiB,GAE7CG,IAAgB,OAAOlB,KAAU,WAAWA,IAAQE;AAG1D,EAAI,QAAQ,IAAI,aAAa,gBAAgBD,MAAc,UACzD,QAAQ;AAAA,IACN;AAAA,EAAA;AASJ,QAAMkB,IAAkBnB,KAASC,MAAc,IACzCmB,IAAoBD,IACtB,SACCF,MAAmBjB,IAAQU,IAAU,SACpCW,IACJL,MAAeI,IAAoC,SAAhBF,IAI/B7B,IAAkBoB,EAAM,QAAQzB,EAAeyB,EAAM,KAAK,IAAI,QAG9Da,IAAmBzB,MAErBY,EAAM,QACJrB,GAAuBqB,EAAM,KAAK,IAClC,OAKAc,IAAkBxB,IACpB,CAACjB,MACKA,KAAS,OAEPoB,KAAe,OACV,OAEF,gBAAAR,EAAC,QAAA,EAAK,WAAU,yBAAyB,UAAAQ,GAAY,IAIvDH,EAAYjB,CAAY,IAEjC,QAGE,EAAE,OAAO0C,IAAQ,GAAGC,MAAchB,GAElCiB,IACJ,gBAAAC;AAAA,IAACC;AAAAA,IAAA;AAAA,MACE,GAAGH;AAAA,MACJ,OAAOpC;AAAA,MACP,UAAUc,KAAWM,EAAM;AAAA,MAE3B,UAAA;AAAA,QAAA,gBAAAkB;AAAA,UAACE;AAAAA,UAAA;AAAA,YACC,WAAWnD;AAAA,cACTF,GAAe,EAAE,MAAAC,GAAM;AAAA,cACvBgC,EAAM,YAAY;AAAA,cAClBX;AAAA,YAAA;AAAA,YAEF,cAAYuB;AAAA,YACZ,mBAAiBD;AAAA,YAEhB,UAAA;AAAA,cAAAjB,IACC,gBAAAT,EAACoC,GAAA,EAAa,WAAU,OAAA,CAAO,IAE/B,gBAAApC;AAAA,gBAACqC;AAAAA,gBAAA;AAAA,kBACC,aAAA7B;AAAA,kBACA,WAAU;AAAA,kBAET,UAAAqB;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGL,gBAAA7B;AAAA,gBAACsC;AAAAA,gBAAA;AAAA,kBACC,WAAWtD;AAAA,oBACT;AAAA,oBACAE,EAAkBH,CAAI,EAAE;AAAA,kBAAA;AAAA,kBAG1B,UAAA,gBAAAiB;AAAA,oBAACuC;AAAA,oBAAA;AAAA,sBACC,MAAMrD,EAAkBH,CAAI,EAAE;AAAA,sBAC9B,WAAU;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACZ;AAAA,cAAA;AAAA,YACF;AAAA,UAAA;AAAA,QAAA;AAAA,QAEF,gBAAAiB,EAACwC,IAAA,EAAkB,WAAApB,GACjB,UAAA,gBAAApB,EAACyC,IAAA,EACC,UAAA,gBAAAzC;AAAA,UAAC0C;AAAAA,UAAA;AAAA,YACC,WAAW1D;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,YAGF,UAAA,gBAAAgB;AAAA,cAAC2C;AAAAA,cAAA;AAAA,gBACC,WAAW3D;AAAA,kBACT;AAAA,gBAAA;AAAA,gBAGD,UAAA4C;AAAA,cAAA;AAAA,YAAA;AAAA,UACH;AAAA,QAAA,GAEJ,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAKJ,MAAIH;AACF,WACE,gBAAAzB;AAAA,MAAC4C;AAAA,MAAA;AAAA,QACC,OAAAtC;AAAA,QACA,UAAAO;AAAA,QACA,cAAAH;AAAA,QACA,aAAAC;AAAA,QACA,OACEC,IACI,OAAOA,KAAU,WACf,EAAE,SAASA,GAAO,OAAO,GAAA,IACzBA,IACF;AAAA,QAGL,UAAAoB;AAAA,MAAA;AAAA,IAAA;AAOP,QAAMa,IAAkBjC,IACpB,OAAOA,KAAU,WACf,EAAE,SAASA,EAA4B,IACvCA,IACF;AAEJ,SACE,gBAAAqB,EAAC,OAAA,EAAI,WAAU,cACZ,UAAA;AAAA,IAAA3B,uBACE,QAAA,EAAK,IAAIU,GAAS,WAAU,WAC1B,UAAAV,GACH;AAAA,IAED0B;AAAA,IACAa,IACC,gBAAA7C,EAAC,QAAA,EAAK,WAAU,4BACb,UAAA6C,EAAgB,QAAA,CACnB,IAEAlC,KACE,gBAAAX,EAAC,QAAA,EAAK,WAAU,yCACb,UAAAW,EAAA,CACH;AAAA,EAAA,GAGN;AAEJ;AAWA,SAASV,EAAU,EAAE,UAAAE,GAAU,OAAAf,GAAO,UAAA0D,GAAU,WAAA1C,KAA6B;AAC3E,SACE,gBAAA6B;AAAA,IAACc;AAAAA,IAAA;AAAA,MACC,OAAA3D;AAAA,MACA,UAAA0D;AAAA,MACA,WAAW9D;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAoB;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,gBAAAJ,EAACgD,IAAA,EAAqB,UAAA7C,GAAS;AAAA,0BAC9B8C,IAAA,EACC,UAAA,gBAAAjD,EAACkD,KAAU,EAAA,CACb;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAsBA,MAAMC,IAAQC;AAAA,EACZ,CAAC,EAAE,UAAAjD,GAAU,WAAAC,KAAaiD,MACxB,gBAAArD,EAACsD,IAAA,EAAiB,KAAAD,GAAU,WAAWrE,EAAGoB,CAAS,GAChD,UAAAD,EAAA,CACH;AAEJ;AACAgD,EAAM,cAAc;AAsBpB,MAAMI,IAAaH;AAAA,EACjB,CAAC,EAAE,UAAAjD,GAAU,WAAAC,EAAA,GAAaiD,MACxB,gBAAArD;AAAA,IAACwD;AAAAA,IAAA;AAAA,MACC,KAAAH;AAAA,MACA,WAAWrE;AAAA,QACT;AAAA,QACAoB;AAAA,MAAA;AAAA,MAGD,UAAAD;AAAA,IAAA;AAAA,EAAA;AAGP;AACAoD,EAAW,cAAc;AAmBzB,MAAME,IAAYL;AAAA,EAChB,CAAC,EAAE,WAAAhD,KAAaiD,MACd,gBAAArD;AAAA,IAAC0D;AAAAA,IAAA;AAAA,MACC,KAAAL;AAAA,MACA,WAAWrE,EAAG,oCAAoCoB,CAAS;AAAA,IAAA;AAAA,EAAA;AAGjE;AACAqD,EAAU,cAAc;AAIxBvD,EAAO,SAASD;AAChBC,EAAO,QAAQiD;AACfjD,EAAO,aAAaqD;AACpBrD,EAAO,YAAYuD;AAElBvD,EAAO,OAAoC,cAAc;"}
@@ -1,92 +0,0 @@
1
- "use client";
2
- import { jsxs as d, jsx as a } from "react/jsx-runtime";
3
- import { c as s } from "./cn-ct4n7r74mh8y0f48.js";
4
- import { bd as x, be as T, bf as w, bg as N } from "./vendor-base-ui-epfrwb4nfbd4btaz.js";
5
- const V = {
6
- variant: "segmented"
7
- };
8
- function z({
9
- tabs: u,
10
- value: n,
11
- selectedValue: m,
12
- onValueChange: c,
13
- activateOnFocus: b,
14
- className: g,
15
- listClassName: f,
16
- indicatorClassName: h,
17
- variant: i = V.variant
18
- }) {
19
- const o = u ?? [];
20
- if (o.length === 0)
21
- return null;
22
- const v = o[0]?.value, l = n !== void 0, p = {
23
- value: l ? n : void 0,
24
- defaultValue: l ? void 0 : m ?? v
25
- }, t = i === "segmented", r = i === "underline";
26
- return /* @__PURE__ */ d(
27
- x,
28
- {
29
- ...p,
30
- className: s("relative isolate min-w-0 font-medium", g),
31
- onValueChange: (e) => {
32
- const k = String(e);
33
- c?.(k);
34
- },
35
- children: [
36
- t && /* @__PURE__ */ a("div", { className: "absolute inset-x-0 top-1/2 z-0 h-9 -translate-y-1/2 rounded-lg bg-kumo-recessed" }),
37
- /* @__PURE__ */ d(
38
- T,
39
- {
40
- activateOnFocus: b,
41
- className: s(
42
- "scrollbar-hide relative flex min-w-0 shrink items-stretch",
43
- t && "h-9 rounded-lg bg-kumo-recessed px-0.5 ring ring-kumo-hairline/70",
44
- r && "h-7 gap-4 border-b border-kumo-hairline pb-2",
45
- f
46
- ),
47
- children: [
48
- o.map((e) => /* @__PURE__ */ a(
49
- w,
50
- {
51
- value: e.value,
52
- render: e.render,
53
- className: s(
54
- "relative z-2 flex cursor-pointer items-center rounded bg-transparent text-base whitespace-nowrap focus:outline-none focus:ring-kumo-focus/50 focus-visible:ring-2 focus-visible:ring-kumo-brand",
55
- t && "my-0.5 rounded-md px-2.5 text-kumo-subtle hover:text-kumo-default aria-selected:text-kumo-default focus-visible:ring-inset",
56
- r && "px-2 py-2.5 text-kumo-subtle hover:bg-kumo-tint hover:text-kumo-default aria-selected:hover:bg-kumo-tint aria-selected:font-medium aria-selected:text-kumo-default",
57
- e.className
58
- ),
59
- children: e.label
60
- },
61
- e.value
62
- )),
63
- /* @__PURE__ */ a(
64
- N,
65
- {
66
- render: (e) => /* @__PURE__ */ a(
67
- "div",
68
- {
69
- ...e,
70
- className: s(
71
- "absolute z-1 left-0",
72
- "w-(--active-tab-width) translate-x-(--active-tab-left) transition-all duration-200",
73
- "data-[rendered=false]:scale-90 data-[rendered=false]:opacity-0",
74
- t && "top-(--active-tab-top) h-(--active-tab-height) rounded-md bg-kumo-base shadow-sm ring ring-kumo-line",
75
- r && "bottom-0 h-0.5 bg-kumo-brand",
76
- h
77
- )
78
- }
79
- )
80
- }
81
- )
82
- ]
83
- }
84
- )
85
- ]
86
- }
87
- );
88
- }
89
- export {
90
- z as T
91
- };
92
- //# sourceMappingURL=tabs-fdkhdhv8kvnpp8nt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tabs-fdkhdhv8kvnpp8nt.js","sources":["../../src/components/tabs/tabs.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { TabsTab } from \"@base-ui/react/tabs\";\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport { cn } from \"../../utils/cn\";\n\n/** Tabs variant definitions. */\nexport const KUMO_TABS_VARIANTS = {\n variant: [\"segmented\", \"underline\"],\n} as const;\n\nexport const KUMO_TABS_DEFAULT_VARIANTS = {\n variant: \"segmented\",\n} as const;\n\nexport const KUMO_TABS_STYLING = {\n container: {\n height: 34,\n borderRadius: 8,\n background: \"color-accent\",\n padding: 1,\n },\n tab: {\n paddingX: 10,\n verticalMargin: 1,\n fontSize: 16,\n fontWeight: 500,\n borderRadius: 8,\n activeColor: \"text-color-surface\",\n inactiveColor: \"text-color-label\",\n },\n indicator: {\n background: \"color-surface-secondary\",\n ring: \"color-color-2\",\n borderRadius: 6,\n shadow: \"shadow-sm\",\n },\n} as const;\n\n// Derived types from KUMO_TABS_VARIANTS\nexport interface KumoTabsVariantsProps {\n /**\n * Tab style.\n * - `\"segmented\"` — Pill-shaped indicator on a filled track\n * - `\"underline\"` — Underline indicator below tab text\n * @default \"segmented\"\n */\n variant?: (typeof KUMO_TABS_VARIANTS.variant)[number];\n}\n\n/** Configuration for a single tab within the Tabs component. */\nexport type TabsItem = {\n /** Unique identifier for the tab, used as the controlled value. */\n value: string;\n /** Display content for the tab trigger. */\n label: ReactNode;\n /** Additional CSS classes for this tab trigger. */\n className?: string;\n /**\n * Custom render function or element to replace the tab element (e.g. for link-based tabs).\n * When using a function, it receives the props to spread on the element and the tab's state.\n */\n render?: TabsTab.Props[\"render\"];\n};\n\n/**\n * Tabs component props.\n *\n * @example\n * ```tsx\n * <Tabs\n * tabs={[\n * { value: \"overview\", label: \"Overview\" },\n * { value: \"settings\", label: \"Settings\" },\n * ]}\n * value={activeTab}\n * onValueChange={setActiveTab}\n * />\n * ```\n */\nexport type TabsProps = KumoTabsVariantsProps & {\n /** Array of tab items to render. */\n tabs?: TabsItem[];\n /** Controlled value. When set, component becomes controlled. */\n value?: string;\n /** Default selected value for uncontrolled mode. Ignored when `value` is set. */\n selectedValue?: string;\n /** Callback fired when the active tab changes. */\n onValueChange?: (value: string) => void;\n /**\n * When `true`, tabs are activated immediately upon receiving focus via arrow keys.\n * When `false` (default), tabs receive focus but require Enter/Space to activate.\n */\n activateOnFocus?: boolean;\n /** Additional CSS classes for the root element. */\n className?: string;\n /** Additional CSS classes for the tab list element. */\n listClassName?: string;\n /** Additional CSS classes for the indicator element. */\n indicatorClassName?: string;\n};\n\n/**\n * Tab navigation component with segmented or underline style.\n * Built on Base UI Tabs with animated active indicator.\n *\n * @example\n * ```tsx\n * <Tabs\n * variant=\"segmented\"\n * tabs={[{ value: \"tab1\", label: \"Tab 1\" }, { value: \"tab2\", label: \"Tab 2\" }]}\n * value={active}\n * onValueChange={setActive}\n * />\n * ```\n */\nexport function Tabs({\n tabs,\n value,\n selectedValue,\n onValueChange,\n activateOnFocus,\n className,\n listClassName,\n indicatorClassName,\n variant = KUMO_TABS_DEFAULT_VARIANTS.variant,\n}: TabsProps) {\n const items: TabsItem[] = tabs ?? [];\n\n if (items.length === 0) {\n return null;\n }\n\n const fallbackValue = items[0]?.value;\n const isControlled = value !== undefined;\n const rootProps = {\n value: isControlled ? value : undefined,\n defaultValue: isControlled ? undefined : (selectedValue ?? fallbackValue),\n };\n\n const isSegmented = variant === \"segmented\";\n const isUnderline = variant === \"underline\";\n\n return (\n <TabsPrimitive.Root\n {...rootProps}\n className={cn(\"relative isolate min-w-0 font-medium\", className)}\n onValueChange={(nextValue) => {\n const stringValue = String(nextValue);\n onValueChange?.(stringValue);\n }}\n >\n {/* Background element for segmented variant */}\n {isSegmented && (\n <div className=\"absolute inset-x-0 top-1/2 z-0 h-9 -translate-y-1/2 rounded-lg bg-kumo-recessed\" />\n )}\n <TabsPrimitive.List\n activateOnFocus={activateOnFocus}\n className={cn(\n \"scrollbar-hide relative flex min-w-0 shrink items-stretch\",\n isSegmented && \"h-9 rounded-lg bg-kumo-recessed px-0.5 ring ring-kumo-hairline/70\",\n isUnderline && \"h-7 gap-4 border-b border-kumo-hairline pb-2\",\n listClassName,\n )}\n >\n {items.map((tab) => (\n <TabsPrimitive.Tab\n key={tab.value}\n value={tab.value}\n render={tab.render}\n className={cn(\n \"relative z-2 flex cursor-pointer items-center rounded bg-transparent text-base whitespace-nowrap focus:outline-none focus:ring-kumo-focus/50 focus-visible:ring-2 focus-visible:ring-kumo-brand\",\n isSegmented &&\n \"my-0.5 rounded-md px-2.5 text-kumo-subtle hover:text-kumo-default aria-selected:text-kumo-default focus-visible:ring-inset\",\n isUnderline &&\n \"px-2 py-2.5 text-kumo-subtle hover:bg-kumo-tint hover:text-kumo-default aria-selected:hover:bg-kumo-tint aria-selected:font-medium aria-selected:text-kumo-default\",\n tab.className,\n )}\n >\n {tab.label}\n </TabsPrimitive.Tab>\n ))}\n <TabsPrimitive.Indicator\n render={(props) => (\n <div\n {...props}\n className={cn(\n \"absolute z-1 left-0\",\n \"w-(--active-tab-width) translate-x-(--active-tab-left) transition-all duration-200\",\n \"data-[rendered=false]:scale-90 data-[rendered=false]:opacity-0\",\n isSegmented &&\n \"top-(--active-tab-top) h-(--active-tab-height) rounded-md bg-kumo-base shadow-sm ring ring-kumo-line\",\n isUnderline && \"bottom-0 h-0.5 bg-kumo-brand\",\n indicatorClassName,\n )}\n />\n )}\n />\n </TabsPrimitive.List>\n </TabsPrimitive.Root>\n );\n}\n"],"names":["KUMO_TABS_DEFAULT_VARIANTS","Tabs","tabs","value","selectedValue","onValueChange","activateOnFocus","className","listClassName","indicatorClassName","variant","items","fallbackValue","isControlled","rootProps","isSegmented","isUnderline","jsxs","TabsPrimitive.Root","cn","nextValue","stringValue","jsx","TabsPrimitive.List","tab","TabsPrimitive.Tab","TabsPrimitive.Indicator","props"],"mappings":";;;;AAUO,MAAMA,IAA6B;AAAA,EACxC,SAAS;AACX;AAuGO,SAASC,EAAK;AAAA,EACnB,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,eAAAC;AAAA,EACA,eAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,SAAAC,IAAUV,EAA2B;AACvC,GAAc;AACZ,QAAMW,IAAoBT,KAAQ,CAAA;AAElC,MAAIS,EAAM,WAAW;AACnB,WAAO;AAGT,QAAMC,IAAgBD,EAAM,CAAC,GAAG,OAC1BE,IAAeV,MAAU,QACzBW,IAAY;AAAA,IAChB,OAAOD,IAAeV,IAAQ;AAAA,IAC9B,cAAcU,IAAe,SAAaT,KAAiBQ;AAAA,EAAA,GAGvDG,IAAcL,MAAY,aAC1BM,IAAcN,MAAY;AAEhC,SACE,gBAAAO;AAAA,IAACC;AAAAA,IAAA;AAAA,MACE,GAAGJ;AAAA,MACJ,WAAWK,EAAG,wCAAwCZ,CAAS;AAAA,MAC/D,eAAe,CAACa,MAAc;AAC5B,cAAMC,IAAc,OAAOD,CAAS;AACpC,QAAAf,IAAgBgB,CAAW;AAAA,MAC7B;AAAA,MAGC,UAAA;AAAA,QAAAN,KACC,gBAAAO,EAAC,OAAA,EAAI,WAAU,kFAAA,CAAkF;AAAA,QAEnG,gBAAAL;AAAA,UAACM;AAAAA,UAAA;AAAA,YACC,iBAAAjB;AAAA,YACA,WAAWa;AAAA,cACT;AAAA,cACAJ,KAAe;AAAA,cACfC,KAAe;AAAA,cACfR;AAAA,YAAA;AAAA,YAGD,UAAA;AAAA,cAAAG,EAAM,IAAI,CAACa,MACV,gBAAAF;AAAA,gBAACG;AAAAA,gBAAA;AAAA,kBAEC,OAAOD,EAAI;AAAA,kBACX,QAAQA,EAAI;AAAA,kBACZ,WAAWL;AAAA,oBACT;AAAA,oBACAJ,KACE;AAAA,oBACFC,KACE;AAAA,oBACFQ,EAAI;AAAA,kBAAA;AAAA,kBAGL,UAAAA,EAAI;AAAA,gBAAA;AAAA,gBAZAA,EAAI;AAAA,cAAA,CAcZ;AAAA,cACD,gBAAAF;AAAA,gBAACI;AAAAA,gBAAA;AAAA,kBACC,QAAQ,CAACC,MACP,gBAAAL;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACE,GAAGK;AAAA,sBACJ,WAAWR;AAAA,wBACT;AAAA,wBACA;AAAA,wBACA;AAAA,wBACAJ,KACE;AAAA,wBACFC,KAAe;AAAA,wBACfP;AAAA,sBAAA;AAAA,oBACF;AAAA,kBAAA;AAAA,gBACF;AAAA,cAAA;AAAA,YAEJ;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAGN;"}