@weasel-js/ui 1.1.0 → 1.3.0-pre.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 (237) hide show
  1. package/dist/chunks/{ActionBar-BvPEd_GW.js → ActionBar-BTev_ZZl.js} +21 -21
  2. package/dist/chunks/ActionBar-BTev_ZZl.js.map +1 -0
  3. package/dist/chunks/{ActionsBar-9aR5N3lU.js → ActionsBar-gTuCtkv8.js} +4 -4
  4. package/dist/chunks/{ActionsBar-9aR5N3lU.js.map → ActionsBar-gTuCtkv8.js.map} +1 -1
  5. package/dist/chunks/{Badge-DZQqAV4d.js → Badge-9dPfvYOk.js} +715 -707
  6. package/dist/chunks/Badge-9dPfvYOk.js.map +1 -0
  7. package/dist/chunks/{BandEditor-D3i6l299.js → BandEditor-DKbcHG2_.js} +46 -46
  8. package/dist/chunks/BandEditor-DKbcHG2_.js.map +1 -0
  9. package/dist/chunks/{Button-9QNIYugK.js → Button-CIu40Epu.js} +28 -28
  10. package/dist/chunks/Button-CIu40Epu.js.map +1 -0
  11. package/dist/chunks/{Callout-NSOjza6G.js → Callout-CHs98djt.js} +40 -39
  12. package/dist/chunks/Callout-CHs98djt.js.map +1 -0
  13. package/dist/chunks/Checkbox-BLEw-wEb.js +47 -0
  14. package/dist/chunks/Checkbox-BLEw-wEb.js.map +1 -0
  15. package/dist/chunks/ColorField-D1t-BdSa.js +60 -0
  16. package/dist/chunks/ColorField-D1t-BdSa.js.map +1 -0
  17. package/dist/chunks/{ComboBox-ONQISwtI.js → ComboBox-cvdKolWv.js} +28 -28
  18. package/dist/chunks/ComboBox-cvdKolWv.js.map +1 -0
  19. package/dist/chunks/{CurveEditor-SmwwvrsA.js → CurveEditor-BaA-PabB.js} +116 -116
  20. package/dist/chunks/CurveEditor-BaA-PabB.js.map +1 -0
  21. package/dist/chunks/DataGrid-D15I779H.js +210 -0
  22. package/dist/chunks/DataGrid-D15I779H.js.map +1 -0
  23. package/dist/chunks/Dialog-DC1x46Sq.js +59 -0
  24. package/dist/chunks/Dialog-DC1x46Sq.js.map +1 -0
  25. package/dist/chunks/{Field-VQwmrIna.js → Field-BjFl_yng.js} +6 -6
  26. package/dist/chunks/Field-BjFl_yng.js.map +1 -0
  27. package/dist/chunks/GradientEditor-BJRD0n1g.js +308 -0
  28. package/dist/chunks/GradientEditor-BJRD0n1g.js.map +1 -0
  29. package/dist/chunks/InlineRange-C6UYKxLD.js +24 -0
  30. package/dist/chunks/InlineRange-C6UYKxLD.js.map +1 -0
  31. package/dist/chunks/Input-DhWBgpRx.js +55 -0
  32. package/dist/chunks/Input-DhWBgpRx.js.map +1 -0
  33. package/dist/chunks/{Keycaps-CFX7UAj8.js → Keycaps-BhCKdyws.js} +15 -15
  34. package/dist/chunks/Keycaps-BhCKdyws.js.map +1 -0
  35. package/dist/chunks/NumberField-ZdVa4bpJ.js +59 -0
  36. package/dist/chunks/NumberField-ZdVa4bpJ.js.map +1 -0
  37. package/dist/chunks/{OptionsBar-CHvH4n4u.js → OptionsBar-DahCI4Aq.js} +4 -4
  38. package/dist/chunks/{OptionsBar-CHvH4n4u.js.map → OptionsBar-DahCI4Aq.js.map} +1 -1
  39. package/dist/chunks/PaintInput-Cggm9OIl.js +205 -0
  40. package/dist/chunks/PaintInput-Cggm9OIl.js.map +1 -0
  41. package/dist/chunks/PatternPicker-B63SlDoF.js +93 -0
  42. package/dist/chunks/PatternPicker-B63SlDoF.js.map +1 -0
  43. package/dist/chunks/{Plot2D-CEnhzodm.js → Plot2D-sPXTw_-l.js} +27 -27
  44. package/dist/chunks/{Plot2D-CEnhzodm.js.map → Plot2D-sPXTw_-l.js.map} +1 -1
  45. package/dist/chunks/{PointPlotter-BUIse9c4.js → PointPlotter-CLd9u5Bq.js} +2 -2
  46. package/dist/chunks/{PointPlotter-BUIse9c4.js.map → PointPlotter-CLd9u5Bq.js.map} +1 -1
  47. package/dist/chunks/{Powerline-Dd9Ukhcl.js → Powerline-DhQJYaUg.js} +2 -2
  48. package/dist/chunks/{Powerline-Dd9Ukhcl.js.map → Powerline-DhQJYaUg.js.map} +1 -1
  49. package/dist/chunks/Prefs-BSJ0lMmJ.js +300 -0
  50. package/dist/chunks/Prefs-BSJ0lMmJ.js.map +1 -0
  51. package/dist/chunks/RadioGroup-vtwjRiUm.js +49 -0
  52. package/dist/chunks/RadioGroup-vtwjRiUm.js.map +1 -0
  53. package/dist/chunks/RangeSlider-B-n_7AgJ.js +52 -0
  54. package/dist/chunks/RangeSlider-B-n_7AgJ.js.map +1 -0
  55. package/dist/chunks/{ResizeHandle-BOpmtOOj.js → ResizeHandle--ZExnMfa.js} +8 -8
  56. package/dist/chunks/{ResizeHandle-BOpmtOOj.js.map → ResizeHandle--ZExnMfa.js.map} +1 -1
  57. package/dist/chunks/{Select-CHsuQCp0.js → Select--BVTi-j0.js} +32 -32
  58. package/dist/chunks/Select--BVTi-j0.js.map +1 -0
  59. package/dist/chunks/SelectionPanel-C7kygTFE.js +446 -0
  60. package/dist/chunks/SelectionPanel-C7kygTFE.js.map +1 -0
  61. package/dist/chunks/{Sidebar-DP_nyJze.js → Sidebar-CtwBdr4n.js} +1 -1
  62. package/dist/chunks/{Sidebar-DP_nyJze.js.map → Sidebar-CtwBdr4n.js.map} +1 -1
  63. package/dist/chunks/SidebarPanel-AeSc7wNR.js +59 -0
  64. package/dist/chunks/SidebarPanel-AeSc7wNR.js.map +1 -0
  65. package/dist/chunks/{Slider-tGbqoAZH.js → Slider-cxWR47gi.js} +39 -39
  66. package/dist/chunks/Slider-cxWR47gi.js.map +1 -0
  67. package/dist/chunks/{StatusBar-DBO0E0Yd.js → StatusBar-D_wu-SZh.js} +6 -6
  68. package/dist/chunks/StatusBar-D_wu-SZh.js.map +1 -0
  69. package/dist/chunks/Switch-CtZwp5zm.js +27 -0
  70. package/dist/chunks/Switch-CtZwp5zm.js.map +1 -0
  71. package/dist/chunks/Tabs-lB0IB4TX.js +41 -0
  72. package/dist/chunks/Tabs-lB0IB4TX.js.map +1 -0
  73. package/dist/chunks/{Toast-DFw4IrD_.js → Toast-hr9BYsho.js} +31 -31
  74. package/dist/chunks/{Toast-DFw4IrD_.js.map → Toast-hr9BYsho.js.map} +1 -1
  75. package/dist/chunks/{ToggleBar-BP1zFcvg.js → ToggleBar-BxgWq-wO.js} +11 -10
  76. package/dist/chunks/ToggleBar-BxgWq-wO.js.map +1 -0
  77. package/dist/chunks/{ToolButton-ClPz5L6j.js → ToolButton-CJrPjbsj.js} +16 -16
  78. package/dist/chunks/ToolButton-CJrPjbsj.js.map +1 -0
  79. package/dist/chunks/{ToolGroup-BTIwd4U4.js → ToolGroup-D_lDzkvU.js} +1 -1
  80. package/dist/chunks/{ToolGroup-BTIwd4U4.js.map → ToolGroup-D_lDzkvU.js.map} +1 -1
  81. package/dist/chunks/{ToolOptionsBar-JvmY7iNe.js → ToolOptionsBar-BA6Sb3U2.js} +4 -4
  82. package/dist/chunks/ToolOptionsBar-BA6Sb3U2.js.map +1 -0
  83. package/dist/chunks/{ToolPalette-DAiVhdtV.js → ToolPalette-TMvkaJwr.js} +24 -24
  84. package/dist/chunks/ToolPalette-TMvkaJwr.js.map +1 -0
  85. package/dist/chunks/Tooltip-Di7vxbFa.js +40 -0
  86. package/dist/chunks/Tooltip-Di7vxbFa.js.map +1 -0
  87. package/dist/chunks/{keyGlyph-BDH5fqkO.js → keyGlyph-DNpLxF8u.js} +1 -1
  88. package/dist/chunks/{keyGlyph-BDH5fqkO.js.map → keyGlyph-DNpLxF8u.js.map} +1 -1
  89. package/dist/chunks/segmentedControl.module-D4b7x19O.js +11 -0
  90. package/dist/chunks/segmentedControl.module-D4b7x19O.js.map +1 -0
  91. package/dist/chunks/{useRovingTabIndex-DBZtq4IH.js → useRovingTabIndex-CQz8EiKh.js} +1 -1
  92. package/dist/chunks/{useRovingTabIndex-DBZtq4IH.js.map → useRovingTabIndex-CQz8EiKh.js.map} +1 -1
  93. package/dist/components/ActionBar/index.js +1 -1
  94. package/dist/components/ActionsBar/index.js +1 -1
  95. package/dist/components/Badge/Badge.d.ts.map +1 -1
  96. package/dist/components/Badge/bases/index.d.ts.map +1 -1
  97. package/dist/components/Badge/effects/index.d.ts.map +1 -1
  98. package/dist/components/Badge/index.js +1 -1
  99. package/dist/components/Badge/shapes/index.d.ts.map +1 -1
  100. package/dist/components/BandEditor/index.js +1 -1
  101. package/dist/components/Button/index.js +1 -1
  102. package/dist/components/Callout/Callout.d.ts.map +1 -1
  103. package/dist/components/Callout/index.js +1 -1
  104. package/dist/components/Checkbox/Checkbox.d.ts +1 -1
  105. package/dist/components/Checkbox/index.js +1 -1
  106. package/dist/components/ColorField/ColorField.d.ts.map +1 -1
  107. package/dist/components/ColorField/index.js +1 -1
  108. package/dist/components/ComboBox/index.js +1 -1
  109. package/dist/components/CurveEditor/LayeredCurveEditor.d.ts +1 -1
  110. package/dist/components/CurveEditor/LayeredCurveEditor.d.ts.map +1 -1
  111. package/dist/components/CurveEditor/createFunctionLayer.d.ts +1 -2
  112. package/dist/components/CurveEditor/createFunctionLayer.d.ts.map +1 -1
  113. package/dist/components/CurveEditor/index.js +1 -1
  114. package/dist/components/DataGrid/index.js +1 -1
  115. package/dist/components/Dialog/index.js +1 -1
  116. package/dist/components/Field/index.js +1 -1
  117. package/dist/components/GradientEditor/SceneGradientHandles.d.ts +41 -0
  118. package/dist/components/GradientEditor/SceneGradientHandles.d.ts.map +1 -0
  119. package/dist/components/GradientEditor/index.d.ts +1 -0
  120. package/dist/components/GradientEditor/index.d.ts.map +1 -1
  121. package/dist/components/GradientEditor/index.js +2 -2
  122. package/dist/components/InlineRange/InlineRange.d.ts +17 -0
  123. package/dist/components/InlineRange/InlineRange.d.ts.map +1 -0
  124. package/dist/components/InlineRange/index.d.ts +2 -0
  125. package/dist/components/InlineRange/index.d.ts.map +1 -0
  126. package/dist/components/InlineRange/index.js +2 -0
  127. package/dist/components/Input/Input.d.ts +1 -1
  128. package/dist/components/Input/index.js +1 -1
  129. package/dist/components/Keycaps/index.js +2 -2
  130. package/dist/components/NumberField/NumberField.d.ts +1 -1
  131. package/dist/components/NumberField/index.js +1 -1
  132. package/dist/components/OptionsBar/index.js +1 -1
  133. package/dist/components/PaintInput/PaintInput.d.ts +40 -0
  134. package/dist/components/PaintInput/PaintInput.d.ts.map +1 -0
  135. package/dist/components/PaintInput/index.d.ts +2 -0
  136. package/dist/components/PaintInput/index.d.ts.map +1 -0
  137. package/dist/components/PaintInput/index.js +2 -0
  138. package/dist/components/PatternPicker/PatternPicker.d.ts +31 -0
  139. package/dist/components/PatternPicker/PatternPicker.d.ts.map +1 -0
  140. package/dist/components/PatternPicker/index.d.ts +2 -0
  141. package/dist/components/PatternPicker/index.d.ts.map +1 -0
  142. package/dist/components/PatternPicker/index.js +2 -0
  143. package/dist/components/Plot2D/Plot2D.d.ts.map +1 -1
  144. package/dist/components/Plot2D/index.js +1 -1
  145. package/dist/components/PointPlotter/index.js +1 -1
  146. package/dist/components/Powerline/index.js +2 -2
  147. package/dist/components/Prefs/PrefsForm.d.ts.map +1 -1
  148. package/dist/components/Prefs/index.d.ts +1 -1
  149. package/dist/components/Prefs/index.d.ts.map +1 -1
  150. package/dist/components/Prefs/index.js +1 -1
  151. package/dist/components/Prefs/schema.d.ts +4 -93
  152. package/dist/components/Prefs/schema.d.ts.map +1 -1
  153. package/dist/components/RadioGroup/index.js +1 -1
  154. package/dist/components/RangeSlider/index.js +1 -1
  155. package/dist/components/ResizeHandle/index.js +1 -1
  156. package/dist/components/Select/index.js +1 -1
  157. package/dist/components/SelectionPanel/SelectionPanel.d.ts +32 -1
  158. package/dist/components/SelectionPanel/SelectionPanel.d.ts.map +1 -1
  159. package/dist/components/SelectionPanel/index.js +1 -1
  160. package/dist/components/Sidebar/index.js +1 -1
  161. package/dist/components/SidebarPanel/index.js +1 -1
  162. package/dist/components/Slider/index.js +1 -1
  163. package/dist/components/StatusBar/index.js +1 -1
  164. package/dist/components/Switch/Switch.d.ts +1 -1
  165. package/dist/components/Switch/index.js +1 -1
  166. package/dist/components/Tabs/index.js +1 -1
  167. package/dist/components/Toast/index.js +1 -1
  168. package/dist/components/ToggleBar/ToggleBar.d.ts +1 -1
  169. package/dist/components/ToggleBar/ToggleBar.d.ts.map +1 -1
  170. package/dist/components/ToggleBar/index.js +1 -1
  171. package/dist/components/ToolButton/index.js +1 -1
  172. package/dist/components/ToolGroup/index.js +1 -1
  173. package/dist/components/ToolOptionsBar/index.js +1 -1
  174. package/dist/components/ToolPalette/index.js +1 -1
  175. package/dist/components/Tooltip/index.js +1 -1
  176. package/dist/components/paintValue.d.ts +8 -0
  177. package/dist/components/paintValue.d.ts.map +1 -0
  178. package/dist/icons/Icon.d.ts +17 -0
  179. package/dist/icons/Icon.d.ts.map +1 -0
  180. package/dist/icons/index.d.ts +50 -0
  181. package/dist/icons/index.d.ts.map +1 -0
  182. package/dist/icons/paths.d.ts +71 -0
  183. package/dist/icons/paths.d.ts.map +1 -0
  184. package/dist/index.d.ts +5 -0
  185. package/dist/index.d.ts.map +1 -1
  186. package/dist/index.js +184 -48
  187. package/dist/index.js.map +1 -1
  188. package/dist/style.css +1 -1
  189. package/package.json +4 -3
  190. package/dist/chunks/ActionBar-BvPEd_GW.js.map +0 -1
  191. package/dist/chunks/Badge-DZQqAV4d.js.map +0 -1
  192. package/dist/chunks/BandEditor-D3i6l299.js.map +0 -1
  193. package/dist/chunks/Button-9QNIYugK.js.map +0 -1
  194. package/dist/chunks/Callout-NSOjza6G.js.map +0 -1
  195. package/dist/chunks/Checkbox-KQ5L8APP.js +0 -47
  196. package/dist/chunks/Checkbox-KQ5L8APP.js.map +0 -1
  197. package/dist/chunks/ColorField-ykpiD3XU.js +0 -60
  198. package/dist/chunks/ColorField-ykpiD3XU.js.map +0 -1
  199. package/dist/chunks/ComboBox-ONQISwtI.js.map +0 -1
  200. package/dist/chunks/CurveEditor-SmwwvrsA.js.map +0 -1
  201. package/dist/chunks/DataGrid-DZQ4Chbd.js +0 -210
  202. package/dist/chunks/DataGrid-DZQ4Chbd.js.map +0 -1
  203. package/dist/chunks/Dialog-CqwdJv_t.js +0 -59
  204. package/dist/chunks/Dialog-CqwdJv_t.js.map +0 -1
  205. package/dist/chunks/Field-VQwmrIna.js.map +0 -1
  206. package/dist/chunks/GradientEditor-Bg6SX64V.js +0 -280
  207. package/dist/chunks/GradientEditor-Bg6SX64V.js.map +0 -1
  208. package/dist/chunks/Input-DpkwYtUY.js +0 -55
  209. package/dist/chunks/Input-DpkwYtUY.js.map +0 -1
  210. package/dist/chunks/Keycaps-CFX7UAj8.js.map +0 -1
  211. package/dist/chunks/NumberField-BbzI0GtU.js +0 -59
  212. package/dist/chunks/NumberField-BbzI0GtU.js.map +0 -1
  213. package/dist/chunks/Prefs-BMR9wMiZ.js +0 -238
  214. package/dist/chunks/Prefs-BMR9wMiZ.js.map +0 -1
  215. package/dist/chunks/RadioGroup-CIpHr3g6.js +0 -49
  216. package/dist/chunks/RadioGroup-CIpHr3g6.js.map +0 -1
  217. package/dist/chunks/RangeSlider-CaDogGTj.js +0 -52
  218. package/dist/chunks/RangeSlider-CaDogGTj.js.map +0 -1
  219. package/dist/chunks/Select-CHsuQCp0.js.map +0 -1
  220. package/dist/chunks/SelectionPanel-D_wk_8ZN.js +0 -303
  221. package/dist/chunks/SelectionPanel-D_wk_8ZN.js.map +0 -1
  222. package/dist/chunks/SidebarPanel-BVTQ1ZyM.js +0 -59
  223. package/dist/chunks/SidebarPanel-BVTQ1ZyM.js.map +0 -1
  224. package/dist/chunks/Slider-tGbqoAZH.js.map +0 -1
  225. package/dist/chunks/StatusBar-DBO0E0Yd.js.map +0 -1
  226. package/dist/chunks/Switch-JyVSSAzC.js +0 -27
  227. package/dist/chunks/Switch-JyVSSAzC.js.map +0 -1
  228. package/dist/chunks/Tabs-Df0sDomx.js +0 -41
  229. package/dist/chunks/Tabs-Df0sDomx.js.map +0 -1
  230. package/dist/chunks/ToggleBar-BP1zFcvg.js.map +0 -1
  231. package/dist/chunks/ToolButton-ClPz5L6j.js.map +0 -1
  232. package/dist/chunks/ToolOptionsBar-JvmY7iNe.js.map +0 -1
  233. package/dist/chunks/ToolPalette-DAiVhdtV.js.map +0 -1
  234. package/dist/chunks/Tooltip-DXJbdR5B.js +0 -40
  235. package/dist/chunks/Tooltip-DXJbdR5B.js.map +0 -1
  236. package/dist/chunks/segmentedControl.module-DCyuDbj1.js +0 -11
  237. package/dist/chunks/segmentedControl.module-DCyuDbj1.js.map +0 -1
@@ -1,16 +1,16 @@
1
- import { Fragment as e, useEffect as t, useId as n, useRef as r } from "react";
2
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
1
+ import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
+ import { Fragment as n, useEffect as r, useId as i, useRef as a } from "react";
3
3
  var o = {
4
- root: "_root_amv2k_1",
5
- label: "_label_amv2k_11",
6
- ruler: "_ruler_amv2k_19",
7
- tick: "_tick_amv2k_25",
8
- tickLabel: "_tickLabel_amv2k_35",
9
- bands: "_bands_amv2k_45",
10
- band: "_band_amv2k_45",
11
- selected: "_selected_amv2k_92",
12
- bandContent: "_bandContent_amv2k_99",
13
- seam: "_seam_amv2k_107"
4
+ root: "_root_1mpyk_1",
5
+ label: "_label_1mpyk_11",
6
+ ruler: "_ruler_1mpyk_19",
7
+ tick: "_tick_1mpyk_25",
8
+ tickLabel: "_tickLabel_1mpyk_35",
9
+ bands: "_bands_1mpyk_45",
10
+ band: "_band_1mpyk_45",
11
+ selected: "_selected_1mpyk_92",
12
+ bandContent: "_bandContent_1mpyk_99",
13
+ seam: "_seam_1mpyk_107"
14
14
  };
15
15
  //#endregion
16
16
  //#region src/components/BandEditor/scale.ts
@@ -108,11 +108,11 @@ function D(e) {
108
108
  return t === "INPUT" || t === "TEXTAREA" || t === "SELECT";
109
109
  }
110
110
  function O(c) {
111
- let { value: l, onInput: u, onChange: d, min: O, max: k, scale: A, ticks: j, renderBand: M, selectedIndex: N, onSelect: P, label: F, className: I } = c, L = c.snap ?? !0, R = c.splitBand ?? E, z = r(null), B = r(null);
112
- t(() => () => {
111
+ let { value: l, onInput: u, onChange: d, min: O, max: k, scale: A, ticks: j, renderBand: M, selectedIndex: N, onSelect: P, label: F, className: I } = c, L = c.snap ?? !0, R = c.splitBand ?? E, z = a(null), B = a(null);
112
+ r(() => () => {
113
113
  B.current?.();
114
114
  }, []);
115
- let V = n(), H = p(l, O), U = f(A, O), W = (e) => s(U.toUnit(e, O, k)), G = (e) => U.fromUnit(s(e), O, k), K = () => z.current?.getBoundingClientRect().width ?? 0, q = (e) => {
115
+ let V = i(), H = p(l, O), U = f(A, O), W = (e) => s(U.toUnit(e, O, k)), G = (e) => U.fromUnit(s(e), O, k), K = () => z.current?.getBoundingClientRect().width ?? 0, q = (e) => {
116
116
  let t = z.current?.getBoundingClientRect();
117
117
  return !t || t.width === 0 ? 0 : s((e - t.left) / t.width);
118
118
  }, J = (e, t) => {
@@ -167,7 +167,7 @@ function O(c) {
167
167
  }, $ = (e) => () => {
168
168
  e !== N && P?.(e);
169
169
  };
170
- return /* @__PURE__ */ a("div", {
170
+ return /* @__PURE__ */ t("div", {
171
171
  className: [o.root, I].filter(Boolean).join(" "),
172
172
  role: "group",
173
173
  "aria-label": typeof F == "string" ? F : void 0,
@@ -178,12 +178,12 @@ function O(c) {
178
178
  t !== H && (e.preventDefault(), d(t), P?.(N - 1));
179
179
  },
180
180
  children: [
181
- F !== void 0 && /* @__PURE__ */ i("div", {
181
+ F !== void 0 && /* @__PURE__ */ e("div", {
182
182
  id: V,
183
183
  className: o.label,
184
184
  children: F
185
185
  }),
186
- /* @__PURE__ */ i("div", {
186
+ /* @__PURE__ */ e("div", {
187
187
  className: o.ruler,
188
188
  ref: z,
189
189
  "data-band-ruler": "",
@@ -193,50 +193,50 @@ function O(c) {
193
193
  let t = x(H, G(q(e.clientX)), O, k, R);
194
194
  t !== H && d(t);
195
195
  },
196
- children: j?.map((e, t) => /* @__PURE__ */ i("span", {
196
+ children: j?.map((t, n) => /* @__PURE__ */ e("span", {
197
197
  className: o.tick,
198
- "data-tick-at": e.at,
199
- style: { "--be-at": T(W(e.at)) },
200
- children: e.label !== void 0 && /* @__PURE__ */ i("span", {
198
+ "data-tick-at": t.at,
199
+ style: { "--be-at": T(W(t.at)) },
200
+ children: t.label !== void 0 && /* @__PURE__ */ e("span", {
201
201
  className: o.tickLabel,
202
- children: e.label
202
+ children: t.label
203
203
  })
204
- }, t))
204
+ }, n))
205
205
  }),
206
- /* @__PURE__ */ i("div", {
206
+ /* @__PURE__ */ e("div", {
207
207
  className: o.bands,
208
- children: H.map((t, n) => {
209
- let [r, s] = m(H, n, O, k), c = N === n;
210
- return /* @__PURE__ */ a(e, { children: [/* @__PURE__ */ i("button", {
208
+ children: H.map((r, i) => {
209
+ let [a, s] = m(H, i, O, k), c = N === i;
210
+ return /* @__PURE__ */ t(n, { children: [/* @__PURE__ */ e("button", {
211
211
  type: "button",
212
212
  className: [o.band, c ? o.selected : null].filter(Boolean).join(" "),
213
213
  style: {
214
- "--be-from": T(W(r)),
214
+ "--be-from": T(W(a)),
215
215
  "--be-to": T(W(s))
216
216
  },
217
- "aria-label": `Band ${n + 1}`,
217
+ "aria-label": `Band ${i + 1}`,
218
218
  "aria-pressed": c,
219
- "data-band-index": n,
220
- onPointerDown: Q(n),
221
- onFocus: $(n),
222
- children: /* @__PURE__ */ i("span", {
219
+ "data-band-index": i,
220
+ onPointerDown: Q(i),
221
+ onFocus: $(i),
222
+ children: /* @__PURE__ */ e("span", {
223
223
  className: o.bandContent,
224
- children: M?.(t, n)
224
+ children: M?.(r, i)
225
225
  })
226
- }), n < H.length - 1 && /* @__PURE__ */ i("div", {
226
+ }), i < H.length - 1 && /* @__PURE__ */ e("div", {
227
227
  role: "slider",
228
228
  tabIndex: 0,
229
229
  className: o.seam,
230
- style: { "--be-at": T(W(H[n + 1].from)) },
231
- "aria-label": `Seam ${n + 1}`,
230
+ style: { "--be-at": T(W(H[i + 1].from)) },
231
+ "aria-label": `Seam ${i + 1}`,
232
232
  "aria-orientation": "horizontal",
233
- "aria-valuemin": h(H, n, O, k)[0],
234
- "aria-valuemax": h(H, n, O, k)[1],
235
- "aria-valuenow": H[n + 1].from,
236
- "data-seam-index": n,
237
- onPointerDown: X(n),
238
- onKeyDown: Z(n)
239
- })] }, n);
233
+ "aria-valuemin": h(H, i, O, k)[0],
234
+ "aria-valuemax": h(H, i, O, k)[1],
235
+ "aria-valuenow": H[i + 1].from,
236
+ "data-seam-index": i,
237
+ onPointerDown: X(i),
238
+ onKeyDown: Z(i)
239
+ })] }, i);
240
240
  })
241
241
  })
242
242
  ]
@@ -245,4 +245,4 @@ function O(c) {
245
245
  //#endregion
246
246
  export { c as n, l as r, O as t };
247
247
 
248
- //# sourceMappingURL=BandEditor-D3i6l299.js.map
248
+ //# sourceMappingURL=BandEditor-DKbcHG2_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BandEditor-DKbcHG2_.js","names":[],"sources":["../../src/components/BandEditor/BandEditor.module.css","../../src/components/BandEditor/scale.ts","../../src/components/BandEditor/bands.ts","../../src/components/BandEditor/BandEditor.tsx"],"sourcesContent":[".root {\n position: relative;\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.label {\n font: var(--wzl-font-weight-medium) var(--wzl-font-size-sm) / var(--wzl-leading-tight) var(--wzl-font-ui);\n color: var(--wzl-fg-muted);\n}\n\n/* The ruler carries the ticks and is the split affordance: a click anywhere\n * on it divides the band underneath. The band strip below owns selection and\n * body drags, so neither gesture has to guess which the pointer meant. */\n.ruler {\n position: relative;\n height: var(--be-ruler-height, 20px);\n cursor: crosshair;\n}\n\n.tick {\n position: absolute;\n left: var(--be-at);\n bottom: 0;\n width: 1px;\n height: 6px;\n background: var(--wzl-fg-subtle);\n pointer-events: none;\n}\n\n.tickLabel {\n position: absolute;\n bottom: 7px;\n left: 0;\n transform: translateX(-50%);\n font: var(--wzl-font-weight-medium) var(--wzl-font-size-xs) / var(--wzl-leading-tight) var(--wzl-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n color: var(--wzl-fg-muted);\n white-space: nowrap;\n}\n\n.bands {\n position: relative;\n height: var(--be-band-height, 34px);\n}\n\n.band {\n position: absolute;\n top: 0;\n bottom: 0;\n left: var(--be-from);\n width: calc(var(--be-to) - var(--be-from));\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 0 4px;\n margin: 0;\n background: var(--wzl-surface-raised);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-fg);\n font: var(--wzl-font-weight-medium) var(--wzl-font-size-sm) / var(--wzl-leading-tight) var(--wzl-font-ui, ui-sans-serif, system-ui, sans-serif);\n cursor: grab;\n}\n\n.band:hover {\n background: var(--wzl-surface-hover);\n}\n\n.band:active {\n cursor: grabbing;\n}\n\n.band:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: -2px;\n}\n\n/* First and last bands are pinned to `min` / `max`, so their bodies do not\n * translate — the cursor should not promise otherwise. */\n.band:first-of-type,\n.band:last-of-type {\n cursor: default;\n}\n\n/* Accent mixed toward transparent rather than a flat token, so the tint\n reads over whatever surface the consumer's theme puts behind it. */\n.selected {\n background: color-mix(in srgb, var(--wzl-accent) 22%, transparent);\n border-color: var(--wzl-accent);\n box-shadow: inset 0 0 0 1px var(--wzl-accent);\n color: var(--wzl-fg);\n}\n\n.bandContent {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n pointer-events: none;\n}\n\n/* Wider than the line it draws: a 1px seam is unhittable. */\n.seam {\n position: absolute;\n left: var(--be-at);\n top: -3px;\n bottom: -3px;\n width: 11px;\n margin-left: -5px;\n z-index: 1;\n cursor: ew-resize;\n background: none;\n border: none;\n}\n\n.seam::before {\n content: '';\n position: absolute;\n top: 0;\n bottom: 0;\n left: 5px;\n width: 1px;\n background: var(--wzl-border-strong);\n}\n\n.seam:hover::before,\n.seam:focus-visible::before {\n background: var(--wzl-accent);\n width: 2px;\n}\n\n.seam:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: 0;\n border-radius: var(--wzl-radius-sm);\n}\n","/**\n * Maps a domain value onto its position along the track, and back.\n *\n * Deliberately narrow — two functions over an explicit `[min, max]` — rather\n * than a general scale type for the package. `Plot2D`, `CurveEditor` and\n * `@weasel-js/core` each already use \"scale\" or \"domain\" to mean something\n * else; generalizing is a job for a second consumer that needs one.\n */\nexport interface BandScale {\n /** Domain → position in [0,1]. Must be monotonic increasing. */\n toUnit(value: number, min: number, max: number): number;\n /** Inverse of `toUnit`. */\n fromUnit(unit: number, min: number, max: number): number;\n}\n\nexport function clamp01(u: number): number {\n return u < 0 ? 0 : u > 1 ? 1 : u;\n}\n\n/** Even domain steps take even track steps. */\nexport const linearScale: BandScale = {\n toUnit: (value, min, max) => (max === min ? 0 : (value - min) / (max - min)),\n fromUnit: (unit, min, max) => min + unit * (max - min),\n};\n\n/** Even *ratios* take even track steps. Requires `min > 0`. */\nexport const logScale: BandScale = {\n toUnit: (value, min, max) => {\n const lo = Math.log(min);\n const hi = Math.log(max);\n return hi === lo ? 0 : (Math.log(value) - lo) / (hi - lo);\n },\n fromUnit: (unit, min, max) => {\n const lo = Math.log(min);\n return Math.exp(lo + unit * (Math.log(max) - lo));\n },\n};\n\nlet warnedNonPositiveMin = false;\n\nfunction isDev(): boolean {\n return typeof process !== 'undefined' ? process.env.NODE_ENV !== 'production' : true;\n}\n\n/**\n * Resolves the `scale` prop, substituting `linearScale` for a `logScale`\n * that `min` would send to `NaN`.\n */\nexport function resolveScale(\n scale: 'linear' | 'log' | BandScale | undefined,\n min: number,\n): BandScale {\n const requested =\n scale === undefined || scale === 'log'\n ? logScale\n : scale === 'linear'\n ? linearScale\n : scale;\n\n if (requested !== logScale || min > 0) return requested;\n\n if (isDev() && !warnedNonPositiveMin) {\n warnedNonPositiveMin = true;\n console.warn(\n `BandEditor: a log scale needs min > 0, but min is ${min}. Falling back to a linear scale. ` +\n `Pass scale=\"linear\" to silence this.`,\n );\n }\n return linearScale;\n}\n","import type { BandScale } from './scale';\nimport { clamp01 } from './scale';\n\nexport interface Band<T> {\n /** Domain value where this band starts. The first band's is normalized to `min`. */\n from: number;\n data: T;\n}\n\n/**\n * A band list covers `[min, max]` exactly: N bands, N−1 interior seams, no\n * gaps and no overlaps. Seam *k* is `bands[k + 1].from`, and lives between\n * `bands[k].from` and the start of the band after next (or `max`).\n *\n * Every function here preserves that. Each returns the array it was given\n * when the edit would be a no-op, so callers can skip a callback with `===`.\n */\n\n/** Pins the first band's start to `min`; leaves the rest alone. */\nexport function normalizeBands<T>(value: readonly Band<T>[], min: number): Band<T>[] {\n const bands = value.map((b) => ({ ...b }));\n if (bands.length > 0) bands[0].from = min;\n return bands;\n}\n\n/** `[from, to]` of band `index` in domain space. */\nexport function bandBounds<T>(\n bands: readonly Band<T>[],\n index: number,\n min: number,\n max: number,\n): [number, number] {\n const from = index === 0 ? min : bands[index].from;\n const to = index === bands.length - 1 ? max : bands[index + 1].from;\n return [from, to];\n}\n\n/** How far seam `index` can travel before it would cross a neighbour. */\nexport function seamBounds<T>(\n bands: readonly Band<T>[],\n index: number,\n min: number,\n max: number,\n): [number, number] {\n const lo = index === 0 ? min : bands[index].from;\n const hi = index + 2 <= bands.length - 1 ? bands[index + 2].from : max;\n return [lo, hi];\n}\n\n/** Clamps a target position for seam `index` to its neighbours, inclusive. */\nexport function clampSeamTo<T>(\n bands: readonly Band<T>[],\n index: number,\n to: number,\n min: number,\n max: number,\n): number {\n const [lo, hi] = seamBounds(bands, index, min, max);\n return Math.max(lo, Math.min(hi, to));\n}\n\nexport function setSeam<T>(bands: readonly Band<T>[], index: number, to: number): Band<T>[] {\n if (bands[index + 1] === undefined || bands[index + 1].from === to) return bands as Band<T>[];\n const next = bands.map((b) => ({ ...b }));\n next[index + 1].from = to;\n return next;\n}\n\n/** Band edges as track positions: `length + 1` values from 0 to 1. */\nexport function unitEdges<T>(\n bands: readonly Band<T>[],\n scale: BandScale,\n min: number,\n max: number,\n): number[] {\n const edges = bands.map((b, i) => (i === 0 ? 0 : clamp01(scale.toUnit(b.from, min, max))));\n edges.push(1);\n return edges;\n}\n\n/**\n * Largest part of `shift` band `index` can take without pushing a neighbour's\n * far edge past it. Zero for the first and last band, whose outer edges are\n * `min` and `max` and do not move.\n */\nexport function clampBandShift(edges: readonly number[], index: number, shift: number): number {\n const isFirst = index === 0;\n const isLast = index === edges.length - 2;\n if (isFirst || isLast) return 0;\n const lo = edges[index - 1] - edges[index];\n const hi = edges[index + 2] - edges[index + 1];\n return Math.max(lo, Math.min(hi, shift));\n}\n\n/** Moves both edges of band `index`, which is the same as moving two seams. */\nexport function moveBandEdges<T>(\n bands: readonly Band<T>[],\n index: number,\n from: number,\n to: number,\n): Band<T>[] {\n const next = bands.map((b) => ({ ...b }));\n next[index].from = from;\n if (next[index + 1] !== undefined) next[index + 1].from = to;\n return next;\n}\n\n/**\n * Splits the band containing `at` in two, the new band starting there.\n * A position already on a seam or on `min` / `max` splits nothing.\n */\nexport function splitBands<T>(\n bands: readonly Band<T>[],\n at: number,\n min: number,\n max: number,\n makeData: (at: number, from: T) => T,\n): Band<T>[] {\n if (bands.length === 0 || at <= min || at >= max) return bands as Band<T>[];\n let index = -1;\n for (let i = 0; i < bands.length; i++) {\n const [from, to] = bandBounds(bands, i, min, max);\n if (at > from && at < to) {\n index = i;\n break;\n }\n }\n if (index < 0) return bands as Band<T>[];\n const next = bands.map((b) => ({ ...b }));\n next.splice(index + 1, 0, { from: at, data: makeData(at, bands[index].data) });\n return next;\n}\n\n/**\n * Merges band `index` into its left neighbour, which keeps its payload and\n * absorbs the span. The first band has no left neighbour and cannot be\n * merged away — a partition always has at least one part.\n */\nexport function mergeBand<T>(bands: readonly Band<T>[], index: number): Band<T>[] {\n if (index <= 0 || index >= bands.length) return bands as Band<T>[];\n return bands.filter((_, i) => i !== index).map((b) => ({ ...b }));\n}\n","import {\n Fragment,\n useEffect,\n useId,\n useRef,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport s from './BandEditor.module.css';\nimport { clamp01, resolveScale, type BandScale } from './scale';\nimport {\n bandBounds,\n clampBandShift,\n clampSeamTo,\n mergeBand,\n moveBandEdges,\n normalizeBands,\n seamBounds,\n setSeam,\n splitBands,\n unitEdges,\n type Band,\n} from './bands';\n\nexport type { Band, BandScale };\n\nexport interface BandEditorProps<T> {\n /** Ascending by `from`. `value[0].from` is normalized to `min` on read. */\n value: Band<T>[];\n /** Live during a drag — wire for preview, do not write to history. */\n onInput?: (next: Band<T>[]) => void;\n /** Committed at gesture end: one call per gesture. */\n onChange: (next: Band<T>[]) => void;\n min: number;\n max: number;\n /** Default `'log'`. */\n scale?: 'linear' | 'log' | BandScale;\n ticks?: { at: number; label?: ReactNode }[];\n /** Snap a dragged seam to a tick within ~6px. Default true; `alt` defeats it per-drag. */\n snap?: boolean;\n renderBand?: (band: Band<T>, index: number) => ReactNode;\n selectedIndex?: number | null;\n onSelect?: (index: number) => void;\n /** Payload for a band split off an existing one. Default duplicates `from`. */\n splitBand?: (at: number, from: T) => T;\n label?: ReactNode;\n className?: string;\n}\n\n/** Snap radius, in track pixels. */\nconst SNAP_PX = 6;\n\n/** One arrow-key step, as a fraction of the track. */\nconst KEY_STEP = 0.01;\n\nfunction pct(unit: number): string {\n return `${clamp01(unit) * 100}%`;\n}\n\nfunction keepData<T>(_at: number, from: T): T {\n return from;\n}\n\nfunction isTextEntry(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n const tag = target.tagName;\n return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT';\n}\n\n/**\n * Divides a numeric axis into contiguous bands and lets you drag the seams\n * between them. Each band carries a payload the consumer supplies and\n * renders through `renderBand`; the control itself knows nothing about what\n * a band means.\n *\n * The axis is always fully covered — N bands, N−1 interior seams, no gaps and\n * no overlaps — so editing is editing a sorted list of seam positions. Seams\n * clamp at their neighbours rather than crossing, which means a drag can\n * never destroy a band: removal is only ever the explicit `x` / `Delete`\n * merge. The first band is doubly exceptional, its left edge pinned to `min`\n * and its body immovable, and it has no left neighbour to merge into.\n *\n * | Gesture | Effect |\n * |---|---|\n * | drag a seam | resize the two bands either side |\n * | drag a band body | move both its seams, preserving its span |\n * | click the ruler | split the band under the pointer |\n * | `x` / `Delete` | merge the selected band into its left neighbour |\n * | click a band | select it |\n * | `←` `→` on a focused seam | move it by one step; `shift` for ten |\n *\n * `scale` defaults to `'log'`, because the interesting part of a width axis\n * is usually its narrow end.\n */\nexport function BandEditor<T>(props: BandEditorProps<T>): ReactElement {\n const {\n value,\n onInput,\n onChange,\n min,\n max,\n scale,\n ticks,\n renderBand,\n selectedIndex,\n onSelect,\n label,\n className,\n } = props;\n const snap = props.snap ?? true;\n const splitBand = props.splitBand ?? keepData;\n\n const trackRef = useRef<HTMLDivElement | null>(null);\n const endDragRef = useRef<(() => void) | null>(null);\n useEffect(() => () => { endDragRef.current?.(); }, []);\n const labelId = useId();\n const bands = normalizeBands(value, min);\n const sc = resolveScale(scale, min);\n const toUnit = (v: number): number => clamp01(sc.toUnit(v, min, max));\n const fromUnit = (u: number): number => sc.fromUnit(clamp01(u), min, max);\n\n const trackWidth = (): number => trackRef.current?.getBoundingClientRect().width ?? 0;\n\n const unitAt = (clientX: number): number => {\n const rect = trackRef.current?.getBoundingClientRect();\n if (!rect || rect.width === 0) return 0;\n return clamp01((clientX - rect.left) / rect.width);\n };\n\n const snapped = (unit: number, altKey: boolean): number => {\n if (!snap || altKey || !ticks || ticks.length === 0) return unit;\n const width = trackWidth();\n if (width === 0) return unit;\n let best = unit;\n let bestDistance = SNAP_PX / width;\n for (const tick of ticks) {\n const tickUnit = toUnit(tick.at);\n const distance = Math.abs(tickUnit - unit);\n if (distance <= bestDistance) {\n bestDistance = distance;\n best = tickUnit;\n }\n }\n return best;\n };\n\n const drag = (onMove: (ev: PointerEvent) => void, onEnd: () => void): void => {\n const move = (ev: PointerEvent): void => onMove(ev);\n const unlisten = (): void => {\n document.removeEventListener('pointermove', move);\n document.removeEventListener('pointerup', up);\n document.removeEventListener('pointercancel', cancel);\n endDragRef.current = null;\n };\n // A canceled pointer never fires `pointerup`; without this the seam keeps\n // tracking a released pointer and the gesture never commits.\n const cancel = (): void => unlisten();\n const up = (): void => {\n unlisten();\n onEnd();\n };\n document.addEventListener('pointermove', move);\n document.addEventListener('pointerup', up);\n document.addEventListener('pointercancel', cancel);\n endDragRef.current = cancel;\n };\n\n const onSeamPointerDown = (index: number) => (e: ReactPointerEvent<HTMLDivElement>): void => {\n if (typeof e.button === 'number' && e.button > 0) return;\n e.preventDefault();\n e.stopPropagation();\n const base = bands;\n let latest: Band<T>[] | null = null;\n drag(\n (ev) => {\n const to = clampSeamTo(base, index, fromUnit(snapped(unitAt(ev.clientX), ev.altKey)), min, max);\n latest = setSeam(base, index, to);\n onInput?.(latest);\n },\n () => {\n if (latest) onChange(latest);\n },\n );\n };\n\n const onSeamKeyDown = (index: number) => (e: ReactKeyboardEvent<HTMLDivElement>): void => {\n const [lo, hi] = seamBounds(bands, index, min, max);\n let target: number;\n if (e.key === 'Home') target = lo;\n else if (e.key === 'End') target = hi;\n else {\n let delta = 0;\n if (e.key === 'ArrowRight' || e.key === 'ArrowUp') delta = e.shiftKey ? KEY_STEP * 10 : KEY_STEP;\n else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') delta = e.shiftKey ? -KEY_STEP * 10 : -KEY_STEP;\n else return;\n target = fromUnit(toUnit(bands[index + 1].from) + delta);\n }\n e.preventDefault();\n const next = setSeam(bands, index, clampSeamTo(bands, index, target, min, max));\n if (next !== bands) onChange(next);\n };\n\n const onBandPointerDown = (index: number) => (e: ReactPointerEvent<HTMLButtonElement>): void => {\n if (typeof e.button === 'number' && e.button > 0) return;\n if (index !== selectedIndex) onSelect?.(index);\n // The first and last bands' outer edges are `min` and `max`, which do not\n // move, so their bodies have nothing to translate.\n if (index === 0 || index === bands.length - 1) return;\n const base = bands;\n const edges = unitEdges(base, sc, min, max);\n const startUnit = unitAt(e.clientX);\n let latest: Band<T>[] | null = null;\n drag(\n (ev) => {\n const shift = clampBandShift(edges, index, unitAt(ev.clientX) - startUnit);\n latest = moveBandEdges(\n base,\n index,\n fromUnit(edges[index] + shift),\n fromUnit(edges[index + 1] + shift),\n );\n onInput?.(latest);\n },\n () => {\n if (latest) onChange(latest);\n },\n );\n };\n\n const onBandFocus = (index: number) => (): void => {\n if (index !== selectedIndex) onSelect?.(index);\n };\n\n const onTrackPointerDown = (e: ReactPointerEvent<HTMLDivElement>): void => {\n if (typeof e.button === 'number' && e.button > 0) return;\n e.preventDefault();\n const next = splitBands(bands, fromUnit(unitAt(e.clientX)), min, max, splitBand);\n if (next !== bands) onChange(next);\n };\n\n const onRootKeyDown = (e: ReactKeyboardEvent<HTMLDivElement>): void => {\n if (e.key !== 'x' && e.key !== 'Delete') return;\n // `x` is a bare letter and Cmd/Ctrl+X is cut: neither may be swallowed\n // when the keystroke belongs to something a consumer put in a band.\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n if (isTextEntry(e.target)) return;\n if (selectedIndex === null || selectedIndex === undefined) return;\n const next = mergeBand(bands, selectedIndex);\n if (next === bands) return;\n e.preventDefault();\n onChange(next);\n onSelect?.(selectedIndex - 1);\n };\n\n return (\n <div\n className={[s.root, className].filter(Boolean).join(' ')}\n role=\"group\"\n aria-label={typeof label === 'string' ? label : undefined}\n aria-labelledby={label !== undefined && typeof label !== 'string' ? labelId : undefined}\n onKeyDown={onRootKeyDown}\n >\n {label !== undefined && <div id={labelId} className={s.label}>{label}</div>}\n <div className={s.ruler} ref={trackRef} data-band-ruler=\"\" onPointerDown={onTrackPointerDown}>\n {ticks?.map((tick, i) => (\n <span\n key={i}\n className={s.tick}\n data-tick-at={tick.at}\n style={{ '--be-at': pct(toUnit(tick.at)) } as CSSProperties}\n >\n {tick.label !== undefined && <span className={s.tickLabel}>{tick.label}</span>}\n </span>\n ))}\n </div>\n <div className={s.bands}>\n {bands.map((band, i) => {\n const [from, to] = bandBounds(bands, i, min, max);\n const isSelected = selectedIndex === i;\n return (\n <Fragment key={i}>\n <button\n type=\"button\"\n className={[s.band, isSelected ? s.selected : null].filter(Boolean).join(' ')}\n style={{ '--be-from': pct(toUnit(from)), '--be-to': pct(toUnit(to)) } as CSSProperties}\n aria-label={`Band ${i + 1}`}\n aria-pressed={isSelected}\n data-band-index={i}\n onPointerDown={onBandPointerDown(i)}\n onFocus={onBandFocus(i)}\n >\n <span className={s.bandContent}>{renderBand?.(band, i)}</span>\n </button>\n {i < bands.length - 1 && (\n <div\n role=\"slider\"\n tabIndex={0}\n className={s.seam}\n style={{ '--be-at': pct(toUnit(bands[i + 1].from)) } as CSSProperties}\n aria-label={`Seam ${i + 1}`}\n aria-orientation=\"horizontal\"\n aria-valuemin={seamBounds(bands, i, min, max)[0]}\n aria-valuemax={seamBounds(bands, i, min, max)[1]}\n aria-valuenow={bands[i + 1].from}\n data-seam-index={i}\n onPointerDown={onSeamPointerDown(i)}\n onKeyDown={onSeamKeyDown(i)}\n />\n )}\n </Fragment>\n );\n })}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,31 +1,31 @@
1
- import { forwardRef as e } from "react";
2
- import { jsx as t, jsxs as n } from "react/jsx-runtime";
1
+ import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
+ import { forwardRef as n } from "react";
3
3
  var r = {
4
- button: "_button_yji6d_3",
5
- size_sm: "_size_sm_yji6d_110",
6
- size_md: "_size_md_yji6d_111",
7
- iconOnly: "_iconOnly_yji6d_113",
8
- variant_primary: "_variant_primary_yji6d_121",
9
- variant_secondary: "_variant_secondary_yji6d_168",
10
- variant_ghost: "_variant_ghost_yji6d_203",
11
- fullWidth: "_fullWidth_yji6d_220",
12
- loading: "_loading_yji6d_221",
13
- label: "_label_yji6d_221",
14
- iconSlot: "_iconSlot_yji6d_225",
15
- spinner: "_spinner_yji6d_239",
16
- "wzl-btn-spin": "_wzl-btn-spin_yji6d_1"
4
+ button: "_button_wj58b_3",
5
+ size_sm: "_size_sm_wj58b_110",
6
+ size_md: "_size_md_wj58b_111",
7
+ iconOnly: "_iconOnly_wj58b_113",
8
+ variant_primary: "_variant_primary_wj58b_121",
9
+ variant_secondary: "_variant_secondary_wj58b_168",
10
+ variant_ghost: "_variant_ghost_wj58b_203",
11
+ fullWidth: "_fullWidth_wj58b_220",
12
+ loading: "_loading_wj58b_221",
13
+ label: "_label_wj58b_221",
14
+ iconSlot: "_iconSlot_wj58b_225",
15
+ spinner: "_spinner_wj58b_239",
16
+ "wzl-btn-spin": "_wzl-btn-spin_wj58b_1"
17
17
  };
18
18
  //#endregion
19
19
  //#region src/components/Button/Button.tsx
20
20
  function i() {
21
- return /* @__PURE__ */ t("span", {
21
+ return /* @__PURE__ */ e("span", {
22
22
  className: r.spinner,
23
23
  "aria-hidden": "true",
24
- children: /* @__PURE__ */ n("svg", {
24
+ children: /* @__PURE__ */ t("svg", {
25
25
  viewBox: "0 0 16 16",
26
26
  width: "14",
27
27
  height: "14",
28
- children: [/* @__PURE__ */ t("circle", {
28
+ children: [/* @__PURE__ */ e("circle", {
29
29
  cx: "8",
30
30
  cy: "8",
31
31
  r: "6",
@@ -33,7 +33,7 @@ function i() {
33
33
  stroke: "currentColor",
34
34
  strokeWidth: "2",
35
35
  strokeOpacity: "0.25"
36
- }), /* @__PURE__ */ t("path", {
36
+ }), /* @__PURE__ */ e("path", {
37
37
  d: "M 8 2 A 6 6 0 0 1 14 8",
38
38
  fill: "none",
39
39
  stroke: "currentColor",
@@ -43,9 +43,9 @@ function i() {
43
43
  })
44
44
  });
45
45
  }
46
- var a = e(function(e, a) {
47
- let { variant: o = "secondary", size: s = "md", disabled: c, loading: l, leadingIcon: u, trailingIcon: d, fullWidth: f, iconOnly: p, ariaLabel: m, type: h = "button", className: g, style: _, children: v, onClick: y } = e;
48
- return /* @__PURE__ */ n("button", {
46
+ var a = n(function(n, a) {
47
+ let { variant: o = "secondary", size: s = "md", disabled: c, loading: l, leadingIcon: u, trailingIcon: d, fullWidth: f, iconOnly: p, ariaLabel: m, type: h = "button", className: g, style: _, children: v, onClick: y } = n;
48
+ return /* @__PURE__ */ t("button", {
49
49
  ref: a,
50
50
  type: h,
51
51
  className: [
@@ -63,18 +63,18 @@ var a = e(function(e, a) {
63
63
  "aria-label": m,
64
64
  onClick: y,
65
65
  children: [
66
- !p && (l || u) && /* @__PURE__ */ t("span", {
66
+ !p && (l || u) && /* @__PURE__ */ e("span", {
67
67
  className: r.iconSlot,
68
- children: l ? /* @__PURE__ */ t(i, {}) : u
68
+ children: l ? /* @__PURE__ */ e(i, {}) : u
69
69
  }),
70
- p ? l ? /* @__PURE__ */ t(i, {}) : /* @__PURE__ */ t("span", {
70
+ p ? l ? /* @__PURE__ */ e(i, {}) : /* @__PURE__ */ e("span", {
71
71
  className: r.iconSlot,
72
72
  children: v
73
- }) : v !== void 0 && /* @__PURE__ */ t("span", {
73
+ }) : v !== void 0 && /* @__PURE__ */ e("span", {
74
74
  className: r.label,
75
75
  children: v
76
76
  }),
77
- !p && d && /* @__PURE__ */ t("span", {
77
+ !p && d && /* @__PURE__ */ e("span", {
78
78
  className: r.iconSlot,
79
79
  children: d
80
80
  })
@@ -84,4 +84,4 @@ var a = e(function(e, a) {
84
84
  //#endregion
85
85
  export { a as t };
86
86
 
87
- //# sourceMappingURL=Button-9QNIYugK.js.map
87
+ //# sourceMappingURL=Button-CIu40Epu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button-CIu40Epu.js","names":[],"sources":["../../src/components/Button/Button.module.css","../../src/components/Button/Button.tsx"],"sourcesContent":["/* Aqua-glass button. Every visual parameter is exposed as a CSS custom\n property so the Button Lab can override per-instance via inline style. */\n.button {\n /* ---- Tunables (with Aqua-biased defaults) ---- */\n /* Corner radius = 10% of the button's height (the shorter axis on every\n realistic button shape). Using calc against --btn-height keeps the\n corners circular rather than elliptical, which a % value would\n otherwise produce on a wide-but-short pill. */\n --btn-radius: calc(var(--btn-height) * 0.1);\n --btn-fontweight: var(--wzl-font-weight-medium);\n --btn-fontsize: var(--wzl-font-size);\n --btn-height: 24px;\n --btn-padx: 12px;\n\n /* Body gradient — alpha-laced top, opaque bottom. Percentages are\n \"color-mix accent ratio\" so 45% = 45% accent + 55% transparent. */\n --btn-top-alpha: 45%;\n --btn-upper-alpha: 70%;\n --btn-equator: 52%; /* vertical position of the bright-to-deep transition */\n --btn-equator-spread: 12%; /* half-width of the equator transition band */\n --btn-equator-tint: 95%; /* accent vs white at equator */\n --btn-base-tint: 70%; /* accent vs black at base */\n --btn-blur: 6px;\n --btn-saturate: 1.3;\n\n /* Specular gloss (::before) */\n --btn-gloss-top: 0.42;\n --btn-gloss-mid: 0.12;\n --btn-gloss-bottom: 50%; /* inset from bottom — 50% = upper hemisphere */\n\n /* 3D shadows */\n --btn-rim: 0.22;\n --btn-drop-near: 0.30;\n --btn-drop-far: 0.18;\n --btn-inset-hi: 0.42;\n --btn-inset-lo: 0.3;\n\n /* Text — main shadow + a second engraving shadow you can angle.\n `inset-x` / `inset-y` are pre-projected offsets from `inset-angle` so\n the lab can drive them with a single slider. */\n --btn-text-shadow: 0.35;\n --btn-text-inset: 0.55;\n --btn-text-inset-x: 0px;\n --btn-text-inset-y: 1px;\n\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n border: none;\n border-radius: var(--btn-radius);\n font-family: var(--wzl-font-ui);\n font-weight: var(--btn-fontweight);\n font-style: normal;\n font-size: var(--btn-fontsize);\n height: var(--btn-height);\n padding: 0 var(--btn-padx);\n line-height: 1;\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n isolation: isolate;\n overflow: hidden;\n transition: filter var(--wzl-motion-fast), box-shadow var(--wzl-motion-fast), transform 80ms;\n}\n\n/* Specular gloss — covers the upper hemisphere of the pill with a bright\n white sheen that fades to nothing by the equator. The single detail that\n sells the glass-cylinder illusion. */\n.button::before {\n content: '';\n position: absolute;\n inset: 1px 1px var(--btn-gloss-bottom) 1px;\n /* Top corners hug the button's outline; bottom corners are flat so the\n gloss terminates in a straight line at the equator rather than two\n little arcs that read as `)(` brackets at smaller radii. */\n border-top-left-radius: var(--btn-radius);\n border-top-right-radius: var(--btn-radius);\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, var(--btn-gloss-top)) 0%,\n rgba(255, 255, 255, var(--btn-gloss-mid)) 60%,\n rgba(255, 255, 255, 0) 100%\n );\n pointer-events: none;\n z-index: 1;\n transition: opacity var(--wzl-motion-fast);\n}\n\n.button > * {\n position: relative;\n z-index: 2;\n}\n\n.button:focus-visible {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: 1px;\n}\n\n.button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ---------- Sizes — set defaults for the custom props ---------- */\n\n.size_sm { --btn-height: 20px; --btn-padx: 8px; --btn-fontsize: var(--wzl-font-size-sm); }\n.size_md { --btn-height: 24px; --btn-padx: 12px; --btn-fontsize: var(--wzl-font-size); }\n\n.iconOnly.size_sm { width: 20px; --btn-padx: 0; }\n.iconOnly.size_md { width: 24px; --btn-padx: 0; }\n\n/* ---------- Variants ---------- */\n\n/* Primary: tinted aqua glass — body uses --wzl-accent. The upper / equator\n / lower stops are positioned around --btn-equator so dragging the equator\n shifts the entire transition zone as one block. */\n.variant_primary {\n background: linear-gradient(\n 180deg,\n color-mix(in srgb, var(--wzl-accent) var(--btn-top-alpha), transparent) 0%,\n color-mix(in srgb, var(--wzl-accent) var(--btn-upper-alpha), transparent) calc(var(--btn-equator) - var(--btn-equator-spread)),\n color-mix(in srgb, var(--wzl-accent) var(--btn-equator-tint), white) var(--btn-equator),\n var(--wzl-accent) calc(var(--btn-equator) + var(--btn-equator-spread) * 1.6),\n color-mix(in srgb, var(--wzl-accent) var(--btn-base-tint), black) 100%\n );\n backdrop-filter: blur(var(--btn-blur)) saturate(var(--btn-saturate));\n -webkit-backdrop-filter: blur(var(--btn-blur)) saturate(var(--btn-saturate));\n color: var(--wzl-fg-on-accent);\n /* Main shadow below for legibility, then a second engraving shadow at a\n configurable angle (defaults below) — a near-black, lower-alpha stamp\n that sits underneath the glyphs and reads as recessed type. */\n text-shadow:\n 0 1px 0 rgba(0, 0, 0, var(--btn-text-shadow)),\n var(--btn-text-inset-x) var(--btn-text-inset-y) 0 rgba(0, 0, 0, var(--btn-text-inset)),\n 0 0 6px rgba(0, 0, 0, calc(var(--btn-text-shadow) * 0.5));\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, var(--btn-inset-hi)),\n inset 0 -1px 2px rgba(0, 0, 0, var(--btn-inset-lo)),\n 0 0 0 1px rgba(0, 0, 0, var(--btn-rim)),\n 0 1px 2px rgba(0, 0, 0, var(--btn-drop-near)),\n 0 3px 6px rgba(0, 0, 0, var(--btn-drop-far));\n}\n\n.variant_primary:hover:not(:disabled) {\n filter: brightness(1.08) saturate(1.06);\n}\n\n.variant_primary:active:not(:disabled) {\n background: linear-gradient(\n 180deg,\n color-mix(in srgb, var(--wzl-accent) 80%, black) 0%,\n color-mix(in srgb, var(--wzl-accent) 95%, black) 50%,\n color-mix(in srgb, var(--wzl-accent) 60%, white) 100%\n );\n box-shadow:\n inset 0 2px 4px rgba(0, 0, 0, 0.35),\n inset 0 -1px 0 rgba(255, 255, 255, 0.25),\n 0 0 0 1px rgba(0, 0, 0, calc(var(--btn-rim) + 0.06));\n transform: translateY(0.5px);\n}\n.variant_primary:active::before { opacity: 0.3; }\n\n/* Secondary: neutral glass — drained of color. */\n.variant_secondary {\n background: linear-gradient(\n 180deg,\n color-mix(in srgb, var(--wzl-fg) 25%, transparent) 0%,\n color-mix(in srgb, var(--wzl-fg) 10%, transparent) calc(var(--btn-equator) - var(--btn-equator-spread)),\n color-mix(in srgb, var(--wzl-surface-raised) 90%, white) var(--btn-equator),\n var(--wzl-surface-raised) calc(var(--btn-equator) + var(--btn-equator-spread) * 1.6),\n color-mix(in srgb, var(--wzl-surface-sunken) 80%, black) 100%\n );\n backdrop-filter: blur(var(--btn-blur)) saturate(var(--btn-saturate));\n -webkit-backdrop-filter: blur(var(--btn-blur)) saturate(var(--btn-saturate));\n color: var(--wzl-fg);\n text-shadow:\n 0 1px 0 rgba(0, 0, 0, calc(var(--btn-text-shadow) * 0.7)),\n var(--btn-text-inset-x) var(--btn-text-inset-y) 0 rgba(0, 0, 0, calc(var(--btn-text-inset) * 0.7));\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, calc(var(--btn-inset-hi) * 0.5)),\n inset 0 -1px 2px rgba(0, 0, 0, calc(var(--btn-inset-lo) * 0.83)),\n 0 0 0 1px rgba(0, 0, 0, calc(var(--btn-rim) + 0.03)),\n 0 1px 2px rgba(0, 0, 0, calc(var(--btn-drop-near) * 0.93)),\n 0 3px 6px rgba(0, 0, 0, calc(var(--btn-drop-far) * 0.89));\n}\n\n.variant_secondary:hover:not(:disabled) { filter: brightness(1.1); }\n\n.variant_secondary:active:not(:disabled) {\n background: linear-gradient(180deg, var(--wzl-surface-sunken) 0%, var(--wzl-surface-raised) 100%);\n box-shadow:\n inset 0 2px 4px rgba(0, 0, 0, 0.4),\n 0 0 0 1px rgba(0, 0, 0, 0.3);\n transform: translateY(0.5px);\n}\n.variant_secondary:active::before { opacity: 0.2; }\n\n/* Ghost: silhouette only — no glass body, no gloss. */\n.variant_ghost {\n background: transparent;\n color: var(--wzl-fg);\n box-shadow: none;\n}\n.variant_ghost::before { display: none; }\n\n.variant_ghost:hover:not(:disabled) {\n background: var(--wzl-surface-hover);\n}\n\n.variant_ghost:active:not(:disabled) {\n background: var(--wzl-surface-pressed);\n}\n\n/* ---------- Modifiers ---------- */\n\n.fullWidth { width: 100%; }\n.loading .label { opacity: 0.7; }\n\n/* ---------- Slots ---------- */\n\n.iconSlot {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n}\n\n.size_sm .iconSlot > svg { width: 12px; height: 12px; }\n.size_md .iconSlot > svg { width: 14px; height: 14px; }\n\n.label { display: inline-block; }\n\n/* ---------- Spinner ---------- */\n\n.spinner {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n animation: wzl-btn-spin 0.7s linear infinite;\n}\n\n@keyframes wzl-btn-spin {\n to { transform: rotate(360deg); }\n}\n","import { forwardRef, type ButtonHTMLAttributes, type ReactNode, type Ref } from 'react';\nimport s from './Button.module.css';\n\n/** Visual weight of a button. Defaults to `secondary`. */\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost';\n/** Button height and type scale. */\nexport type ButtonSize = 'sm' | 'md';\n\ntype ButtonBase = {\n variant?: ButtonVariant;\n size?: ButtonSize;\n disabled?: boolean;\n loading?: boolean;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n fullWidth?: boolean;\n type?: 'button' | 'submit' | 'reset';\n className?: string;\n style?: ButtonHTMLAttributes<HTMLButtonElement>['style'];\n children?: ReactNode;\n onClick?: ButtonHTMLAttributes<HTMLButtonElement>['onClick'];\n};\n\ntype ButtonRegular = ButtonBase & {\n iconOnly?: false;\n ariaLabel?: string;\n};\n\ntype ButtonIconOnly = ButtonBase & {\n iconOnly: true;\n ariaLabel: string;\n};\n\n/**\n * Props for {@link Button}. Setting `iconOnly` makes `ariaLabel` required,\n * since an icon-only button has no text for a screen reader to announce.\n */\nexport type ButtonProps = ButtonRegular | ButtonIconOnly;\n\nfunction Spinner(): ReactNode {\n return (\n <span className={s.spinner} aria-hidden=\"true\">\n <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\">\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeOpacity=\"0.25\"\n />\n <path\n d=\"M 8 2 A 6 6 0 0 1 14 8\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </span>\n );\n}\n\n/**\n * Standard button. `loading` swaps the leading icon for a spinner, marks the\n * button `aria-busy`, and leaves the label in place; it does not disable the\n * button, so pass `disabled` too if the click should be blocked.\n *\n * `ref` forwards to the underlying `<button>`.\n */\nexport const Button = forwardRef(function Button(\n props: ButtonProps,\n ref: Ref<HTMLButtonElement>,\n) {\n const {\n variant = 'secondary',\n size = 'md',\n disabled,\n loading,\n leadingIcon,\n trailingIcon,\n fullWidth,\n iconOnly,\n ariaLabel,\n type = 'button',\n className,\n style,\n children,\n onClick,\n } = props;\n\n const cls = [\n s.button,\n s[`variant_${variant}`],\n s[`size_${size}`],\n fullWidth && s.fullWidth,\n iconOnly && s.iconOnly,\n loading && s.loading,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const showLeading = !iconOnly && (loading || leadingIcon);\n\n return (\n <button\n ref={ref}\n type={type}\n className={cls}\n style={style}\n disabled={disabled}\n aria-busy={loading ? true : undefined}\n aria-label={ariaLabel}\n onClick={onClick}\n >\n {showLeading && (\n <span className={s.iconSlot}>{loading ? <Spinner /> : leadingIcon}</span>\n )}\n {iconOnly ? (\n loading ? <Spinner /> : <span className={s.iconSlot}>{children}</span>\n ) : (\n children !== undefined && <span className={s.label}>{children}</span>\n )}\n {!iconOnly && trailingIcon && (\n <span className={s.iconSlot}>{trailingIcon}</span>\n )}\n </button>\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;ACuCA,SAAS,IAAqB;AAC5B,QACE,kBAAC,QAAD;EAAM,WAAW,EAAE;EAAS,eAAY;YACtC,kBAAC,OAAD;GAAK,SAAQ;GAAY,OAAM;GAAK,QAAO;aAA3C,CACE,kBAAC,UAAD;IACE,IAAG;IACH,IAAG;IACH,GAAE;IACF,MAAK;IACL,QAAO;IACP,aAAY;IACZ,eAAc;IACd,CAAA,EACF,kBAAC,QAAD;IACE,GAAE;IACF,MAAK;IACL,QAAO;IACP,aAAY;IACZ,eAAc;IACd,CAAA,CACE;;EACD,CAAA;;AAWX,IAAa,IAAS,EAAW,SAC/B,GACA,GACA;CACA,IAAM,EACJ,aAAU,aACV,UAAO,MACP,aACA,YACA,gBACA,iBACA,cACA,aACA,cACA,UAAO,UACP,cACA,UACA,aACA,eACE;AAgBJ,QACE,kBAAC,UAAD;EACO;EACC;EACN,WAlBQ;GACV,EAAE;GACF,EAAE,WAAW;GACb,EAAE,QAAQ;GACV,KAAa,EAAE;GACf,KAAY,EAAE;GACd,KAAW,EAAE;GACb;GACD,CACE,OAAO,QAAQ,CACf,KAAK,IAQO;EACJ;EACG;EACV,aAAW,IAAU,KAAO,KAAA;EAC5B,cAAY;EACH;YARX;GAHkB,CAAC,MAAa,KAAW,MAcvC,kBAAC,QAAD;IAAM,WAAW,EAAE;cAAW,IAAU,kBAAC,GAAD,EAAW,CAAA,GAAG;IAAmB,CAAA;GAE1E,IACC,IAAU,kBAAC,GAAD,EAAW,CAAA,GAAG,kBAAC,QAAD;IAAM,WAAW,EAAE;IAAW;IAAgB,CAAA,GAEtE,MAAa,KAAA,KAAa,kBAAC,QAAD;IAAM,WAAW,EAAE;IAAQ;IAAgB,CAAA;GAEtE,CAAC,KAAY,KACZ,kBAAC,QAAD;IAAM,WAAW,EAAE;cAAW;IAAoB,CAAA;GAE7C;;EAEX"}
@@ -1,42 +1,43 @@
1
- import { useCallback as e, useEffect as t, useId as n, useRef as r } from "react";
2
- import { Dialog as i, DialogTrigger as a, Heading as o, OverlayArrow as s, Popover as c } from "react-aria-components";
3
- import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
1
+ import { Fragment as e, jsx as t, jsxs as n } from "react/jsx-runtime";
2
+ import { useCallback as r, useEffect as i, useId as a, useRef as o } from "react";
3
+ import { Dialog as s, DialogTrigger as c, Heading as l, OverlayArrow as u, Popover as d } from "react-aria-components";
4
4
  import { createPortal as f } from "react-dom";
5
5
  var p = {
6
- anchor: "_anchor_18o4b_1",
7
- popover: "_popover_18o4b_6",
8
- toneWarning: "_toneWarning_18o4b_25",
9
- toneDanger: "_toneDanger_18o4b_29",
10
- arrow: "_arrow_18o4b_33",
11
- dialog: "_dialog_18o4b_52",
12
- header: "_header_18o4b_59",
13
- title: "_title_18o4b_66",
14
- close: "_close_18o4b_73",
15
- body: "_body_18o4b_89",
16
- footer: "_footer_18o4b_96"
6
+ anchor: "_anchor_vtcyj_1",
7
+ popover: "_popover_vtcyj_6",
8
+ toneWarning: "_toneWarning_vtcyj_25",
9
+ toneDanger: "_toneDanger_vtcyj_29",
10
+ arrow: "_arrow_vtcyj_33",
11
+ dialog: "_dialog_vtcyj_52",
12
+ header: "_header_vtcyj_59",
13
+ title: "_title_vtcyj_66",
14
+ close: "_close_vtcyj_73",
15
+ body: "_body_vtcyj_89",
16
+ footer: "_footer_vtcyj_96"
17
17
  }, m = {
18
18
  info: p.toneInfo,
19
19
  warning: p.toneWarning,
20
20
  danger: p.toneDanger
21
21
  };
22
- function h(a) {
23
- let { children: h, className: g, title: _, footer: v, tone: y = "info", modal: b = !1, showCloseButton: x, onDismiss: S, triggerRef: C, anchorRect: w, placement: T = "top", offset: E = 12, maxHeight: D = 400, onOpenChange: O, shouldCloseOnInteractOutside: k, "aria-label": A, "aria-labelledby": j, ...M } = a, N = r(null), P = x ?? !b, F = r(S);
22
+ function h(c) {
23
+ let { children: h, className: g, title: _, footer: v, tone: y = "info", modal: b = !1, showCloseButton: x, onDismiss: S, triggerRef: C, anchorRect: w, placement: T = "top", offset: E = 12, maxHeight: D = 400, onOpenChange: O, shouldCloseOnInteractOutside: k, "aria-label": A, "aria-labelledby": j, ...M } = c, N = o(null), P = x ?? !b, F = o(S);
24
24
  F.current = S;
25
- let I = r((e) => {
25
+ let I = o((e) => {
26
26
  e.key === "Escape" && F.current?.();
27
- }), L = r(null), R = e((e) => {
27
+ }), L = o(null), R = r((e) => {
28
28
  L.current?.removeEventListener("keydown", I.current), L.current = e, e?.addEventListener("keydown", I.current);
29
- }, []), z = n();
30
- t(() => {
31
- w === void 0 || typeof window > "u" || window.dispatchEvent(new Event("resize"));
29
+ }, []), z = a(), B = w !== void 0;
30
+ i(() => {
31
+ !B || typeof window > "u" || window.dispatchEvent(new Event("resize"));
32
32
  }, [
33
+ B,
33
34
  w?.x,
34
35
  w?.y,
35
36
  w?.width,
36
37
  w?.height
37
38
  ]);
38
- let B = b && _ !== void 0 ? z : j, V = b ? A : void 0;
39
- return /* @__PURE__ */ d(l, { children: [w !== void 0 && f(/* @__PURE__ */ u("span", {
39
+ let V = b && _ !== void 0 ? z : j, H = b ? A : void 0;
40
+ return /* @__PURE__ */ n(e, { children: [w !== void 0 && f(/* @__PURE__ */ t("span", {
40
41
  ref: N,
41
42
  "data-callout-anchor": "",
42
43
  className: p.anchor,
@@ -47,7 +48,7 @@ function h(a) {
47
48
  width: w.width,
48
49
  height: w.height
49
50
  }
50
- }), document.body), /* @__PURE__ */ d(c, {
51
+ }), document.body), /* @__PURE__ */ n(d, {
51
52
  ...M,
52
53
  triggerRef: w === void 0 ? C : N,
53
54
  isNonModal: !b,
@@ -56,52 +57,52 @@ function h(a) {
56
57
  maxHeight: D,
57
58
  onOpenChange: O,
58
59
  shouldCloseOnInteractOutside: k ?? (b ? () => !1 : void 0),
59
- "aria-label": V,
60
- "aria-labelledby": B,
60
+ "aria-label": H,
61
+ "aria-labelledby": V,
61
62
  className: [
62
63
  p.popover,
63
64
  m[y],
64
65
  g
65
66
  ].filter(Boolean).join(" "),
66
67
  "data-weasel-overlay": "",
67
- children: [/* @__PURE__ */ u(s, {
68
+ children: [/* @__PURE__ */ t(u, {
68
69
  className: p.arrow,
69
- children: /* @__PURE__ */ u("svg", {
70
+ children: /* @__PURE__ */ t("svg", {
70
71
  width: 12,
71
72
  height: 12,
72
73
  viewBox: "0 0 12 12",
73
74
  "aria-hidden": "true",
74
- children: /* @__PURE__ */ u("path", { d: "M0 0 L6 6 L12 0" })
75
+ children: /* @__PURE__ */ t("path", { d: "M0 0 L6 6 L12 0" })
75
76
  })
76
- }), /* @__PURE__ */ u(i, {
77
+ }), /* @__PURE__ */ t(s, {
77
78
  role: b ? "alertdialog" : "dialog",
78
79
  className: p.dialog,
79
80
  "aria-label": A,
80
81
  "aria-labelledby": j,
81
82
  ref: R,
82
- children: ({ close: e }) => /* @__PURE__ */ d(l, { children: [
83
- (_ !== void 0 || P) && /* @__PURE__ */ d("header", {
83
+ children: ({ close: r }) => /* @__PURE__ */ n(e, { children: [
84
+ (_ !== void 0 || P) && /* @__PURE__ */ n("header", {
84
85
  className: p.header,
85
- children: [_ !== void 0 && /* @__PURE__ */ u(o, {
86
+ children: [_ !== void 0 && /* @__PURE__ */ t(l, {
86
87
  id: z,
87
88
  slot: "title",
88
89
  className: p.title,
89
90
  children: _
90
- }), P && /* @__PURE__ */ u("button", {
91
+ }), P && /* @__PURE__ */ t("button", {
91
92
  type: "button",
92
93
  className: p.close,
93
94
  onClick: () => {
94
- e(), O?.(!1), S?.();
95
+ r(), O?.(!1), S?.();
95
96
  },
96
97
  "aria-label": "Close callout",
97
98
  children: "×"
98
99
  })]
99
100
  }),
100
- /* @__PURE__ */ u("div", {
101
+ /* @__PURE__ */ t("div", {
101
102
  className: p.body,
102
103
  children: h
103
104
  }),
104
- v !== void 0 && /* @__PURE__ */ u("footer", {
105
+ v !== void 0 && /* @__PURE__ */ t("footer", {
105
106
  className: p.footer,
106
107
  children: v
107
108
  })
@@ -110,6 +111,6 @@ function h(a) {
110
111
  })] });
111
112
  }
112
113
  //#endregion
113
- export { a as n, h as t };
114
+ export { c as n, h as t };
114
115
 
115
- //# sourceMappingURL=Callout-NSOjza6G.js.map
116
+ //# sourceMappingURL=Callout-CHs98djt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Callout-CHs98djt.js","names":[],"sources":["../../src/components/Callout/Callout.module.css","../../src/components/Callout/Callout.tsx"],"sourcesContent":[".anchor {\n position: fixed;\n pointer-events: none;\n}\n\n.popover {\n /* Above Dialog overlay (1000) and ToastRegion (1100) — RAC sets no z-index. */\n z-index: 1200;\n --callout-accent: var(--wzl-accent-strong);\n background: var(--wzl-surface);\n border: 1px solid var(--callout-accent);\n border-radius: var(--wzl-radius-md);\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n max-width: 320px;\n transition: opacity var(--wzl-motion-fast);\n}\n\n.popover[data-entering],\n.popover[data-exiting] {\n opacity: 0;\n}\n\n.toneWarning {\n --callout-accent: var(--wzl-warning, #d99a3f);\n}\n\n.toneDanger {\n --callout-accent: var(--wzl-danger);\n}\n\n.arrow svg {\n display: block;\n fill: var(--wzl-surface);\n stroke: var(--callout-accent);\n stroke-width: 1;\n}\n\n.arrow[data-placement='bottom'] svg {\n transform: rotate(180deg);\n}\n\n.arrow[data-placement='left'] svg {\n transform: rotate(-90deg);\n}\n\n.arrow[data-placement='right'] svg {\n transform: rotate(90deg);\n}\n\n.dialog {\n outline: none;\n max-height: inherit;\n display: flex;\n flex-direction: column;\n}\n\n.header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 0;\n}\n\n.title {\n margin: 0;\n flex: 1;\n font-size: var(--wzl-font-size);\n font-weight: var(--wzl-font-weight-bold);\n}\n\n.close {\n flex: 0 0 auto;\n background: none;\n border: none;\n color: var(--wzl-fg-muted);\n font-size: var(--wzl-font-size-lg);\n line-height: 1;\n padding: 2px 4px;\n cursor: pointer;\n border-radius: var(--wzl-radius-sm);\n}\n\n.close:hover {\n color: var(--wzl-fg);\n}\n\n.body {\n padding: 8px 12px 10px;\n font-size: var(--wzl-font-size);\n line-height: 1.4;\n overflow-y: auto;\n}\n\n.footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 0 12px 10px;\n}\n","import { useCallback, useEffect, useId, useRef, type ReactNode, type RefObject } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n DialogTrigger,\n Popover as RACPopover,\n OverlayArrow,\n Dialog as RACDialog,\n Heading,\n type PopoverProps as RACPopoverProps,\n} from 'react-aria-components';\nimport s from './Callout.module.css';\n\n/** Accent color of a {@link Callout}'s border and arrow. */\nexport type CalloutTone = 'info' | 'warning' | 'danger';\n\n/**\n * Composition wrapper for press-to-open callouts:\n * `<CalloutTrigger><Pressable>…</Pressable><Callout>…</Callout></CalloutTrigger>`.\n * Re-exported RAC DialogTrigger — non-RAC trigger elements must be wrapped\n * in `<Pressable>` from react-aria-components.\n * In composed mode, put `defaultOpen` on `CalloutTrigger`, not `Callout` —\n * RAC detaches to local open state on the trigger, not the popover.\n */\nexport { DialogTrigger as CalloutTrigger };\n\n/** Props for {@link Callout}, on top of React Aria's `Popover` props. */\nexport type CalloutProps = Omit<\n RACPopoverProps,\n 'children' | 'className' | 'isNonModal' | 'triggerRef'\n> & {\n children?: ReactNode;\n className?: string;\n /** Optional heading rendered above the body. */\n title?: ReactNode;\n /** Footer slot — typically action buttons. */\n footer?: ReactNode;\n /** Accent tone for border + arrow. Default `info`. */\n tone?: CalloutTone;\n /**\n * `true` — blocks interaction with the rest of the app until dismissed;\n * inner dialog is `role=\"alertdialog\"`. `false` (default) — non-blocking:\n * the app stays interactive; Esc / outside click / close button dismiss.\n */\n modal?: boolean;\n /**\n * Show the × button. Defaults to `!modal`. In programmatic\n * `triggerRef`/`anchorRect` modes the close button requires either\n * controlled open (`isOpen` + `onOpenChange`) or `onDismiss`; with only\n * `defaultOpen` it has no open-state setter to call and cannot close.\n */\n showCloseButton?: boolean;\n /**\n * The user asked for this callout to go away — the × button or Escape.\n *\n * Distinct from `onOpenChange`, which a non-modal popover *also* fires when\n * interaction or focus merely leaves it. On a canvas that's every click on\n * the artwork, so a consumer that pins `isOpen` and treats `onOpenChange`\n * as dismissal retires messages nobody read. Use this instead: it fires\n * only on a deliberate act, and never on incidental focus loss.\n */\n onDismiss?: () => void;\n /** Anchor to an arbitrary element (programmatic use, with `isOpen`). */\n triggerRef?: RefObject<Element | null>;\n /**\n * Anchor to a client-coordinate rect — e.g. a scene node's on-screen box.\n * The callout re-anchors whenever this rect changes, so a consumer that\n * recomputes it on pan, zoom, or scene edits keeps the arrow on its target.\n * Takes precedence over `triggerRef`.\n */\n anchorRect?: { x: number; y: number; width: number; height: number };\n};\n\nconst toneClass: Record<CalloutTone, string> = {\n info: s.toneInfo,\n warning: s.toneWarning,\n danger: s.toneDanger,\n};\n\n/**\n * Anchored callout with an arrow pointing at its source — a trigger\n * element, an arbitrary `triggerRef`, or a client-space `anchorRect`.\n * Wraps React Aria Popover + Dialog; positioning, collision flipping,\n * dismissal, and focus behavior come from the underlying primitives.\n */\nexport function Callout(props: CalloutProps) {\n const {\n children,\n className,\n title,\n footer,\n tone = 'info',\n modal = false,\n showCloseButton,\n onDismiss,\n triggerRef,\n anchorRect,\n placement = 'top',\n offset = 12,\n maxHeight = 400,\n onOpenChange,\n shouldCloseOnInteractOutside,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...rest\n } = props;\n const anchorRef = useRef<HTMLSpanElement>(null);\n const showClose = showCloseButton ?? !modal;\n // Escape is a dismissal like the × is. It can't ride on a React `onKeyDown`:\n // RAC's Dialog runs its props through filterDOMProps, which drops handlers\n // it doesn't know, so the listener goes on the section itself. RAC's own\n // Escape handling is untouched — this only adds the signal.\n const onDismissRef = useRef(onDismiss);\n onDismissRef.current = onDismiss;\n const escapeListener = useRef((e: KeyboardEvent) => {\n if (e.key === 'Escape') onDismissRef.current?.();\n });\n const listeningTo = useRef<HTMLElement | null>(null);\n const dialogRef = useCallback((node: HTMLElement | null) => {\n listeningTo.current?.removeEventListener('keydown', escapeListener.current);\n listeningTo.current = node;\n node?.addEventListener('keydown', escapeListener.current);\n }, []);\n const titleId = useId();\n // RAC positions on open and recomputes on scroll, resize, and a\n // ResizeObserver on the anchor — none of which fire when `anchorRect` is\n // merely *translated*, as it is when a consumer tracks a scene node across a\n // pan. (Zoom happens to work, since scaling also changes the anchor's size.)\n // Nudging RAC's own resize listener is the supported way to make it\n // recompute; there's no public updatePosition on Popover.\n const hasAnchorRect = anchorRect !== undefined;\n useEffect(() => {\n if (!hasAnchorRect || typeof window === 'undefined') return;\n window.dispatchEvent(new Event('resize'));\n }, [hasAnchorRect, anchorRect?.x, anchorRect?.y, anchorRect?.width, anchorRect?.height]);\n // RAC's popover role-heuristic misses alertdialog; label the outer role\n // it stamps. Upstream: react-spectrum Popover.mjs querySelector('[role=dialog]').\n const popoverAriaLabelledby =\n modal && title !== undefined ? titleId : ariaLabelledby;\n const popoverAriaLabel = modal ? ariaLabel : undefined;\n return (\n <>\n {/* Harmless while closed — RAC reads the ref only when the popover is open. */}\n {anchorRect !== undefined &&\n createPortal(\n <span\n ref={anchorRef}\n data-callout-anchor=\"\"\n className={s.anchor}\n aria-hidden=\"true\"\n // Dynamic geometry — inline style is the mechanism here, not styling.\n style={{\n left: anchorRect.x,\n top: anchorRect.y,\n width: anchorRect.width,\n height: anchorRect.height,\n }}\n />,\n document.body,\n )}\n <RACPopover\n {...rest}\n triggerRef={anchorRect !== undefined ? anchorRef : triggerRef}\n isNonModal={!modal}\n placement={placement}\n offset={offset}\n maxHeight={maxHeight}\n onOpenChange={onOpenChange}\n shouldCloseOnInteractOutside={\n shouldCloseOnInteractOutside ?? (modal ? () => false : undefined)\n }\n aria-label={popoverAriaLabel}\n aria-labelledby={popoverAriaLabelledby}\n className={[s.popover, toneClass[tone], className].filter(Boolean).join(' ')}\n data-weasel-overlay=\"\"\n >\n <OverlayArrow className={s.arrow}>\n <svg width={12} height={12} viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n <path d=\"M0 0 L6 6 L12 0\" />\n </svg>\n </OverlayArrow>\n <RACDialog\n role={modal ? 'alertdialog' : 'dialog'}\n className={s.dialog}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n ref={dialogRef}\n >\n {({ close }) => (\n <>\n {(title !== undefined || showClose) && (\n <header className={s.header}>\n {title !== undefined && (\n <Heading id={titleId} slot=\"title\" className={s.title}>\n {title}\n </Heading>\n )}\n {showClose && (\n <button\n type=\"button\"\n className={s.close}\n onClick={() => {\n // `close()` resolves OverlayTriggerStateContext, only\n // provided by DialogTrigger (composed mode). In\n // triggerRef/anchorRect modes there is no such\n // context, so `close()` is a no-op there — the\n // controlled-open fallback below does the work.\n close();\n onOpenChange?.(false);\n onDismiss?.();\n }}\n aria-label=\"Close callout\"\n >\n ×\n </button>\n )}\n </header>\n )}\n <div className={s.body}>{children}</div>\n {footer !== undefined && <footer className={s.footer}>{footer}</footer>}\n </>\n )}\n </RACDialog>\n </RACPopover>\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;GCwEM,IAAyC;CAC7C,MAAM,EAAE;CACR,SAAS,EAAE;CACX,QAAQ,EAAE;CACX;AAQD,SAAgB,EAAQ,GAAqB;CAC3C,IAAM,EACJ,aACA,cACA,UACA,WACA,UAAO,QACP,WAAQ,IACR,oBACA,cACA,eACA,eACA,eAAY,OACZ,YAAS,IACT,eAAY,KACZ,iBACA,iCACA,cAAc,GACd,mBAAmB,GACnB,GAAG,MACD,GACE,IAAY,EAAwB,KAAK,EACzC,IAAY,KAAmB,CAAC,GAKhC,IAAe,EAAO,EAAU;AACtC,GAAa,UAAU;CACvB,IAAM,IAAiB,GAAQ,MAAqB;AAClD,EAAI,EAAE,QAAQ,YAAU,EAAa,WAAW;GAChD,EACI,IAAc,EAA2B,KAAK,EAC9C,IAAY,GAAa,MAA6B;AAG1D,EAFA,EAAY,SAAS,oBAAoB,WAAW,EAAe,QAAQ,EAC3E,EAAY,UAAU,GACtB,GAAM,iBAAiB,WAAW,EAAe,QAAQ;IACxD,EAAE,CAAC,EACA,IAAU,GAAO,EAOjB,IAAgB,MAAe,KAAA;AACrC,SAAgB;AACV,GAAC,KAAiB,OAAO,SAAW,OACxC,OAAO,cAAc,IAAI,MAAM,SAAS,CAAC;IACxC;EAAC;EAAe,GAAY;EAAG,GAAY;EAAG,GAAY;EAAO,GAAY;EAAO,CAAC;CAGxF,IAAM,IACJ,KAAS,MAAU,KAAA,IAAY,IAAU,GACrC,IAAmB,IAAQ,IAAY,KAAA;AAC7C,QACE,kBAAA,GAAA,EAAA,UAAA,CAEG,MAAe,KAAA,KACd,EACE,kBAAC,QAAD;EACE,KAAK;EACL,uBAAoB;EACpB,WAAW,EAAE;EACb,eAAY;EAEZ,OAAO;GACL,MAAM,EAAW;GACjB,KAAK,EAAW;GAChB,OAAO,EAAW;GAClB,QAAQ,EAAW;GACpB;EACD,CAAA,EACF,SAAS,KACV,EACH,kBAAC,GAAD;EACE,GAAI;EACJ,YAAY,MAAe,KAAA,IAAwB,IAAZ;EACvC,YAAY,CAAC;EACF;EACH;EACG;EACG;EACd,8BACE,MAAiC,UAAc,KAAQ,KAAA;EAEzD,cAAY;EACZ,mBAAiB;EACjB,WAAW;GAAC,EAAE;GAAS,EAAU;GAAO;GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EAC5E,uBAAoB;YAdtB,CAgBE,kBAAC,GAAD;GAAc,WAAW,EAAE;aACzB,kBAAC,OAAD;IAAK,OAAO;IAAI,QAAQ;IAAI,SAAQ;IAAY,eAAY;cAC1D,kBAAC,QAAD,EAAM,GAAE,mBAAoB,CAAA;IACxB,CAAA;GACO,CAAA,EACf,kBAAC,GAAD;GACE,MAAM,IAAQ,gBAAgB;GAC9B,WAAW,EAAE;GACb,cAAY;GACZ,mBAAiB;GACjB,KAAK;cAEH,EAAE,eACF,kBAAA,GAAA,EAAA,UAAA;KACI,MAAU,KAAA,KAAa,MACvB,kBAAC,UAAD;KAAQ,WAAW,EAAE;eAArB,CACG,MAAU,KAAA,KACT,kBAAC,GAAD;MAAS,IAAI;MAAS,MAAK;MAAQ,WAAW,EAAE;gBAC7C;MACO,CAAA,EAEX,KACC,kBAAC,UAAD;MACE,MAAK;MACL,WAAW,EAAE;MACb,eAAe;AAQb,OAFA,GAAO,EACP,IAAe,GAAM,EACrB,KAAa;;MAEf,cAAW;gBACZ;MAEQ,CAAA,CAEJ;;IAEX,kBAAC,OAAD;KAAK,WAAW,EAAE;KAAO;KAAe,CAAA;IACvC,MAAW,KAAA,KAAa,kBAAC,UAAD;KAAQ,WAAW,EAAE;eAAS;KAAgB,CAAA;IACtE,EAAA,CAAA;GAEK,CAAA,CACD;IACZ,EAAA,CAAA"}
@@ -0,0 +1,47 @@
1
+ import { Fragment as e, jsx as t, jsxs as n } from "react/jsx-runtime";
2
+ import { forwardRef as r } from "react";
3
+ import { Checkbox as i } from "react-aria-components";
4
+ var a = {
5
+ checkbox: "_checkbox_w5y2z_1",
6
+ box: "_box_w5y2z_18",
7
+ checkmark: "_checkmark_w5y2z_47",
8
+ label: "_label_w5y2z_60"
9
+ }, o = r(function(r, o) {
10
+ let { children: s, className: c, ...l } = r;
11
+ return /* @__PURE__ */ t(i, {
12
+ ...l,
13
+ ref: o,
14
+ className: [a.checkbox, c].filter(Boolean).join(" "),
15
+ children: ({ isIndeterminate: r }) => /* @__PURE__ */ n(e, { children: [/* @__PURE__ */ t("span", {
16
+ className: a.box,
17
+ children: /* @__PURE__ */ t("svg", {
18
+ className: a.checkmark,
19
+ viewBox: "0 0 14 14",
20
+ "aria-hidden": "true",
21
+ children: r ? /* @__PURE__ */ t("line", {
22
+ x1: "3",
23
+ y1: "7",
24
+ x2: "11",
25
+ y2: "7",
26
+ stroke: "currentColor",
27
+ strokeWidth: "2",
28
+ strokeLinecap: "round"
29
+ }) : /* @__PURE__ */ t("polyline", {
30
+ points: "3,7.5 6,10.5 11,4.5",
31
+ fill: "none",
32
+ stroke: "currentColor",
33
+ strokeWidth: "2",
34
+ strokeLinecap: "round",
35
+ strokeLinejoin: "round"
36
+ })
37
+ })
38
+ }), s !== void 0 && /* @__PURE__ */ t("span", {
39
+ className: a.label,
40
+ children: s
41
+ })] })
42
+ });
43
+ });
44
+ //#endregion
45
+ export { o as t };
46
+
47
+ //# sourceMappingURL=Checkbox-BLEw-wEb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox-BLEw-wEb.js","names":[],"sources":["../../src/components/Checkbox/Checkbox.module.css","../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":[".checkbox {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size);\n color: var(--wzl-fg);\n user-select: none;\n -webkit-user-select: none;\n}\n\n.checkbox[data-disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.box {\n position: relative;\n flex: 0 0 auto;\n width: 14px;\n height: 14px;\n background: var(--wzl-surface-sunken);\n border: 1px solid var(--wzl-border-strong);\n border-radius: var(--wzl-radius-sm);\n transition: background-color var(--wzl-motion-fast), border-color var(--wzl-motion-fast), box-shadow var(--wzl-motion-fast);\n}\n\n.checkbox[data-focus-visible] .box {\n box-shadow: 0 0 0 2px var(--wzl-focus-ring);\n}\n\n.checkbox[data-hovered]:not([data-disabled]) .box {\n border-color: var(--wzl-fg-muted);\n}\n\n.checkbox[data-selected] .box,\n.checkbox[data-indeterminate] .box {\n background: var(--wzl-accent-strong);\n border-color: var(--wzl-accent-strong);\n}\n\n.checkbox[data-invalid] .box {\n border-color: var(--wzl-danger);\n}\n\n.checkmark {\n position: absolute;\n inset: 0;\n color: var(--wzl-fg-on-accent);\n opacity: 0;\n pointer-events: none;\n}\n\n.checkbox[data-selected] .checkmark,\n.checkbox[data-indeterminate] .checkmark {\n opacity: 1;\n}\n\n.label {\n line-height: 1.2;\n}\n","import { forwardRef, type ReactNode, type Ref } from 'react';\nimport {\n Checkbox as RACCheckbox,\n type CheckboxProps as RACCheckboxProps,\n} from 'react-aria-components';\nimport s from './Checkbox.module.css';\n\n/**\n * Props for {@link Checkbox}, on top of React Aria's `Checkbox` props. The\n * label is passed as children.\n */\nexport type CheckboxProps = Omit<RACCheckboxProps, 'children' | 'className'> & {\n children?: ReactNode;\n className?: string;\n};\n\n/**\n * Single checkbox wrapping React Aria's Checkbox. Supports indeterminate\n * via `isIndeterminate`. The label is supplied as children.\n */\nexport const Checkbox = forwardRef(function Checkbox(\n props: CheckboxProps,\n ref: Ref<HTMLLabelElement>,\n) {\n const { children, className, ...rest } = props;\n return (\n <RACCheckbox\n {...rest}\n ref={ref}\n className={[s.checkbox, className].filter(Boolean).join(' ')}\n >\n {({ isIndeterminate }) => (\n <>\n <span className={s.box}>\n <svg className={s.checkmark} viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n {isIndeterminate ? (\n <line x1=\"3\" y1=\"7\" x2=\"11\" y2=\"7\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n ) : (\n <polyline\n points=\"3,7.5 6,10.5 11,4.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n )}\n </svg>\n </span>\n {children !== undefined && <span className={s.label}>{children}</span>}\n </>\n )}\n </RACCheckbox>\n );\n});\n"],"mappings":";;;;;;;;GCoBa,IAAW,EAAW,SACjC,GACA,GACA;CACA,IAAM,EAAE,aAAU,cAAW,GAAG,MAAS;AACzC,QACE,kBAAC,GAAD;EACE,GAAI;EACC;EACL,WAAW,CAAC,EAAE,UAAU,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;aAE1D,EAAE,yBACF,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,QAAD;GAAM,WAAW,EAAE;aACjB,kBAAC,OAAD;IAAK,WAAW,EAAE;IAAW,SAAQ;IAAY,eAAY;cAC1D,IACC,kBAAC,QAAD;KAAM,IAAG;KAAI,IAAG;KAAI,IAAG;KAAK,IAAG;KAAI,QAAO;KAAe,aAAY;KAAI,eAAc;KAAU,CAAA,GAEjG,kBAAC,YAAD;KACE,QAAO;KACP,MAAK;KACL,QAAO;KACP,aAAY;KACZ,eAAc;KACd,gBAAe;KACf,CAAA;IAEA,CAAA;GACD,CAAA,EACN,MAAa,KAAA,KAAa,kBAAC,QAAD;GAAM,WAAW,EAAE;GAAQ;GAAgB,CAAA,CACrE,EAAA,CAAA;EAEO,CAAA;EAEhB"}