@cloudflare/kumo 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/ai/component-registry.json +27 -7
  3. package/ai/component-registry.md +88 -12
  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-dkq90770ad7hgzx3.js +635 -0
  11. package/dist/chunks/SankeyChart-dkq90770ad7hgzx3.js.map +1 -0
  12. package/dist/chunks/{autocomplete-1hi2rgzo10bczkfa.js → autocomplete-mhrvtq4y5n21vr0t.js} +4 -4
  13. package/dist/chunks/{autocomplete-1hi2rgzo10bczkfa.js.map → autocomplete-mhrvtq4y5n21vr0t.js.map} +1 -1
  14. package/dist/chunks/banner-ip2lm8r87hich557.js +88 -0
  15. package/dist/chunks/banner-ip2lm8r87hich557.js.map +1 -0
  16. package/dist/chunks/{breadcrumbs-davmangc0urzivbs.js → breadcrumbs-ohstavaqvycoremm.js} +2 -2
  17. package/dist/chunks/{breadcrumbs-davmangc0urzivbs.js.map → breadcrumbs-ohstavaqvycoremm.js.map} +1 -1
  18. package/dist/chunks/{button-n859eyw550yi2b9z.js → button-oevxukl0zmwoq4tb.js} +2 -2
  19. package/dist/chunks/{button-n859eyw550yi2b9z.js.map → button-oevxukl0zmwoq4tb.js.map} +1 -1
  20. package/dist/chunks/{checkbox-dfl2fr8nchh43qfc.js → checkbox-h6vkv17lnq854z2c.js} +3 -3
  21. package/dist/chunks/{checkbox-dfl2fr8nchh43qfc.js.map → checkbox-h6vkv17lnq854z2c.js.map} +1 -1
  22. package/dist/chunks/{clipboard-text-ic9k5qjkljlr9z3b.js → clipboard-text-kyy71jmx7umdh8k8.js} +4 -4
  23. package/dist/chunks/{clipboard-text-ic9k5qjkljlr9z3b.js.map → clipboard-text-kyy71jmx7umdh8k8.js.map} +1 -1
  24. package/dist/chunks/{collapsible-jvebgqfqljzokj8h.js → collapsible-ej6p2bq758sw30nk.js} +2 -2
  25. package/dist/chunks/{collapsible-jvebgqfqljzokj8h.js.map → collapsible-ej6p2bq758sw30nk.js.map} +1 -1
  26. package/dist/chunks/{combobox-f5nyw45yiwx5f69l.js → combobox-g3cudlfajecou4va.js} +4 -4
  27. package/dist/chunks/{combobox-f5nyw45yiwx5f69l.js.map → combobox-g3cudlfajecou4va.js.map} +1 -1
  28. package/dist/chunks/{command-palette-ezbzp2fpbbo97ogf.js → command-palette-eep807rf6iapoz8r.js} +3 -3
  29. package/dist/chunks/{command-palette-ezbzp2fpbbo97ogf.js.map → command-palette-eep807rf6iapoz8r.js.map} +1 -1
  30. package/dist/chunks/{dialog-n6uc2s99xwdn2pnb.js → dialog-fo3qhv9fgiadq5gp.js} +3 -3
  31. package/dist/chunks/{dialog-n6uc2s99xwdn2pnb.js.map → dialog-fo3qhv9fgiadq5gp.js.map} +1 -1
  32. package/dist/chunks/{dropdown-mftv4iv9nzhprg81.js → dropdown-cobpydatw4vlb3ov.js} +2 -2
  33. package/dist/chunks/{dropdown-mftv4iv9nzhprg81.js.map → dropdown-cobpydatw4vlb3ov.js.map} +1 -1
  34. package/dist/chunks/{empty-mmtirqntk6enx51o.js → empty-n3r7xutkb9sxjaso.js} +2 -2
  35. package/dist/chunks/{empty-mmtirqntk6enx51o.js.map → empty-n3r7xutkb9sxjaso.js.map} +1 -1
  36. package/dist/chunks/{field-mil8efu3x0s68eed.js → field-l1oapopp6kjnephi.js} +36 -30
  37. package/dist/chunks/field-l1oapopp6kjnephi.js.map +1 -0
  38. package/dist/chunks/input-area-gudamx1ruz8rxiw2.js +78 -0
  39. package/dist/chunks/input-area-gudamx1ruz8rxiw2.js.map +1 -0
  40. package/dist/chunks/{input-group-5luo0442jgsie018.js → input-group-gy08vju7eoogil8k.js} +5 -5
  41. package/dist/chunks/{input-group-5luo0442jgsie018.js.map → input-group-gy08vju7eoogil8k.js.map} +1 -1
  42. package/dist/chunks/{input-kmztt6h4mzy101ho.js → input-i3os21puacqw4r75.js} +61 -45
  43. package/dist/chunks/input-i3os21puacqw4r75.js.map +1 -0
  44. package/dist/chunks/{label-d14ibjmcbk1qmyrt.js → label-i0bj94d43irz0k1x.js} +3 -3
  45. package/dist/chunks/{label-d14ibjmcbk1qmyrt.js.map → label-i0bj94d43irz0k1x.js.map} +1 -1
  46. package/dist/chunks/{layer-card-eomdoafn3sfpih1d.js → layer-card-hyz8lfxceudt05pv.js} +2 -2
  47. package/dist/chunks/{layer-card-eomdoafn3sfpih1d.js.map → layer-card-hyz8lfxceudt05pv.js.map} +1 -1
  48. package/dist/chunks/{link-ihastr6a2dmo1so5.js → link-lkzjiitte3l29q87.js} +2 -2
  49. package/dist/chunks/{link-ihastr6a2dmo1so5.js.map → link-lkzjiitte3l29q87.js.map} +1 -1
  50. package/dist/chunks/{menubar-f6xelkurau8cl60f.js → menubar-jalggrag4utvdpey.js} +2 -2
  51. package/dist/chunks/{menubar-f6xelkurau8cl60f.js.map → menubar-jalggrag4utvdpey.js.map} +1 -1
  52. package/dist/chunks/{meter-g1ja8cwtum0frcdj.js → meter-jbxkh6gfggx1kjna.js} +2 -2
  53. package/dist/chunks/{meter-g1ja8cwtum0frcdj.js.map → meter-jbxkh6gfggx1kjna.js.map} +1 -1
  54. package/dist/chunks/{pagination-kmtbb3twehv79tm8.js → pagination-ceetno8sc1rd0wr2.js} +3 -3
  55. package/dist/chunks/{pagination-kmtbb3twehv79tm8.js.map → pagination-ceetno8sc1rd0wr2.js.map} +1 -1
  56. package/dist/chunks/{popover-f3t99000mahsnjzc.js → popover-i4opvl9g0as52fyx.js} +2 -2
  57. package/dist/chunks/{popover-f3t99000mahsnjzc.js.map → popover-i4opvl9g0as52fyx.js.map} +1 -1
  58. package/dist/chunks/{radio-me5m5ei86beum5bo.js → radio-g56o5rftpu1qpxuv.js} +6 -6
  59. package/dist/chunks/{radio-me5m5ei86beum5bo.js.map → radio-g56o5rftpu1qpxuv.js.map} +1 -1
  60. package/dist/chunks/select-g1xvti1k1hj7xe5t.js +226 -0
  61. package/dist/chunks/select-g1xvti1k1hj7xe5t.js.map +1 -0
  62. package/dist/chunks/{sensitive-input-gyf5hhgyolt07y1p.js → sensitive-input-hokm527ollnz9dqc.js} +4 -4
  63. package/dist/chunks/{sensitive-input-gyf5hhgyolt07y1p.js.map → sensitive-input-hokm527ollnz9dqc.js.map} +1 -1
  64. package/dist/chunks/{sidebar-o8y71x814ptc0xpf.js → sidebar-oan40ylmqkyui21w.js} +3 -3
  65. package/dist/chunks/{sidebar-o8y71x814ptc0xpf.js.map → sidebar-oan40ylmqkyui21w.js.map} +1 -1
  66. package/dist/chunks/{surface-ivrb4btwdoq91ytl.js → surface-ck1nt2uqfzmod4sz.js} +2 -2
  67. package/dist/chunks/{surface-ivrb4btwdoq91ytl.js.map → surface-ck1nt2uqfzmod4sz.js.map} +1 -1
  68. package/dist/chunks/{switch-c0avfhj6n85inmtb.js → switch-fv0ttj24uhocvuh8.js} +3 -3
  69. package/dist/chunks/{switch-c0avfhj6n85inmtb.js.map → switch-fv0ttj24uhocvuh8.js.map} +1 -1
  70. package/dist/chunks/{table-htqdo9dgy8c6hwuq.js → table-nsfcgpo93gfetrhh.js} +2 -2
  71. package/dist/chunks/{table-htqdo9dgy8c6hwuq.js.map → table-nsfcgpo93gfetrhh.js.map} +1 -1
  72. package/dist/chunks/tabs-g8ier5pehjpfxauf.js +152 -0
  73. package/dist/chunks/tabs-g8ier5pehjpfxauf.js.map +1 -0
  74. package/dist/chunks/{toast-evn3ce20j18hpyqt.js → toast-ofqlfmddcyka091n.js} +42 -38
  75. package/dist/chunks/{toast-evn3ce20j18hpyqt.js.map → toast-ofqlfmddcyka091n.js.map} +1 -1
  76. package/dist/chunks/{tooltip-fjxy4s4l75hjxp1x.js → tooltip-icvb67awe1zolz61.js} +7 -7
  77. package/dist/chunks/tooltip-icvb67awe1zolz61.js.map +1 -0
  78. package/dist/chunks/{vendor-base-ui-epfrwb4nfbd4btaz.js → vendor-base-ui-nbyiqqi138hcoz52.js} +30 -29
  79. package/dist/chunks/{vendor-base-ui-epfrwb4nfbd4btaz.js.map → vendor-base-ui-nbyiqqi138hcoz52.js.map} +1 -1
  80. package/dist/code.js +1 -1
  81. package/dist/components/autocomplete.js +1 -1
  82. package/dist/components/banner.js +1 -1
  83. package/dist/components/breadcrumbs.js +1 -1
  84. package/dist/components/button.js +1 -1
  85. package/dist/components/chart.js +1 -1
  86. package/dist/components/checkbox.js +1 -1
  87. package/dist/components/clipboard-text.js +1 -1
  88. package/dist/components/collapsible.js +1 -1
  89. package/dist/components/combobox.js +1 -1
  90. package/dist/components/command-palette.js +1 -1
  91. package/dist/components/dialog.js +1 -1
  92. package/dist/components/dropdown.js +1 -1
  93. package/dist/components/empty.js +1 -1
  94. package/dist/components/field.js +6 -5
  95. package/dist/components/input-group.js +1 -1
  96. package/dist/components/input.js +3 -3
  97. package/dist/components/label.js +1 -1
  98. package/dist/components/layer-card.js +1 -1
  99. package/dist/components/link.js +1 -1
  100. package/dist/components/menubar.js +1 -1
  101. package/dist/components/meter.js +1 -1
  102. package/dist/components/pagination.js +1 -1
  103. package/dist/components/popover.js +1 -1
  104. package/dist/components/radio.js +1 -1
  105. package/dist/components/select.js +1 -1
  106. package/dist/components/sensitive-input.js +1 -1
  107. package/dist/components/sidebar.js +1 -1
  108. package/dist/components/surface.js +1 -1
  109. package/dist/components/switch.js +1 -1
  110. package/dist/components/table.js +1 -1
  111. package/dist/components/tabs.js +1 -1
  112. package/dist/components/toast.js +2 -2
  113. package/dist/components/tooltip.js +1 -1
  114. package/dist/index.js +140 -139
  115. package/dist/primitives/accordion.js +1 -1
  116. package/dist/primitives/alert-dialog.js +1 -1
  117. package/dist/primitives/autocomplete.js +1 -1
  118. package/dist/primitives/avatar.js +1 -1
  119. package/dist/primitives/button.js +1 -1
  120. package/dist/primitives/checkbox-group.js +1 -1
  121. package/dist/primitives/checkbox.js +1 -1
  122. package/dist/primitives/collapsible.js +1 -1
  123. package/dist/primitives/combobox.js +1 -1
  124. package/dist/primitives/context-menu.js +1 -1
  125. package/dist/primitives/csp-provider.js +1 -1
  126. package/dist/primitives/dialog.js +1 -1
  127. package/dist/primitives/direction-provider.js +1 -1
  128. package/dist/primitives/drawer.js +1 -1
  129. package/dist/primitives/field.js +1 -1
  130. package/dist/primitives/fieldset.js +1 -1
  131. package/dist/primitives/form.js +1 -1
  132. package/dist/primitives/input.js +1 -1
  133. package/dist/primitives/menu.js +1 -1
  134. package/dist/primitives/menubar.js +1 -1
  135. package/dist/primitives/meter.js +1 -1
  136. package/dist/primitives/navigation-menu.js +1 -1
  137. package/dist/primitives/number-field.js +1 -1
  138. package/dist/primitives/otp-field.js +1 -1
  139. package/dist/primitives/popover.js +1 -1
  140. package/dist/primitives/preview-card.js +1 -1
  141. package/dist/primitives/progress.js +1 -1
  142. package/dist/primitives/radio-group.js +1 -1
  143. package/dist/primitives/radio.js +1 -1
  144. package/dist/primitives/scroll-area.js +1 -1
  145. package/dist/primitives/select.js +1 -1
  146. package/dist/primitives/separator.js +1 -1
  147. package/dist/primitives/slider.js +1 -1
  148. package/dist/primitives/switch.js +1 -1
  149. package/dist/primitives/tabs.js +1 -1
  150. package/dist/primitives/toast.js +1 -1
  151. package/dist/primitives/toggle-group.js +1 -1
  152. package/dist/primitives/toggle.js +1 -1
  153. package/dist/primitives/toolbar.js +1 -1
  154. package/dist/primitives/tooltip.js +1 -1
  155. package/dist/primitives.js +1 -1
  156. package/dist/src/components/banner/banner.d.ts +3 -3
  157. package/dist/src/components/banner/banner.d.ts.map +1 -1
  158. package/dist/src/components/chart/SankeyChart.d.ts +5 -1
  159. package/dist/src/components/chart/SankeyChart.d.ts.map +1 -1
  160. package/dist/src/components/chart/TimeseriesChart.d.ts +7 -1
  161. package/dist/src/components/chart/TimeseriesChart.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/select/select.d.ts.map +1 -1
  170. package/dist/src/components/tabs/tabs.d.ts +10 -1
  171. package/dist/src/components/tabs/tabs.d.ts.map +1 -1
  172. package/dist/src/components/toast/toast.d.ts +28 -1
  173. package/dist/src/components/toast/toast.d.ts.map +1 -1
  174. package/dist/src/components/tooltip/tooltip.d.ts.map +1 -1
  175. package/dist/src/index.d.ts +1 -1
  176. package/dist/src/index.d.ts.map +1 -1
  177. package/dist/styles/kumo-binding.css +65 -0
  178. package/dist/styles/kumo-standalone.css +1 -1
  179. package/package.json +3 -3
  180. package/dist/chunks/SankeyChart-i4vgcatj89zpgpl9.js +0 -626
  181. package/dist/chunks/SankeyChart-i4vgcatj89zpgpl9.js.map +0 -1
  182. package/dist/chunks/banner-eux4y8xaogjg64af.js +0 -80
  183. package/dist/chunks/banner-eux4y8xaogjg64af.js.map +0 -1
  184. package/dist/chunks/field-mil8efu3x0s68eed.js.map +0 -1
  185. package/dist/chunks/input-area-hl1rdb9xcrqyt8xw.js +0 -78
  186. package/dist/chunks/input-area-hl1rdb9xcrqyt8xw.js.map +0 -1
  187. package/dist/chunks/input-kmztt6h4mzy101ho.js.map +0 -1
  188. package/dist/chunks/select-brzswxbhhf1ktx9t.js +0 -215
  189. package/dist/chunks/select-brzswxbhhf1ktx9t.js.map +0 -1
  190. package/dist/chunks/tabs-fdkhdhv8kvnpp8nt.js +0 -92
  191. package/dist/chunks/tabs-fdkhdhv8kvnpp8nt.js.map +0 -1
  192. package/dist/chunks/tooltip-fjxy4s4l75hjxp1x.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"SankeyChart-i4vgcatj89zpgpl9.js","sources":["../../src/components/chart/Color.ts","../../src/components/chart/EChart.tsx","../../src/components/chart/TimeseriesChart.tsx","../../src/components/chart/Legend.tsx","../../src/components/chart/SankeyChart.tsx"],"sourcesContent":["/**\n * Categorical colors for light mode — used when assigning colors to data series\n * by index (e.g. the first series gets Blue, the second gets Violet, etc.).\n */\nenum ChartCategoricalLightColors {\n Blue = \"#4290F0\",\n Yellow = \"#F5B647\",\n Pink = \"#E8649D\",\n Purple = \"#8D58EE\",\n Teal = \"#50C3B6\",\n Orange = \"#D37536\",\n}\n\n/**\n * Categorical colors for dark mode\n */\nenum ChartCategoricalDarkColors {\n Blue = \"#4290F0\",\n Yellow = \"#EEB720\",\n Pink = \"#E8649D\",\n Purple = \"#8D58EE\",\n Teal = \"#50C3B6\",\n Orange = \"#D37536\",\n}\n\n/**\n * Semantic colors for light mode — used to convey meaning (status, severity)\n * rather than just distinguishing series. Use via `ChartPalette.semantic()`.\n */\nenum ChartSemanticLightColors {\n Attention = \"#FC574A\",\n Warning = \"#F8A054\",\n Success = \"#00A63E\",\n Neutral = \"#B9D6FF\",\n Disabled = \"#CBCBCB\",\n Skeleton = \"#DDDDDD\",\n}\n\n/**\n * Semantic colors for dark mode\n */\nenum ChartSemanticDarkColors {\n Attention = \"#FC574A\",\n Warning = \"#F8A054\",\n Success = \"#00A63E\",\n Neutral = \"#8EC5FF\",\n Disabled = \"#878787\",\n Skeleton = \"#5C5C5C\",\n}\n\nexport type ChartSemanticColorName =\n | \"Attention\"\n | \"Warning\"\n | \"Success\"\n | \"Neutral\"\n | \"Disabled\"\n | \"Skeleton\";\n\n/**\n * Sequential color palettes for light mode with the colour in position #2 of the array as the base.\n */\nconst sequentialLight = {\n blues: [\"#E1EAF4\", \"#8EBCF6\", \"#4290F0\", \"#0E58B4\", \"#03254F\"],\n};\n\n/**\n * Sequential color palettes for dark mode. These are the reverse of the light mode palettes using the same base color (position 2).\n */\nconst sequentialDark = {\n blues: [\"#03254F\", \"#0E58B4\", \"#4290F0\", \"#A6BFDD\", \"#E1EAF4\"],\n};\n\n/**\n * Ordered list of categorical colors for light mode, indexed by series position.\n * Used as the default ECharts color palette when `isDarkMode` is `false`.\n */\nexport const CHART_LIGHT_COLORS = [\n ChartCategoricalLightColors.Blue,\n ChartCategoricalLightColors.Yellow,\n ChartCategoricalLightColors.Pink,\n ChartCategoricalLightColors.Purple,\n ChartCategoricalLightColors.Teal,\n ChartCategoricalLightColors.Orange,\n];\n\n/**\n * Ordered list of categorical colors for dark mode, indexed by series position.\n * Used as the default ECharts color palette when `isDarkMode` is `true`.\n */\nexport const CHART_DARK_COLORS = [\n ChartCategoricalDarkColors.Blue,\n ChartCategoricalDarkColors.Yellow,\n ChartCategoricalDarkColors.Pink,\n ChartCategoricalDarkColors.Purple,\n ChartCategoricalDarkColors.Teal,\n ChartCategoricalDarkColors.Orange,\n];\n\n/**\n * Utilities for resolving Kumo chart colors by semantic name or series index.\n * All functions accept an `isDarkMode` flag and return the appropriate color string.\n */\nexport namespace ChartPalette {\n /**\n * Returns the hex color for a named semantic value (status, severity, etc.).\n *\n * @example\n * ```ts\n * ChartPalette.semantic(\"Attention\") // \"#FC574A\" (light)\n * ChartPalette.semantic(\"Warning\", true) // \"#F8A054\" (dark)\n * ```\n */\n export function semantic(\n name: ChartSemanticColorName,\n isDarkMode = false,\n ): string {\n return isDarkMode\n ? ChartSemanticDarkColors[name]\n : ChartSemanticLightColors[name];\n }\n\n /**\n * Returns the categorical color for a given series index.\n * Wraps around via modulo when `index` exceeds the palette length (6 colors).\n *\n * @example\n * ```ts\n * ChartPalette.categorical(0) // Blue (light)\n * ChartPalette.categorical(0, true) // Blue (dark)\n * ChartPalette.categorical(6) // wraps back to Blue\n * ```\n */\n export function categorical(index: number, isDarkMode = false): string {\n return isDarkMode\n ? CHART_DARK_COLORS[index % CHART_DARK_COLORS.length]\n : CHART_LIGHT_COLORS[index % CHART_LIGHT_COLORS.length];\n }\n\n /**\n * Returns all steps of a named sequential palette as an array.\n *\n * @example\n * ```ts\n * ChartPalette.sequential(\"blues\") // 5-step array (light)\n * ChartPalette.sequential(\"blues\", true) // 5-step array (dark)\n * ```\n */\n export function sequential(\n palette: keyof typeof sequentialLight,\n isDarkMode = false,\n ): string[] {\n return isDarkMode\n ? [...sequentialDark[palette]]\n : [...sequentialLight[palette]];\n }\n\n /**\n * Returns the hex color for chart text/labels.\n *\n * @example\n * ```ts\n * ChartPalette.text(\"primary\") // \"#6B7280\" (light)\n * ChartPalette.text(\"primary\", true) // \"#9CA3AF\" (dark)\n * ChartPalette.text(\"secondary\") // \"#9CA3AF\" (light)\n * ```\n */\n export function text(variant: \"primary\" | \"secondary\", isDarkMode = false) {\n const colors = {\n light: { primary: \"#6B7280\", secondary: \"#9CA3AF\" },\n dark: { primary: \"#9CA3AF\", secondary: \"#6B7280\" },\n };\n return isDarkMode ? colors.dark[variant] : colors.light[variant];\n }\n}\n","import type * as echarts from \"echarts/core\";\nimport type {\n EChartsOption,\n SetOptionOpts,\n TooltipComponentOption,\n} from \"echarts\";\nimport { forwardRef, useEffect, useRef } from \"react\";\nimport { cn } from \"../../utils\";\nimport { CHART_DARK_COLORS, CHART_LIGHT_COLORS } from \"./Color\";\n\n/** Parameters passed to mouse event handlers on chart elements */\ntype EChartsMouseEventParams = {\n /** The type of component that triggered the event (e.g. \"series\", \"markPoint\") */\n componentType: string;\n /** Series type (e.g. \"line\", \"bar\") — present when componentType is \"series\" */\n seriesType?: string;\n /** Zero-based index of the series in the option.series array */\n seriesIndex?: number;\n /** Name of the series */\n seriesName?: string;\n /** Name of the data item */\n name?: string;\n /** Zero-based index of the data item within its series */\n dataIndex?: number;\n /** Raw data item value */\n data?: any;\n /** Sub-type of data (e.g. \"node\", \"edge\" for graph series) */\n dataType?: string;\n /** Numeric or array value of the data item */\n value?: number | any[];\n /** Resolved color of the series or data item */\n color?: string;\n};\n\n/**\n * Tooltip options with the `formatter` property removed and replaced with\n * `dangerousHtmlFormatter` to make the security implications more explicit.\n */\nexport type SafeTooltipOption = Omit<TooltipComponentOption, \"formatter\"> & {\n /**\n * USE WITH CAUTION: Use this only for trusted HTML content.\n * When building tooltip HTML with user-provided data, always sanitize\n * the input to prevent XSS vulnerabilities. Recommended: use\n * `encodeHTML` from `echarts/format` to escape HTML special characters.\n */\n dangerousHtmlFormatter?: TooltipComponentOption[\"formatter\"];\n};\n\nexport type KumoChartOption = {\n [K in keyof EChartsOption]: K extends \"tooltip\"\n ? SafeTooltipOption | SafeTooltipOption[] | undefined\n : EChartsOption[K];\n};\n\n/**\n * ECharts event handlers that can be attached to a `Chart`.\n * Pass a subset via the `onEvents` prop; handlers are registered lazily and\n * cleaned up automatically when removed or when the chart is unmounted.\n */\nexport interface ChartEvents {\n // Mouse events — fired on chart elements (series, marks, etc.)\n click: (params: EChartsMouseEventParams) => void;\n dblclick: (params: EChartsMouseEventParams) => void;\n mousedown: (params: EChartsMouseEventParams) => void;\n mousemove: (params: EChartsMouseEventParams) => void;\n mouseup: (params: EChartsMouseEventParams) => void;\n mouseover: (params: EChartsMouseEventParams) => void;\n mouseout: (params: EChartsMouseEventParams) => void;\n /** Fired when the pointer leaves the chart canvas entirely */\n globalout: (params: any) => void;\n contextmenu: (params: any) => void;\n\n // Legend events\n /** Fired when any legend item's selected state changes */\n legendselectchanged: (params: {\n name: string;\n /** Map of series name → selected state for all legend items */\n selected: Record<string, boolean>;\n }) => void;\n legendselected: (params: any) => void;\n legendunselected: (params: any) => void;\n legendscroll: (params: any) => void;\n\n // Data zoom / timeline events\n datazoom: (params: any) => void;\n datarangeselected: (params: any) => void;\n timelinechanged: (params: any) => void;\n timelineplaychanged: (params: any) => void;\n\n // Toolbox events\n restore: (params: any) => void;\n dataviewchanged: (params: any) => void;\n magictypechanged: (params: any) => void;\n\n // Pie chart selection events\n pieselectchanged: (params: any) => void;\n pieselected: (params: any) => void;\n pieunselected: (params: any) => void;\n\n // Map / geo selection events\n mapselectchanged: (params: any) => void;\n mapselected: (params: any) => void;\n mapunselected: (params: any) => void;\n geoselectchanged: (params: any) => void;\n geoselected: (params: any) => void;\n geounselected: (params: any) => void;\n\n axisareaselected: (params: any) => void;\n\n // Brush / selection events\n brush: (params: any) => void;\n brushselected: (params: any) => void;\n /** Fired when the user finishes drawing a brush selection */\n brushend: (params: {\n areas: Array<{\n /** Coordinate range covered by the brush — interpretation depends on axis type */\n coordRange: any;\n brushType?: string;\n panelId?: string;\n range?: any;\n }>;\n }) => void;\n}\n\n/** Props for the low-level `Chart` wrapper around Apache ECharts */\nexport interface ChartProps {\n /**\n * The ECharts core instance imported by the consumer.\n * Passed in rather than imported directly so the consumer controls which\n * ECharts modules are bundled (tree-shaking).\n */\n echarts: typeof echarts;\n /** ECharts option object — passed through to `chart.setOption()` */\n options: KumoChartOption;\n /**\n * Additional options passed as the second argument to `chart.setOption()`.\n * Defaults to `{ notMerge: false, lazyUpdate: true }`.\n */\n optionUpdateBehavior?: SetOptionOpts;\n /** Additional CSS classes applied to the chart container `<div>` */\n className?: string;\n /**\n * When `true`, initialises ECharts with its built-in dark theme.\n * Changing this value after mount destroys and re-creates the chart instance.\n */\n isDarkMode?: boolean;\n /** Height of the chart container in pixels. Defaults to `350`. */\n height?: number;\n /** Subset of ECharts events to listen for. Handlers are bound/unbound reactively. */\n onEvents?: Partial<ChartEvents>;\n}\n\nconst transformTooltip = (tooltipObj: SafeTooltipOption) => {\n const { dangerousHtmlFormatter, ...restOfTooltip } = tooltipObj;\n return {\n ...restOfTooltip,\n formatter: dangerousHtmlFormatter,\n };\n};\n\nconst prepareChartOptions = (options: KumoChartOption): EChartsOption => {\n if (!options.tooltip) return options;\n\n return {\n ...options,\n tooltip: Array.isArray(options.tooltip)\n ? options.tooltip.map(transformTooltip)\n : transformTooltip(options.tooltip),\n };\n};\n\n/**\n * Chart — a low-level wrapper around [Apache ECharts](https://echarts.apache.org).\n *\n * Manages the ECharts instance lifecycle (init, option updates, event binding,\n * resize observation, and disposal). Exposes the raw `echarts.ECharts` instance\n * via `ref` for imperative access when needed.\n *\n * Prefer `TimeseriesChart` for time-series data; use this component when you\n * need full control over the ECharts option object.\n *\n * @example\n * ```tsx\n * import * as echarts from \"echarts/core\";\n * import { BarChart } from \"echarts/charts\";\n * import { GridComponent } from \"echarts/components\";\n * import { CanvasRenderer } from \"echarts/renderers\";\n *\n * echarts.use([BarChart, GridComponent, CanvasRenderer]);\n *\n * <Chart\n * echarts={echarts}\n * options={{ xAxis: { data: [\"A\", \"B\"] }, yAxis: {}, series: [{ type: \"bar\", data: [1, 2] }] }}\n * />\n * ```\n */\nexport const Chart = forwardRef<echarts.ECharts, ChartProps>(function Chart(\n {\n echarts,\n options,\n optionUpdateBehavior,\n className,\n isDarkMode,\n height = 350,\n onEvents,\n }: ChartProps,\n ref,\n) {\n // Ref to the container DOM node that ECharts renders into\n const elRef = useRef<HTMLDivElement | null>(null);\n // Ref to the active ECharts instance\n const chartRef = useRef<echarts.ECharts | null>(null);\n // Keeps the latest onEvents object without triggering re-binding on every render\n const handlersRef = useRef<Partial<ChartEvents>>({});\n // Stable wrapper functions per event name — avoids creating new closures on re-render\n const wrappersRef = useRef<Record<string, (params: any) => void>>({});\n // Tracks which event names are currently bound to the chart instance\n const boundEventsRef = useRef<Set<string>>(new Set());\n\n // Init and cleanup\n useEffect(() => {\n if (!elRef.current) return;\n\n const chart = echarts.init(\n elRef.current,\n isDarkMode\n ? \"dark\"\n : {\n color: isDarkMode ? CHART_DARK_COLORS : CHART_LIGHT_COLORS,\n },\n );\n chartRef.current = chart;\n\n if (typeof ref === \"function\") ref(chart);\n else if (ref) ref.current = chart;\n\n return () => {\n for (const event of boundEventsRef.current) {\n const wrapper = wrappersRef.current[event];\n if (wrapper) chart.off(event, wrapper);\n }\n boundEventsRef.current.clear();\n if (typeof ref === \"function\") ref(null);\n else if (ref) ref.current = null;\n chartRef.current = null;\n chart.dispose();\n };\n }, [elRef, isDarkMode]);\n\n // Update options\n useEffect(() => {\n const chart = chartRef.current;\n if (!chart) return;\n\n chart.setOption(prepareChartOptions(options), {\n notMerge: false,\n lazyUpdate: true,\n ...optionUpdateBehavior,\n });\n }, [isDarkMode, optionUpdateBehavior, options]);\n\n // Keep handlersRef in sync so wrapper closures always call the latest handler\n // without needing to re-bind listeners on every render\n useEffect(() => {\n handlersRef.current = onEvents ?? {};\n }, [onEvents]);\n\n // Reactively bind and unbind event listeners when onEvents changes.\n // Uses stable wrapper functions (wrappersRef) so the same function reference\n // is passed to both chart.on() and chart.off(), which ECharts requires.\n useEffect(() => {\n const chart = chartRef.current;\n if (!chart) return;\n\n const nextBound = new Set<string>();\n\n for (const [event, handler] of Object.entries(onEvents ?? {})) {\n if (typeof handler !== \"function\") continue;\n nextBound.add(event);\n\n if (!wrappersRef.current[event]) {\n wrappersRef.current[event] = (params: any) => {\n const current = handlersRef.current as Record<\n string,\n ((p: any) => void) | undefined\n >;\n current[event]?.(params);\n };\n }\n\n if (!boundEventsRef.current.has(event)) {\n chart.on(event, wrappersRef.current[event]);\n }\n }\n\n for (const event of boundEventsRef.current) {\n if (nextBound.has(event)) continue;\n const wrapper = wrappersRef.current[event];\n if (wrapper) {\n chart.off(event, wrapper);\n }\n }\n\n boundEventsRef.current = nextBound;\n }, [echarts, isDarkMode, onEvents]);\n\n // Resize handling\n useEffect(() => {\n const chart = chartRef.current;\n const el = elRef.current;\n if (!chart || !el) return;\n\n // Flag to skip the very first trigger\n let isInitial = true;\n\n const ro = new ResizeObserver(() => {\n if (isInitial) {\n isInitial = false;\n return; // Skip the first resize to let the animation play\n }\n chart.resize();\n });\n\n ro.observe(el);\n\n return () => ro.disconnect();\n }, []);\n\n return (\n <div\n ref={elRef}\n className={cn(\"w-full\", className)}\n style={{ height }}\n tabIndex={options.aria?.enabled ? 0 : undefined}\n role={options.aria?.enabled ? \"img\" : undefined}\n />\n );\n});\n\nChart.displayName = \"Chart\";\n","import type * as echarts from \"echarts/core\";\nimport type { LineSeriesOption, BarSeriesOption } from \"echarts/charts\";\nimport type { EChartsOption, SeriesOption } from \"echarts\";\nimport { useEffect, useMemo, useRef } from \"react\";\nimport { Chart, ChartEvents, KumoChartOption } from \"./EChart\";\n\n/** A single data series rendered on a `TimeseriesChart` */\nexport interface TimeseriesData {\n /** Display name shown in tooltips and legends */\n name: string;\n /** Array of `[timestamp_ms, value]` tuples ordered by time */\n data: [number, number][];\n /** Hex color string used for this series' line, bars, and legend dot */\n color: string;\n}\n\n/** Props for `TimeseriesChart` */\nexport interface TimeseriesChartProps {\n /**\n * The ECharts core instance imported by the consumer.\n * Passed in rather than imported directly so the consumer controls which\n * ECharts modules are bundled (tree-shaking).\n */\n echarts: typeof echarts;\n /** Visual style of each series. Defaults to `\"line\"`. */\n type?: \"line\" | \"bar\";\n /** Array of time series data to display on the chart */\n data: TimeseriesData[];\n /** Label for the x-axis (time axis) */\n xAxisName?: string;\n /** Number of ticks to display on the x-axis */\n xAxisTickCount?: number;\n /**\n * Custom formatter for x-axis tick labels.\n * Receives the raw timestamp in milliseconds and returns a display string,\n * overriding ECharts' built-in time formatting.\n */\n xAxisTickFormat?: (value: number) => string;\n /**\n * Custom formatter for y-axis tick labels.\n * Receives the raw value and returns a display string.\n * When omitted, ECharts' built-in formatter is used.\n */\n yAxisTickFormat?: (value: number) => string;\n /**\n * @deprecated Use `tooltipValueFormat` instead. This prop formats tooltip\n * values, not y-axis tick labels. It will be removed in a future major version.\n */\n yAxisTickLabelFormat?: (value: number) => string;\n /** Label for the y-axis (value axis) */\n yAxisName?: string;\n /** Number of ticks to display on the y-axis */\n yAxisTickCount?: number;\n /**\n * Custom formatter for tooltip values.\n * Receives the raw y-value and returns a display string.\n * When omitted, the raw value is shown. Takes precedence over the\n * deprecated `yAxisTickLabelFormat` prop.\n */\n tooltipValueFormat?: (value: number) => string;\n /** Indicates incomplete data periods with optional before/after timestamps in ms */\n incomplete?: { before?: number; after?: number };\n /** Height of the chart in pixels. Defaults to `350`. */\n height?: number;\n /** Callback fired when user selects a time range via brush selection */\n onTimeRangeChange?: (from: number, to: number) => void;\n /** When `true`, switches the chart to ECharts' built-in dark theme */\n isDarkMode?: boolean;\n /**\n * When `true`, renders a vertical gradient fill beneath each line series.\n * The gradient fades from the series' color at the top to transparent at the bottom.\n * Has no effect when `type` is `\"bar\"`.\n */\n gradient?: boolean;\n /**\n * When `true`, hides the chart and displays an animated sine-wave skeleton\n * that oscillates back and forth to indicate that data is being fetched.\n */\n loading?: boolean;\n /**\n * Accessible description for screen readers. When provided, it is passed to\n * ECharts' `aria.label.description` and announced when the chart receives\n * focus. Consumers are responsible for writing a meaningful description —\n * see the W3C guidance on complex images for recommendations.\n *\n * @see https://www.w3.org/WAI/tutorials/images/complex/\n * @see https://echarts.apache.org/handbook/en/best-practices/aria/\n */\n ariaDescription?: string;\n}\n\n/**\n * TimeseriesChart — a time-series line or bar chart.\n *\n * Built on `Chart` (Apache ECharts) with opinionated defaults for time-series data:\n * a time-typed x-axis, dashed lines for incomplete data periods, brush-based\n * time range selection, and automatic tooltip deduplication.\n *\n * @example\n * ```tsx\n * import * as echarts from \"echarts/core\";\n * import { LineChart } from \"echarts/charts\";\n * import { GridComponent, TooltipComponent, BrushComponent, ToolboxComponent } from \"echarts/components\";\n * import { CanvasRenderer } from \"echarts/renderers\";\n *\n * echarts.use([LineChart, GridComponent, TooltipComponent, BrushComponent, ToolboxComponent, CanvasRenderer]);\n *\n * const [range, setRange] = useState<[number, number]>();\n *\n * <TimeseriesChart\n * echarts={echarts}\n * data={[{ name: \"Requests\", data: [[Date.now(), 42]], color: \"#086FFF\" }]}\n * xAxisName=\"Time\"\n * xAxisTickFormat={(ts) => new Date(ts).toLocaleTimeString()}\n * yAxisName=\"Count\"\n * yAxisTickFormat={(value) => `${value / 1000}k`}\n * tooltipValueFormat={(value) => `${value.toFixed(2)} req/s`}\n * onTimeRangeChange={(from, to) => setRange([from, to])}\n * />\n * ```\n */\nexport function TimeseriesChart({\n echarts,\n type = \"line\",\n data,\n xAxisName,\n xAxisTickCount,\n xAxisTickFormat,\n yAxisTickFormat,\n yAxisTickLabelFormat,\n yAxisName,\n yAxisTickCount,\n tooltipValueFormat,\n onTimeRangeChange,\n height = 350,\n incomplete,\n isDarkMode,\n gradient,\n loading,\n ariaDescription,\n}: TimeseriesChartProps) {\n const chartRef = useRef<echarts.ECharts | null>(null);\n const incompleteBefore = incomplete?.before;\n const incompleteAfter = incomplete?.after;\n\n const options = useMemo(() => {\n const transformSeries: Array<LineSeriesOption | BarSeriesOption> = [];\n\n const seriesType =\n type === \"bar\"\n ? ({ type: \"bar\", stack: \"total\" } as const)\n : ({ type: \"line\", showSymbol: false } as const);\n\n for (const s of data) {\n const incompleteBeforePoints =\n incompleteBefore && type === \"line\"\n ? s.data.filter((point) => point[0] <= incompleteBefore)\n : [];\n\n const incompleteAfterPoints =\n incompleteAfter && type === \"line\"\n ? s.data.filter((point) => point[0] >= incompleteAfter)\n : [];\n\n const completePoints =\n incompleteBeforePoints.length > 0 || incompleteAfterPoints.length > 0\n ? s.data.slice(\n Math.max(0, incompleteBeforePoints.length - 1),\n Math.max(0, s.data.length - incompleteAfterPoints.length + 1),\n )\n : s.data;\n\n // Main complete data series\n const areaStyle =\n gradient && type === \"line\"\n ? {\n color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [\n { offset: 0, color: colorWithOpacity(s.color, 0.4) },\n { offset: 1, color: colorWithOpacity(s.color, 0) },\n ]),\n }\n : undefined;\n\n transformSeries.push({\n data: completePoints,\n color: s.color,\n name: s.name,\n emphasis: { focus: \"series\" },\n ...(areaStyle ? { areaStyle } : {}),\n ...seriesType,\n });\n\n // Incomplete data series with dashed lines\n const incompleteSeriesConfig = {\n color: s.color,\n name: s.name,\n type: \"line\" as const,\n lineStyle: { type: \"dashed\" as const },\n showSymbol: false,\n emphasis: { focus: \"series\" as const },\n };\n\n if (incompleteBeforePoints.length > 0) {\n transformSeries.push({\n ...incompleteSeriesConfig,\n data: incompleteBeforePoints,\n });\n }\n\n if (incompleteAfterPoints.length > 0) {\n transformSeries.push({\n ...incompleteSeriesConfig,\n data: incompleteAfterPoints,\n });\n }\n }\n\n return {\n aria: {\n enabled: true,\n ...(ariaDescription && { label: { description: ariaDescription } }),\n },\n brush: {\n xAxisIndex: \"all\" as const,\n brushType: \"lineX\" as const,\n brushMode: \"single\" as const,\n outOfBrush: {\n colorAlpha: 0.3,\n },\n brushStyle: {\n borderWidth: 1,\n color: \"rgba(120,140,180,0.3)\",\n borderColor: \"rgba(120,140,180,0.8)\",\n },\n },\n tooltip: {\n trigger: \"axis\" as const,\n appendTo: \"body\",\n axisPointer: { type: \"shadow\" as const },\n dangerousHtmlFormatter: (params) => {\n const items = Array.isArray(params) ? params : [params];\n\n // Track seen series names to avoid duplicates in tooltip\n // This is needed because incomplete data series (dashed lines) and complete data series\n // can overlap at the same timestamp, causing duplicate entries in the tooltip\n const seenNames = new Set<string>();\n const filteredParams = items.filter((param: any) => {\n if (seenNames.has(param.seriesName)) return false;\n seenNames.add(param.seriesName);\n return true;\n });\n\n const first = filteredParams[0] as {\n value?: [number, number];\n axisValue?: number;\n };\n\n const ts = first?.value?.[0] ?? first?.axisValue;\n\n const header =\n ts != null\n ? `<div style=\"font-weight:600;margin-bottom:4px;\">${echarts.format.encodeHTML(formatTimestamp(ts))}</div>`\n : \"\";\n\n const rows = filteredParams\n .map((param: any) => {\n const value = param?.value?.[1];\n const formatFn = tooltipValueFormat ?? yAxisTickLabelFormat;\n const formattedValue = formatFn\n ? echarts.format.encodeHTML(String(formatFn(value)))\n : echarts.format.encodeHTML(String(value));\n\n return `${param.marker} ${echarts.format.encodeHTML(param.seriesName)}: <strong>${formattedValue}</strong>`;\n })\n .join(\"<br/>\");\n\n return `${header}${rows}`;\n },\n },\n backgroundColor: \"transparent\",\n toolbox: { show: false },\n xAxis: {\n name: xAxisName,\n nameLocation: \"middle\" as const,\n nameGap: 30,\n type: \"time\" as const,\n splitLine: {\n show: false,\n },\n axisLine: { show: false },\n splitNumber: xAxisTickCount ?? 5,\n ...(xAxisTickFormat && {\n axisLabel: {\n formatter: (value: number) => xAxisTickFormat(value),\n },\n }),\n },\n yAxis: {\n name: yAxisName,\n nameLocation: \"middle\" as const,\n nameGap: 40,\n type: \"value\" as const,\n axisTick: { show: true },\n axisLabel: {\n margin: 15,\n ...(yAxisTickFormat && {\n formatter: (value: number) => yAxisTickFormat(value),\n }),\n },\n splitLine: {\n show: true,\n lineStyle: { type: \"dashed\" as const, width: 1 },\n },\n splitNumber: yAxisTickCount,\n },\n grid: {\n left: yAxisName ? 30 : 24,\n right: 24,\n top: 24,\n bottom: xAxisName ? 30 : 24,\n },\n series: transformSeries as SeriesOption[],\n } satisfies KumoChartOption;\n }, [\n data,\n xAxisName,\n xAxisTickCount,\n xAxisTickFormat,\n yAxisTickFormat,\n yAxisTickLabelFormat,\n yAxisName,\n yAxisTickCount,\n tooltipValueFormat,\n incompleteBefore,\n incompleteAfter,\n type,\n gradient,\n echarts,\n ariaDescription,\n ]);\n\n const events = useMemo<Partial<ChartEvents>>(() => {\n if (!onTimeRangeChange) return {};\n\n return {\n brushend: (params) => {\n const range = params.areas[0].coordRange;\n onTimeRangeChange(range[0], range[1]);\n chartRef.current?.dispatchAction({ type: \"brush\", areas: [] });\n },\n };\n }, [onTimeRangeChange]);\n\n // Activate the lineX brush cursor when a time-range callback is provided,\n // and deactivate it on cleanup so the cursor resets when the prop is removed.\n const hasTimeRangeCallback = !!onTimeRangeChange;\n useEffect(() => {\n const chart = chartRef.current;\n if (chart && hasTimeRangeCallback) {\n chart.dispatchAction({\n type: \"takeGlobalCursor\",\n key: \"brush\",\n brushOption: {\n brushType: \"lineX\" as const,\n brushMode: \"single\" as const,\n },\n });\n\n return () => {\n chart.dispatchAction({\n type: \"takeGlobalCursor\",\n key: \"brush\",\n brushOption: {\n brushType: false,\n },\n });\n };\n }\n // `loading` controls whether <Chart> is mounted. When it flips to false,\n // chartRef.current becomes available and the brush cursor must be activated.\n // Without this dep, the effect won't re-run after Chart mounts.\n }, [chartRef, hasTimeRangeCallback, loading]);\n\n return (\n <div className=\"relative w-full\" style={{ height }}>\n {loading && <ChartWaveLoader height={height} isDarkMode={isDarkMode} />}\n {!loading && (\n <Chart\n echarts={echarts}\n ref={chartRef}\n options={options as EChartsOption}\n height={height}\n isDarkMode={isDarkMode}\n onEvents={events}\n />\n )}\n </div>\n );\n}\n\n/**\n * Animated sine-wave skeleton shown while `TimeseriesChart` is in `loading` state.\n * Renders multiple staggered wave paths that sweep continuously left-to-right,\n * mimicking the motion of live time-series data being drawn.\n */\nfunction ChartWaveLoader({\n height,\n isDarkMode,\n}: {\n height: number;\n isDarkMode?: boolean;\n}) {\n const mid = height / 2;\n const amp = Math.min(height * 0.12, 28);\n const period = 400;\n const steps = 120;\n\n const points: string[] = [];\n for (let i = 0; i <= steps; i++) {\n const x = -period + (i / steps) * period * 3;\n const y = mid + Math.sin((i / steps) * 2 * Math.PI * 3) * amp;\n points.push(`${i === 0 ? \"M\" : \"L\"}${x.toFixed(2)},${y.toFixed(2)}`);\n }\n const d = points.join(\" \");\n\n const strokeColor = isDarkMode ? \"rgba(255,255,255,0.5)\" : \"rgba(0,0,0,0.2)\";\n\n return (\n <div\n aria-hidden=\"true\"\n className=\"absolute inset-0 overflow-hidden\"\n style={{ height }}\n >\n <svg\n width=\"100%\"\n height={height}\n viewBox={`0 0 ${period} ${height}`}\n preserveAspectRatio=\"none\"\n className=\"w-full animate-pulse\"\n >\n <path\n d={d}\n fill=\"none\"\n stroke={strokeColor}\n strokeWidth=\"2\"\n style={{\n animation: `kumo-chart-wave 2.4s linear infinite`,\n transformOrigin: \"0 0\",\n }}\n />\n </svg>\n </div>\n );\n}\n\n/**\n * Returns an `rgba(r, g, b, alpha)` string for any hex or rgb(a) color input,\n * replacing whatever opacity was already present with the given `alpha` (0–1).\n *\n * Handles:\n * - 6-digit hex: `#RRGGBB`\n * - 8-digit hex: `#RRGGBBAA` ← strips existing alpha\n * - 3-digit hex: `#RGB`\n * - `rgb(r, g, b)`\n * - `rgba(r, g, b, a)` ← replaces existing alpha\n */\nfunction colorWithOpacity(color: string, alpha: number): string {\n const a = Math.max(0, Math.min(1, alpha));\n\n // rgb / rgba\n const rgbMatch = color.match(\n /rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i,\n );\n if (rgbMatch) {\n return `rgba(${rgbMatch[1]}, ${rgbMatch[2]}, ${rgbMatch[3]}, ${a})`;\n }\n\n // hex — strip leading #\n let hex = color.replace(/^#/, \"\");\n\n // expand 3-digit → 6-digit\n if (hex.length === 3) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n }\n\n // strip 8-digit alpha → keep only 6\n if (hex.length === 8) {\n hex = hex.slice(0, 6);\n }\n\n const r = parseInt(hex.slice(0, 2), 16);\n const g = parseInt(hex.slice(2, 4), 16);\n const b = parseInt(hex.slice(4, 6), 16);\n\n return `rgba(${r}, ${g}, ${b}, ${a})`;\n}\n\n/** Zero-pads a number to two digits (e.g. `5` → `\"05\"`) */\nfunction pad(n: number) {\n return n.toString().padStart(2, \"0\");\n}\n\n/**\n * Formats a timestamp as `\"YYYY-MM-DD HH:mm:ss\"` for use in chart tooltips.\n * Accepts a Unix timestamp in milliseconds, an ISO date string, or a `Date` object.\n */\nfunction formatTimestamp(ts: number | string | Date): string {\n const d = new Date(ts);\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;\n}\n","import { cn } from \"../../utils\";\n\n/** Shared props for both legend item variants */\ninterface LegendItemProps {\n /** Series name shown as a label */\n name: string;\n /** Hex color string for the series indicator dot */\n color: string;\n /** Formatted value string to display */\n value: string;\n /** Optional unit label shown after the value (e.g. `\"ms\"`, `\"%\"`) */\n unit?: string;\n /** When `true`, renders the item at 50% opacity to indicate a deselected state */\n inactive?: boolean;\n}\n\n/**\n * Large legend item — stacked layout with a colored dot + series name on top\n * and a large value with an optional small unit below. Use for prominent\n * single-metric displays such as dashboard cards.\n */\nfunction LargeItem({ color, value, name, unit, inactive }: LegendItemProps) {\n return (\n <div className=\"inline-flex flex-col gap-2 min-w-42 py-2\">\n <div className=\"flex items-center gap-2\">\n <span\n className={cn(\"size-2 rounded-full inline-block\", {\n \"opacity-50\": inactive,\n })}\n style={{ backgroundColor: color }}\n />\n <span className={cn(\"text-xs\", { \"opacity-50\": inactive })}>\n {name}\n </span>\n </div>\n <div className=\"flex items-baseline gap-0.5\">\n <span\n className={cn(\"text-lg font-medium leading-none\", {\n \"opacity-50\": inactive,\n })}\n >\n {value}\n </span>\n {unit && (\n <span\n className={cn(\"text-xs text-kumo-subtle leading-none\", {\n \"opacity-50\": inactive,\n })}\n >\n {unit}\n </span>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Small legend item — inline layout with a colored dot, series name, and value\n * on a single row. Use for compact legends below or beside a chart.\n */\nfunction SmallItem({ color, value, name, inactive }: LegendItemProps) {\n return (\n <div className=\"inline-flex items-center gap-2\">\n <span\n className={cn(\"size-2 rounded-full inline-block\", {\n \"opacity-50\": inactive,\n })}\n style={{ backgroundColor: color }}\n />\n <span className={cn(\"text-xs\", { \"opacity-50\": inactive })}>{name}</span>\n <span className={cn(\"text-xs font-medium\", { \"opacity-50\": inactive })}>\n {value}\n </span>\n </div>\n );\n}\n\n/**\n * ChartLegend — pre-built legend item components for use alongside a chart.\n *\n * - `ChartLegend.SmallItem` — compact inline layout; suited for multi-series legends\n * - `ChartLegend.LargeItem` — stacked layout with a large value; suited for single-metric cards\n *\n * @example\n * ```tsx\n * <ChartLegend.SmallItem name=\"Requests\" color=\"#086FFF\" value=\"1,234\" />\n * <ChartLegend.LargeItem name=\"Latency\" color=\"#CF7EE9\" value=\"42\" unit=\"ms\" inactive />\n * ```\n */\nexport const ChartLegend = {\n SmallItem,\n LargeItem,\n};\n","import type * as echarts from \"echarts/core\";\nimport type { EChartsOption } from \"echarts\";\nimport { useMemo, useCallback } from \"react\";\nimport { Chart, type ChartEvents } from \"./EChart\";\nimport { ChartPalette } from \"./Color\";\n\nexport interface SankeyNodeData {\n id?: string;\n name: string;\n color?: string;\n /** Optional value/count to display above the node label */\n value?: number;\n /** Additional data to show in tooltip (e.g., { Apps: 166, Sessions: 122600 }) */\n tooltipData?: Record<string, number | string>;\n isDrillable?: boolean;\n childCount?: number;\n}\n\nexport interface SankeyLinkData {\n id?: string;\n source: number;\n target: number;\n value: number;\n isDrillable?: boolean;\n}\n\nexport type DrillTarget =\n | { type: \"node\"; nodeId: string }\n | { type: \"link\"; sourceId: string; targetId: string };\n\nexport interface DrillSelection {\n id: string;\n type: \"node\" | \"link\";\n label: string;\n depth: number;\n}\n\nexport interface DrillDownContext {\n selections: DrillSelection[];\n isMultiSelect: boolean;\n}\n\nexport interface SankeyData {\n nodes: SankeyNodeData[];\n links: SankeyLinkData[];\n}\n\n/** Parameters passed to the tooltip formatter */\nexport interface SankeyTooltipParams {\n type: \"node\" | \"link\";\n name: string;\n node?: SankeyNodeData;\n link?: { source: string; target: string; value: number };\n color?: string;\n}\n\nexport interface SankeyChartProps {\n /**\n * The ECharts core instance imported by the consumer.\n * Passed in rather than imported directly so the consumer controls which\n * ECharts modules are bundled (tree-shaking).\n */\n echarts: typeof echarts;\n /** Array of nodes in the Sankey diagram */\n nodes: SankeyNodeData[];\n /** Array of links connecting nodes by index */\n links: SankeyLinkData[];\n /** Height of the chart in pixels */\n height?: number;\n /** Show node values above labels (default: true if any node has a value) */\n showNodeValues?: boolean;\n /** Format function for node values (default: toLocaleString) */\n formatValue?: (value: number) => string;\n /** Custom tooltip formatter. Return HTML string or empty string to hide tooltip. */\n tooltipFormatter?: (params: SankeyTooltipParams) => string;\n nodeWidth?: number;\n nodePadding?: number;\n showTooltip?: boolean;\n defaultNodeColor?: string;\n /** Link fill style: 'gradient' blends source to target colors, 'gray' uses flat gray */\n linkColor?: \"gradient\" | \"gray\";\n linkOpacity?: number;\n className?: string;\n isDarkMode?: boolean;\n onNodeClick?: (node: SankeyNodeData) => void;\n onLinkClick?: (link: SankeyLinkData) => void;\n}\n\nconst defaultFormatValue = (value: number) => value.toLocaleString();\n\n/** Type guard for ECharts tooltip params */\ninterface TooltipParams {\n dataType?: string;\n name?: string;\n data?: { source?: string; target?: string; value?: number };\n value?: number | number[];\n color?: string;\n}\n\nfunction isTooltipParams(params: unknown): params is TooltipParams {\n return typeof params === \"object\" && params !== null;\n}\n\n/** Escape HTML special characters to prevent XSS in tooltips */\nconst escapeHtml = (str: string): string =>\n str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n\n/**\n * Escape ECharts rich text metacharacters to prevent formatting issues.\n * Rich text syntax uses {styleName|text}, so | and } must be escaped.\n */\nconst escapeRichText = (str: string): string =>\n str.replace(/[{}|]/g, (char) => `\\\\${char}`);\n\n/**\n * Sanitize a CSS color value to prevent injection attacks.\n * Only allows valid hex colors, rgb/rgba, hsl/hsla, and named colors.\n */\nconst sanitizeColor = (color: string): string => {\n const fallback = \"#666\";\n if (!color || typeof color !== \"string\") return fallback;\n\n // Hex colors: #RGB, #RRGGBB, #RRGGBBAA\n if (/^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(color)) {\n return color;\n }\n\n // rgb/rgba: rgb(0,0,0) or rgba(0,0,0,0.5)\n if (\n /^rgba?\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*(?:,\\s*[\\d.]+\\s*)?\\)$/i.test(\n color,\n )\n ) {\n return color;\n }\n\n // hsl/hsla: hsl(0,0%,0%) or hsla(0,0%,0%,0.5)\n if (\n /^hsla?\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}%\\s*,\\s*\\d{1,3}%\\s*(?:,\\s*[\\d.]+\\s*)?\\)$/i.test(\n color,\n )\n ) {\n return color;\n }\n\n // Named colors (basic set) - only alphanumeric, no special chars\n if (/^[a-z]{3,20}$/i.test(color)) {\n return color;\n }\n\n return fallback;\n};\n\nexport function SankeyChart({\n echarts,\n nodes,\n links,\n height = 400,\n nodeWidth = 8,\n nodePadding = 10,\n showTooltip: enableTooltip = true,\n showNodeValues,\n formatValue = defaultFormatValue,\n tooltipFormatter,\n defaultNodeColor,\n linkColor = \"gradient\",\n linkOpacity = 0.5,\n className,\n isDarkMode,\n onNodeClick,\n onLinkClick,\n}: SankeyChartProps) {\n const hasNodeValues = nodes.some((n) => n.value !== undefined);\n const shouldShowValues = showNodeValues ?? hasNodeValues;\n const options = useMemo<EChartsOption>(() => {\n const labelColor = ChartPalette.text(\"primary\", isDarkMode);\n const secondaryColor = ChartPalette.text(\"secondary\", isDarkMode);\n // Build a map of node name to original node data for tooltip access\n const nodeDataMap = new Map(nodes.map((n) => [n.name, n]));\n\n const echartsNodes = nodes.map((node, index) => ({\n name: node.name,\n value: node.value,\n itemStyle: {\n color:\n node.color ??\n defaultNodeColor ??\n ChartPalette.categorical(index, isDarkMode),\n },\n }));\n\n const echartsLinks = links.map((link) => ({\n source: nodes[link.source]?.name ?? \"\",\n target: nodes[link.target]?.name ?? \"\",\n value: link.value,\n }));\n\n return {\n animation: true,\n animationDuration: 500,\n animationDurationUpdate: 300,\n animationEasingUpdate: \"cubicInOut\",\n tooltip: enableTooltip\n ? {\n trigger: \"item\",\n triggerOn: \"mousemove\",\n dangerousHtmlFormatter: (params: unknown) => {\n if (!isTooltipParams(params)) return \"\";\n\n if (params.dataType === \"node\" && params.name) {\n const nodeData = nodeDataMap.get(params.name);\n const color = sanitizeColor(\n nodeData?.color ?? params.color ?? \"#666\",\n );\n\n // Use custom formatter if provided\n if (tooltipFormatter) {\n return tooltipFormatter({\n type: \"node\",\n name: params.name,\n node: nodeData,\n color,\n });\n }\n\n // Default node tooltip\n const safeName = escapeHtml(params.name);\n return `<div style=\"display:flex;align-items:center;gap:6px;\"><span style=\"display:inline-block;width:10px;height:10px;border-radius:50%;background:${color}\"></span><strong>${safeName}</strong></div>`;\n }\n\n if (params.dataType === \"edge\" && params.data) {\n const { source, target, value } = params.data;\n\n // Use custom formatter if provided\n if (tooltipFormatter) {\n return tooltipFormatter({\n type: \"link\",\n name: `${source} → ${target}`,\n link: {\n source: source ?? \"\",\n target: target ?? \"\",\n value: value ?? 0,\n },\n });\n }\n\n // Get colors for source and target nodes\n const sourceNode = nodeDataMap.get(source ?? \"\");\n const targetNode = nodeDataMap.get(target ?? \"\");\n const sourceColor = sanitizeColor(sourceNode?.color ?? \"#666\");\n const targetColor = sanitizeColor(targetNode?.color ?? \"#666\");\n\n // Default link tooltip with colored dots\n const safeSource = escapeHtml(source ?? \"\");\n const safeTarget = escapeHtml(target ?? \"\");\n return `<div style=\"display:flex;align-items:center;gap:6px;margin-bottom:4px;\">\n <span style=\"display:inline-block;width:10px;height:10px;border-radius:50%;background:${sourceColor}\"></span>\n <strong>${safeSource}</strong>\n <span style=\"color:${secondaryColor}\">→</span>\n <span style=\"display:inline-block;width:10px;height:10px;border-radius:50%;background:${targetColor}\"></span>\n <strong>${safeTarget}</strong>\n </div>\n <strong>${value !== undefined ? escapeHtml(formatValue(value)) : \"\"}</strong>`;\n }\n\n return \"\";\n },\n }\n : undefined,\n series: [\n {\n type: \"sankey\",\n data: echartsNodes,\n links: echartsLinks,\n draggable: false,\n emphasis: {\n focus: \"adjacency\",\n },\n nodeWidth,\n nodeGap: nodePadding,\n lineStyle: {\n color: linkColor === \"gradient\" ? \"source\" : \"#d1d5db\",\n opacity: linkColor === \"gradient\" ? linkOpacity : 0.4,\n curveness: 0.5,\n },\n label: {\n show: true,\n color: labelColor,\n fontSize: 12,\n formatter: shouldShowValues\n ? (params: { name?: string }) => {\n const name = params.name ?? \"\";\n const nodeData = nodeDataMap.get(name);\n const safeName = escapeRichText(name);\n if (nodeData?.value !== undefined) {\n return `{value|${escapeRichText(formatValue(nodeData.value))}}\\n{name|${safeName}}`;\n }\n return safeName;\n }\n : undefined,\n rich: shouldShowValues\n ? {\n value: {\n fontSize: 11,\n color: labelColor,\n lineHeight: 16,\n },\n name: {\n fontSize: 12,\n color: labelColor,\n fontWeight: 700,\n },\n }\n : undefined,\n },\n },\n ],\n };\n }, [\n nodes,\n links,\n enableTooltip,\n nodeWidth,\n nodePadding,\n defaultNodeColor,\n isDarkMode,\n linkColor,\n linkOpacity,\n shouldShowValues,\n formatValue,\n tooltipFormatter,\n ]);\n\n const handleClick = useCallback(\n (params: Parameters<ChartEvents[\"click\"]>[0]) => {\n if (params.dataType === \"node\" && onNodeClick && params.name) {\n const nodeIndex = nodes.findIndex((n) => n.name === params.name);\n const originalNode = nodeIndex >= 0 ? nodes[nodeIndex] : null;\n\n const nodeData: SankeyNodeData = {\n ...originalNode,\n name: params.name,\n };\n onNodeClick(nodeData);\n } else if (params.dataType === \"edge\" && onLinkClick && params.data) {\n const data = params.data;\n const source =\n typeof data === \"object\" && data !== null && \"source\" in data\n ? String(data.source)\n : \"\";\n const target =\n typeof data === \"object\" && data !== null && \"target\" in data\n ? String(data.target)\n : \"\";\n const sourceIndex = nodes.findIndex((n) => n.name === source);\n const targetIndex = nodes.findIndex((n) => n.name === target);\n\n if (sourceIndex === -1 || targetIndex === -1) return;\n\n const rawValue = params.value;\n const value =\n typeof rawValue === \"number\"\n ? rawValue\n : Array.isArray(rawValue) && typeof rawValue[0] === \"number\"\n ? rawValue[0]\n : 0;\n\n // Find original link to preserve id and isDrillable properties\n const originalLink = links.find(\n (l) => l.source === sourceIndex && l.target === targetIndex,\n );\n onLinkClick({\n ...originalLink,\n source: sourceIndex,\n target: targetIndex,\n value,\n });\n }\n },\n [nodes, links, onNodeClick, onLinkClick],\n );\n\n const onEvents = useMemo<Partial<ChartEvents>>(\n () => ({\n click: handleClick,\n }),\n [handleClick],\n );\n\n return (\n <Chart\n echarts={echarts}\n options={options}\n className={className}\n isDarkMode={isDarkMode}\n height={height}\n onEvents={onEvents}\n />\n );\n}\n\nSankeyChart.displayName = \"SankeyChart\";\n"],"names":["ChartSemanticLightColors","ChartSemanticDarkColors","sequentialLight","sequentialDark","CHART_LIGHT_COLORS","CHART_DARK_COLORS","ChartPalette","semantic","name","isDarkMode","categorical","index","sequential","palette","text","variant","colors","transformTooltip","tooltipObj","dangerousHtmlFormatter","restOfTooltip","prepareChartOptions","options","Chart","forwardRef","echarts","optionUpdateBehavior","className","height","onEvents","ref","elRef","useRef","chartRef","handlersRef","wrappersRef","boundEventsRef","useEffect","chart","event","wrapper","nextBound","handler","params","el","isInitial","ro","jsx","cn","TimeseriesChart","type","data","xAxisName","xAxisTickCount","xAxisTickFormat","yAxisTickFormat","yAxisTickLabelFormat","yAxisName","yAxisTickCount","tooltipValueFormat","onTimeRangeChange","incomplete","gradient","loading","ariaDescription","incompleteBefore","incompleteAfter","useMemo","transformSeries","seriesType","s","incompleteBeforePoints","point","incompleteAfterPoints","completePoints","areaStyle","colorWithOpacity","incompleteSeriesConfig","items","seenNames","filteredParams","param","first","ts","header","formatTimestamp","rows","value","formatFn","formattedValue","events","range","hasTimeRangeCallback","ChartWaveLoader","mid","amp","period","steps","points","i","x","y","d","strokeColor","color","alpha","a","rgbMatch","hex","r","g","b","pad","n","LargeItem","unit","inactive","jsxs","SmallItem","ChartLegend","defaultFormatValue","isTooltipParams","escapeHtml","str","escapeRichText","char","sanitizeColor","fallback","SankeyChart","nodes","links","nodeWidth","nodePadding","enableTooltip","showNodeValues","formatValue","tooltipFormatter","defaultNodeColor","linkColor","linkOpacity","onNodeClick","onLinkClick","hasNodeValues","shouldShowValues","labelColor","secondaryColor","nodeDataMap","echartsNodes","node","echartsLinks","link","nodeData","safeName","source","target","sourceNode","targetNode","sourceColor","targetColor","safeSource","safeTarget","handleClick","useCallback","nodeIndex","sourceIndex","targetIndex","rawValue","originalLink","l"],"mappings":"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"}
@@ -1,80 +0,0 @@
1
- "use client";
2
- import { jsxs as i, jsx as n } from "react/jsx-runtime";
3
- import { forwardRef as h, isValidElement as g } from "react";
4
- import { c as r } from "./cn-ct4n7r74mh8y0f48.js";
5
- import { r as k } from "./resolve-variant-gw6eh7fa4st8ej7m.js";
6
- const E = "flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-base", N = {
7
- variant: {
8
- default: {
9
- classes: "bg-kumo-info-tint/30 border-kumo-info/50 text-kumo-info selection:bg-kumo-info",
10
- iconClasses: "text-kumo-info",
11
- description: "Informational banner for general messages"
12
- },
13
- alert: {
14
- classes: "bg-kumo-warning-tint/15 border-kumo-warning/50 text-kumo-warning selection:bg-kumo-warning",
15
- iconClasses: "text-kumo-warning",
16
- description: "Warning banner for cautionary messages"
17
- },
18
- error: {
19
- classes: "bg-kumo-danger-tint/15 border-kumo-danger/50 text-kumo-danger selection:bg-kumo-danger",
20
- iconClasses: "text-kumo-danger",
21
- description: "Error banner for critical issues"
22
- }
23
- }
24
- }, t = {
25
- variant: "default"
26
- };
27
- function x({
28
- variant: e = t.variant
29
- } = {}) {
30
- return r(
31
- // Base styles (exported as KUMO_BANNER_BASE_STYLES for Figma plugin)
32
- E,
33
- // Apply variant styles from KUMO_BANNER_VARIANTS
34
- k(N.variant, e, t.variant).classes
35
- );
36
- }
37
- var R = /* @__PURE__ */ ((e) => (e[e.DEFAULT = 0] = "DEFAULT", e[e.ALERT = 1] = "ALERT", e[e.ERROR = 2] = "ERROR", e))(R || {});
38
- const A = h(function({
39
- icon: a,
40
- title: o,
41
- description: s,
42
- action: m,
43
- children: b,
44
- text: p,
45
- variant: l = t.variant,
46
- className: d
47
- }, u) {
48
- const f = k(N.variant, l, t.variant);
49
- if (o || s)
50
- return /* @__PURE__ */ i("div", { ref: u, className: r(x({ variant: l }), d), children: [
51
- a && /* @__PURE__ */ n(
52
- "span",
53
- {
54
- className: r(
55
- "shrink-0 flex items-center h-[1.375em]",
56
- f.iconClasses
57
- ),
58
- children: a
59
- }
60
- ),
61
- /* @__PURE__ */ i("div", { className: "flex min-w-0 flex-1 items-center justify-between gap-3", children: [
62
- /* @__PURE__ */ i("div", { className: "flex flex-col gap-0.5", children: [
63
- o && /* @__PURE__ */ n("p", { className: "font-medium leading-snug", children: o }),
64
- s && /* @__PURE__ */ n("div", { className: "text-sm leading-snug", children: g(s) ? s : /* @__PURE__ */ n("p", { children: s }) })
65
- ] }),
66
- m && /* @__PURE__ */ n("div", { className: "flex shrink-0 items-center gap-2", children: m })
67
- ] })
68
- ] });
69
- const c = b ?? p, v = g(c) ? c : /* @__PURE__ */ n("p", { children: c });
70
- return /* @__PURE__ */ i("div", { ref: u, className: r(x({ variant: l }), d), children: [
71
- a && /* @__PURE__ */ n("span", { className: r("shrink-0", f.iconClasses), children: a }),
72
- v
73
- ] });
74
- });
75
- A.displayName = "Banner";
76
- export {
77
- A as B,
78
- R as a
79
- };
80
- //# sourceMappingURL=banner-eux4y8xaogjg64af.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"banner-eux4y8xaogjg64af.js","sources":["../../src/components/banner/banner.tsx"],"sourcesContent":["import { type ReactNode, isValidElement, forwardRef } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { resolveVariant } from \"../../utils/resolve-variant\";\n\n/** Base styles applied to all banner variants. */\nexport const KUMO_BANNER_BASE_STYLES =\n \"flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-base\";\n\n/** Banner variant definitions mapping variant names to their Tailwind classes and descriptions. */\nexport const KUMO_BANNER_VARIANTS = {\n variant: {\n default: {\n classes:\n \"bg-kumo-info-tint/30 border-kumo-info/50 text-kumo-info selection:bg-kumo-info\",\n iconClasses: \"text-kumo-info\",\n description: \"Informational banner for general messages\",\n },\n alert: {\n classes:\n \"bg-kumo-warning-tint/15 border-kumo-warning/50 text-kumo-warning selection:bg-kumo-warning\",\n iconClasses: \"text-kumo-warning\",\n description: \"Warning banner for cautionary messages\",\n },\n error: {\n classes:\n \"bg-kumo-danger-tint/15 border-kumo-danger/50 text-kumo-danger selection:bg-kumo-danger\",\n iconClasses: \"text-kumo-danger\",\n description: \"Error banner for critical issues\",\n },\n },\n} as const;\n\nexport const KUMO_BANNER_DEFAULT_VARIANTS = {\n variant: \"default\",\n} as const;\n\n// Derived types from KUMO_BANNER_VARIANTS\nexport type KumoBannerVariant = keyof typeof KUMO_BANNER_VARIANTS.variant;\n\nexport interface KumoBannerVariantsProps {\n /**\n * Visual style of the banner.\n * - `\"default\"` — Informational banner for general messages\n * - `\"alert\"` — Warning banner for cautionary messages\n * - `\"error\"` — Error banner for critical issues\n * @default \"default\"\n */\n variant?: KumoBannerVariant;\n}\n\nexport function bannerVariants({\n variant = KUMO_BANNER_DEFAULT_VARIANTS.variant,\n}: KumoBannerVariantsProps = {}) {\n return cn(\n // Base styles (exported as KUMO_BANNER_BASE_STYLES for Figma plugin)\n KUMO_BANNER_BASE_STYLES,\n // Apply variant styles from KUMO_BANNER_VARIANTS\n resolveVariant(KUMO_BANNER_VARIANTS.variant, variant, KUMO_BANNER_DEFAULT_VARIANTS.variant).classes,\n );\n}\n\n// Legacy enum for backwards compatibility\nexport enum BannerVariant {\n DEFAULT,\n ALERT,\n ERROR,\n}\n\n/**\n * Banner component props.\n *\n * @example\n * ```tsx\n * <Banner title=\"Update available\" description=\"A new version is ready to install.\" />\n * <Banner variant=\"alert\" title=\"Session expiring\" description=\"Your session will expire soon.\" />\n * <Banner variant=\"error\" title=\"Save failed\" description=\"We couldn't save your changes.\" />\n * ```\n */\nexport interface BannerProps {\n /** Icon element rendered before the banner content (e.g. from `@phosphor-icons/react`). */\n icon?: ReactNode;\n /** Primary heading text for the banner. Use for i18n string injection. */\n title?: string;\n /** Secondary description text displayed below the title. Use for i18n string injection. */\n description?: ReactNode;\n /** Action slot rendered at the trailing end of the banner (e.g. a CTA button or link). Only used in structured mode (with `title` or `description`). */\n action?: ReactNode;\n /** @deprecated Use `title` and `description` instead. Will be removed in a future major version. */\n text?: string;\n /** @deprecated Use `title` and `description` instead for better i18n support. */\n children?: ReactNode;\n /**\n * Visual style of the banner.\n * - `\"default\"` — Informational blue banner for general messages\n * - `\"alert\"` — Warning yellow banner for cautionary messages\n * - `\"error\"` — Error red banner for critical issues\n * @default \"default\"\n */\n variant?: KumoBannerVariant;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n}\n\n/**\n * Full-width message bar for informational, warning, or error notices.\n * Supports structured title/description for i18n, or simple children for basic usage.\n *\n * @example\n * ```tsx\n * // Structured (recommended for i18n)\n * <Banner\n * variant=\"alert\"\n * icon={<WarningCircle />}\n * title=\"Review required\"\n * description=\"Please review your billing information.\"\n * />\n *\n * // Simple (backwards compatible)\n * <Banner variant=\"alert\" icon={<WarningCircle />}>\n * Review your billing information.\n * </Banner>\n * ```\n */\nexport const Banner = forwardRef<HTMLDivElement, BannerProps>(function Banner(\n {\n icon,\n title,\n description,\n action,\n children,\n text,\n variant = KUMO_BANNER_DEFAULT_VARIANTS.variant,\n className,\n },\n ref,\n) {\n const variantConfig = resolveVariant(KUMO_BANNER_VARIANTS.variant, variant, KUMO_BANNER_DEFAULT_VARIANTS.variant);\n\n // Structured mode: title and/or description provided\n if (title || description) {\n return (\n <div ref={ref} className={cn(bannerVariants({ variant }), className)}>\n {icon && (\n <span\n className={cn(\n \"shrink-0 flex items-center h-[1.375em]\",\n variantConfig.iconClasses,\n )}\n >\n {icon}\n </span>\n )}\n <div className=\"flex min-w-0 flex-1 items-center justify-between gap-3\">\n <div className=\"flex flex-col gap-0.5\">\n {title && <p className=\"font-medium leading-snug\">{title}</p>}\n {description && (\n <div className=\"text-sm leading-snug\">\n {isValidElement(description) ? (\n description\n ) : (\n <p>{description}</p>\n )}\n </div>\n )}\n </div>\n {action && (\n <div className=\"flex shrink-0 items-center gap-2\">{action}</div>\n )}\n </div>\n </div>\n );\n }\n\n // Legacy mode: children or text prop\n const value = children ?? text;\n const content = isValidElement(value) ? value : <p>{value}</p>;\n\n return (\n <div ref={ref} className={cn(bannerVariants({ variant }), className)}>\n {icon && (\n <span className={cn(\"shrink-0\", variantConfig.iconClasses)}>\n {icon}\n </span>\n )}\n {content}\n </div>\n );\n});\n\nBanner.displayName = \"Banner\";\n"],"names":["KUMO_BANNER_BASE_STYLES","KUMO_BANNER_VARIANTS","KUMO_BANNER_DEFAULT_VARIANTS","bannerVariants","variant","cn","resolveVariant","BannerVariant","Banner","forwardRef","icon","title","description","action","children","text","className","ref","variantConfig","jsxs","jsx","isValidElement","value","content"],"mappings":";;;;;AAKO,MAAMA,IACX,uEAGWC,IAAuB;AAAA,EAClC,SAAS;AAAA,IACP,SAAS;AAAA,MACP,SACE;AAAA,MACF,aAAa;AAAA,MACb,aAAa;AAAA,IAAA;AAAA,IAEf,OAAO;AAAA,MACL,SACE;AAAA,MACF,aAAa;AAAA,MACb,aAAa;AAAA,IAAA;AAAA,IAEf,OAAO;AAAA,MACL,SACE;AAAA,MACF,aAAa;AAAA,MACb,aAAa;AAAA,IAAA;AAAA,EACf;AAEJ,GAEaC,IAA+B;AAAA,EAC1C,SAAS;AACX;AAgBO,SAASC,EAAe;AAAA,EAC7B,SAAAC,IAAUF,EAA6B;AACzC,IAA6B,IAAI;AAC/B,SAAOG;AAAA;AAAA,IAELL;AAAA;AAAA,IAEAM,EAAeL,EAAqB,SAASG,GAASF,EAA6B,OAAO,EAAE;AAAA,EAAA;AAEhG;AAGO,IAAKK,sBAAAA,OACVA,EAAAA,EAAA,UAAA,CAAA,IAAA,WACAA,EAAAA,EAAA,QAAA,CAAA,IAAA,SACAA,EAAAA,EAAA,QAAA,CAAA,IAAA,SAHUA,IAAAA,KAAA,CAAA,CAAA;AA6DL,MAAMC,IAASC,EAAwC,SAC5D;AAAA,EACE,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC;AAAA,EACA,SAAAX,IAAUF,EAA6B;AAAA,EACvC,WAAAc;AACF,GACAC,GACA;AACA,QAAMC,IAAgBZ,EAAeL,EAAqB,SAASG,GAASF,EAA6B,OAAO;AAGhH,MAAIS,KAASC;AACX,WACE,gBAAAO,EAAC,OAAA,EAAI,KAAAF,GAAU,WAAWZ,EAAGF,EAAe,EAAE,SAAAC,EAAA,CAAS,GAAGY,CAAS,GAChE,UAAA;AAAA,MAAAN,KACC,gBAAAU;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWf;AAAA,YACT;AAAA,YACAa,EAAc;AAAA,UAAA;AAAA,UAGf,UAAAR;AAAA,QAAA;AAAA,MAAA;AAAA,MAGL,gBAAAS,EAAC,OAAA,EAAI,WAAU,0DACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yBACZ,UAAA;AAAA,UAAAR,KAAS,gBAAAS,EAAC,KAAA,EAAE,WAAU,4BAA4B,UAAAT,GAAM;AAAA,UACxDC,KACC,gBAAAQ,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAAC,EAAeT,CAAW,IACzBA,IAEA,gBAAAQ,EAAC,KAAA,EAAG,UAAAR,EAAA,CAAY,EAAA,CAEpB;AAAA,QAAA,GAEJ;AAAA,QACCC,KACC,gBAAAO,EAAC,OAAA,EAAI,WAAU,oCAAoC,UAAAP,EAAA,CAAO;AAAA,MAAA,EAAA,CAE9D;AAAA,IAAA,GACF;AAKJ,QAAMS,IAAQR,KAAYC,GACpBQ,IAAUF,EAAeC,CAAK,IAAIA,IAAQ,gBAAAF,EAAC,OAAG,UAAAE,GAAM;AAE1D,SACE,gBAAAH,EAAC,OAAA,EAAI,KAAAF,GAAU,WAAWZ,EAAGF,EAAe,EAAE,SAAAC,EAAA,CAAS,GAAGY,CAAS,GAChE,UAAA;AAAA,IAAAN,KACC,gBAAAU,EAAC,UAAK,WAAWf,EAAG,YAAYa,EAAc,WAAW,GACtD,UAAAR,EAAA,CACH;AAAA,IAEDa;AAAA,EAAA,GACH;AAEJ,CAAC;AAEDf,EAAO,cAAc;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"field-mil8efu3x0s68eed.js","sources":["../../src/components/field/field.tsx"],"sourcesContent":["import { Field as FieldBase } from \"@base-ui/react/field\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Label } from \"../label\";\n\n/** Field variant definitions (currently empty, reserved for future additions). */\nexport const KUMO_FIELD_VARIANTS = {\n // Field currently has no variant options but structure is ready for future additions\n} as const;\n\nexport const KUMO_FIELD_DEFAULT_VARIANTS = {} as const;\n\n// Derived types from KUMO_FIELD_VARIANTS\nexport interface KumoFieldVariantsProps {\n /**\n * When true, places the control (checkbox/switch) before the label visually.\n * When false (default), places the label before the control.\n * Used to support different layout patterns (e.g., iOS-style toggles on the right).\n */\n controlFirst?: boolean;\n}\n\nexport function fieldVariants({\n controlFirst = false,\n}: KumoFieldVariantsProps = {}) {\n return cn(\n // Base styles - vertical layout (default)\n \"grid gap-2\",\n\n // Horizontal layout for checkbox and switch\n // Default: Grid auto-reverses in RTL (desired)\n \"has-[input[type=checkbox]]:grid-cols-[auto_1fr] has-[input[type=checkbox]]:items-center\",\n \"has-[[role=switch]]:grid-cols-[auto_1fr] has-[[role=switch]]:items-center\",\n\n // Control first: use flexbox with row-reverse to flip visual order without affecting text direction\n // flex-row-reverse in LTR: Control→Label, in RTL: Label→Control (opposite of grid default)\n controlFirst && [\n \"has-[input[type=checkbox]]:flex has-[input[type=checkbox]]:flex-row-reverse has-[input[type=checkbox]]:flex-wrap has-[input[type=checkbox]]:items-center\",\n \"has-[[role=switch]]:flex has-[[role=switch]]:flex-row-reverse has-[[role=switch]]:flex-wrap has-[[role=switch]]:items-center\",\n \"[&>label]:flex-1\",\n ],\n );\n}\n\n/**\n * Match type for field validation errors.\n * Can be a boolean or a key from the browser's ValidityState interface.\n * Source: BaseErrorProps[\"match\"] (ComponentPropsWithoutRef<typeof FieldBase.Error>)\n */\nexport type FieldErrorMatch =\n | boolean\n | \"badInput\"\n | \"customError\"\n | \"patternMismatch\"\n | \"rangeOverflow\"\n | \"rangeUnderflow\"\n | \"stepMismatch\"\n | \"tooLong\"\n | \"tooShort\"\n | \"typeMismatch\"\n | \"valid\"\n | \"valueMissing\";\n\n/**\n * Field component props — wraps a form control with label, description, and error message.\n *\n * @example\n * ```tsx\n * <Field label=\"Email\" required>\n * <Input placeholder=\"you@example.com\" />\n * </Field>\n *\n * <Field label=\"Phone\" required={false} description=\"We'll only use this for account recovery.\">\n * <Input placeholder=\"+1 555-0000\" />\n * </Field>\n * ```\n */\nexport interface FieldProps extends KumoFieldVariantsProps {\n /** The form control element(s) to wrap (Input, Select, Checkbox, etc.). */\n children: ReactNode;\n /** The label content — can be a string or any React node. */\n label: ReactNode;\n /**\n * When explicitly `false`, shows gray \"(optional)\" text after the label.\n * When `true` or `undefined`, no indicator is shown.\n */\n required?: boolean;\n /** Tooltip content displayed next to the label via an info icon. */\n labelTooltip?: ReactNode;\n /** Validation error with a message and a browser `ValidityState` match key. */\n error?: {\n message: ReactNode;\n match: FieldErrorMatch;\n };\n /** Helper text displayed below the control (hidden when `error` is present). */\n description?: ReactNode;\n /** When `true`, places the control before the label (for checkbox/switch layouts). */\n controlFirst?: boolean;\n}\n\n/**\n * Form field wrapper that provides a label, optional description, and error display\n * around any form control. Built on Base UI Field primitives.\n *\n * @example\n * ```tsx\n * <Field label=\"Username\">\n * <Input placeholder=\"Choose a username\" />\n * </Field>\n * ```\n */\nexport function Field({\n children,\n label,\n required,\n labelTooltip,\n error,\n description,\n controlFirst = false,\n}: FieldProps) {\n // Show \"(optional)\" when required is explicitly false\n const showOptional = required === false;\n\n return (\n <FieldBase.Root className={fieldVariants({ controlFirst })}>\n <FieldBase.Label className=\"m-0 text-base font-medium text-kumo-default\">\n <Label showOptional={showOptional} tooltip={labelTooltip} asContent>\n {label}\n </Label>\n </FieldBase.Label>\n {children}\n {error ? (\n <FieldBase.Error\n className={cn(\n \"text-sm leading-snug text-kumo-danger\",\n // Span full width in horizontal layout\n \"col-span-full\",\n )}\n match={error.match}\n >\n {error.message}\n </FieldBase.Error>\n ) : (\n description && (\n <FieldBase.Description\n className={cn(\n \"text-sm leading-snug text-kumo-subtle\",\n // Span full width in horizontal layout\n \"col-span-full\",\n )}\n >\n {description}\n </FieldBase.Description>\n )\n )}\n </FieldBase.Root>\n );\n}\n"],"names":["KUMO_FIELD_VARIANTS","KUMO_FIELD_DEFAULT_VARIANTS","fieldVariants","controlFirst","cn","Field","children","label","required","labelTooltip","error","description","showOptional","jsxs","FieldBase.Root","jsx","FieldBase.Label","Label","FieldBase.Error","FieldBase.Description"],"mappings":";;;;;AAMO,MAAMA,IAAsB;AAAA;AAEnC,GAEaC,IAA8B,CAAA;AAYpC,SAASC,EAAc;AAAA,EAC5B,cAAAC,IAAe;AACjB,IAA4B,IAAI;AAC9B,SAAOC;AAAA;AAAA,IAEL;AAAA;AAAA;AAAA,IAIA;AAAA,IACA;AAAA;AAAA;AAAA,IAIAD,KAAgB;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EACF;AAEJ;AAqEO,SAASE,EAAM;AAAA,EACpB,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,cAAAC;AAAA,EACA,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAR,IAAe;AACjB,GAAe;AAEb,QAAMS,IAAeJ,MAAa;AAElC,SACE,gBAAAK,EAACC,GAAA,EAAe,WAAWZ,EAAc,EAAE,cAAAC,EAAA,CAAc,GACvD,UAAA;AAAA,IAAA,gBAAAY,EAACC,GAAA,EAAgB,WAAU,+CACzB,UAAA,gBAAAD,EAACE,GAAA,EAAM,cAAAL,GAA4B,SAASH,GAAc,WAAS,IAChE,aACH,GACF;AAAA,IACCH;AAAA,IACAI,IACC,gBAAAK;AAAA,MAACG;AAAAA,MAAA;AAAA,QACC,WAAWd;AAAA,UACT;AAAA;AAAA,UAEA;AAAA,QAAA;AAAA,QAEF,OAAOM,EAAM;AAAA,QAEZ,UAAAA,EAAM;AAAA,MAAA;AAAA,IAAA,IAGTC,KACE,gBAAAI;AAAA,MAACI;AAAAA,MAAA;AAAA,QACC,WAAWf;AAAA,UACT;AAAA;AAAA,UAEA;AAAA,QAAA;AAAA,QAGD,UAAAO;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GAGN;AAEJ;"}
@@ -1,78 +0,0 @@
1
- "use client";
2
- import { jsx as e } from "react/jsx-runtime";
3
- import { i as y } from "./input-kmztt6h4mzy101ho.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-mil8efu3x0s68eed.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-hl1rdb9xcrqyt8xw.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"input-area-hl1rdb9xcrqyt8xw.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-kmztt6h4mzy101ho.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,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-n859eyw550yi2b9z.js";
7
- import { K as H } from "./input-kmztt6h4mzy101ho.js";
8
- import { S as J } from "./skeleton-line-epxenksfesr2fkcv.js";
9
- import { F as Q } from "./field-mil8efu3x0s68eed.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-brzswxbhhf1ktx9t.js.map