@cloudflare/kumo 1.17.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/ai/USAGE.md +38 -32
  3. package/ai/component-registry.json +289 -178
  4. package/ai/component-registry.md +980 -507
  5. package/ai/schemas.ts +20 -4
  6. package/dist/.build-complete +1 -1
  7. package/dist/ai/schemas.d.ts +95 -56
  8. package/dist/ai/schemas.d.ts.map +1 -1
  9. package/dist/ai/schemas.js +165 -148
  10. package/dist/ai/schemas.js.map +1 -1
  11. package/dist/chunks/{Legend-o0ntojbaplmszwk0.js → Legend-ks7se6149vsa3tze.js} +127 -118
  12. package/dist/chunks/Legend-ks7se6149vsa3tze.js.map +1 -0
  13. package/dist/chunks/badge-dan90i0rzy4pwa1j.js +102 -0
  14. package/dist/chunks/badge-dan90i0rzy4pwa1j.js.map +1 -0
  15. package/dist/chunks/{banner-nz0eryqnz3qd86ln.js → banner-eiwcnk7ts21s3bnb.js} +4 -4
  16. package/dist/chunks/{banner-nz0eryqnz3qd86ln.js.map → banner-eiwcnk7ts21s3bnb.js.map} +1 -1
  17. package/dist/chunks/{breadcrumbs-cjgn3w4drahvqnuj.js → breadcrumbs-ge20hcb3o5spswrk.js} +2 -2
  18. package/dist/chunks/{breadcrumbs-cjgn3w4drahvqnuj.js.map → breadcrumbs-ge20hcb3o5spswrk.js.map} +1 -1
  19. package/dist/chunks/{button-odxi0hp4fvi5i2w3.js → button-oaqi7ykdisyskoos.js} +8 -8
  20. package/dist/chunks/button-oaqi7ykdisyskoos.js.map +1 -0
  21. package/dist/chunks/{checkbox-dx8x0rzv582yjv7n.js → checkbox-mwgmohffm22ut13s.js} +15 -15
  22. package/dist/chunks/checkbox-mwgmohffm22ut13s.js.map +1 -0
  23. package/dist/chunks/{clipboard-text-kyk51d1ze7zvdn4q.js → clipboard-text-dxczqon3d27xp6f0.js} +10 -10
  24. package/dist/chunks/{clipboard-text-kyk51d1ze7zvdn4q.js.map → clipboard-text-dxczqon3d27xp6f0.js.map} +1 -1
  25. package/dist/chunks/{cloudflare-logo-bgts2jgsdh7sslw4.js → cloudflare-logo-pbavoe1wu8nr5c4n.js} +9 -9
  26. package/dist/chunks/{cloudflare-logo-bgts2jgsdh7sslw4.js.map → cloudflare-logo-pbavoe1wu8nr5c4n.js.map} +1 -1
  27. package/dist/chunks/{code-liq1g6f5lhee305d.js → code-cz0w1y5z4h29a9eg.js} +18 -18
  28. package/dist/chunks/code-cz0w1y5z4h29a9eg.js.map +1 -0
  29. package/dist/chunks/{combobox-9fhjzprab46csmon.js → combobox-eaowwt1xr4d23gsn.js} +113 -101
  30. package/dist/chunks/combobox-eaowwt1xr4d23gsn.js.map +1 -0
  31. package/dist/chunks/{command-palette-kenx2bbdzd4kpx36.js → command-palette-maqtbmpfev9mysqd.js} +20 -20
  32. package/dist/chunks/command-palette-maqtbmpfev9mysqd.js.map +1 -0
  33. package/dist/chunks/{dialog-e05ysa8t2fklw065.js → dialog-e3m5bhs7fds26p9y.js} +25 -25
  34. package/dist/chunks/dialog-e3m5bhs7fds26p9y.js.map +1 -0
  35. package/dist/chunks/{dropdown-g587px7zv3ssaxr4.js → dropdown-ewte287db3vyt8t5.js} +94 -92
  36. package/dist/chunks/{dropdown-g587px7zv3ssaxr4.js.map → dropdown-ewte287db3vyt8t5.js.map} +1 -1
  37. package/dist/chunks/{empty-fuz1un7r7mbz0kim.js → empty-dr1eckm2z40euns6.js} +2 -2
  38. package/dist/chunks/{empty-fuz1un7r7mbz0kim.js.map → empty-dr1eckm2z40euns6.js.map} +1 -1
  39. package/dist/chunks/{field-fq504lyu7ttsh5m9.js → field-bo5gmna16odrrb1q.js} +3 -3
  40. package/dist/chunks/{field-fq504lyu7ttsh5m9.js.map → field-bo5gmna16odrrb1q.js.map} +1 -1
  41. package/dist/chunks/{grid-m9r71jxo2b8q1972.js → grid-hj1ylz16p7g5uelh.js} +2 -2
  42. package/dist/chunks/{grid-m9r71jxo2b8q1972.js.map → grid-hj1ylz16p7g5uelh.js.map} +1 -1
  43. package/dist/chunks/input-area-jkkkjej6luumrqpa.js +78 -0
  44. package/dist/chunks/input-area-jkkkjej6luumrqpa.js.map +1 -0
  45. package/dist/chunks/input-cw05pbqdburghkus.js +113 -0
  46. package/dist/chunks/input-cw05pbqdburghkus.js.map +1 -0
  47. package/dist/chunks/{input-group-hbebbyh8fo6aqydn.js → input-group-lfugneuz71g42n0w.js} +27 -27
  48. package/dist/chunks/input-group-lfugneuz71g42n0w.js.map +1 -0
  49. package/dist/chunks/label-cvyvbqmt4mt757ff.js +68 -0
  50. package/dist/chunks/{label-j9owppbgnn35mebg.js.map → label-cvyvbqmt4mt757ff.js.map} +1 -1
  51. package/dist/chunks/layer-card-ljqth3yxgnk04v2o.js +46 -0
  52. package/dist/chunks/layer-card-ljqth3yxgnk04v2o.js.map +1 -0
  53. package/dist/chunks/{link-hmmf3k1xn6rm72rt.js → link-fjnhtxvfe5ieamjf.js} +2 -2
  54. package/dist/chunks/{link-hmmf3k1xn6rm72rt.js.map → link-fjnhtxvfe5ieamjf.js.map} +1 -1
  55. package/dist/chunks/{loader-m5wfmqwgucrr4i5v.js → loader-hr2w7cpqeev3p3vl.js} +9 -6
  56. package/dist/chunks/loader-hr2w7cpqeev3p3vl.js.map +1 -0
  57. package/dist/chunks/menubar-e5e4zwfagr0wx023.js +96 -0
  58. package/dist/chunks/menubar-e5e4zwfagr0wx023.js.map +1 -0
  59. package/dist/chunks/{meter-i84dte2f82qmvn7y.js → meter-duj3micor1lqj3y2.js} +2 -2
  60. package/dist/chunks/{meter-i84dte2f82qmvn7y.js.map → meter-duj3micor1lqj3y2.js.map} +1 -1
  61. package/dist/chunks/pagination-olaypvwr8swsmn8m.js +266 -0
  62. package/dist/chunks/pagination-olaypvwr8swsmn8m.js.map +1 -0
  63. package/dist/chunks/{popover-i951xjcgezeqr4iv.js → popover-nv9cmzbo7mf6bky0.js} +68 -72
  64. package/dist/chunks/popover-nv9cmzbo7mf6bky0.js.map +1 -0
  65. package/dist/chunks/{radio-l2vkcue40d84fmo1.js → radio-ihxbe37us2jnqtzf.js} +38 -38
  66. package/dist/chunks/radio-ihxbe37us2jnqtzf.js.map +1 -0
  67. package/dist/chunks/select-nx6ded5swra74iar.js +213 -0
  68. package/dist/chunks/select-nx6ded5swra74iar.js.map +1 -0
  69. package/dist/chunks/{sensitive-input-kznmknpp5h1grc6k.js → sensitive-input-00fujb510rrn61v9.js} +34 -34
  70. package/dist/chunks/{sensitive-input-kznmknpp5h1grc6k.js.map → sensitive-input-00fujb510rrn61v9.js.map} +1 -1
  71. package/dist/chunks/{sidebar-jepeq7gaf4issuw6.js → sidebar-ltbfius1eolkl8tb.js} +24 -28
  72. package/dist/chunks/sidebar-ltbfius1eolkl8tb.js.map +1 -0
  73. package/dist/chunks/surface-dfgurg5eu3et4vw1.js +29 -0
  74. package/dist/chunks/surface-dfgurg5eu3et4vw1.js.map +1 -0
  75. package/dist/chunks/{switch-i0zwcp3wq6vsxm1c.js → switch-fbv3iawqo3o3jgap.js} +104 -102
  76. package/dist/chunks/switch-fbv3iawqo3o3jgap.js.map +1 -0
  77. package/dist/chunks/table-of-contents-f813ivi7ta23vqdm.js +88 -0
  78. package/dist/chunks/table-of-contents-f813ivi7ta23vqdm.js.map +1 -0
  79. package/dist/chunks/table-olwwulga2l3hdwlx.js +189 -0
  80. package/dist/chunks/table-olwwulga2l3hdwlx.js.map +1 -0
  81. package/dist/chunks/{tabs-bw92jb303zxw7w4f.js → tabs-lohcglgppp6gj0hp.js} +16 -16
  82. package/dist/chunks/{tabs-bw92jb303zxw7w4f.js.map → tabs-lohcglgppp6gj0hp.js.map} +1 -1
  83. package/dist/chunks/{toast-lrnwby56drs7vtae.js → toast-dg52x89yd231mxhe.js} +30 -30
  84. package/dist/chunks/{toast-lrnwby56drs7vtae.js.map → toast-dg52x89yd231mxhe.js.map} +1 -1
  85. package/dist/chunks/{tooltip-cit9ltlxfuhwctuj.js → tooltip-hikjvdbg3xghnq1x.js} +38 -33
  86. package/dist/chunks/tooltip-hikjvdbg3xghnq1x.js.map +1 -0
  87. package/dist/chunks/{vendor-base-ui-n30qblevnpk9cc5c.js → vendor-base-ui-m5pz3e8c4grg5qmj.js} +46 -43
  88. package/dist/chunks/{vendor-base-ui-n30qblevnpk9cc5c.js.map → vendor-base-ui-m5pz3e8c4grg5qmj.js.map} +1 -1
  89. package/dist/code.js +1 -1
  90. package/dist/components/badge.js +1 -1
  91. package/dist/components/banner.js +1 -1
  92. package/dist/components/breadcrumbs.js +1 -1
  93. package/dist/components/button.js +1 -1
  94. package/dist/components/chart.js +1 -1
  95. package/dist/components/checkbox.js +1 -1
  96. package/dist/components/clipboard-text.js +1 -1
  97. package/dist/components/cloudflare-logo.js +1 -1
  98. package/dist/components/code.js +1 -1
  99. package/dist/components/combobox.js +1 -1
  100. package/dist/components/command-palette.js +1 -1
  101. package/dist/components/dialog.js +1 -1
  102. package/dist/components/dropdown.js +1 -1
  103. package/dist/components/empty.js +1 -1
  104. package/dist/components/field.js +1 -1
  105. package/dist/components/flow.js +2 -2
  106. package/dist/components/flow.js.map +1 -1
  107. package/dist/components/grid.js +1 -1
  108. package/dist/components/input.js +3 -3
  109. package/dist/components/label.js +1 -1
  110. package/dist/components/layer-card.js +1 -1
  111. package/dist/components/link.js +1 -1
  112. package/dist/components/loader.js +1 -1
  113. package/dist/components/menubar.js +1 -1
  114. package/dist/components/meter.js +1 -1
  115. package/dist/components/pagination.js +1 -1
  116. package/dist/components/popover.js +1 -1
  117. package/dist/components/radio.js +1 -1
  118. package/dist/components/select.js +1 -1
  119. package/dist/components/sensitive-input.js +1 -1
  120. package/dist/components/sidebar.js +1 -1
  121. package/dist/components/surface.js +1 -1
  122. package/dist/components/switch.js +1 -1
  123. package/dist/components/table-of-contents.js +8 -0
  124. package/dist/components/table-of-contents.js.map +1 -0
  125. package/dist/components/table.js +1 -1
  126. package/dist/components/tabs.js +1 -1
  127. package/dist/components/toast.js +2 -2
  128. package/dist/components/tooltip.js +1 -1
  129. package/dist/index.js +128 -124
  130. package/dist/index.js.map +1 -1
  131. package/dist/primitives/accordion.js +1 -1
  132. package/dist/primitives/alert-dialog.js +1 -1
  133. package/dist/primitives/autocomplete.js +1 -1
  134. package/dist/primitives/avatar.js +1 -1
  135. package/dist/primitives/button.js +1 -1
  136. package/dist/primitives/checkbox-group.js +1 -1
  137. package/dist/primitives/checkbox.js +1 -1
  138. package/dist/primitives/collapsible.js +1 -1
  139. package/dist/primitives/combobox.js +1 -1
  140. package/dist/primitives/context-menu.js +1 -1
  141. package/dist/primitives/csp-provider.js +1 -1
  142. package/dist/primitives/dialog.js +1 -1
  143. package/dist/primitives/direction-provider.js +1 -1
  144. package/dist/primitives/drawer.js +1 -1
  145. package/dist/primitives/field.js +1 -1
  146. package/dist/primitives/fieldset.js +1 -1
  147. package/dist/primitives/form.js +1 -1
  148. package/dist/primitives/input.js +1 -1
  149. package/dist/primitives/menu.js +1 -1
  150. package/dist/primitives/menubar.js +1 -1
  151. package/dist/primitives/meter.js +1 -1
  152. package/dist/primitives/navigation-menu.js +1 -1
  153. package/dist/primitives/number-field.js +1 -1
  154. package/dist/primitives/popover.js +1 -1
  155. package/dist/primitives/preview-card.js +1 -1
  156. package/dist/primitives/progress.js +1 -1
  157. package/dist/primitives/radio-group.js +1 -1
  158. package/dist/primitives/radio.js +1 -1
  159. package/dist/primitives/scroll-area.js +1 -1
  160. package/dist/primitives/select.js +1 -1
  161. package/dist/primitives/separator.js +1 -1
  162. package/dist/primitives/slider.js +1 -1
  163. package/dist/primitives/switch.js +1 -1
  164. package/dist/primitives/tabs.js +1 -1
  165. package/dist/primitives/toast.js +1 -1
  166. package/dist/primitives/toggle-group.js +1 -1
  167. package/dist/primitives/toggle.js +1 -1
  168. package/dist/primitives/toolbar.js +1 -1
  169. package/dist/primitives/tooltip.js +1 -1
  170. package/dist/primitives.js +1 -1
  171. package/dist/scripts/theme-generator/config.d.ts.map +1 -1
  172. package/dist/scripts/theme-generator/config.js +32 -113
  173. package/dist/scripts/theme-generator/config.js.map +1 -1
  174. package/dist/src/components/badge/badge.d.ts +61 -79
  175. package/dist/src/components/badge/badge.d.ts.map +1 -1
  176. package/dist/src/components/banner/banner.d.ts +3 -3
  177. package/dist/src/components/button/button.d.ts +3 -3
  178. package/dist/src/components/button/button.d.ts.map +1 -1
  179. package/dist/src/components/chart/EChart.d.ts +18 -2
  180. package/dist/src/components/chart/EChart.d.ts.map +1 -1
  181. package/dist/src/components/chart/TimeseriesChart.d.ts.map +1 -1
  182. package/dist/src/components/chart/index.d.ts +1 -1
  183. package/dist/src/components/chart/index.d.ts.map +1 -1
  184. package/dist/src/components/checkbox/checkbox.d.ts +1 -1
  185. package/dist/src/components/code/code.d.ts.map +1 -1
  186. package/dist/src/components/combobox/combobox.d.ts +16 -2
  187. package/dist/src/components/combobox/combobox.d.ts.map +1 -1
  188. package/dist/src/components/dropdown/dropdown.d.ts.map +1 -1
  189. package/dist/src/components/input/input-area.d.ts.map +1 -1
  190. package/dist/src/components/input/input.d.ts +1 -2
  191. package/dist/src/components/input/input.d.ts.map +1 -1
  192. package/dist/src/components/label/label.d.ts.map +1 -1
  193. package/dist/src/components/layer-card/layer-card.d.ts +39 -5
  194. package/dist/src/components/layer-card/layer-card.d.ts.map +1 -1
  195. package/dist/src/components/loader/loader.d.ts +7 -1
  196. package/dist/src/components/loader/loader.d.ts.map +1 -1
  197. package/dist/src/components/menubar/menubar.d.ts.map +1 -1
  198. package/dist/src/components/pagination/pagination.d.ts +62 -2
  199. package/dist/src/components/pagination/pagination.d.ts.map +1 -1
  200. package/dist/src/components/popover/popover.d.ts +35 -8
  201. package/dist/src/components/popover/popover.d.ts.map +1 -1
  202. package/dist/src/components/radio/radio.d.ts +2 -2
  203. package/dist/src/components/select/select.d.ts +115 -7
  204. package/dist/src/components/select/select.d.ts.map +1 -1
  205. package/dist/src/components/sensitive-input/sensitive-input.d.ts +1 -1
  206. package/dist/src/components/sidebar/sidebar.d.ts +2 -2
  207. package/dist/src/components/sidebar/sidebar.d.ts.map +1 -1
  208. package/dist/src/components/surface/index.d.ts +3 -0
  209. package/dist/src/components/surface/index.d.ts.map +1 -1
  210. package/dist/src/components/surface/surface.d.ts +14 -10
  211. package/dist/src/components/surface/surface.d.ts.map +1 -1
  212. package/dist/src/components/switch/switch.d.ts.map +1 -1
  213. package/dist/src/components/table/table.d.ts.map +1 -1
  214. package/dist/src/components/table-of-contents/index.d.ts +2 -0
  215. package/dist/src/components/table-of-contents/index.d.ts.map +1 -0
  216. package/dist/src/components/table-of-contents/table-of-contents.d.ts +70 -0
  217. package/dist/src/components/table-of-contents/table-of-contents.d.ts.map +1 -0
  218. package/dist/src/components/toast/toast.d.ts +1 -1
  219. package/dist/src/components/tooltip/tooltip.d.ts +25 -6
  220. package/dist/src/components/tooltip/tooltip.d.ts.map +1 -1
  221. package/dist/src/index.d.ts +6 -2
  222. package/dist/src/index.d.ts.map +1 -1
  223. package/dist/styles/kumo-binding.css +4 -0
  224. package/dist/styles/kumo-standalone.css +1 -1
  225. package/dist/styles/theme-fedramp.css +3 -3
  226. package/dist/styles/theme-kumo.css +66 -127
  227. package/package.json +5 -1
  228. package/scripts/component-registry/index.test.ts +4 -4
  229. package/scripts/component-registry/metadata.ts +3 -3
  230. package/scripts/theme-generator/config.ts +37 -116
  231. package/dist/chunks/Legend-o0ntojbaplmszwk0.js.map +0 -1
  232. package/dist/chunks/badge-n80t3z8u9ttlxi20.js +0 -120
  233. package/dist/chunks/badge-n80t3z8u9ttlxi20.js.map +0 -1
  234. package/dist/chunks/button-odxi0hp4fvi5i2w3.js.map +0 -1
  235. package/dist/chunks/checkbox-dx8x0rzv582yjv7n.js.map +0 -1
  236. package/dist/chunks/code-liq1g6f5lhee305d.js.map +0 -1
  237. package/dist/chunks/combobox-9fhjzprab46csmon.js.map +0 -1
  238. package/dist/chunks/command-palette-kenx2bbdzd4kpx36.js.map +0 -1
  239. package/dist/chunks/dialog-e05ysa8t2fklw065.js.map +0 -1
  240. package/dist/chunks/input-area-nq40szg9110on89c.js +0 -74
  241. package/dist/chunks/input-area-nq40szg9110on89c.js.map +0 -1
  242. package/dist/chunks/input-group-hbebbyh8fo6aqydn.js.map +0 -1
  243. package/dist/chunks/input-kvhyo3p4859bexvx.js +0 -109
  244. package/dist/chunks/input-kvhyo3p4859bexvx.js.map +0 -1
  245. package/dist/chunks/label-j9owppbgnn35mebg.js +0 -62
  246. package/dist/chunks/layer-card-l5yjvrxry1dhte57.js +0 -44
  247. package/dist/chunks/layer-card-l5yjvrxry1dhte57.js.map +0 -1
  248. package/dist/chunks/loader-m5wfmqwgucrr4i5v.js.map +0 -1
  249. package/dist/chunks/menubar-abojnm0uwjuni8ok.js +0 -92
  250. package/dist/chunks/menubar-abojnm0uwjuni8ok.js.map +0 -1
  251. package/dist/chunks/pagination-pbd7qqik97ac0l7m.js +0 -224
  252. package/dist/chunks/pagination-pbd7qqik97ac0l7m.js.map +0 -1
  253. package/dist/chunks/popover-i951xjcgezeqr4iv.js.map +0 -1
  254. package/dist/chunks/radio-l2vkcue40d84fmo1.js.map +0 -1
  255. package/dist/chunks/select-paedwa3nlhpq82ua.js +0 -132
  256. package/dist/chunks/select-paedwa3nlhpq82ua.js.map +0 -1
  257. package/dist/chunks/sidebar-jepeq7gaf4issuw6.js.map +0 -1
  258. package/dist/chunks/surface-blo81kgy9g0sexgm.js +0 -36
  259. package/dist/chunks/surface-blo81kgy9g0sexgm.js.map +0 -1
  260. package/dist/chunks/switch-i0zwcp3wq6vsxm1c.js.map +0 -1
  261. package/dist/chunks/table-nrcw19tlpduayukl.js +0 -183
  262. package/dist/chunks/table-nrcw19tlpduayukl.js.map +0 -1
  263. package/dist/chunks/tooltip-cit9ltlxfuhwctuj.js.map +0 -1
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import { jsxs as y, Fragment as ce, jsx as a } from "react/jsx-runtime";
2
+ import { jsxs as y, Fragment as ce, jsx as r } from "react/jsx-runtime";
3
3
  import { EyeSlash as ue, Eye as pe } from "@phosphor-icons/react";
4
4
  import { forwardRef as de, useState as C, useRef as N, useId as T, useCallback as c, useEffect as fe } from "react";
5
5
  import { c as p } from "./cn-ct4n7r74mh8y0f48.js";
6
- import { K as me, i as he } from "./input-kvhyo3p4859bexvx.js";
7
- import { F as ve } from "./field-fq504lyu7ttsh5m9.js";
8
- import { I as ge } from "./vendor-base-ui-n30qblevnpk9cc5c.js";
6
+ import { K as me, i as he } from "./input-cw05pbqdburghkus.js";
7
+ import { F as ve } from "./field-bo5gmna16odrrb1q.js";
8
+ import { I as ge } from "./vendor-base-ui-m5pz3e8c4grg5qmj.js";
9
9
  const Te = me, M = {
10
10
  size: "base",
11
11
  variant: "default"
@@ -18,7 +18,7 @@ const Te = me, M = {
18
18
  onCopy: k,
19
19
  size: t = M.size,
20
20
  variant: j = M.variant,
21
- disabled: r = !1,
21
+ disabled: a = !1,
22
22
  readOnly: d = !1,
23
23
  id: $,
24
24
  autoComplete: H = "off",
@@ -73,7 +73,7 @@ const Te = me, M = {
73
73
  A.current !== o && (A.current = o, !o && n === "masked" && l("empty"));
74
74
  const te = c(
75
75
  (e) => {
76
- if (!r) {
76
+ if (!a) {
77
77
  if (u.current) {
78
78
  const i = u.current.getBoundingClientRect();
79
79
  if (!(e.clientX >= i.left && e.clientX <= i.right && e.clientY >= i.top && e.clientY <= i.bottom)) return;
@@ -81,7 +81,7 @@ const Te = me, M = {
81
81
  n === "masked" && o && (l("revealed"), d || setTimeout(() => I.current?.focus(), 0));
82
82
  }
83
83
  },
84
- [n, o, r, d]
84
+ [n, o, a, d]
85
85
  ), ne = c(
86
86
  (e) => {
87
87
  e.stopPropagation(), n === "revealed" ? l("masked") : n === "empty" && o && l("revealed");
@@ -98,26 +98,26 @@ const Te = me, M = {
98
98
  u.current && e.relatedTarget instanceof Node && u.current.contains(e.relatedTarget) || o && l("masked");
99
99
  },
100
100
  [o]
101
- ), re = c(
101
+ ), ae = c(
102
102
  (e) => {
103
- r || n === "masked" && o && (e.key === "Enter" || e.key === " ") && (e.preventDefault(), l("revealed"), d || setTimeout(() => I.current?.focus(), 0));
103
+ a || n === "masked" && o && (e.key === "Enter" || e.key === " ") && (e.preventDefault(), l("revealed"), d || setTimeout(() => I.current?.focus(), 0));
104
104
  },
105
- [n, o, r, d]
106
- ), ae = c(
105
+ [n, o, a, d]
106
+ ), re = c(
107
107
  (e) => {
108
108
  n === "revealed" && e.key === "Escape" && (l("masked"), setTimeout(() => u.current?.focus(), 0));
109
109
  },
110
110
  [n]
111
- ), s = n === "masked" && o, _ = !r && (n === "revealed" || n === "empty" && o), se = t === "xs" || t === "sm" ? "size-3" : "size-4", D = p(
111
+ ), s = n === "masked" && o, _ = !a && (n === "revealed" || n === "empty" && o), se = t === "xs" || t === "sm" ? "size-3" : "size-4", D = p(
112
112
  he({ size: t, variant: j, parentFocusIndicator: !0 }),
113
113
  "group/container relative flex w-full items-center",
114
114
  // Show browser-native focus outline on container when child input is focused
115
115
  "focus-within:outline focus-within:outline-2 focus-within:outline-[-webkit-focus-ring-color]",
116
- s && !r && "cursor-pointer",
117
- r && "cursor-not-allowed",
116
+ s && !a && "cursor-pointer",
117
+ a && "cursor-not-allowed",
118
118
  L
119
119
  ), P = /* @__PURE__ */ y(ce, { children: [
120
- /* @__PURE__ */ a(
120
+ /* @__PURE__ */ r(
121
121
  ge,
122
122
  {
123
123
  ref: z,
@@ -126,8 +126,8 @@ const Te = me, M = {
126
126
  value: m,
127
127
  onChange: oe,
128
128
  onBlur: ie,
129
- onKeyDown: ae,
130
- disabled: r,
129
+ onKeyDown: re,
130
+ disabled: a,
131
131
  readOnly: d || s,
132
132
  autoComplete: H,
133
133
  tabIndex: s ? -1 : 0,
@@ -143,7 +143,7 @@ const Te = me, M = {
143
143
  ...q
144
144
  }
145
145
  ),
146
- /* @__PURE__ */ a(
146
+ /* @__PURE__ */ r(
147
147
  "span",
148
148
  {
149
149
  className: p(
@@ -169,20 +169,20 @@ const Te = me, M = {
169
169
  ),
170
170
  "aria-hidden": "true",
171
171
  children: /* @__PURE__ */ y("span", { className: "relative", children: [
172
- /* @__PURE__ */ a(
172
+ /* @__PURE__ */ r(
173
173
  "span",
174
174
  {
175
175
  className: p(
176
- s && !r && "group-focus-within/container:invisible group-hover/mask:invisible"
176
+ s && !a && "group-focus-within/container:invisible group-hover/mask:invisible"
177
177
  ),
178
178
  children: "••••••••"
179
179
  }
180
180
  ),
181
- s && !r && /* @__PURE__ */ a("span", { className: "invisible absolute left-0 top-0 whitespace-nowrap text-kumo-subtle group-focus-within/container:visible group-hover/mask:visible", children: "Click to reveal" })
181
+ s && !a && /* @__PURE__ */ r("span", { className: "invisible absolute left-0 top-0 whitespace-nowrap text-kumo-subtle group-focus-within/container:visible group-hover/mask:visible", children: "Click to reveal" })
182
182
  ] })
183
183
  }
184
184
  ),
185
- /* @__PURE__ */ a(
185
+ /* @__PURE__ */ r(
186
186
  "button",
187
187
  {
188
188
  type: "button",
@@ -191,7 +191,7 @@ const Te = me, M = {
191
191
  "aria-label": n === "revealed" ? "Hide value" : "Reveal value",
192
192
  tabIndex: _ ? 0 : -1,
193
193
  className: p(
194
- "absolute top-1/2 right-0 -translate-y-1/2 cursor-pointer text-kumo-subtle hover:text-kumo-default focus:text-kumo-default focus-visible:ring-1 focus-visible:ring-kumo-ring focus-visible:rounded-sm",
194
+ "absolute top-1/2 right-0 -translate-y-1/2 cursor-pointer text-kumo-subtle hover:text-kumo-default focus:text-kumo-default focus-visible:ring-1 focus-visible:ring-kumo-hairline focus-visible:rounded-sm",
195
195
  // Defensive styles to prevent global CSS pollution (e.g., button { background: gray })
196
196
  "bg-transparent border-none shadow-none p-0 m-0 h-auto min-h-0 inline-flex items-center justify-center",
197
197
  // Match right padding from inputVariants
@@ -202,10 +202,10 @@ const Te = me, M = {
202
202
  se,
203
203
  !_ && "pointer-events-none opacity-0"
204
204
  ),
205
- children: n === "revealed" ? /* @__PURE__ */ a(ue, { className: "size-full" }) : /* @__PURE__ */ a(pe, { className: "size-full" })
205
+ children: n === "revealed" ? /* @__PURE__ */ r(ue, { className: "size-full" }) : /* @__PURE__ */ r(pe, { className: "size-full" })
206
206
  }
207
207
  ),
208
- o && !r && /* @__PURE__ */ a(
208
+ o && !a && /* @__PURE__ */ r(
209
209
  "button",
210
210
  {
211
211
  type: "button",
@@ -213,7 +213,7 @@ const Te = me, M = {
213
213
  onKeyDown: (e) => e.stopPropagation(),
214
214
  "aria-label": h ? "Copied" : "Copy to clipboard",
215
215
  className: p(
216
- "absolute -top-px right-2 -translate-y-full cursor-pointer rounded-t-md bg-kumo-brand px-2 py-0.5 text-xs text-white opacity-0 transition-opacity group-focus-within/container:opacity-100 group-hover/container:opacity-100 hover:brightness-120 focus-visible:outline focus-visible:outline-offset-1 focus-visible:outline-kumo-ring",
216
+ "absolute -top-px right-2 -translate-y-full cursor-pointer rounded-t-md bg-kumo-brand px-2 py-0.5 text-xs text-white opacity-0 transition-opacity group-focus-within/container:opacity-100 group-hover/container:opacity-100 hover:brightness-120 focus-visible:outline focus-visible:outline-offset-1 focus-visible:outline-kumo-hairline",
217
217
  // Defensive styles to prevent global CSS pollution
218
218
  "border-none shadow-none m-0 h-auto min-h-0"
219
219
  ),
@@ -221,28 +221,28 @@ const Te = me, M = {
221
221
  }
222
222
  )
223
223
  ] }), U = /* @__PURE__ */ y("div", { children: [
224
- s ? /* @__PURE__ */ a(
224
+ s ? /* @__PURE__ */ r(
225
225
  "div",
226
226
  {
227
227
  ref: u,
228
228
  role: "button",
229
- tabIndex: r ? -1 : 0,
229
+ tabIndex: a ? -1 : 0,
230
230
  className: D,
231
231
  onClick: te,
232
- onKeyDown: re,
232
+ onKeyDown: ae,
233
233
  "aria-label": `${G}, masked.`,
234
234
  "aria-describedby": `${K} ${V}`,
235
- "aria-disabled": r,
235
+ "aria-disabled": a,
236
236
  children: P
237
237
  }
238
- ) : /* @__PURE__ */ a("div", { ref: u, className: D, children: P }),
239
- s && /* @__PURE__ */ a("span", { id: K, className: "sr-only", children: "Click or press Enter to reveal." }),
238
+ ) : /* @__PURE__ */ r("div", { ref: u, className: D, children: P }),
239
+ s && /* @__PURE__ */ r("span", { id: K, className: "sr-only", children: "Click or press Enter to reveal." }),
240
240
  /* @__PURE__ */ y("span", { id: V, className: "sr-only", "aria-live": "polite", children: [
241
241
  n === "masked" && o && "Value hidden",
242
242
  h && "Copied to clipboard"
243
243
  ] })
244
244
  ] });
245
- return g ? /* @__PURE__ */ a(
245
+ return g ? /* @__PURE__ */ r(
246
246
  ve,
247
247
  {
248
248
  label: g,
@@ -261,4 +261,4 @@ export {
261
261
  be as S,
262
262
  M as a
263
263
  };
264
- //# sourceMappingURL=sensitive-input-kznmknpp5h1grc6k.js.map
264
+ //# sourceMappingURL=sensitive-input-00fujb510rrn61v9.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sensitive-input-kznmknpp5h1grc6k.js","sources":["../../src/components/sensitive-input/sensitive-input.tsx"],"sourcesContent":["import { Eye, EyeSlash } from \"@phosphor-icons/react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Input as BaseInput } from \"@base-ui/react/input\";\nimport {\n inputVariants,\n KUMO_INPUT_VARIANTS,\n type KumoInputSize,\n type KumoInputVariant,\n} from \"../input/input\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\n\nexport const KUMO_SENSITIVE_INPUT_VARIANTS = KUMO_INPUT_VARIANTS;\n\nexport const KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS = {\n size: \"base\",\n variant: \"default\",\n} as const;\n\ntype Mode = \"masked\" | \"revealed\" | \"empty\";\n\n/**\n * SensitiveInput component props.\n *\n * @example\n * ```tsx\n * <SensitiveInput label=\"API Key\" defaultValue=\"sk_live_abc123xyz789\" />\n * <SensitiveInput label=\"Secret\" value={secret} onValueChange={setSecret} />\n * ```\n */\nexport interface SensitiveInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"size\" | \"type\" | \"value\" | \"defaultValue\"\n > {\n /** Controlled value */\n value?: string;\n /** Uncontrolled default value */\n defaultValue?: string;\n /** Simplified change handler receiving just the value */\n onValueChange?: (value: string) => void;\n /** Callback fired after value is copied to clipboard */\n onCopy?: () => void;\n /**\n * Size of the input.\n * - `\"xs\"` — Extra small for compact UIs\n * - `\"sm\"` — Small for secondary fields\n * - `\"base\"` — Default input size\n * - `\"lg\"` — Large for prominent fields\n * @default \"base\"\n */\n size?: KumoInputSize;\n /**\n * Style variant of the input.\n * - `\"default\"` — Default input appearance\n * - `\"error\"` — Error state for validation failures\n * @default \"default\"\n */\n variant?: KumoInputVariant;\n /** Label content for the input (enables Field wrapper and sets masked state label) - 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\n/**\n * Password/secret input that masks its value by default and reveals on click.\n * Includes a built-in copy-to-clipboard button on hover.\n *\n * @example\n * ```tsx\n * <SensitiveInput label=\"API Key\" defaultValue=\"sk_live_abc123xyz789\" />\n * ```\n */\nexport const SensitiveInput = forwardRef<HTMLInputElement, SensitiveInputProps>(\n (\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onValueChange,\n onCopy,\n size = KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS.size,\n variant = KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS.variant,\n disabled = false,\n readOnly = false,\n id,\n autoComplete = \"off\",\n className,\n label,\n labelTooltip,\n description,\n error,\n required,\n ...inputProps\n },\n ref,\n ) => {\n // For aria-label, only use string labels (ReactNode labels can't be used for aria-label)\n const ariaLabelFallback =\n typeof label === \"string\" ? label : \"Sensitive value\";\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue);\n const value = isControlled ? controlledValue : internalValue;\n const hasValue = value.length > 0;\n\n const [mode, setMode] = useState<Mode>(() =>\n hasValue ? \"masked\" : \"empty\",\n );\n\n const [copied, setCopied] = useState(false);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const liveRegionId = useId();\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const maskedInstructionId = useId();\n\n const mergedRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref],\n );\n\n // Reset copied state after 2 seconds\n useEffect(() => {\n if (copied) {\n const timeoutId = setTimeout(() => setCopied(false), 2000);\n return () => clearTimeout(timeoutId);\n }\n }, [copied]);\n\n const copyToClipboard = useCallback(\n async (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.clipboard &&\n typeof navigator.clipboard.writeText === \"function\"\n ) {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n onCopy?.();\n return;\n }\n } catch {\n // Fall through to manual fallback\n }\n\n if (typeof document !== \"undefined\") {\n const textarea = document.createElement(\"textarea\");\n textarea.value = value;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"absolute\";\n textarea.style.left = \"-9999px\";\n document.body.appendChild(textarea);\n const selection = document.getSelection();\n const previousRange = selection?.rangeCount\n ? selection.getRangeAt(0)\n : null;\n textarea.select();\n try {\n document.execCommand(\"copy\");\n setCopied(true);\n onCopy?.();\n } catch (error) {\n console.warn(\"Clipboard copy failed\", error);\n } finally {\n document.body.removeChild(textarea);\n if (previousRange) {\n selection?.removeAllRanges();\n selection?.addRange(previousRange);\n }\n }\n }\n },\n [value, onCopy],\n );\n\n // Sync mode when value changes externally\n const prevHasValueRef = useRef(hasValue);\n if (prevHasValueRef.current !== hasValue) {\n prevHasValueRef.current = hasValue;\n if (!hasValue && mode === \"masked\") {\n setMode(\"empty\");\n }\n }\n\n const handleContainerClick = useCallback(\n (e: React.MouseEvent) => {\n if (disabled) return;\n // Ignore clicks that originated from outside (e.g., label click focusing input)\n // Label clicks trigger a click on the input, but the click coordinates are outside the container\n if (containerRef.current) {\n const rect = containerRef.current.getBoundingClientRect();\n const isClickInsideContainer =\n e.clientX >= rect.left &&\n e.clientX <= rect.right &&\n e.clientY >= rect.top &&\n e.clientY <= rect.bottom;\n if (!isClickInsideContainer) return;\n }\n if (mode === \"masked\" && hasValue) {\n setMode(\"revealed\");\n if (!readOnly) {\n setTimeout(() => inputRef.current?.focus(), 0);\n }\n }\n },\n [mode, hasValue, disabled, readOnly],\n );\n\n const handleToggleVisibility = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (mode === \"revealed\") {\n setMode(\"masked\");\n } else if (mode === \"empty\" && hasValue) {\n setMode(\"revealed\");\n }\n },\n [mode, hasValue],\n );\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n if (!isControlled) {\n setInternalValue(newValue);\n }\n // When typing into an empty field, switch to revealed mode\n // so the input shows as type=\"text\" instead of type=\"password\"\n if (mode === \"empty\" && newValue.length > 0) {\n setMode(\"revealed\");\n }\n onChange?.(e);\n onValueChange?.(newValue);\n },\n [isControlled, onChange, onValueChange, mode],\n );\n\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n // Don't mask if focus is moving to a button inside the container (copy/eye buttons)\n if (\n containerRef.current &&\n e.relatedTarget instanceof Node &&\n containerRef.current.contains(e.relatedTarget)\n ) {\n return;\n }\n if (hasValue) {\n setMode(\"masked\");\n }\n },\n [hasValue],\n );\n\n const handleContainerKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (mode === \"masked\" && hasValue) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setMode(\"revealed\");\n if (!readOnly) {\n setTimeout(() => inputRef.current?.focus(), 0);\n }\n }\n }\n },\n [mode, hasValue, disabled, readOnly],\n );\n\n const handleInputKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (mode === \"revealed\" && e.key === \"Escape\") {\n setMode(\"masked\");\n // Move focus to container to avoid focus trap (input becomes tabIndex={-1})\n setTimeout(() => containerRef.current?.focus(), 0);\n }\n },\n [mode],\n );\n\n const isMaskedWithValue = mode === \"masked\" && hasValue;\n const showEyeButton =\n !disabled && (mode === \"revealed\" || (mode === \"empty\" && hasValue));\n\n // Icon sizes matching input sizes\n const iconSize = size === \"xs\" || size === \"sm\" ? \"size-3\" : \"size-4\";\n\n const containerClassName = cn(\n inputVariants({ size, variant, parentFocusIndicator: true }),\n \"group/container relative flex w-full items-center\",\n // Show browser-native focus outline on container when child input is focused\n \"focus-within:outline focus-within:outline-2 focus-within:outline-[-webkit-focus-ring-color]\",\n isMaskedWithValue && !disabled && \"cursor-pointer\",\n disabled && \"cursor-not-allowed\",\n className,\n );\n\n const containerContent = (\n <>\n {/* Input - defines the width, always rendered */}\n <BaseInput\n ref={mergedRef}\n id={inputId}\n type={mode === \"revealed\" ? \"text\" : \"password\"}\n value={value}\n onChange={handleChange}\n onBlur={handleBlur}\n onKeyDown={handleInputKeyDown}\n disabled={disabled}\n readOnly={readOnly || isMaskedWithValue}\n autoComplete={autoComplete}\n tabIndex={isMaskedWithValue ? -1 : 0}\n className={cn(\n \"w-full border-0 bg-transparent p-0 text-kumo-default ring-0 outline-none kumo-input-placeholder disabled:cursor-not-allowed disabled:text-kumo-subtle\",\n size === \"xs\" && \"pr-5\",\n size === \"sm\" && \"pr-6\",\n size === \"base\" && \"pr-8\",\n size === \"lg\" && \"pr-10\",\n isMaskedWithValue && \"pointer-events-none text-transparent\",\n )}\n aria-hidden={isMaskedWithValue}\n {...inputProps}\n />\n\n {/* Mask overlay - absolutely positioned, doesn't affect layout */}\n <span\n className={cn(\n \"pointer-events-none absolute inset-y-0 left-0 flex items-center overflow-hidden select-none\",\n // Match input pr padding (space for icon)\n size === \"xs\" && \"right-5\",\n size === \"sm\" && \"right-6\",\n size === \"base\" && \"right-8\",\n size === \"lg\" && \"right-10\",\n // Match the padding from inputVariants\n size === \"xs\" && \"px-1.5\",\n size === \"sm\" && \"px-2\",\n size === \"base\" && \"px-3\",\n size === \"lg\" && \"px-4\",\n // Hidden when not masked\n !isMaskedWithValue && \"invisible\",\n // When masked: enable pointer events\n isMaskedWithValue && \"pointer-events-auto\",\n // Text color - use text-kumo-default to contrast with bg-kumo-control input background\n \"text-kumo-default\",\n // Hover state - pure CSS, no React state (group for children)\n \"group/mask\",\n )}\n aria-hidden=\"true\"\n >\n {/* Both texts rendered, stacked. Visibility toggled on hover to prevent layout shift */}\n <span className=\"relative\">\n <span\n className={cn(\n isMaskedWithValue &&\n !disabled &&\n \"group-focus-within/container:invisible group-hover/mask:invisible\",\n )}\n >\n ••••••••\n </span>\n {isMaskedWithValue && !disabled && (\n <span className=\"invisible absolute left-0 top-0 whitespace-nowrap text-kumo-subtle group-focus-within/container:visible group-hover/mask:visible\">\n Click to reveal\n </span>\n )}\n </span>\n </span>\n\n {/* Eye button - absolutely positioned to the right */}\n <button\n type=\"button\"\n onClick={handleToggleVisibility}\n onKeyDown={(e) => e.stopPropagation()}\n aria-label={mode === \"revealed\" ? \"Hide value\" : \"Reveal value\"}\n tabIndex={showEyeButton ? 0 : -1}\n className={cn(\n \"absolute top-1/2 right-0 -translate-y-1/2 cursor-pointer text-kumo-subtle hover:text-kumo-default focus:text-kumo-default focus-visible:ring-1 focus-visible:ring-kumo-ring focus-visible:rounded-sm\",\n // Defensive styles to prevent global CSS pollution (e.g., button { background: gray })\n \"bg-transparent border-none shadow-none p-0 m-0 h-auto min-h-0 inline-flex items-center justify-center\",\n // Match right padding from inputVariants\n size === \"xs\" && \"right-1.5\",\n size === \"sm\" && \"right-2\",\n size === \"base\" && \"right-3\",\n size === \"lg\" && \"right-4\",\n iconSize,\n !showEyeButton && \"pointer-events-none opacity-0\",\n )}\n >\n {mode === \"revealed\" ? (\n <EyeSlash className=\"size-full\" />\n ) : (\n <Eye className=\"size-full\" />\n )}\n </button>\n\n {/* Copy tab - appears on hover/focus at top right (hidden when disabled) */}\n {hasValue && !disabled && (\n <button\n type=\"button\"\n onClick={copyToClipboard}\n onKeyDown={(e) => e.stopPropagation()}\n aria-label={copied ? \"Copied\" : \"Copy to clipboard\"}\n className={cn(\n \"absolute -top-px right-2 -translate-y-full cursor-pointer rounded-t-md bg-kumo-brand px-2 py-0.5 text-xs text-white opacity-0 transition-opacity group-focus-within/container:opacity-100 group-hover/container:opacity-100 hover:brightness-120 focus-visible:outline focus-visible:outline-offset-1 focus-visible:outline-kumo-ring\",\n // Defensive styles to prevent global CSS pollution\n \"border-none shadow-none m-0 h-auto min-h-0\",\n )}\n >\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n )}\n </>\n );\n\n const input = (\n <div>\n {isMaskedWithValue ? (\n <div\n ref={containerRef}\n // Cannot use <button> here because containerContent contains interactive button elements (Copy, Reveal).\n // Using role=\"button\" with proper keyboard handling instead.\n // oxlint-disable-next-line prefer-tag-over-role\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n className={containerClassName}\n onClick={handleContainerClick}\n onKeyDown={handleContainerKeyDown}\n aria-label={`${ariaLabelFallback}, masked.`}\n aria-describedby={`${maskedInstructionId} ${liveRegionId}`}\n aria-disabled={disabled}\n >\n {containerContent}\n </div>\n ) : (\n <div ref={containerRef} className={containerClassName}>\n {containerContent}\n </div>\n )}\n {isMaskedWithValue && (\n <span id={maskedInstructionId} className=\"sr-only\">\n Click or press Enter to reveal.\n </span>\n )}\n <span id={liveRegionId} className=\"sr-only\" aria-live=\"polite\">\n {mode === \"masked\" && hasValue && \"Value hidden\"}\n {copied && \"Copied to clipboard\"}\n </span>\n </div>\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);\n\nSensitiveInput.displayName = \"SensitiveInput\";\n"],"names":["KUMO_SENSITIVE_INPUT_VARIANTS","KUMO_INPUT_VARIANTS","KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS","SensitiveInput","forwardRef","controlledValue","defaultValue","onChange","onValueChange","onCopy","size","variant","disabled","readOnly","id","autoComplete","className","label","labelTooltip","description","error","required","inputProps","ref","ariaLabelFallback","isControlled","internalValue","setInternalValue","useState","value","hasValue","mode","setMode","copied","setCopied","inputRef","useRef","containerRef","liveRegionId","useId","generatedId","inputId","maskedInstructionId","mergedRef","useCallback","node","useEffect","timeoutId","copyToClipboard","textarea","selection","previousRange","prevHasValueRef","handleContainerClick","rect","handleToggleVisibility","handleChange","newValue","handleBlur","handleContainerKeyDown","handleInputKeyDown","isMaskedWithValue","showEyeButton","iconSize","containerClassName","cn","inputVariants","containerContent","jsxs","Fragment","jsx","BaseInput","EyeSlash","Eye","input","Field"],"mappings":"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"}
1
+ {"version":3,"file":"sensitive-input-00fujb510rrn61v9.js","sources":["../../src/components/sensitive-input/sensitive-input.tsx"],"sourcesContent":["import { Eye, EyeSlash } from \"@phosphor-icons/react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Input as BaseInput } from \"@base-ui/react/input\";\nimport {\n inputVariants,\n KUMO_INPUT_VARIANTS,\n type KumoInputSize,\n type KumoInputVariant,\n} from \"../input/input\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\n\nexport const KUMO_SENSITIVE_INPUT_VARIANTS = KUMO_INPUT_VARIANTS;\n\nexport const KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS = {\n size: \"base\",\n variant: \"default\",\n} as const;\n\ntype Mode = \"masked\" | \"revealed\" | \"empty\";\n\n/**\n * SensitiveInput component props.\n *\n * @example\n * ```tsx\n * <SensitiveInput label=\"API Key\" defaultValue=\"sk_live_abc123xyz789\" />\n * <SensitiveInput label=\"Secret\" value={secret} onValueChange={setSecret} />\n * ```\n */\nexport interface SensitiveInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"size\" | \"type\" | \"value\" | \"defaultValue\"\n > {\n /** Controlled value */\n value?: string;\n /** Uncontrolled default value */\n defaultValue?: string;\n /** Simplified change handler receiving just the value */\n onValueChange?: (value: string) => void;\n /** Callback fired after value is copied to clipboard */\n onCopy?: () => void;\n /**\n * Size of the input.\n * - `\"xs\"` — Extra small for compact UIs\n * - `\"sm\"` — Small for secondary fields\n * - `\"base\"` — Default input size\n * - `\"lg\"` — Large for prominent fields\n * @default \"base\"\n */\n size?: KumoInputSize;\n /**\n * Style variant of the input.\n * - `\"default\"` — Default input appearance\n * - `\"error\"` — Error state for validation failures\n * @default \"default\"\n */\n variant?: KumoInputVariant;\n /** Label content for the input (enables Field wrapper and sets masked state label) - 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\n/**\n * Password/secret input that masks its value by default and reveals on click.\n * Includes a built-in copy-to-clipboard button on hover.\n *\n * @example\n * ```tsx\n * <SensitiveInput label=\"API Key\" defaultValue=\"sk_live_abc123xyz789\" />\n * ```\n */\nexport const SensitiveInput = forwardRef<HTMLInputElement, SensitiveInputProps>(\n (\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onValueChange,\n onCopy,\n size = KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS.size,\n variant = KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS.variant,\n disabled = false,\n readOnly = false,\n id,\n autoComplete = \"off\",\n className,\n label,\n labelTooltip,\n description,\n error,\n required,\n ...inputProps\n },\n ref,\n ) => {\n // For aria-label, only use string labels (ReactNode labels can't be used for aria-label)\n const ariaLabelFallback =\n typeof label === \"string\" ? label : \"Sensitive value\";\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue);\n const value = isControlled ? controlledValue : internalValue;\n const hasValue = value.length > 0;\n\n const [mode, setMode] = useState<Mode>(() =>\n hasValue ? \"masked\" : \"empty\",\n );\n\n const [copied, setCopied] = useState(false);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const liveRegionId = useId();\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const maskedInstructionId = useId();\n\n const mergedRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref],\n );\n\n // Reset copied state after 2 seconds\n useEffect(() => {\n if (copied) {\n const timeoutId = setTimeout(() => setCopied(false), 2000);\n return () => clearTimeout(timeoutId);\n }\n }, [copied]);\n\n const copyToClipboard = useCallback(\n async (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.clipboard &&\n typeof navigator.clipboard.writeText === \"function\"\n ) {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n onCopy?.();\n return;\n }\n } catch {\n // Fall through to manual fallback\n }\n\n if (typeof document !== \"undefined\") {\n const textarea = document.createElement(\"textarea\");\n textarea.value = value;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"absolute\";\n textarea.style.left = \"-9999px\";\n document.body.appendChild(textarea);\n const selection = document.getSelection();\n const previousRange = selection?.rangeCount\n ? selection.getRangeAt(0)\n : null;\n textarea.select();\n try {\n document.execCommand(\"copy\");\n setCopied(true);\n onCopy?.();\n } catch (error) {\n console.warn(\"Clipboard copy failed\", error);\n } finally {\n document.body.removeChild(textarea);\n if (previousRange) {\n selection?.removeAllRanges();\n selection?.addRange(previousRange);\n }\n }\n }\n },\n [value, onCopy],\n );\n\n // Sync mode when value changes externally\n const prevHasValueRef = useRef(hasValue);\n if (prevHasValueRef.current !== hasValue) {\n prevHasValueRef.current = hasValue;\n if (!hasValue && mode === \"masked\") {\n setMode(\"empty\");\n }\n }\n\n const handleContainerClick = useCallback(\n (e: React.MouseEvent) => {\n if (disabled) return;\n // Ignore clicks that originated from outside (e.g., label click focusing input)\n // Label clicks trigger a click on the input, but the click coordinates are outside the container\n if (containerRef.current) {\n const rect = containerRef.current.getBoundingClientRect();\n const isClickInsideContainer =\n e.clientX >= rect.left &&\n e.clientX <= rect.right &&\n e.clientY >= rect.top &&\n e.clientY <= rect.bottom;\n if (!isClickInsideContainer) return;\n }\n if (mode === \"masked\" && hasValue) {\n setMode(\"revealed\");\n if (!readOnly) {\n setTimeout(() => inputRef.current?.focus(), 0);\n }\n }\n },\n [mode, hasValue, disabled, readOnly],\n );\n\n const handleToggleVisibility = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (mode === \"revealed\") {\n setMode(\"masked\");\n } else if (mode === \"empty\" && hasValue) {\n setMode(\"revealed\");\n }\n },\n [mode, hasValue],\n );\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n if (!isControlled) {\n setInternalValue(newValue);\n }\n // When typing into an empty field, switch to revealed mode\n // so the input shows as type=\"text\" instead of type=\"password\"\n if (mode === \"empty\" && newValue.length > 0) {\n setMode(\"revealed\");\n }\n onChange?.(e);\n onValueChange?.(newValue);\n },\n [isControlled, onChange, onValueChange, mode],\n );\n\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n // Don't mask if focus is moving to a button inside the container (copy/eye buttons)\n if (\n containerRef.current &&\n e.relatedTarget instanceof Node &&\n containerRef.current.contains(e.relatedTarget)\n ) {\n return;\n }\n if (hasValue) {\n setMode(\"masked\");\n }\n },\n [hasValue],\n );\n\n const handleContainerKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (mode === \"masked\" && hasValue) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setMode(\"revealed\");\n if (!readOnly) {\n setTimeout(() => inputRef.current?.focus(), 0);\n }\n }\n }\n },\n [mode, hasValue, disabled, readOnly],\n );\n\n const handleInputKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (mode === \"revealed\" && e.key === \"Escape\") {\n setMode(\"masked\");\n // Move focus to container to avoid focus trap (input becomes tabIndex={-1})\n setTimeout(() => containerRef.current?.focus(), 0);\n }\n },\n [mode],\n );\n\n const isMaskedWithValue = mode === \"masked\" && hasValue;\n const showEyeButton =\n !disabled && (mode === \"revealed\" || (mode === \"empty\" && hasValue));\n\n // Icon sizes matching input sizes\n const iconSize = size === \"xs\" || size === \"sm\" ? \"size-3\" : \"size-4\";\n\n const containerClassName = cn(\n inputVariants({ size, variant, parentFocusIndicator: true }),\n \"group/container relative flex w-full items-center\",\n // Show browser-native focus outline on container when child input is focused\n \"focus-within:outline focus-within:outline-2 focus-within:outline-[-webkit-focus-ring-color]\",\n isMaskedWithValue && !disabled && \"cursor-pointer\",\n disabled && \"cursor-not-allowed\",\n className,\n );\n\n const containerContent = (\n <>\n {/* Input - defines the width, always rendered */}\n <BaseInput\n ref={mergedRef}\n id={inputId}\n type={mode === \"revealed\" ? \"text\" : \"password\"}\n value={value}\n onChange={handleChange}\n onBlur={handleBlur}\n onKeyDown={handleInputKeyDown}\n disabled={disabled}\n readOnly={readOnly || isMaskedWithValue}\n autoComplete={autoComplete}\n tabIndex={isMaskedWithValue ? -1 : 0}\n className={cn(\n \"w-full border-0 bg-transparent p-0 text-kumo-default ring-0 outline-none kumo-input-placeholder disabled:cursor-not-allowed disabled:text-kumo-subtle\",\n size === \"xs\" && \"pr-5\",\n size === \"sm\" && \"pr-6\",\n size === \"base\" && \"pr-8\",\n size === \"lg\" && \"pr-10\",\n isMaskedWithValue && \"pointer-events-none text-transparent\",\n )}\n aria-hidden={isMaskedWithValue}\n {...inputProps}\n />\n\n {/* Mask overlay - absolutely positioned, doesn't affect layout */}\n <span\n className={cn(\n \"pointer-events-none absolute inset-y-0 left-0 flex items-center overflow-hidden select-none\",\n // Match input pr padding (space for icon)\n size === \"xs\" && \"right-5\",\n size === \"sm\" && \"right-6\",\n size === \"base\" && \"right-8\",\n size === \"lg\" && \"right-10\",\n // Match the padding from inputVariants\n size === \"xs\" && \"px-1.5\",\n size === \"sm\" && \"px-2\",\n size === \"base\" && \"px-3\",\n size === \"lg\" && \"px-4\",\n // Hidden when not masked\n !isMaskedWithValue && \"invisible\",\n // When masked: enable pointer events\n isMaskedWithValue && \"pointer-events-auto\",\n // Text color - use text-kumo-default to contrast with bg-kumo-control input background\n \"text-kumo-default\",\n // Hover state - pure CSS, no React state (group for children)\n \"group/mask\",\n )}\n aria-hidden=\"true\"\n >\n {/* Both texts rendered, stacked. Visibility toggled on hover to prevent layout shift */}\n <span className=\"relative\">\n <span\n className={cn(\n isMaskedWithValue &&\n !disabled &&\n \"group-focus-within/container:invisible group-hover/mask:invisible\",\n )}\n >\n ••••••••\n </span>\n {isMaskedWithValue && !disabled && (\n <span className=\"invisible absolute left-0 top-0 whitespace-nowrap text-kumo-subtle group-focus-within/container:visible group-hover/mask:visible\">\n Click to reveal\n </span>\n )}\n </span>\n </span>\n\n {/* Eye button - absolutely positioned to the right */}\n <button\n type=\"button\"\n onClick={handleToggleVisibility}\n onKeyDown={(e) => e.stopPropagation()}\n aria-label={mode === \"revealed\" ? \"Hide value\" : \"Reveal value\"}\n tabIndex={showEyeButton ? 0 : -1}\n className={cn(\n \"absolute top-1/2 right-0 -translate-y-1/2 cursor-pointer text-kumo-subtle hover:text-kumo-default focus:text-kumo-default focus-visible:ring-1 focus-visible:ring-kumo-hairline focus-visible:rounded-sm\",\n // Defensive styles to prevent global CSS pollution (e.g., button { background: gray })\n \"bg-transparent border-none shadow-none p-0 m-0 h-auto min-h-0 inline-flex items-center justify-center\",\n // Match right padding from inputVariants\n size === \"xs\" && \"right-1.5\",\n size === \"sm\" && \"right-2\",\n size === \"base\" && \"right-3\",\n size === \"lg\" && \"right-4\",\n iconSize,\n !showEyeButton && \"pointer-events-none opacity-0\",\n )}\n >\n {mode === \"revealed\" ? (\n <EyeSlash className=\"size-full\" />\n ) : (\n <Eye className=\"size-full\" />\n )}\n </button>\n\n {/* Copy tab - appears on hover/focus at top right (hidden when disabled) */}\n {hasValue && !disabled && (\n <button\n type=\"button\"\n onClick={copyToClipboard}\n onKeyDown={(e) => e.stopPropagation()}\n aria-label={copied ? \"Copied\" : \"Copy to clipboard\"}\n className={cn(\n \"absolute -top-px right-2 -translate-y-full cursor-pointer rounded-t-md bg-kumo-brand px-2 py-0.5 text-xs text-white opacity-0 transition-opacity group-focus-within/container:opacity-100 group-hover/container:opacity-100 hover:brightness-120 focus-visible:outline focus-visible:outline-offset-1 focus-visible:outline-kumo-hairline\",\n // Defensive styles to prevent global CSS pollution\n \"border-none shadow-none m-0 h-auto min-h-0\",\n )}\n >\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n )}\n </>\n );\n\n const input = (\n <div>\n {isMaskedWithValue ? (\n <div\n ref={containerRef}\n // Cannot use <button> here because containerContent contains interactive button elements (Copy, Reveal).\n // Using role=\"button\" with proper keyboard handling instead.\n // oxlint-disable-next-line prefer-tag-over-role\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n className={containerClassName}\n onClick={handleContainerClick}\n onKeyDown={handleContainerKeyDown}\n aria-label={`${ariaLabelFallback}, masked.`}\n aria-describedby={`${maskedInstructionId} ${liveRegionId}`}\n aria-disabled={disabled}\n >\n {containerContent}\n </div>\n ) : (\n <div ref={containerRef} className={containerClassName}>\n {containerContent}\n </div>\n )}\n {isMaskedWithValue && (\n <span id={maskedInstructionId} className=\"sr-only\">\n Click or press Enter to reveal.\n </span>\n )}\n <span id={liveRegionId} className=\"sr-only\" aria-live=\"polite\">\n {mode === \"masked\" && hasValue && \"Value hidden\"}\n {copied && \"Copied to clipboard\"}\n </span>\n </div>\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);\n\nSensitiveInput.displayName = \"SensitiveInput\";\n"],"names":["KUMO_SENSITIVE_INPUT_VARIANTS","KUMO_INPUT_VARIANTS","KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS","SensitiveInput","forwardRef","controlledValue","defaultValue","onChange","onValueChange","onCopy","size","variant","disabled","readOnly","id","autoComplete","className","label","labelTooltip","description","error","required","inputProps","ref","ariaLabelFallback","isControlled","internalValue","setInternalValue","useState","value","hasValue","mode","setMode","copied","setCopied","inputRef","useRef","containerRef","liveRegionId","useId","generatedId","inputId","maskedInstructionId","mergedRef","useCallback","node","useEffect","timeoutId","copyToClipboard","textarea","selection","previousRange","prevHasValueRef","handleContainerClick","rect","handleToggleVisibility","handleChange","newValue","handleBlur","handleContainerKeyDown","handleInputKeyDown","isMaskedWithValue","showEyeButton","iconSize","containerClassName","cn","inputVariants","containerContent","jsxs","Fragment","jsx","BaseInput","EyeSlash","Eye","input","Field"],"mappings":"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"}
@@ -4,8 +4,8 @@ import ke, { forwardRef as u, useState as k, useCallback as D, useMemo as W, cre
4
4
  import { CaretRightIcon as F, MagnifyingGlassIcon as Ce, SidebarSimpleIcon as Me } from "@phosphor-icons/react";
5
5
  import { c as i } from "./cn-ct4n7r74mh8y0f48.js";
6
6
  import { u as X } from "./link-provider-mn2voeohon7cj9o4.js";
7
- import { a as Ie, T as Re } from "./tooltip-cit9ltlxfuhwctuj.js";
8
- import { bn as U, bo as V, ap as Te, au as ze, av as _e, aw as Be, bp as De } from "./vendor-base-ui-n30qblevnpk9cc5c.js";
7
+ import { a as Ie, T as Re } from "./tooltip-hikjvdbg3xghnq1x.js";
8
+ import { bq as U, br as V, ap as Te, au as ze, av as _e, aw as Be, bs as De } from "./vendor-base-ui-m5pz3e8c4grg5qmj.js";
9
9
  const $e = {
10
10
  variant: {
11
11
  sidebar: {
@@ -195,8 +195,8 @@ const $ = u(
195
195
  },
196
196
  className: i(
197
197
  "relative flex h-full shrink-0 grow-0 flex-col overflow-hidden bg-kumo-base text-kumo-default",
198
- l === "sidebar" && (d === "left" ? "border-r border-kumo-line" : "border-l border-kumo-line"),
199
- l === "floating" && "m-2 rounded-lg border border-kumo-line shadow-lg",
198
+ l === "sidebar" && (d === "left" ? "border-r border-kumo-hairline" : "border-l border-kumo-hairline"),
199
+ l === "floating" && "m-2 rounded-lg border border-kumo-hairline shadow-lg",
200
200
  t
201
201
  ),
202
202
  ...e,
@@ -257,8 +257,8 @@ const $ = u(
257
257
  "motion-reduce:transition-none",
258
258
  // Disable transition during resize drag
259
259
  x && "transition-none!",
260
- l === "sidebar" && (d === "left" ? "border-r border-kumo-line" : "border-l border-kumo-line"),
261
- l === "floating" && "m-2 rounded-lg border border-kumo-line shadow-lg",
260
+ l === "sidebar" && (d === "left" ? "border-r border-kumo-hairline" : "border-l border-kumo-hairline"),
261
+ l === "floating" && "m-2 rounded-lg border border-kumo-hairline shadow-lg",
262
262
  t
263
263
  ),
264
264
  ...e,
@@ -274,7 +274,7 @@ const Y = u(({ className: t, ...a }, e) => /* @__PURE__ */ s(
274
274
  ref: e,
275
275
  "data-sidebar": "header",
276
276
  className: i(
277
- "flex items-center gap-2 border-b border-kumo-line px-2 py-3",
277
+ "flex items-center gap-2 border-b border-kumo-hairline px-2 py-3",
278
278
  "overflow-hidden",
279
279
  // Collapsed: just remove border, keep same height
280
280
  "group-data-[state=collapsed]/sidebar:border-b-0",
@@ -306,7 +306,7 @@ const Q = u(({ className: t, ...a }, e) => /* @__PURE__ */ s(
306
306
  ref: e,
307
307
  "data-sidebar": "footer",
308
308
  className: i(
309
- "flex min-w-0 flex-col gap-2 border-t border-kumo-line px-2 py-2",
309
+ "flex min-w-0 flex-col gap-2 border-t border-kumo-hairline px-2 py-2",
310
310
  // Collapsed: remove border, tighten padding
311
311
  "group-data-[state=collapsed]/sidebar:border-t-0 group-data-[state=collapsed]/sidebar:py-1",
312
312
  t
@@ -509,7 +509,7 @@ const re = u(
509
509
  // When a child sub-button is active, don't show active styling on the parent trigger
510
510
  "has-[[data-active]]:bg-transparent has-[[data-active]]:hover:bg-kumo-tint",
511
511
  // Focus
512
- "focus-visible:ring-1 focus-visible:ring-kumo-ring",
512
+ "focus-visible:ring-1 focus-visible:ring-kumo-hairline",
513
513
  // Collapsed: px-2 centers the icon (48px sidebar − 16px content padding = 32px;
514
514
  // 32px − 2×8px padding = 16px = icon size). Padding transition keeps it smooth.
515
515
  "group-data-[state=collapsed]/sidebar:px-2",
@@ -541,7 +541,7 @@ const re = u(
541
541
  ...m,
542
542
  children: h
543
543
  }
544
- ), l === "collapsed" && o && (f = /* @__PURE__ */ s(Re, { content: o, side: "right", asChild: !0, children: f })), x ? f : /* @__PURE__ */ s("li", { "data-sidebar": "menu-item", className: "relative", children: f });
544
+ ), l === "collapsed" && o && (f = /* @__PURE__ */ s(Re, { content: o, side: "right", render: f })), x ? f : /* @__PURE__ */ s("li", { "data-sidebar": "menu-item", className: "relative", children: f });
545
545
  }
546
546
  );
547
547
  re.displayName = "Sidebar.MenuButton";
@@ -568,7 +568,7 @@ const de = u(({ className: t, ...a }, e) => /* @__PURE__ */ s(
568
568
  ref: e,
569
569
  "data-sidebar": "menu-badge",
570
570
  className: i(
571
- "inline-flex shrink-0 items-center rounded-full border border-dashed border-kumo-line",
571
+ "inline-flex shrink-0 items-center rounded-full border border-dashed border-kumo-hairline",
572
572
  "select-none px-1.5 py-0.5 text-[11px]/none font-medium text-kumo-strong",
573
573
  // Hidden when collapsed
574
574
  "group-data-[state=collapsed]/sidebar:hidden",
@@ -584,7 +584,7 @@ const le = u(({ className: t, ...a }, e) => /* @__PURE__ */ s(
584
584
  ref: e,
585
585
  "data-sidebar": "menu-sub",
586
586
  className: i(
587
- "m-0 ml-3.5 flex min-w-0 list-none flex-col gap-0.5 border-l border-kumo-line p-0 pl-2.5",
587
+ "m-0 ml-3.5 flex min-w-0 list-none flex-col gap-0.5 border-l border-kumo-hairline p-0 pl-2.5",
588
588
  // Hidden when collapsed
589
589
  "group-data-[state=collapsed]/sidebar:hidden",
590
590
  t
@@ -610,7 +610,7 @@ const ce = u(({ className: t, active: a = !1, href: e, children: n, ...r }, o) =
610
610
  "text-kumo-default transition-colors duration-150",
611
611
  !a && "hover:bg-kumo-tint",
612
612
  a && "bg-kumo-tint",
613
- "focus-visible:ring-1 focus-visible:ring-kumo-ring",
613
+ "focus-visible:ring-1 focus-visible:ring-kumo-hairline",
614
614
  t
615
615
  ), l = /* @__PURE__ */ s("span", { className: "flex-1 truncate text-left", children: n });
616
616
  let c;
@@ -645,7 +645,7 @@ const be = u(({ className: t, ...a }, e) => /* @__PURE__ */ s(
645
645
  {
646
646
  ref: e,
647
647
  "data-sidebar": "separator",
648
- className: i("mx-2 min-h-px h-px border-0 bg-kumo-line", t),
648
+ className: i("mx-2 min-h-px h-px border-0 bg-kumo-hairline", t),
649
649
  ...a
650
650
  }
651
651
  ));
@@ -659,7 +659,7 @@ const pe = u(
659
659
  "data-sidebar": "input",
660
660
  className: i(
661
661
  "flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm",
662
- "bg-kumo-base text-kumo-subtle ring ring-kumo-line",
662
+ "bg-kumo-base text-kumo-subtle ring ring-kumo-hairline",
663
663
  "transition-[color,background-color,padding,box-shadow] duration-250 ease-[cubic-bezier(0.77,0,0.175,1)]",
664
664
  "hover:bg-kumo-overlay",
665
665
  // Collapsed: icon-only, padding centers icon, ring fades via box-shadow transition
@@ -726,15 +726,7 @@ const ge = u(({ className: t, ...a }, e) => {
726
726
  });
727
727
  ge.displayName = "Sidebar.Rail";
728
728
  const fe = u(({ className: t, ...a }, e) => {
729
- const {
730
- side: n,
731
- resizable: r,
732
- setIsResizing: o,
733
- setWidth: b,
734
- setOpen: m,
735
- open: d,
736
- minWidth: l
737
- } = T(), c = P(0), x = P(0), g = P(!1);
729
+ const { side: n, resizable: r, setIsResizing: o, setWidth: b, setOpen: m, open: d, minWidth: l } = T(), c = P(0), x = P(0), g = P(!1);
738
730
  if (!r) return null;
739
731
  const h = (p) => {
740
732
  p.preventDefault(), o(!0), c.current = p.clientX, g.current = !d;
@@ -801,13 +793,17 @@ const He = U, We = V, xe = u(({ className: t, keepMounted: a = !0, ...e }, n) =>
801
793
  keepMounted: a,
802
794
  className: i(
803
795
  "overflow-hidden",
804
- // Default: show at measured height (when data-open, no override matches)
796
+ // Default: keep the measured height that Base UI writes to --collapsible-panel-height.
797
+ // This must also remain true during the initial close frame so the exit transition has
798
+ // a real starting height before data-ending-style flips it to 0.
805
799
  "h-[var(--collapsible-panel-height)]",
806
800
  // Transition height — matches production NavGroup easing
807
801
  "transition-[height] duration-250 ease-[cubic-bezier(0.77,0,0.175,1)]",
808
802
  "motion-reduce:transition-none",
809
- // Closed / animating in / animating out: height 0
810
- "data-[closed]:h-0 data-[starting-style]:h-0 data-[ending-style]:h-0",
803
+ // Only force height 0 during the active enter/exit transition phases.
804
+ // Applying h-0 for data-closed snaps the panel shut before Base UI adds
805
+ // data-ending-style, skipping the collapse animation.
806
+ "data-[starting-style]:h-0 data-[ending-style]:h-0",
811
807
  t
812
808
  ),
813
809
  ...e
@@ -872,4 +868,4 @@ export {
872
868
  xe as y,
873
869
  T as z
874
870
  };
875
- //# sourceMappingURL=sidebar-jepeq7gaf4issuw6.js.map
871
+ //# sourceMappingURL=sidebar-ltbfius1eolkl8tb.js.map