@weasel-js/ui 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (530) hide show
  1. package/dist/chunks/{ActionBar-CYvfmEz0.js → ActionBar-DCq16yFA.js} +9 -9
  2. package/dist/chunks/ActionBar-DCq16yFA.js.map +1 -0
  3. package/dist/chunks/Badge-CTc9Lkwn.js +14 -0
  4. package/dist/chunks/Badge-CTc9Lkwn.js.map +1 -0
  5. package/dist/chunks/{Badge-DZ0lFs14.js → Badge-D2aD7xVL.js} +418 -369
  6. package/dist/chunks/Badge-D2aD7xVL.js.map +1 -0
  7. package/dist/chunks/BandEditor-Dd0egAgE.js +292 -0
  8. package/dist/chunks/BandEditor-Dd0egAgE.js.map +1 -0
  9. package/dist/chunks/{Button-Dyp31jMt.js → Button-BIdXHQOx.js} +3 -3
  10. package/dist/chunks/Button-BIdXHQOx.js.map +1 -0
  11. package/dist/chunks/{ButtonBar-smZzFuEo.js → ButtonBar-DIQTe5GQ.js} +4 -4
  12. package/dist/chunks/ButtonBar-DIQTe5GQ.js.map +1 -0
  13. package/dist/chunks/Callout-ndW5_Bqx.js +116 -0
  14. package/dist/chunks/Callout-ndW5_Bqx.js.map +1 -0
  15. package/dist/chunks/{Checkbox-ChZz30Ds.js → Checkbox-DHXTUHO9.js} +1 -1
  16. package/dist/chunks/Checkbox-DHXTUHO9.js.map +1 -0
  17. package/dist/chunks/CloseButton-C2J7wVfo.js +26 -0
  18. package/dist/chunks/CloseButton-C2J7wVfo.js.map +1 -0
  19. package/dist/chunks/{Code-v4tDWuuN.js → Code-AsKpgnv6.js} +3 -3
  20. package/dist/chunks/Code-AsKpgnv6.js.map +1 -0
  21. package/dist/chunks/ColorField-Yz_BkcCT.js +69 -0
  22. package/dist/chunks/ColorField-Yz_BkcCT.js.map +1 -0
  23. package/dist/chunks/{ColorModeControl-JOEiqtE0.js → ColorModeControl-BewxA0rX.js} +3 -3
  24. package/dist/chunks/ColorModeControl-BewxA0rX.js.map +1 -0
  25. package/dist/chunks/{ComboBox-C1JgIpML.js → ComboBox-B34H76CW.js} +14 -14
  26. package/dist/chunks/ComboBox-B34H76CW.js.map +1 -0
  27. package/dist/chunks/{CurveEditor-f1R4kSbD.js → CurveEditor-DUVjd25R.js} +35 -35
  28. package/dist/chunks/CurveEditor-DUVjd25R.js.map +1 -0
  29. package/dist/chunks/{DataGrid-CZPrB_3a.js → DataGrid-LZ2JgY2Y.js} +27 -27
  30. package/dist/chunks/DataGrid-LZ2JgY2Y.js.map +1 -0
  31. package/dist/chunks/DetailList-BKomDzg5.js +52 -0
  32. package/dist/chunks/DetailList-BKomDzg5.js.map +1 -0
  33. package/dist/chunks/{DetentSlider-BYyaZha6.js → DetentSlider-5uQPFucv.js} +2 -2
  34. package/dist/chunks/DetentSlider-5uQPFucv.js.map +1 -0
  35. package/dist/chunks/Dialog-DGFutQ--.js +63 -0
  36. package/dist/chunks/Dialog-DGFutQ--.js.map +1 -0
  37. package/dist/chunks/{Disclosure-D79jhmh2.js → Disclosure-Ch2KxYuB.js} +7 -7
  38. package/dist/chunks/Disclosure-Ch2KxYuB.js.map +1 -0
  39. package/dist/chunks/{DragGhost-DcU7cOwy.js → DragGhost-B5_hb9W9.js} +2 -2
  40. package/dist/chunks/DragGhost-B5_hb9W9.js.map +1 -0
  41. package/dist/chunks/{DragHandleGlyph-BtBxHjZS.js → DragGrip-AoIZXfZb.js} +2 -2
  42. package/dist/chunks/DragGrip-AoIZXfZb.js.map +1 -0
  43. package/dist/chunks/FallthroughDiagram-BEHiM5IS.js +284 -0
  44. package/dist/chunks/FallthroughDiagram-BEHiM5IS.js.map +1 -0
  45. package/dist/chunks/{Field-xbqRmjsI.js → Field--onYxXTF.js} +7 -6
  46. package/dist/chunks/Field--onYxXTF.js.map +1 -0
  47. package/dist/chunks/{FillStrokeSwatch-BViKXIPx.js → FillStrokeSwatch-DNb0KXPk.js} +11 -11
  48. package/dist/chunks/FillStrokeSwatch-DNb0KXPk.js.map +1 -0
  49. package/dist/chunks/{FontFamilySelect-r9TV_xIH.js → FontFamilySelect-DkRgNtag.js} +2 -2
  50. package/dist/chunks/FontFamilySelect-DkRgNtag.js.map +1 -0
  51. package/dist/chunks/GestureRoute-C_YGl7bJ.js +82 -0
  52. package/dist/chunks/GestureRoute-C_YGl7bJ.js.map +1 -0
  53. package/dist/chunks/GradientEditor-b7v4Ph3i.js +363 -0
  54. package/dist/chunks/GradientEditor-b7v4Ph3i.js.map +1 -0
  55. package/dist/chunks/{Icon-BW0qv_U7.js → Icon-CcVjdq2C.js} +32 -2
  56. package/dist/chunks/Icon-CcVjdq2C.js.map +1 -0
  57. package/dist/chunks/{InlineRange-BwGFDhpT.js → InlineRange-P01ABSzo.js} +3 -3
  58. package/dist/chunks/InlineRange-P01ABSzo.js.map +1 -0
  59. package/dist/chunks/{Input-Bx2cuUbS.js → Input-CHmkfYaD.js} +2 -2
  60. package/dist/chunks/Input-CHmkfYaD.js.map +1 -0
  61. package/dist/chunks/{ItemList-DzJ2lK0R.js → ItemList-Cm-HUWCi.js} +6 -7
  62. package/dist/chunks/ItemList-Cm-HUWCi.js.map +1 -0
  63. package/dist/chunks/{ItemList.module-DDUXfuZL.js → ItemList.module-BSpCSxan.js} +1 -1
  64. package/dist/chunks/ItemList.module-BSpCSxan.js.map +1 -0
  65. package/dist/chunks/{Jog-LPoac9s4.js → Jog-DRmfrkCg.js} +4 -4
  66. package/dist/chunks/Jog-DRmfrkCg.js.map +1 -0
  67. package/dist/chunks/{Keycaps-CKiKOJnJ.js → Keycaps-C-FJyG8k.js} +15 -15
  68. package/dist/chunks/Keycaps-C-FJyG8k.js.map +1 -0
  69. package/dist/chunks/{LayerList-BeGrkLb9.js → LayerList-wCI1EueM.js} +150 -154
  70. package/dist/chunks/LayerList-wCI1EueM.js.map +1 -0
  71. package/dist/chunks/ListEditor-BeA60TAA.js +71 -0
  72. package/dist/chunks/ListEditor-BeA60TAA.js.map +1 -0
  73. package/dist/chunks/{MenuButton-BcdhrNGh.js → MenuButton-BSqEChJE.js} +9 -9
  74. package/dist/chunks/MenuButton-BSqEChJE.js.map +1 -0
  75. package/dist/chunks/{MeshEditor-BOOIFWnz.js → MeshEditor-D1HLZcAh.js} +4 -4
  76. package/dist/chunks/MeshEditor-D1HLZcAh.js.map +1 -0
  77. package/dist/chunks/NumberField-BnJxcazc.js +206 -0
  78. package/dist/chunks/NumberField-BnJxcazc.js.map +1 -0
  79. package/dist/chunks/{OptionsBar-DlcagPYK.js → OptionsBar-ujxYidhj.js} +3 -3
  80. package/dist/chunks/OptionsBar-ujxYidhj.js.map +1 -0
  81. package/dist/chunks/{PaintField-B2mLRZa4.js → PaintField-DadOELMg.js} +4 -4
  82. package/dist/chunks/PaintField-DadOELMg.js.map +1 -0
  83. package/dist/chunks/PaintInput-v8Y7MDbH.js +121 -0
  84. package/dist/chunks/PaintInput-v8Y7MDbH.js.map +1 -0
  85. package/dist/chunks/{PatternPicker-DdfpxoQy.js → PatternPicker-R_EQtw2Q.js} +2 -2
  86. package/dist/chunks/PatternPicker-R_EQtw2Q.js.map +1 -0
  87. package/dist/chunks/{Plot2D-lyO7waPQ.js → Plot2D-CTXHkL5p.js} +13 -13
  88. package/dist/chunks/Plot2D-CTXHkL5p.js.map +1 -0
  89. package/dist/chunks/{PointPlotter-DGs9i5P-.js → PointPlotter-ldI4RrU1.js} +5 -4
  90. package/dist/chunks/PointPlotter-ldI4RrU1.js.map +1 -0
  91. package/dist/chunks/Powerline-DNyH885r.js +42 -0
  92. package/dist/chunks/Powerline-DNyH885r.js.map +1 -0
  93. package/dist/chunks/{Prefs-Ctu0H4-b.js → Prefs-ByA-x51i.js} +60 -47
  94. package/dist/chunks/Prefs-ByA-x51i.js.map +1 -0
  95. package/dist/chunks/{Properties-Bbneh1ws.js → Properties-DmAeQ3mk.js} +43 -36
  96. package/dist/chunks/Properties-DmAeQ3mk.js.map +1 -0
  97. package/dist/chunks/PropertyField-DfIJJ5GS.js +673 -0
  98. package/dist/chunks/PropertyField-DfIJJ5GS.js.map +1 -0
  99. package/dist/chunks/{RadioGroup-BK2mD6Q0.js → RadioGroup-Bh4-12e-.js} +2 -2
  100. package/dist/chunks/RadioGroup-Bh4-12e-.js.map +1 -0
  101. package/dist/chunks/{RangeSlider-BiRAOsTh.js → RangeSlider-SEGE-7VF.js} +8 -8
  102. package/dist/chunks/RangeSlider-SEGE-7VF.js.map +1 -0
  103. package/dist/chunks/{ResizeHandle-Cc6EOehs.js → ResizeHandle-rKVWyeTG.js} +9 -9
  104. package/dist/chunks/ResizeHandle-rKVWyeTG.js.map +1 -0
  105. package/dist/chunks/Select-ClmKtyWg.js +229 -0
  106. package/dist/chunks/Select-ClmKtyWg.js.map +1 -0
  107. package/dist/chunks/SelectionPanel-BaQnX4Bs.js +106 -0
  108. package/dist/chunks/SelectionPanel-BaQnX4Bs.js.map +1 -0
  109. package/dist/chunks/{Sidebar-DKKd4R-x.js → Sidebar-BZ0m4afn.js} +8 -8
  110. package/dist/chunks/Sidebar-BZ0m4afn.js.map +1 -0
  111. package/dist/chunks/SidebarPanel-BblDEz4G.js +53 -0
  112. package/dist/chunks/SidebarPanel-BblDEz4G.js.map +1 -0
  113. package/dist/chunks/Slider-YofwGOI4.js +389 -0
  114. package/dist/chunks/Slider-YofwGOI4.js.map +1 -0
  115. package/dist/chunks/{StatusBar-CdPdmmda.js → StatusBar-Ca9Dvhhq.js} +13 -13
  116. package/dist/chunks/StatusBar-Ca9Dvhhq.js.map +1 -0
  117. package/dist/chunks/{SwatchGrid-C-Zx2Exd.js → SwatchGrid-BYvA8Bmh.js} +3 -3
  118. package/dist/chunks/{SwatchGrid-C-Zx2Exd.js.map → SwatchGrid-BYvA8Bmh.js.map} +1 -1
  119. package/dist/chunks/{Switch-DxF7TsEu.js → Switch-CSYmcM8y.js} +1 -1
  120. package/dist/chunks/Switch-CSYmcM8y.js.map +1 -0
  121. package/dist/chunks/{Tabs-GXEfoe3o.js → Tabs-BbpzLLdY.js} +1 -1
  122. package/dist/chunks/Tabs-BbpzLLdY.js.map +1 -0
  123. package/dist/chunks/ThemeSwitcher-BlsInAmR.js +38 -0
  124. package/dist/chunks/ThemeSwitcher-BlsInAmR.js.map +1 -0
  125. package/dist/chunks/{Timeline-SgmpQtUV.js → Timeline-B39cwfMB.js} +213 -209
  126. package/dist/chunks/Timeline-B39cwfMB.js.map +1 -0
  127. package/dist/chunks/{Toast-BfcljZz6.js → Toast-BF9GE0HC.js} +25 -27
  128. package/dist/chunks/Toast-BF9GE0HC.js.map +1 -0
  129. package/dist/chunks/{ToggleBar-Btnl5r7F.js → ToggleBar-BTYkBXU9.js} +20 -18
  130. package/dist/chunks/ToggleBar-BTYkBXU9.js.map +1 -0
  131. package/dist/chunks/{TokenPanel-5ajHEHha.js → TokenPanel-CMDAOfYH.js} +21 -18
  132. package/dist/chunks/TokenPanel-CMDAOfYH.js.map +1 -0
  133. package/dist/chunks/{ToolButton-rzqlFlAc.js → ToolButton-CAHBa08P.js} +7 -7
  134. package/dist/chunks/ToolButton-CAHBa08P.js.map +1 -0
  135. package/dist/chunks/{ToolGroup-4bUBV5k6.js → ToolGroup-Dpg1LN0l.js} +7 -7
  136. package/dist/chunks/ToolGroup-Dpg1LN0l.js.map +1 -0
  137. package/dist/chunks/{ToolOptionsBar-BF3TNXA3.js → ToolOptionsBar-D_GCrBAN.js} +12 -10
  138. package/dist/chunks/ToolOptionsBar-D_GCrBAN.js.map +1 -0
  139. package/dist/chunks/{ToolPalette-Uw4PvWwa.js → ToolPalette-OOWN51Xx.js} +7 -7
  140. package/dist/chunks/ToolPalette-OOWN51Xx.js.map +1 -0
  141. package/dist/chunks/{Tooltip-9XiJF937.js → Tooltip-Clg2mhSt.js} +2 -2
  142. package/dist/chunks/Tooltip-Clg2mhSt.js.map +1 -0
  143. package/dist/chunks/{Tree-BGt6P8tI.js → Tree-Cc8lIzgM.js} +3 -3
  144. package/dist/chunks/Tree-Cc8lIzgM.js.map +1 -0
  145. package/dist/chunks/{createKeyframeLayer-BzDRCrrh.js → createKeyframeLayer-DVl321_l.js} +46 -47
  146. package/dist/chunks/createKeyframeLayer-DVl321_l.js.map +1 -0
  147. package/dist/chunks/{dlog-CMYiRF3Q.js → dlog-F0I8KsIW.js} +2 -2
  148. package/dist/chunks/dlog-F0I8KsIW.js.map +1 -0
  149. package/dist/chunks/{formatShortcut-BoGqUoWi.js → formatShortcut-DRQrVThu.js} +2 -2
  150. package/dist/chunks/formatShortcut-DRQrVThu.js.map +1 -0
  151. package/dist/chunks/icons-BhcR1l64.js +162 -0
  152. package/dist/chunks/icons-BhcR1l64.js.map +1 -0
  153. package/dist/chunks/{interactiveTarget-C7QUBaJN.js → interactiveTarget-BNZmTow2.js} +1 -1
  154. package/dist/chunks/{interactiveTarget-C7QUBaJN.js.map → interactiveTarget-BNZmTow2.js.map} +1 -1
  155. package/dist/chunks/{keyGlyph-CLvUHU8c.js → keyGlyph-C0qTakG-.js} +1 -1
  156. package/dist/chunks/keyGlyph-C0qTakG-.js.map +1 -0
  157. package/dist/chunks/{model-BQMvTLnW.js → model-BaF65rnX.js} +95 -90
  158. package/dist/chunks/model-BaF65rnX.js.map +1 -0
  159. package/dist/chunks/{paintPreview-DPtZS4yU.js → paintPreview-CuSZiHpR.js} +1 -1
  160. package/dist/chunks/paintPreview-CuSZiHpR.js.map +1 -0
  161. package/dist/chunks/{paintValue-Bz6AVuh3.js → paintValue-BpaGPjV3.js} +3 -3
  162. package/dist/chunks/paintValue-BpaGPjV3.js.map +1 -0
  163. package/dist/chunks/{portalHost-CjpCnuGU.js → portalHost-yTOVuCej.js} +1 -1
  164. package/dist/chunks/portalHost-yTOVuCej.js.map +1 -0
  165. package/dist/chunks/{prefField-CLkhrvYl.js → prefField-BopW9bjx.js} +18 -14
  166. package/dist/chunks/prefField-BopW9bjx.js.map +1 -0
  167. package/dist/chunks/{segmentTooltip-CAkZlW-t.js → segmentTooltip-CStYHKzd.js} +2 -2
  168. package/dist/chunks/segmentTooltip-CStYHKzd.js.map +1 -0
  169. package/dist/chunks/segmentedControl.module-D6SzYJD7.js +11 -0
  170. package/dist/chunks/segmentedControl.module-D6SzYJD7.js.map +1 -0
  171. package/dist/chunks/{snap-DC4Km8xG.js → snap-DRjbOiG9.js} +1 -1
  172. package/dist/chunks/snap-DRjbOiG9.js.map +1 -0
  173. package/dist/chunks/{stance-CarrcbbP.js → stance-BFQpS_fL.js} +1 -1
  174. package/dist/chunks/stance-BFQpS_fL.js.map +1 -0
  175. package/dist/chunks/{useReorderDragList-Dcezzgix.js → useReorderDragList-FCMoFIzH.js} +3 -3
  176. package/dist/chunks/useReorderDragList-FCMoFIzH.js.map +1 -0
  177. package/dist/chunks/{useRovingTabIndex-B4uJqiKP.js → useRovingTabIndex-Bp_hYm_h.js} +1 -1
  178. package/dist/chunks/useRovingTabIndex-Bp_hYm_h.js.map +1 -0
  179. package/dist/components/ActionBar/ActionBar.d.ts +1 -1
  180. package/dist/components/ActionBar/ActionBar.d.ts.map +1 -1
  181. package/dist/components/ActionBar/index.js +1 -1
  182. package/dist/components/Badge/bases/Powerline.d.ts.map +1 -1
  183. package/dist/components/Badge/bases/edgeProfiles.d.ts +31 -4
  184. package/dist/components/Badge/bases/edgeProfiles.d.ts.map +1 -1
  185. package/dist/components/Badge/index.d.ts +1 -0
  186. package/dist/components/Badge/index.d.ts.map +1 -1
  187. package/dist/components/Badge/index.js +3 -2
  188. package/dist/components/Badge/statusIcons.d.ts +5 -0
  189. package/dist/components/Badge/statusIcons.d.ts.map +1 -0
  190. package/dist/components/BandEditor/BandEditor.d.ts +16 -7
  191. package/dist/components/BandEditor/BandEditor.d.ts.map +1 -1
  192. package/dist/components/BandEditor/bands.d.ts +5 -2
  193. package/dist/components/BandEditor/bands.d.ts.map +1 -1
  194. package/dist/components/BandEditor/index.js +1 -1
  195. package/dist/components/Button/index.js +1 -1
  196. package/dist/components/ButtonBar/index.js +1 -1
  197. package/dist/components/Callout/Callout.d.ts +3 -3
  198. package/dist/components/Callout/Callout.d.ts.map +1 -1
  199. package/dist/components/Callout/index.js +1 -1
  200. package/dist/components/Checkbox/index.js +1 -1
  201. package/dist/components/CloseButton/CloseButton.d.ts +21 -0
  202. package/dist/components/CloseButton/CloseButton.d.ts.map +1 -0
  203. package/dist/components/CloseButton/index.d.ts +3 -0
  204. package/dist/components/CloseButton/index.d.ts.map +1 -0
  205. package/dist/components/CloseButton/index.js +2 -0
  206. package/dist/components/Code/Code.d.ts +1 -1
  207. package/dist/components/Code/Code.d.ts.map +1 -1
  208. package/dist/components/Code/index.js +1 -1
  209. package/dist/components/ColorField/ColorField.d.ts +6 -2
  210. package/dist/components/ColorField/ColorField.d.ts.map +1 -1
  211. package/dist/components/ColorField/index.js +1 -1
  212. package/dist/components/ColorModeControl/index.js +1 -1
  213. package/dist/components/ComboBox/ComboBox.d.ts +2 -2
  214. package/dist/components/ComboBox/ComboBox.d.ts.map +1 -1
  215. package/dist/components/ComboBox/index.js +1 -1
  216. package/dist/components/CurveEditor/CurveEditor.d.ts +1 -1
  217. package/dist/components/CurveEditor/CurveEditor.d.ts.map +1 -1
  218. package/dist/components/CurveEditor/LayeredCurveEditor.d.ts +1 -1
  219. package/dist/components/CurveEditor/LayeredCurveEditor.d.ts.map +1 -1
  220. package/dist/components/CurveEditor/index.js +3 -3
  221. package/dist/components/DataGrid/DataGrid.d.ts +1 -1
  222. package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
  223. package/dist/components/DataGrid/index.js +1 -1
  224. package/dist/components/DetailList/DetailList.d.ts +31 -5
  225. package/dist/components/DetailList/DetailList.d.ts.map +1 -1
  226. package/dist/components/DetailList/index.d.ts +1 -1
  227. package/dist/components/DetailList/index.d.ts.map +1 -1
  228. package/dist/components/DetailList/index.js +1 -1
  229. package/dist/components/DetentSlider/index.js +1 -1
  230. package/dist/components/Dialog/Dialog.d.ts +1 -1
  231. package/dist/components/Dialog/Dialog.d.ts.map +1 -1
  232. package/dist/components/Dialog/index.js +1 -1
  233. package/dist/components/Disclosure/Disclosure.d.ts +4 -4
  234. package/dist/components/Disclosure/Disclosure.d.ts.map +1 -1
  235. package/dist/components/Disclosure/index.js +1 -1
  236. package/dist/components/DragGhost/index.js +1 -1
  237. package/dist/components/{DragHandleGlyph/DragHandleGlyph.d.ts → DragGrip/DragGrip.d.ts} +4 -4
  238. package/dist/components/DragGrip/DragGrip.d.ts.map +1 -0
  239. package/dist/components/DragGrip/index.d.ts +3 -0
  240. package/dist/components/DragGrip/index.d.ts.map +1 -0
  241. package/dist/components/DragGrip/index.js +2 -0
  242. package/dist/components/FallthroughDiagram/FallthroughDiagram.d.ts +14 -0
  243. package/dist/components/FallthroughDiagram/FallthroughDiagram.d.ts.map +1 -0
  244. package/dist/components/FallthroughDiagram/fixtures.d.ts +17 -0
  245. package/dist/components/FallthroughDiagram/fixtures.d.ts.map +1 -0
  246. package/dist/components/FallthroughDiagram/index.d.ts +3 -0
  247. package/dist/components/FallthroughDiagram/index.d.ts.map +1 -0
  248. package/dist/components/FallthroughDiagram/index.js +2 -0
  249. package/dist/components/Field/Field.d.ts +1 -1
  250. package/dist/components/Field/Field.d.ts.map +1 -1
  251. package/dist/components/Field/index.js +1 -1
  252. package/dist/components/FillStrokeSwatch/index.js +1 -1
  253. package/dist/components/FontFamilySelect/FontFamilySelect.d.ts +1 -1
  254. package/dist/components/FontFamilySelect/FontFamilySelect.d.ts.map +1 -1
  255. package/dist/components/FontFamilySelect/index.js +1 -1
  256. package/dist/components/GestureRoute/GestureRoute.d.ts +19 -0
  257. package/dist/components/GestureRoute/GestureRoute.d.ts.map +1 -0
  258. package/dist/components/GestureRoute/index.d.ts +3 -0
  259. package/dist/components/GestureRoute/index.d.ts.map +1 -0
  260. package/dist/components/GestureRoute/index.js +2 -0
  261. package/dist/components/GradientEditor/GradientEditor.d.ts +22 -8
  262. package/dist/components/GradientEditor/GradientEditor.d.ts.map +1 -1
  263. package/dist/components/GradientEditor/index.js +1 -1
  264. package/dist/components/InlineRange/index.js +1 -1
  265. package/dist/components/Input/index.js +1 -1
  266. package/dist/components/ItemList/index.js +1 -1
  267. package/dist/components/Jog/Jog.d.ts +1 -1
  268. package/dist/components/Jog/Jog.d.ts.map +1 -1
  269. package/dist/components/Jog/index.js +1 -1
  270. package/dist/components/Keycaps/Keycap.d.ts +1 -1
  271. package/dist/components/Keycaps/Keycap.d.ts.map +1 -1
  272. package/dist/components/Keycaps/Keycaps.d.ts +11 -5
  273. package/dist/components/Keycaps/Keycaps.d.ts.map +1 -1
  274. package/dist/components/Keycaps/index.d.ts +1 -1
  275. package/dist/components/Keycaps/index.d.ts.map +1 -1
  276. package/dist/components/Keycaps/index.js +2 -2
  277. package/dist/components/LayerList/LayerList.d.ts +2 -2
  278. package/dist/components/LayerList/LayerList.d.ts.map +1 -1
  279. package/dist/components/LayerList/index.js +1 -1
  280. package/dist/components/ListEditor/ListEditor.d.ts +1 -1
  281. package/dist/components/ListEditor/ListEditor.d.ts.map +1 -1
  282. package/dist/components/ListEditor/index.js +1 -1
  283. package/dist/components/MenuButton/MenuButton.d.ts +1 -1
  284. package/dist/components/MenuButton/MenuButton.d.ts.map +1 -1
  285. package/dist/components/MenuButton/index.js +1 -1
  286. package/dist/components/MeshEditor/index.js +1 -1
  287. package/dist/components/NumberField/UnitField.d.ts +20 -7
  288. package/dist/components/NumberField/UnitField.d.ts.map +1 -1
  289. package/dist/components/NumberField/index.js +1 -1
  290. package/dist/components/OptionsBar/index.js +1 -1
  291. package/dist/components/PaintField/index.js +1 -1
  292. package/dist/components/PaintInput/PaintInput.d.ts.map +1 -1
  293. package/dist/components/PaintInput/index.js +1 -1
  294. package/dist/components/PatternPicker/index.js +1 -1
  295. package/dist/components/Plot2D/index.js +1 -1
  296. package/dist/components/PointPlotter/PointPlotter.d.ts +1 -1
  297. package/dist/components/PointPlotter/PointPlotter.d.ts.map +1 -1
  298. package/dist/components/PointPlotter/index.js +1 -1
  299. package/dist/components/Powerline/Powerline.d.ts +1 -1
  300. package/dist/components/Powerline/Powerline.d.ts.map +1 -1
  301. package/dist/components/Powerline/index.d.ts +1 -1
  302. package/dist/components/Powerline/index.d.ts.map +1 -1
  303. package/dist/components/Powerline/index.js +2 -2
  304. package/dist/components/Prefs/PrefsDialog.d.ts +1 -1
  305. package/dist/components/Prefs/PrefsDialog.d.ts.map +1 -1
  306. package/dist/components/Prefs/PrefsForm.d.ts +1 -1
  307. package/dist/components/Prefs/PrefsForm.d.ts.map +1 -1
  308. package/dist/components/Prefs/PrefsPane.d.ts +1 -1
  309. package/dist/components/Prefs/PrefsPane.d.ts.map +1 -1
  310. package/dist/components/Prefs/PrefsRail.d.ts +1 -1
  311. package/dist/components/Prefs/PrefsRail.d.ts.map +1 -1
  312. package/dist/components/Prefs/PrefsRow.d.ts +1 -1
  313. package/dist/components/Prefs/PrefsRow.d.ts.map +1 -1
  314. package/dist/components/Prefs/index.d.ts +1 -1
  315. package/dist/components/Prefs/index.d.ts.map +1 -1
  316. package/dist/components/Prefs/index.js +2 -2
  317. package/dist/components/Prefs/prefField.d.ts.map +1 -1
  318. package/dist/components/Prefs/schema.d.ts +2 -2
  319. package/dist/components/Prefs/schema.d.ts.map +1 -1
  320. package/dist/components/Properties/CurveField.d.ts +1 -1
  321. package/dist/components/Properties/CurveField.d.ts.map +1 -1
  322. package/dist/components/Properties/DialogRow.d.ts +1 -1
  323. package/dist/components/Properties/DialogRow.d.ts.map +1 -1
  324. package/dist/components/Properties/PropertyField.d.ts +24 -32
  325. package/dist/components/Properties/PropertyField.d.ts.map +1 -1
  326. package/dist/components/Properties/PropertyGroup.d.ts +1 -1
  327. package/dist/components/Properties/PropertyGroup.d.ts.map +1 -1
  328. package/dist/components/Properties/PropertyPanel.d.ts +4 -11
  329. package/dist/components/Properties/PropertyPanel.d.ts.map +1 -1
  330. package/dist/components/Properties/Subpanel.d.ts +1 -1
  331. package/dist/components/Properties/Subpanel.d.ts.map +1 -1
  332. package/dist/components/Properties/index.d.ts +1 -1
  333. package/dist/components/Properties/index.d.ts.map +1 -1
  334. package/dist/components/Properties/index.js +2 -2
  335. package/dist/components/Properties/storyLayouts.d.ts +1 -1
  336. package/dist/components/Properties/storyLayouts.d.ts.map +1 -1
  337. package/dist/components/RadioGroup/RadioGroup.d.ts +2 -2
  338. package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -1
  339. package/dist/components/RadioGroup/index.js +1 -1
  340. package/dist/components/RangeSlider/RangeSlider.d.ts +1 -1
  341. package/dist/components/RangeSlider/RangeSlider.d.ts.map +1 -1
  342. package/dist/components/RangeSlider/index.js +1 -1
  343. package/dist/components/ResizeHandle/ResizeHandle.d.ts +1 -1
  344. package/dist/components/ResizeHandle/ResizeHandle.d.ts.map +1 -1
  345. package/dist/components/ResizeHandle/index.js +1 -1
  346. package/dist/components/Select/Select.d.ts +3 -3
  347. package/dist/components/Select/Select.d.ts.map +1 -1
  348. package/dist/components/Select/index.js +1 -1
  349. package/dist/components/SelectionPanel/SelectionPanel.d.ts +1 -1
  350. package/dist/components/SelectionPanel/SelectionPanel.d.ts.map +1 -1
  351. package/dist/components/SelectionPanel/index.js +2 -2
  352. package/dist/components/SelectionPanel/renderLeaf.d.ts +7 -0
  353. package/dist/components/SelectionPanel/renderLeaf.d.ts.map +1 -1
  354. package/dist/components/Sidebar/Sidebar.d.ts +1 -1
  355. package/dist/components/Sidebar/Sidebar.d.ts.map +1 -1
  356. package/dist/components/Sidebar/index.js +1 -1
  357. package/dist/components/SidebarPanel/SidebarPanel.d.ts +2 -2
  358. package/dist/components/SidebarPanel/SidebarPanel.d.ts.map +1 -1
  359. package/dist/components/SidebarPanel/index.js +1 -1
  360. package/dist/components/Slider/Slider.d.ts +21 -3
  361. package/dist/components/Slider/Slider.d.ts.map +1 -1
  362. package/dist/components/Slider/index.js +1 -1
  363. package/dist/components/StatusBar/StatusBar.d.ts +3 -3
  364. package/dist/components/StatusBar/StatusBar.d.ts.map +1 -1
  365. package/dist/components/StatusBar/index.js +1 -1
  366. package/dist/components/SwatchGrid/index.js +1 -1
  367. package/dist/components/Switch/index.js +1 -1
  368. package/dist/components/Tabs/Tabs.d.ts +4 -4
  369. package/dist/components/Tabs/Tabs.d.ts.map +1 -1
  370. package/dist/components/Tabs/index.js +1 -1
  371. package/dist/components/ThemeSwitcher/ThemeSwitcher.d.ts +38 -0
  372. package/dist/components/ThemeSwitcher/ThemeSwitcher.d.ts.map +1 -0
  373. package/dist/components/ThemeSwitcher/index.d.ts +3 -0
  374. package/dist/components/ThemeSwitcher/index.d.ts.map +1 -0
  375. package/dist/components/ThemeSwitcher/index.js +2 -0
  376. package/dist/components/Timeline/Transport.d.ts.map +1 -1
  377. package/dist/components/Timeline/index.js +1 -1
  378. package/dist/components/Toast/Toast.d.ts +1 -1
  379. package/dist/components/Toast/Toast.d.ts.map +1 -1
  380. package/dist/components/Toast/index.js +1 -1
  381. package/dist/components/ToggleBar/index.js +1 -1
  382. package/dist/components/TokenPanel/TokenPanel.d.ts +1 -1
  383. package/dist/components/TokenPanel/TokenPanel.d.ts.map +1 -1
  384. package/dist/components/TokenPanel/index.js +1 -1
  385. package/dist/components/ToolButton/ToolButton.d.ts +1 -1
  386. package/dist/components/ToolButton/ToolButton.d.ts.map +1 -1
  387. package/dist/components/ToolButton/index.js +1 -1
  388. package/dist/components/ToolGroup/ToolGroup.d.ts +1 -1
  389. package/dist/components/ToolGroup/ToolGroup.d.ts.map +1 -1
  390. package/dist/components/ToolGroup/index.js +1 -1
  391. package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts +1 -1
  392. package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts.map +1 -1
  393. package/dist/components/ToolOptionsBar/index.js +1 -1
  394. package/dist/components/ToolPalette/ToolPalette.d.ts +3 -2
  395. package/dist/components/ToolPalette/ToolPalette.d.ts.map +1 -1
  396. package/dist/components/ToolPalette/index.js +2 -2
  397. package/dist/components/Tooltip/Tooltip.d.ts +2 -2
  398. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
  399. package/dist/components/Tooltip/index.js +1 -1
  400. package/dist/components/Tree/index.js +1 -1
  401. package/dist/components/spin.d.ts +16 -0
  402. package/dist/components/spin.d.ts.map +1 -0
  403. package/dist/components/stanceSurfaces.d.ts.map +1 -1
  404. package/dist/icons/Icon.d.ts +1 -1
  405. package/dist/icons/Icon.d.ts.map +1 -1
  406. package/dist/icons/index.d.ts +52 -54
  407. package/dist/icons/index.d.ts.map +1 -1
  408. package/dist/icons/paths.d.ts +10 -0
  409. package/dist/icons/paths.d.ts.map +1 -1
  410. package/dist/index.d.ts +6 -2
  411. package/dist/index.d.ts.map +1 -1
  412. package/dist/index.js +86 -83
  413. package/dist/index.js.map +1 -1
  414. package/dist/overlays/portalHost.d.ts +1 -1
  415. package/dist/overlays/portalHost.d.ts.map +1 -1
  416. package/dist/paintGradientTrack.d.ts +5 -2
  417. package/dist/paintGradientTrack.d.ts.map +1 -1
  418. package/dist/style.css +1 -1
  419. package/dist/useReorderDragList.d.ts +1 -1
  420. package/dist/useReorderDragList.d.ts.map +1 -1
  421. package/package.json +9 -8
  422. package/dist/chunks/ActionBar-CYvfmEz0.js.map +0 -1
  423. package/dist/chunks/Badge-DZ0lFs14.js.map +0 -1
  424. package/dist/chunks/BandEditor-D-nVrVO4.js +0 -247
  425. package/dist/chunks/BandEditor-D-nVrVO4.js.map +0 -1
  426. package/dist/chunks/Button-Dyp31jMt.js.map +0 -1
  427. package/dist/chunks/ButtonBar-smZzFuEo.js.map +0 -1
  428. package/dist/chunks/Callout-xLjnx7Mp.js +0 -119
  429. package/dist/chunks/Callout-xLjnx7Mp.js.map +0 -1
  430. package/dist/chunks/Checkbox-ChZz30Ds.js.map +0 -1
  431. package/dist/chunks/Code-v4tDWuuN.js.map +0 -1
  432. package/dist/chunks/ColorField-DJSCuSJv.js +0 -60
  433. package/dist/chunks/ColorField-DJSCuSJv.js.map +0 -1
  434. package/dist/chunks/ColorModeControl-JOEiqtE0.js.map +0 -1
  435. package/dist/chunks/ComboBox-C1JgIpML.js.map +0 -1
  436. package/dist/chunks/CurveEditor-f1R4kSbD.js.map +0 -1
  437. package/dist/chunks/DataGrid-CZPrB_3a.js.map +0 -1
  438. package/dist/chunks/DetailList-DHaXX4TG.js +0 -43
  439. package/dist/chunks/DetailList-DHaXX4TG.js.map +0 -1
  440. package/dist/chunks/DetentSlider-BYyaZha6.js.map +0 -1
  441. package/dist/chunks/Dialog-GIvjoDQj.js +0 -66
  442. package/dist/chunks/Dialog-GIvjoDQj.js.map +0 -1
  443. package/dist/chunks/Disclosure-D79jhmh2.js.map +0 -1
  444. package/dist/chunks/DragGhost-DcU7cOwy.js.map +0 -1
  445. package/dist/chunks/DragHandleGlyph-BtBxHjZS.js.map +0 -1
  446. package/dist/chunks/Field-xbqRmjsI.js.map +0 -1
  447. package/dist/chunks/FillStrokeSwatch-BViKXIPx.js.map +0 -1
  448. package/dist/chunks/FontFamilySelect-r9TV_xIH.js.map +0 -1
  449. package/dist/chunks/GradientEditor-BRTxHG-W.js +0 -333
  450. package/dist/chunks/GradientEditor-BRTxHG-W.js.map +0 -1
  451. package/dist/chunks/Icon-BW0qv_U7.js.map +0 -1
  452. package/dist/chunks/InlineRange-BwGFDhpT.js.map +0 -1
  453. package/dist/chunks/Input-Bx2cuUbS.js.map +0 -1
  454. package/dist/chunks/ItemList-DzJ2lK0R.js.map +0 -1
  455. package/dist/chunks/ItemList.module-DDUXfuZL.js.map +0 -1
  456. package/dist/chunks/Jog-LPoac9s4.js.map +0 -1
  457. package/dist/chunks/Keycaps-CKiKOJnJ.js.map +0 -1
  458. package/dist/chunks/LayerList-BeGrkLb9.js.map +0 -1
  459. package/dist/chunks/ListEditor-C6zLzCsJ.js +0 -74
  460. package/dist/chunks/ListEditor-C6zLzCsJ.js.map +0 -1
  461. package/dist/chunks/MenuButton-BcdhrNGh.js.map +0 -1
  462. package/dist/chunks/MeshEditor-BOOIFWnz.js.map +0 -1
  463. package/dist/chunks/NumberField-C1Y7zP-a.js +0 -117
  464. package/dist/chunks/NumberField-C1Y7zP-a.js.map +0 -1
  465. package/dist/chunks/OptionsBar-DlcagPYK.js.map +0 -1
  466. package/dist/chunks/PaintField-B2mLRZa4.js.map +0 -1
  467. package/dist/chunks/PaintInput-BFKhd83I.js +0 -131
  468. package/dist/chunks/PaintInput-BFKhd83I.js.map +0 -1
  469. package/dist/chunks/PatternPicker-DdfpxoQy.js.map +0 -1
  470. package/dist/chunks/Plot2D-lyO7waPQ.js.map +0 -1
  471. package/dist/chunks/PointPlotter-DGs9i5P-.js.map +0 -1
  472. package/dist/chunks/Powerline-DBEPceLE.js +0 -38
  473. package/dist/chunks/Powerline-DBEPceLE.js.map +0 -1
  474. package/dist/chunks/Prefs-Ctu0H4-b.js.map +0 -1
  475. package/dist/chunks/Properties-Bbneh1ws.js.map +0 -1
  476. package/dist/chunks/PropertyField-CDb19d3F.js +0 -756
  477. package/dist/chunks/PropertyField-CDb19d3F.js.map +0 -1
  478. package/dist/chunks/RadioGroup-BK2mD6Q0.js.map +0 -1
  479. package/dist/chunks/RangeSlider-BiRAOsTh.js.map +0 -1
  480. package/dist/chunks/ResizeHandle-Cc6EOehs.js.map +0 -1
  481. package/dist/chunks/Select-DVValBe1.js +0 -225
  482. package/dist/chunks/Select-DVValBe1.js.map +0 -1
  483. package/dist/chunks/SelectionPanel-C5LmZA7b.js +0 -103
  484. package/dist/chunks/SelectionPanel-C5LmZA7b.js.map +0 -1
  485. package/dist/chunks/Sidebar-DKKd4R-x.js.map +0 -1
  486. package/dist/chunks/SidebarPanel-u5NsuAZY.js +0 -55
  487. package/dist/chunks/SidebarPanel-u5NsuAZY.js.map +0 -1
  488. package/dist/chunks/Slider-BwRrWHFW.js +0 -381
  489. package/dist/chunks/Slider-BwRrWHFW.js.map +0 -1
  490. package/dist/chunks/StatusBar-CdPdmmda.js.map +0 -1
  491. package/dist/chunks/Switch-DxF7TsEu.js.map +0 -1
  492. package/dist/chunks/Tabs-GXEfoe3o.js.map +0 -1
  493. package/dist/chunks/Timeline-SgmpQtUV.js.map +0 -1
  494. package/dist/chunks/Toast-BfcljZz6.js.map +0 -1
  495. package/dist/chunks/ToggleBar-Btnl5r7F.js.map +0 -1
  496. package/dist/chunks/TokenPanel-5ajHEHha.js.map +0 -1
  497. package/dist/chunks/ToolButton-rzqlFlAc.js.map +0 -1
  498. package/dist/chunks/ToolGroup-4bUBV5k6.js.map +0 -1
  499. package/dist/chunks/ToolOptionsBar-BF3TNXA3.js.map +0 -1
  500. package/dist/chunks/ToolPalette-Uw4PvWwa.js.map +0 -1
  501. package/dist/chunks/Tooltip-9XiJF937.js.map +0 -1
  502. package/dist/chunks/Tree-BGt6P8tI.js.map +0 -1
  503. package/dist/chunks/createKeyframeLayer-BzDRCrrh.js.map +0 -1
  504. package/dist/chunks/dlog-CMYiRF3Q.js.map +0 -1
  505. package/dist/chunks/formatShortcut-BoGqUoWi.js.map +0 -1
  506. package/dist/chunks/icons-DbScMMqX.js +0 -179
  507. package/dist/chunks/icons-DbScMMqX.js.map +0 -1
  508. package/dist/chunks/keyGlyph-CLvUHU8c.js.map +0 -1
  509. package/dist/chunks/model-BQMvTLnW.js.map +0 -1
  510. package/dist/chunks/number-6S8IzXVt.js +0 -89
  511. package/dist/chunks/number-6S8IzXVt.js.map +0 -1
  512. package/dist/chunks/paintPreview-DPtZS4yU.js.map +0 -1
  513. package/dist/chunks/paintValue-Bz6AVuh3.js.map +0 -1
  514. package/dist/chunks/portalHost-CjpCnuGU.js.map +0 -1
  515. package/dist/chunks/prefField-CLkhrvYl.js.map +0 -1
  516. package/dist/chunks/segmentTooltip-CAkZlW-t.js.map +0 -1
  517. package/dist/chunks/segmentedControl.module-D2nw68Yo.js +0 -11
  518. package/dist/chunks/segmentedControl.module-D2nw68Yo.js.map +0 -1
  519. package/dist/chunks/snap-DC4Km8xG.js.map +0 -1
  520. package/dist/chunks/stance-CarrcbbP.js.map +0 -1
  521. package/dist/chunks/useReorderDragList-Dcezzgix.js.map +0 -1
  522. package/dist/chunks/useRovingTabIndex-B4uJqiKP.js.map +0 -1
  523. package/dist/components/DragHandleGlyph/DragHandleGlyph.d.ts.map +0 -1
  524. package/dist/components/DragHandleGlyph/index.d.ts +0 -3
  525. package/dist/components/DragHandleGlyph/index.d.ts.map +0 -1
  526. package/dist/components/DragHandleGlyph/index.js +0 -2
  527. package/dist/format/number.d.ts +0 -56
  528. package/dist/format/number.d.ts.map +0 -1
  529. package/dist/icons/ShapeKindIcon.d.ts +0 -10
  530. package/dist/icons/ShapeKindIcon.d.ts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"ColorField-DJSCuSJv.js","names":[],"sources":["../../src/components/ColorField/ColorField.module.css","../../src/components/ColorField/ColorField.tsx"],"sourcesContent":[".root {\n display: inline-flex;\n align-items: center;\n gap: var(--wzl-space-3);\n}\n\n.chip {\n position: relative;\n display: inline-flex;\n border-radius: var(--wzl-radius-sm);\n overflow: hidden;\n}\n\n.color {\n inline-size: 28px;\n block-size: var(--wzl-control-h-sm);\n padding: 0;\n border: 1px solid var(--wzl-border, #444);\n border-radius: var(--wzl-radius-sm);\n background: none;\n cursor: pointer;\n}\n\n.color:focus-visible {\n outline: none;\n border-color: var(--wzl-focus-ring);\n box-shadow: 0 0 0 1px var(--wzl-focus-ring);\n}\n\n/* Indeterminate (mixed) presentation: checkerboard overlay atop the\n * swatch. pointer-events: none so the input stays clickable. */\n.root[data-mixed] .chip::after {\n content: '';\n position: absolute;\n inset: 1px;\n border-radius: var(--wzl-radius-sm);\n pointer-events: none;\n background: repeating-conic-gradient(\n var(--wzl-checker-a) 0% 25%,\n var(--wzl-checker-b) 0% 50%\n )\n 50% / var(--wzl-checker-size) var(--wzl-checker-size);\n}\n\n/* `InlineRange` owns the track; this only says how it shares the row. */\n.alphaRange {\n flex: 1;\n}\n\n.alphaReadout {\n min-inline-size: 3ch;\n text-align: end;\n font-size: var(--wzl-font-size-sm);\n opacity: 0.7;\n}\n","import { useState } from 'react';\nimport { toHex8, getAlpha01, withAlpha01 } from '@weasel-js/core';\nimport { InlineRange } from '../InlineRange';\nimport s from './ColorField.module.css';\n\n/**\n * Props for {@link ColorField}. `onInput` fires throughout a gesture and\n * `onChange` once at its end.\n */\nexport interface ColorFieldProps {\n /** Current color, `#rrggbb` or `#rrggbbaa`. Omit when `mixed`. */\n value?: string;\n /** Indeterminate presentation (multi-selection with differing colors):\n * checkered chip, empty value. The first color edit produces a real\n * value; the opacity slider stays disabled until then (an alpha-only\n * edit would otherwise commit a value composed against the\n * placeholder black). */\n mixed?: boolean;\n /** Show the opacity slider; emitted values are `#rrggbbaa`. */\n alpha?: boolean;\n /** Live value during interaction (picker drag, slider drag). Optional —\n * wire it for live preview; omit it for commit-only consumers. */\n onInput?: (hex: string) => void;\n /** Committed value — picker close (blur) or slider release. One call\n * per user gesture; pair with an undoable write. */\n onChange: (hex: string) => void;\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * Compact color editor: native color input + optional opacity slider.\n * Commit semantics are gesture-based (see `onChange`) because native\n * color/range inputs fire `change` continuously during interaction —\n * commit-on-change would emit one undo entry per tick.\n */\nexport function ColorField(props: ColorFieldProps) {\n const { value, mixed = false, alpha = false, onInput, onChange, className } = props;\n const hex8 = toHex8(value ?? '#000000');\n const rgb6 = hex8.slice(0, 7);\n const alpha01 = getAlpha01(hex8);\n const alphaPct = Math.round(alpha01 * 100);\n\n // Drafts track the control during a gesture (the committed prop only\n // updates after onChange), then reset to follow the prop again.\n const [colorDraft, setColorDraft] = useState<string | null>(null);\n const [alphaDraft, setAlphaDraft] = useState<number | null>(null);\n const visibleRgb = colorDraft ?? rgb6;\n const visibleAlphaPct = alphaDraft ?? alphaPct;\n\n const compose = (rgb: string, a01: number): string =>\n alpha ? withAlpha01(rgb, a01) : rgb;\n\n // Mixed with no color edit yet: the alpha slider has nothing real to\n // compose against (rgb6 is the placeholder black), so keep it disabled\n // until the first color edit lands.\n const alphaLocked = mixed && colorDraft === null;\n\n // Commit only when a gesture actually changed something — blur with no\n // preceding input must not emit (it would create a no-op undo entry).\n const commit = (rgb: string, a01: number): void => {\n if (colorDraft === null && alphaDraft === null) return;\n onChange(compose(rgb, a01));\n setColorDraft(null);\n setAlphaDraft(null);\n };\n\n return (\n <span\n className={[s.root, className].filter(Boolean).join(' ')}\n {...(mixed && colorDraft === null ? { 'data-mixed': '' } : {})}\n >\n <span className={s.chip}>\n <input\n className={s.color}\n type=\"color\"\n value={visibleRgb}\n aria-label={props['aria-label'] ?? 'Color'}\n onInput={(e) => {\n const rgb = (e.target as HTMLInputElement).value;\n setColorDraft(rgb);\n onInput?.(compose(rgb, visibleAlphaPct / 100));\n }}\n onBlur={() => commit(visibleRgb, visibleAlphaPct / 100)}\n />\n </span>\n {alpha && (\n <>\n <InlineRange\n className={s.alphaRange}\n min={0}\n max={100}\n step={1}\n value={visibleAlphaPct}\n disabled={alphaLocked}\n aria-label={props['aria-label'] ? `${props['aria-label']} opacity` : 'Opacity'}\n onInput={(e) => {\n const pct = Number((e.target as HTMLInputElement).value);\n setAlphaDraft(pct);\n onInput?.(compose(visibleRgb, pct / 100));\n }}\n onPointerUp={() => commit(visibleRgb, visibleAlphaPct / 100)}\n onPointerCancel={() => commit(visibleRgb, visibleAlphaPct / 100)}\n onKeyUp={() => commit(visibleRgb, visibleAlphaPct / 100)}\n onBlur={() => commit(visibleRgb, visibleAlphaPct / 100)}\n />\n <span className={s.alphaReadout} aria-hidden=\"true\">{visibleAlphaPct}%</span>\n </>\n )}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;ACoCA,SAAgB,EAAW,GAAwB;CACjD,IAAM,EAAE,UAAO,WAAQ,IAAO,WAAQ,IAAO,YAAS,aAAU,iBAAc,GACxE,IAAO,EAAO,KAAS,UAAU,EACjC,IAAO,EAAK,MAAM,GAAG,EAAE,EACvB,IAAU,EAAW,EAAK,EAC1B,IAAW,KAAK,MAAM,IAAU,IAAI,EAIpC,CAAC,GAAY,KAAiB,EAAwB,KAAK,EAC3D,CAAC,GAAY,KAAiB,EAAwB,KAAK,EAC3D,IAAa,KAAc,GAC3B,IAAkB,KAAc,GAEhC,KAAW,GAAa,MAC5B,IAAQ,EAAY,GAAK,EAAI,GAAG,GAK5B,IAAc,KAAS,MAAe,MAItC,KAAU,GAAa,MAAsB;AAC7C,QAAe,QAAQ,MAAe,SAC1C,EAAS,EAAQ,GAAK,EAAI,CAAC,EAC3B,EAAc,KAAK,EACnB,EAAc,KAAK;;AAGrB,QACE,kBAAC,QAAD;EACE,WAAW,CAAC,EAAE,MAAM,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EACxD,GAAK,KAAS,MAAe,OAAO,EAAE,cAAc,IAAI,GAAG,EAAE;YAF/D,CAIE,kBAAC,QAAD;GAAM,WAAW,EAAE;aACjB,kBAAC,SAAD;IACE,WAAW,EAAE;IACb,MAAK;IACL,OAAO;IACP,cAAY,EAAM,iBAAiB;IACnC,UAAU,MAAM;KACd,IAAM,IAAO,EAAE,OAA4B;AAE3C,KADA,EAAc,EAAI,EAClB,IAAU,EAAQ,GAAK,IAAkB,IAAI,CAAC;;IAEhD,cAAc,EAAO,GAAY,IAAkB,IAAI;IACvD,CAAA;GACG,CAAA,EACN,KACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;GACE,WAAW,EAAE;GACb,KAAK;GACL,KAAK;GACL,MAAM;GACN,OAAO;GACP,UAAU;GACV,cAAY,EAAM,gBAAgB,GAAG,EAAM,cAAc,YAAY;GACrE,UAAU,MAAM;IACd,IAAM,IAAM,OAAQ,EAAE,OAA4B,MAAM;AAExD,IADA,EAAc,EAAI,EAClB,IAAU,EAAQ,GAAY,IAAM,IAAI,CAAC;;GAE3C,mBAAmB,EAAO,GAAY,IAAkB,IAAI;GAC5D,uBAAuB,EAAO,GAAY,IAAkB,IAAI;GAChE,eAAe,EAAO,GAAY,IAAkB,IAAI;GACxD,cAAc,EAAO,GAAY,IAAkB,IAAI;GACvD,CAAA,EACF,kBAAC,QAAD;GAAM,WAAW,EAAE;GAAc,eAAY;aAA7C,CAAqD,GAAgB,IAAQ;KAC5E,EAAA,CAAA,CAEA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ColorModeControl-JOEiqtE0.js","names":[],"sources":["../../src/components/ColorModeControl/ColorModeControl.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { ColorModePreference } from '@weasel-js/theme';\nimport { ModeAutoIcon, ModeDarkIcon, ModeLightIcon } from '../../icons';\nimport { ToggleBar, type ToggleBarItem, type ToggleBarSize, type ToggleBarVariant } from '../ToggleBar/ToggleBar';\n\n/** Props for {@link ColorModeControl}. */\nexport interface ColorModeControlProps {\n value: ColorModePreference;\n onChange: (next: ColorModePreference) => void;\n /** Accessible name of the group. Defaults to `'Color mode'`. */\n ariaLabel?: string;\n size?: ToggleBarSize;\n variant?: ToggleBarVariant;\n className?: string;\n}\n\nfunction items(glyph: number): ToggleBarItem<ColorModePreference>[] {\n return [\n { value: 'auto', label: <ModeAutoIcon size={glyph} />, ariaLabel: 'Auto', tooltip: 'Auto — follow the system' },\n { value: 'light', label: <ModeLightIcon size={glyph} />, ariaLabel: 'Light', tooltip: 'Light' },\n { value: 'dark', label: <ModeDarkIcon size={glyph} />, ariaLabel: 'Dark', tooltip: 'Dark' },\n ];\n}\n\nconst ITEMS = { sm: items(12), md: items(14) };\n\n/**\n * The Auto / Light / Dark choice, as a three-way radiogroup of mode glyphs.\n * Controlled: pair it with `useColorModePreference` from\n * `@weasel-js/theme/react` and put the hook's resolved `mode` in the\n * `ThemeProvider` selection.\n */\nexport function ColorModeControl({\n value,\n onChange,\n ariaLabel = 'Color mode',\n size,\n variant,\n className,\n}: ColorModeControlProps): ReactElement {\n return (\n <ToggleBar\n items={ITEMS[size ?? 'md']}\n value={value}\n onChange={(next) => {\n if (next) onChange(next);\n }}\n ariaLabel={ariaLabel}\n size={size}\n variant={variant}\n className={className}\n />\n );\n}\n"],"mappings":";;;;AAgBA,SAAS,EAAM,GAAqD;AAClE,QAAO;EACL;GAAE,OAAO;GAAQ,OAAO,kBAAC,GAAD,EAAc,MAAM,GAAS,CAAA;GAAE,WAAW;GAAQ,SAAS;GAA4B;EAC/G;GAAE,OAAO;GAAS,OAAO,kBAAC,GAAD,EAAe,MAAM,GAAS,CAAA;GAAE,WAAW;GAAS,SAAS;GAAS;EAC/F;GAAE,OAAO;GAAQ,OAAO,kBAAC,GAAD,EAAc,MAAM,GAAS,CAAA;GAAE,WAAW;GAAQ,SAAS;GAAQ;EAC5F;;AAGH,IAAM,IAAQ;CAAE,IAAI,EAAM,GAAG;CAAE,IAAI,EAAM,GAAG;CAAE;AAQ9C,SAAgB,EAAiB,EAC/B,UACA,aACA,eAAY,cACZ,SACA,YACA,gBACsC;AACtC,QACE,kBAAC,GAAD;EACE,OAAO,EAAM,KAAQ;EACd;EACP,WAAW,MAAS;AAClB,GAAI,KAAM,EAAS,EAAK;;EAEf;EACL;EACG;EACE;EACX,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ComboBox-C1JgIpML.js","names":[],"sources":["../../src/components/ComboBox/ComboBox.module.css","../../src/components/ComboBox/ComboBox.tsx"],"sourcesContent":[".field {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-width: 0;\n gap: var(--wzl-space-2);\n}\n\n.frame {\n display: flex;\n align-items: stretch;\n height: var(--wzl-field-h, var(--wzl-control-h));\n background: var(--wzl-surface-sunken);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size);\n line-height: 1;\n overflow: hidden;\n transition: border-color var(--wzl-motion-fast), box-shadow var(--wzl-motion-fast);\n}\n\n.frame:focus-within {\n border-color: var(--wzl-focus-ring);\n box-shadow: 0 0 0 1px var(--wzl-focus-ring);\n}\n\n.field[data-invalid] .frame {\n border-color: var(--wzl-danger);\n}\n\n.field[data-disabled] .frame {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.frame input {\n flex: 1;\n min-width: 0;\n background: transparent;\n border: none;\n outline: none;\n color: inherit;\n font: inherit;\n padding: 0 var(--wzl-field-pad-x);\n}\n\n.frame input::placeholder {\n color: var(--wzl-fg-subtle);\n}\n\n/* A request is out: the rows on screen are the previous query's, so mark them\n stale rather than clearing the list out from under the arrow keys. */\n.frame:has(input[aria-busy='true'])::after {\n content: '';\n align-self: center;\n flex: none;\n width: 10px;\n height: 10px;\n margin-right: var(--wzl-space-2);\n border: 1.5px solid var(--wzl-fg-subtle);\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 700ms linear infinite;\n}\n\n@keyframes spin {\n to {\n transform: rotate(1turn);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .frame:has(input[aria-busy='true'])::after {\n animation: none;\n border-top-color: var(--wzl-fg-subtle);\n opacity: 0.5;\n }\n}\n\n.openButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wzl-icon-button-size);\n background: transparent;\n border: none;\n border-left: 1px solid var(--wzl-border);\n color: var(--wzl-fg-muted);\n cursor: pointer;\n padding: 0;\n}\n\n.openButton[data-hovered]:not([data-disabled]) {\n color: var(--wzl-fg);\n}\n\n.openButton svg {\n width: 10px;\n height: 10px;\n}\n\n.popover {\n min-width: var(--trigger-width);\n outline: none;\n}\n\n.listbox {\n background: var(--wzl-surface-raised);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-md);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);\n padding: var(--wzl-space-2);\n max-height: 280px;\n overflow: auto;\n outline: none;\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size);\n}\n\n.option {\n display: flex;\n align-items: center;\n padding: var(--wzl-space-2) var(--wzl-space-4);\n border-radius: var(--wzl-radius-sm);\n cursor: pointer;\n color: var(--wzl-fg);\n outline: none;\n}\n\n.option[data-focused] {\n background: var(--wzl-surface-hover);\n}\n\n.option[data-selected] {\n font-weight: var(--wzl-font-weight-medium);\n}\n\n.option[data-disabled] {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.empty {\n padding: var(--wzl-space-3) var(--wzl-space-4);\n color: var(--wzl-fg-subtle);\n font-size: var(--wzl-font-size-sm);\n}\n\n.error {\n padding: var(--wzl-space-3) var(--wzl-space-4);\n color: var(--wzl-danger);\n font-size: var(--wzl-font-size-sm);\n}\n\n/* `width='fit'`: a hidden stack of every option label shares the input's grid\n cell, so the field is wide enough for whichever option is chosen and takes\n no more of the row than that. */\n.fit {\n width: auto;\n max-width: 100%;\n}\n\n.fit .frame {\n display: grid;\n grid-template-columns: auto auto;\n width: fit-content;\n max-width: 100%;\n}\n\n/* `width: 0` keeps the input's 20-character intrinsic width out of the track\n sizing — the sizer is what the column measures — and `min-width` then\n stretches it back across whatever that came to. */\n.fit .frame input {\n grid-area: 1 / 1;\n width: 0;\n min-width: 100%;\n}\n\n.fit .sizer {\n grid-area: 1 / 1;\n}\n\n.fit .openButton {\n grid-area: 1 / 2;\n}\n\n.sizer {\n display: grid;\n height: 0;\n overflow: hidden;\n visibility: hidden;\n white-space: nowrap;\n padding: 0 var(--wzl-field-pad-x);\n}\n\n.sizer > * {\n grid-area: 1 / 1;\n}\n","import { Children, isValidElement, useContext, type KeyboardEvent, type ReactNode } from 'react';\nimport {\n ComboBox as RACComboBox,\n ComboBoxStateContext,\n Label,\n Input as RACInput,\n Button as RACButton,\n Popover as RACPopover,\n ListBox as RACListBox,\n ListBoxItem as RACListBoxItem,\n Text,\n FieldError,\n type ComboBoxProps as RACComboBoxProps,\n type ListBoxItemProps as RACListBoxItemProps,\n type ValidationResult,\n} from 'react-aria-components';\nimport { fieldClasses } from '../Field/Field';\nimport { useOverlayPortal, type OverlayPortalProps } from '../../overlays/portalHost';\nimport s from './ComboBox.module.css';\n\n/**\n * One option in a {@link ComboBox}'s `options` list. `textValue` is the\n * plain-text form used for filtering and screen readers, needed only when\n * `label` isn't a bare string.\n */\nexport type ComboBoxOption = {\n value: string;\n label: ReactNode;\n textValue?: string;\n isDisabled?: boolean;\n};\n\ntype Key = string | number;\n\n/**\n * How the typed text narrows the options.\n *\n * `'contains'` is a locale-aware substring match over each option's text.\n * `'none'` shows every option given — what a list a server already filtered\n * and ranked needs, since a second pass would drop rows that do not contain\n * the query and reorder whatever survived.\n */\nexport type ComboBoxFilter = 'contains' | 'none' | ((textValue: string, inputValue: string) => boolean);\n\n/** What the user committed: an option they picked, or text they typed. */\nexport type ComboBoxCommit<T extends Key = string> =\n | { source: 'option'; key: T }\n | { source: 'text'; text: string };\n\nconst admitEverything = () => true;\n\n/**\n * Props for {@link ComboBox}, on top of React Aria's `ComboBox` props, with\n * the selection key narrowed to the option value type.\n */\nexport type ComboBoxProps<T extends Key = string> = Omit<RACComboBoxProps<object>, 'children' | 'className' | 'selectedKey' | 'defaultSelectedKey' | 'onSelectionChange'> & {\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);\n placeholder?: string;\n options?: ReadonlyArray<ComboBoxOption & { value: T }>;\n children?: ReactNode;\n selectedKey?: T | null;\n defaultSelectedKey?: T;\n onSelectionChange?: (key: T | null) => void;\n emptyLabel?: ReactNode;\n /** Shown in place of `emptyLabel` while `loadError` is set. */\n errorLabel?: ReactNode;\n /**\n * How typed text narrows `options`. Defaults to `'contains'`. `'none'` also\n * keeps the popover open on an empty collection: a list the kit does not\n * filter can arrive empty from a server mid-query, and without that the\n * popover closes and `emptyLabel` is never seen.\n */\n filter?: ComboBoxFilter;\n /** Marks the options as out of date while the next set is being fetched. */\n isLoading?: boolean;\n /** A failed load, shown as `errorLabel` rather than as an empty corpus. */\n loadError?: unknown | null;\n /**\n * Fires when the user commits — Enter on the active option, a click on one,\n * or Enter on text matching none of them when `allowsCustomValue` is set.\n * Empty text commits nothing.\n */\n onCommit?: (commit: ComboBoxCommit<T>) => void;\n /**\n * `'fill'` (the default) takes the width of whatever row the combo box sits\n * in. `'fit'` sizes the input to its widest option, so it neither swallows a\n * toolbar's slack nor cuts a selection off once one is made.\n */\n width?: 'fill' | 'fit';\n className?: string;\n} & OverlayPortalProps;\n\n/**\n * Filterable single-select wrapping React Aria's ComboBox. The user can\n * type to filter; selection commits to `onSelectionChange`. When no value\n * is in the input, selection clears (key becomes null).\n */\nexport function ComboBox<T extends Key = string>(props: ComboBoxProps<T>) {\n const {\n label,\n description,\n errorMessage,\n placeholder,\n options,\n children,\n selectedKey,\n defaultSelectedKey,\n onSelectionChange,\n emptyLabel = 'No matches',\n errorLabel = \"Couldn't load options\",\n filter = 'contains',\n isLoading,\n loadError = null,\n onCommit,\n width = 'fill',\n className,\n portalContainer,\n ...rest\n } = props;\n\n const { anchor, portalProps } = useOverlayPortal(portalContainer);\n\n return (\n <RACComboBox\n {...rest}\n // 'contains' leaves this unset so React Aria uses its own locale-aware\n // match rather than a reimplementation of it.\n defaultFilter={filter === 'none' ? admitEverything : filter === 'contains' ? undefined : filter}\n allowsEmptyCollection={rest.allowsEmptyCollection ?? filter === 'none'}\n selectedKey={selectedKey}\n defaultSelectedKey={defaultSelectedKey}\n onSelectionChange={(k) => {\n onSelectionChange?.(k as T | null);\n if (k !== null) onCommit?.({ source: 'option', key: k as T });\n }}\n className={[s.field, width === 'fit' && s.fit, fieldClasses.root, className]\n .filter(Boolean)\n .join(' ')}\n >\n {anchor}\n {label !== undefined && <Label className={fieldClasses.label}>{label}</Label>}\n <ComboBoxFrame\n placeholder={placeholder}\n isLoading={isLoading}\n onCommitText={onCommit && ((text) => onCommit({ source: 'text', text }))}\n >\n {width === 'fit' && (\n <span className={s.sizer} aria-hidden=\"true\">\n {placeholder !== undefined && <span>{placeholder}</span>}\n {optionLabels(options, children).map((l, i) => (\n <span key={i}>{l}</span>\n ))}\n </span>\n )}\n </ComboBoxFrame>\n {description !== undefined && (\n <Text slot=\"description\" className={fieldClasses.hint}>\n {description}\n </Text>\n )}\n <FieldError className={fieldClasses.error}>{errorMessage}</FieldError>\n <RACPopover className={s.popover} data-weasel-overlay=\"\" {...portalProps}>\n <RACListBox\n className={s.listbox}\n renderEmptyState={() =>\n loadError !== null ? (\n <div className={s.error} role=\"alert\">{errorLabel}</div>\n ) : (\n <div className={s.empty}>{emptyLabel}</div>\n )\n }\n >\n {options !== undefined\n ? options.map((o) => (\n <ComboBoxItem key={String(o.value)} id={o.value} textValue={o.textValue} isDisabled={o.isDisabled}>\n {o.label}\n </ComboBoxItem>\n ))\n : children}\n </RACListBox>\n </RACPopover>\n </RACComboBox>\n );\n}\n\n/**\n * The input and its trigger. Split out so it can read `ComboBoxStateContext`,\n * which only exists below `RACComboBox`.\n */\nfunction ComboBoxFrame({\n placeholder,\n isLoading,\n onCommitText,\n children,\n}: {\n placeholder?: string;\n isLoading?: boolean;\n onCommitText?: (text: string) => void;\n children?: ReactNode;\n}) {\n const state = useContext(ComboBoxStateContext);\n\n // Capture, not bubble: React Aria's own Enter handler runs on the way up and\n // clears the focused key, so by then there is no way to tell an option\n // commit from a text one.\n const onKeyDownCapture = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key !== 'Enter' || e.nativeEvent.isComposing) return;\n if (state?.isOpen && state.selectionManager.focusedKey != null) return;\n const text = e.currentTarget.value;\n if (text !== '') onCommitText?.(text);\n };\n\n return (\n <div className={s.frame}>\n <RACInput\n placeholder={placeholder}\n aria-busy={isLoading || undefined}\n onKeyDownCapture={onCommitText ? onKeyDownCapture : undefined}\n />\n {children}\n <RACButton className={s.openButton} aria-label=\"Show options\">\n <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M2 4 L5 7 L8 4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </RACButton>\n </div>\n );\n}\n\n/**\n * The labels a `width='fit'` input measures itself against. In the children\n * form the label sits one element deep, inside a `ComboBoxItem`.\n */\nfunction optionLabels(\n options: ReadonlyArray<ComboBoxOption> | undefined,\n children: ReactNode,\n): ReactNode[] {\n if (options !== undefined) return options.map((o) => o.label);\n return Children.toArray(children).map((c) =>\n isValidElement<{ children?: ReactNode }>(c) ? c.props.children : c,\n );\n}\n\n/** Props for {@link ComboBoxItem}, on top of React Aria's `ListBoxItem` props. */\nexport type ComboBoxItemProps = Omit<RACListBoxItemProps, 'className'> & {\n className?: string;\n};\n\n/** One row in a {@link ComboBox}'s filtered list. */\nexport function ComboBoxItem({ className, ...rest }: ComboBoxItemProps) {\n return <RACListBoxItem {...rest} className={[s.option, className].filter(Boolean).join(' ')} />;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CurveEditor-f1R4kSbD.js","names":[],"sources":["../../src/components/CurveEditor/catmullRom.ts","../../src/components/CurveEditor/monotone.ts","../../src/components/CurveEditor/interpolation.ts","../../src/components/CurveEditor/createFunctionLayer.tsx","../../src/components/CurveEditor/CurveEditor.tsx","../../src/components/CurveEditor/setCurveOp.ts"],"sourcesContent":["/**\n * Catmull-Rom spline sampling, parameterized by α.\n *\n * α = 0 → uniform parameterization (original Catmull-Rom). Fast, can\n * produce cusps and self-intersections at sharp 2D angles.\n * α = 0.5 → centripetal (Yuksel/Schneider 2011). No cusps, no\n * self-intersection. The \"safe default\" for 2D.\n * α = 1 → chordal. Smoother than uniform, different artifacts.\n *\n * `sampleCurve(...)` is the convenience alias for centripetal (α=0.5).\n */\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nfunction knot(a: Point, b: Point, alpha: number): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n return Math.pow(Math.sqrt(dx * dx + dy * dy), alpha);\n}\n\n/**\n * Sample the Catmull-Rom segment between p1 and p2 at parameter\n * t ∈ [0, 1]. p0 and p3 are the surrounding control points (use phantom\n * reflection at endpoints — see sampleCatmullRom below).\n *\n * Returns p1 at t=0 and p2 at t=1. `alpha` controls parameterization.\n */\nexport function segmentSampleAt(\n p0: Point, p1: Point, p2: Point, p3: Point, t: number,\n alpha: number = 0.5,\n): Point {\n const t0 = 0;\n const t1 = t0 + knot(p0, p1, alpha);\n const t2 = t1 + knot(p1, p2, alpha);\n const t3 = t2 + knot(p2, p3, alpha);\n\n // Degenerate: coincident p1/p2 → linear interpolation fallback.\n if (t2 - t1 === 0) {\n return { x: p1.x + (p2.x - p1.x) * t, y: p1.y + (p2.y - p1.y) * t };\n }\n\n const u = t1 + t * (t2 - t1);\n\n const a1x = ((t1 - u) * p0.x + (u - t0) * p1.x) / (t1 - t0);\n const a1y = ((t1 - u) * p0.y + (u - t0) * p1.y) / (t1 - t0);\n const a2x = ((t2 - u) * p1.x + (u - t1) * p2.x) / (t2 - t1);\n const a2y = ((t2 - u) * p1.y + (u - t1) * p2.y) / (t2 - t1);\n const a3x = ((t3 - u) * p2.x + (u - t2) * p3.x) / (t3 - t2);\n const a3y = ((t3 - u) * p2.y + (u - t2) * p3.y) / (t3 - t2);\n\n const b1x = ((t2 - u) * a1x + (u - t0) * a2x) / (t2 - t0);\n const b1y = ((t2 - u) * a1y + (u - t0) * a2y) / (t2 - t0);\n const b2x = ((t3 - u) * a2x + (u - t1) * a3x) / (t3 - t1);\n const b2y = ((t3 - u) * a2y + (u - t1) * a3y) / (t3 - t1);\n\n const cx = ((t2 - u) * b1x + (u - t1) * b2x) / (t2 - t1);\n const cy = ((t2 - u) * b1y + (u - t1) * b2y) / (t2 - t1);\n return { x: cx, y: cy };\n}\n\n/**\n * Sample the whole curve through `anchors` using Catmull-Rom with the\n * given α. Returns `(n-1) * samplesPerSegment + 1` points. Phantom\n * endpoints by reflection so the first/last segments are tangent to\n * the chord into/out of the endpoints. Returns `[]` for fewer than 2\n * anchors.\n */\nexport function sampleCatmullRom(\n anchors: readonly Point[],\n samplesPerSegment: number,\n alpha: number = 0.5,\n): Point[] {\n if (anchors.length < 2) return [];\n if (samplesPerSegment < 1) samplesPerSegment = 1;\n\n const n = anchors.length;\n const out: Point[] = [];\n\n const reflectStart: Point = {\n x: 2 * anchors[0].x - anchors[1].x,\n y: 2 * anchors[0].y - anchors[1].y,\n };\n const reflectEnd: Point = {\n x: 2 * anchors[n - 1].x - anchors[n - 2].x,\n y: 2 * anchors[n - 1].y - anchors[n - 2].y,\n };\n\n for (let i = 0; i < n - 1; i++) {\n const p0 = i === 0 ? reflectStart : anchors[i - 1];\n const p1 = anchors[i];\n const p2 = anchors[i + 1];\n const p3 = i + 2 < n ? anchors[i + 2] : reflectEnd;\n const tStart = i === 0 ? 0 : 1;\n for (let s = tStart; s <= samplesPerSegment; s++) {\n if (s === 0) {\n out.push(p1);\n continue;\n }\n if (s === samplesPerSegment) {\n out.push(p2);\n continue;\n }\n const t = s / samplesPerSegment;\n out.push(segmentSampleAt(p0, p1, p2, p3, t, alpha));\n }\n }\n return out;\n}\n\n/** Convenience alias for centripetal Catmull-Rom (α=0.5). The most\n * common choice; safe default for 2D paths. */\nexport function sampleCurve(\n anchors: readonly Point[],\n samplesPerSegment: number,\n): Point[] {\n return sampleCatmullRom(anchors, samplesPerSegment, 0.5);\n}\n","/**\n * Monotone cubic interpolation (Fritsch-Carlson / Steffen variant).\n *\n * Passes through every anchor and guarantees the curve never\n * overshoots `min(neighbors)` / `max(neighbors)` along either axis.\n * The right choice for animation timing curves (no anticipation) or\n * audio envelopes (no out-of-range values).\n *\n * Parameterized by index — works for both 1D (function-shaped) and\n * 2D (parametric) anchor sequences. The x and y coordinates are\n * interpolated independently as functions of the anchor index.\n *\n * Reference: Fritsch & Carlson 1980, \"Monotone piecewise cubic\n * interpolation.\" Steffen's 1990 refinement is conceptually the same;\n * we use a min-clamp variant that's monotonicity-preserving by\n * construction.\n */\n\nimport type { Point } from './catmullRom';\n\n/** Per-axis tangent computation for a 1D series of y-values sampled at\n * unit intervals (index-parameterized). Returns one tangent per\n * anchor. */\nfunction tangents(ys: readonly number[]): number[] {\n const n = ys.length;\n if (n === 0) return [];\n if (n === 1) return [0];\n\n // Secant slopes (dx = 1 in index parameterization).\n const m: number[] = new Array(n - 1);\n for (let i = 0; i < n - 1; i++) m[i] = ys[i + 1] - ys[i];\n\n const t: number[] = new Array(n);\n t[0] = m[0];\n t[n - 1] = m[n - 2];\n\n for (let i = 1; i < n - 1; i++) {\n if (m[i - 1] * m[i] <= 0) {\n // Sign change or flat → local extremum; tangent is zero (forces\n // the curve to settle without overshoot).\n t[i] = 0;\n } else {\n // Weighted average of adjacent secants (with dx_i = dx_{i-1} = 1,\n // this is just the arithmetic mean). Clamped by Steffen's rule\n // so the cubic stays monotone within each segment.\n const avg = (m[i - 1] + m[i]) / 2;\n const mag = Math.min(Math.abs(m[i - 1]), Math.abs(m[i]), Math.abs(avg));\n t[i] = Math.sign(avg) * mag;\n }\n }\n return t;\n}\n\n/** Cubic Hermite basis at parameter t ∈ [0, 1] given endpoint values\n * p0, p1 and endpoint tangents m0, m1. */\nfunction hermite(\n p0: number, p1: number, m0: number, m1: number, t: number,\n): number {\n const t2 = t * t;\n const t3 = t2 * t;\n return (\n (2 * t3 - 3 * t2 + 1) * p0 +\n (t3 - 2 * t2 + t) * m0 +\n (-2 * t3 + 3 * t2) * p1 +\n (t3 - t2) * m1\n );\n}\n\n/**\n * Sample the monotone-cubic curve through `anchors`. Returns\n * `(n-1) * samplesPerSegment + 1` points (same shape as\n * `sampleCatmullRom`). `[]` for fewer than 2 anchors.\n */\nexport function sampleMonotone(\n anchors: readonly Point[],\n samplesPerSegment: number,\n): Point[] {\n if (anchors.length < 2) return [];\n if (samplesPerSegment < 1) samplesPerSegment = 1;\n\n const n = anchors.length;\n const xs = anchors.map((a) => a.x);\n const ys = anchors.map((a) => a.y);\n const tx = tangents(xs);\n const ty = tangents(ys);\n\n const out: Point[] = [];\n for (let i = 0; i < n - 1; i++) {\n const startStep = i === 0 ? 0 : 1; // skip duplicate boundary\n for (let s = startStep; s <= samplesPerSegment; s++) {\n if (s === 0) { out.push(anchors[i]); continue; }\n if (s === samplesPerSegment) { out.push(anchors[i + 1]); continue; }\n const t = s / samplesPerSegment;\n out.push({\n x: hermite(xs[i], xs[i + 1], tx[i], tx[i + 1], t),\n y: hermite(ys[i], ys[i + 1], ty[i], ty[i + 1], t),\n });\n }\n }\n return out;\n}\n","/**\n * Interpolation mode dispatcher for CurveEditor. The vocabulary of\n * supported algorithms and the unified `sample(...)` entry point that\n * picks the right one. All algorithms produce\n * `(n-1) * samplesPerSegment + 1` points and pass through every\n * anchor — CurveEditor is strictly interpolating, never approximating.\n */\n\nimport { sampleCatmullRom, type Point } from './catmullRom';\nimport { sampleMonotone } from './monotone';\n\n/** Supported interpolation modes. All are interpolating (pass through\n * every anchor); the differences are in tangent computation and\n * parameterization. */\nexport type InterpolationMode =\n | 'linear'\n | 'catmull-rom' // centripetal (α=0.5) — safe default\n | 'catmull-rom-uniform' // α=0; can cusp on sharp 2D angles\n | 'catmull-rom-chordal' // α=1; smoother than uniform\n | 'monotone'; // Fritsch-Carlson / Steffen; no overshoot\n\n/** Sample anchors as a polyline. Produces the same sample count shape\n * as the Catmull-Rom variants so downstream segment-slicing logic\n * (hit testing, fill path construction) works uniformly. */\nfunction sampleLinear(\n anchors: readonly Point[],\n samplesPerSegment: number,\n): Point[] {\n if (anchors.length < 2) return [];\n if (samplesPerSegment < 1) samplesPerSegment = 1;\n\n const out: Point[] = [];\n for (let i = 0; i < anchors.length - 1; i++) {\n const a = anchors[i];\n const b = anchors[i + 1];\n const startStep = i === 0 ? 0 : 1;\n for (let s = startStep; s <= samplesPerSegment; s++) {\n if (s === 0) { out.push(a); continue; }\n if (s === samplesPerSegment) { out.push(b); continue; }\n const t = s / samplesPerSegment;\n out.push({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t });\n }\n }\n return out;\n}\n\n/** Sample `anchors` using the chosen interpolation mode. */\nexport function sampleByInterpolation(\n anchors: readonly Point[],\n samplesPerSegment: number,\n mode: InterpolationMode,\n): Point[] {\n switch (mode) {\n case 'linear':\n return sampleLinear(anchors, samplesPerSegment);\n case 'catmull-rom-uniform':\n return sampleCatmullRom(anchors, samplesPerSegment, 0);\n case 'catmull-rom-chordal':\n return sampleCatmullRom(anchors, samplesPerSegment, 1);\n case 'monotone':\n return sampleMonotone(anchors, samplesPerSegment);\n case 'catmull-rom':\n default:\n return sampleCatmullRom(anchors, samplesPerSegment, 0.5);\n }\n}\n","/**\n * Built-in function/curve layer for LayeredCurveEditor. Bundles the\n * curve-render + anchor-render + drag/insert/delete gestures that were\n * the entirety of the original `CurveEditor`. Multiple instances coexist\n * by id; consumers can compose several to plot e.g. a primary function\n * and a derived (read-only) curve on the same chart.\n */\nimport type { ReactNode } from 'react';\nimport { sampleByInterpolation, type InterpolationMode } from './interpolation';\nimport { hitTestAnchor, hitTestCurve } from './hitTest';\nimport { handleHalf } from '../../handles';\nimport { dlog } from '../../dlog';\nimport s from './CurveEditor.module.css';\nimport type {\n CurveLayer, LayerCtx, LayerGesture, LayerRenderCtx, ModelPoint, PlotPoint,\n EmptyDownArgs, KeyDownArgs,\n} from './layerTypes';\n\n// ── Public types ─────────────────────────────────────────────────────\n\n/** One anchor of a curve, in model space. */\nexport interface ControlPoint {\n x: number;\n y: number;\n /** When true, this control point can't be moved or deleted by the\n * user. Render as a smaller diamond with locked styling. */\n locked?: boolean;\n}\n\n/**\n * Whether a curve's points keep their x order. In `'1d'` an anchor cannot be\n * dragged past its neighbors and a new point is inserted at its x position;\n * in `'2d'` points are free to move anywhere and keep their list order.\n */\nexport type CurveDomain = '1d' | '2d';\n/**\n * How much of a curve's first and last anchor the user may move: everything,\n * only their y, or nothing.\n */\nexport type EndpointMode = 'free' | 'pinned-x' | 'pinned-both';\n/**\n * Where a click adds a new anchor — on the curve itself, anywhere in the\n * plot, or nowhere.\n */\nexport type AddPointMode = 'click-curve' | 'click-empty' | 'never';\n\n/**\n * What a `renderAnchor` function is given for one anchor: the point, its\n * index, its position in plot space (`cx`/`cy`), and the states that change\n * how it should look.\n */\nexport interface AnchorRenderProps {\n point: ControlPoint;\n index: number;\n cx: number;\n cy: number;\n isActive: boolean;\n isLocked: boolean;\n isPinnedEndpoint: boolean;\n isEndpoint: boolean;\n}\n\n/**\n * Per-instance curve-rendering overrides. Currently empty — passing `{}`\n * means \"draw the curve\", and `false`/`null` means don't.\n */\nexport type CurveSettings = object;\n\n/** Shades the region between the curve and one edge of the plot. */\nexport interface FillSettings {\n side: 'below' | 'above';\n color?: string;\n}\n\n/** Configuration for {@link createFunctionLayer}. */\nexport interface FunctionLayerConfig {\n /** Layer id; default `'function'`. Two instances on the same editor\n * must have distinct ids. */\n id?: string;\n domain?: CurveDomain;\n endpoints?: EndpointMode;\n interpolation?: InterpolationMode;\n constrain?: 'none' | 'function';\n addPointMode?: AddPointMode;\n minPoints?: number;\n maxPoints?: number;\n curve?: CurveSettings | false | null;\n fill?: FillSettings | false | null;\n hideNonInteractive?: boolean;\n renderAnchor?: (info: AnchorRenderProps) => ReactNode;\n /** When false, the layer renders the curve+fill but doesn't render\n * anchors and doesn't accept pointer input. For derived read-only\n * curves (e.g. plotting f'(x) alongside f(x)). Default true. */\n interactive?: boolean;\n /** Override x clamp range for drags and pinned endpoints. Defaults\n * to the editor's modelRange x. Use this to constrain a layer to a\n * sub-range of the plot (e.g. a bevel curve occupying x ∈ [0, b]\n * while the editor's xRange is [0, halfWidth]). */\n xClamp?: readonly [number, number];\n /** Names the curve in each anchor's accessible name. Default `'Point'`. */\n label?: string;\n}\n\n/**\n * The state a function layer owns. Treat it as opaque and round-trip it\n * through `LayeredCurveEditor`'s `onLayerChange`; `points` is the part worth\n * reading.\n */\nexport interface FunctionLayerState {\n points: readonly ControlPoint[];\n /** Layer-internal: the index of the anchor currently being dragged.\n * Cleared between gestures. Consumers treat the whole state as\n * opaque and round-trip it via onLayerChange. */\n activeIndex: number | null;\n}\n\nconst SAMPLES_PER_SEGMENT = 16;\nconst ENDPOINT_HALF = handleHalf('--wzl-handle-size-lg');\nconst LOCKED_HALF = handleHalf('--wzl-handle-size-sm');\nconst ANCHOR_SNAP_PX = 12;\nconst CURVE_HIT_PX = 8;\n/** An arrow-key nudge, as a fraction of the range; shift takes ten. */\nconst KEY_STEP_FRACTION = 0.01;\nconst SHIFT_MULTIPLIER = 10;\n\nconst formatCoord = (n: number): string => String(Number(n.toFixed(3)));\n\n// ── Helpers ───────────────────────────────────────────────────────────\n\nfunction clampToModelRange(p: ModelPoint, ctx: LayerCtx): ModelPoint {\n const m = ctx.modelRange;\n const xLo = Math.min(m.xMin, m.xMax);\n const xHi = Math.max(m.xMin, m.xMax);\n const yLo = Math.min(m.yMin, m.yMax);\n const yHi = Math.max(m.yMin, m.yMax);\n return {\n x: Math.max(xLo, Math.min(xHi, p.x)),\n y: Math.max(yLo, Math.min(yHi, p.y)),\n };\n}\n\nfunction isPinnedEndpointAt(index: number, count: number, endpoints: EndpointMode): boolean {\n if (endpoints === 'free') return false;\n return index === 0 || index === count - 1;\n}\n\nfunction projectAnchors(points: readonly ControlPoint[], ctx: LayerCtx): PlotPoint[] {\n return points.map((p) => ctx.toPlot(p));\n}\n\nfunction segmentSamples(\n points: readonly ControlPoint[],\n interpolation: InterpolationMode,\n ctx: LayerCtx,\n): PlotPoint[][] {\n if (points.length < 2) return [];\n const all = sampleByInterpolation(points, SAMPLES_PER_SEGMENT, interpolation);\n const out: PlotPoint[][] = [];\n for (let i = 0; i < points.length - 1; i++) {\n const start = i * SAMPLES_PER_SEGMENT;\n const end = start + SAMPLES_PER_SEGMENT;\n const slice = all.slice(start, end + 1);\n out.push(slice.map((p) => ctx.toPlot(p)));\n }\n return out;\n}\n\nfunction resolveInterpolation(cfg: FunctionLayerConfig): InterpolationMode {\n return (cfg.constrain ?? 'none') === 'function'\n ? 'monotone'\n : (cfg.interpolation ?? 'catmull-rom');\n}\n\n// ── Factory ───────────────────────────────────────────────────────────\n\n/**\n * Builds the built-in curve layer for `LayeredCurveEditor`: it draws the\n * interpolated curve and its anchors, and handles dragging, inserting and\n * deleting them.\n *\n * Several can coexist on one editor as long as their ids differ — plotting a\n * derived read-only curve beside an editable one is the case it is shaped\n * for, via `interactive: false`.\n */\nexport function createFunctionLayer(cfg: FunctionLayerConfig = {}): CurveLayer<FunctionLayerState> {\n const id = cfg.id ?? 'function';\n const domain = cfg.domain ?? '2d';\n const endpoints = cfg.endpoints ?? 'free';\n const constrain = cfg.constrain ?? 'none';\n const addPointMode = cfg.addPointMode ?? 'click-curve';\n const interpolation = resolveInterpolation(cfg);\n const interactive = cfg.interactive !== false;\n const curveVisible = cfg.curve !== false && cfg.curve !== null;\n\n // ── render ──────────────────────────────────────────────────────────\n function render(state: FunctionLayerState, ctx: LayerRenderCtx): ReactNode {\n const { points, activeIndex } = state;\n const plotAnchors = projectAnchors(points, ctx);\n\n let pathD = '';\n let fillD: string | null = null;\n if (points.length >= 2) {\n const samples = sampleByInterpolation(points, SAMPLES_PER_SEGMENT, interpolation)\n .map((p) => ctx.toPlot(p));\n const parts: string[] = [`M${samples[0].x.toFixed(2)},${samples[0].y.toFixed(2)}`];\n for (let i = 1; i < samples.length; i++) {\n parts.push(`L${samples[i].x.toFixed(2)},${samples[i].y.toFixed(2)}`);\n }\n pathD = parts.join('');\n\n if (cfg.fill) {\n const closingY = cfg.fill.side === 'below' ? ctx.plotSize.height : 0;\n const first = samples[0];\n const last = samples[samples.length - 1];\n const fillParts = [...parts];\n fillParts.push(`L${last.x.toFixed(2)},${closingY.toFixed(2)}`);\n fillParts.push(`L${first.x.toFixed(2)},${closingY.toFixed(2)}`);\n fillParts.push('Z');\n fillD = fillParts.join('');\n }\n }\n\n return (\n <>\n {fillD && (\n <path\n data-curve-element=\"fill\"\n className={s.fill}\n d={fillD}\n fill={cfg.fill ? cfg.fill.color : undefined}\n />\n )}\n {pathD && curveVisible && (\n <path\n className={s.curve}\n d={pathD}\n fill=\"none\"\n />\n )}\n {interactive && plotAnchors.map((a, i) => {\n const pinned = isPinnedEndpointAt(i, points.length, endpoints);\n const locked = points[i]?.locked === true;\n if ((locked || pinned) && cfg.hideNonInteractive) return null;\n const active = activeIndex === i;\n const isEndpoint = curveVisible && (i === 0 || i === points.length - 1);\n const focus = !locked && !(endpoints === 'pinned-both' && pinned)\n ? { tabIndex: 0 }\n : {};\n const a11y = {\n ...focus,\n role: 'button',\n 'aria-label': `${cfg.label ?? 'Point'} ${i + 1} at ${formatCoord(points[i].x)}, ${formatCoord(points[i].y)}`,\n };\n if (cfg.renderAnchor) {\n const node = cfg.renderAnchor({\n point: points[i], index: i,\n cx: a.x, cy: a.y,\n isActive: active, isLocked: locked,\n isPinnedEndpoint: pinned, isEndpoint,\n });\n if (node !== null && node !== undefined) {\n return <g key={i} data-anchor-index={i} {...a11y}>{node}</g>;\n }\n }\n const anchorCls = [\n s.anchor,\n isEndpoint && s.endpoint,\n (pinned || locked) && s.pinned,\n locked && s.locked,\n active && s.active,\n ].filter(Boolean).join(' ');\n const renderAsDiamond = isEndpoint || locked;\n if (renderAsDiamond) {\n const half = locked ? LOCKED_HALF : ENDPOINT_HALF;\n return (\n <rect\n key={i}\n className={anchorCls}\n x={a.x - half}\n y={a.y - half}\n width={half * 2}\n height={half * 2}\n transform={`rotate(45 ${a.x} ${a.y})`}\n data-anchor-index={i}\n {...a11y}\n />\n );\n }\n return (\n <circle\n key={i}\n className={anchorCls}\n cx={a.x}\n cy={a.y}\n r={4}\n data-anchor-index={i}\n {...a11y}\n />\n );\n })}\n </>\n );\n }\n\n // ── hit test ────────────────────────────────────────────────────────\n function hitTest(state: FunctionLayerState, plot: PlotPoint, ctx: LayerCtx) {\n if (!interactive) return null;\n const plotAnchors = projectAnchors(state.points, ctx);\n const a = hitTestAnchor(plotAnchors, plot, ANCHOR_SNAP_PX);\n if (a) return { kind: 'anchor' as const, payload: { index: a.index } };\n if (addPointMode === 'click-curve' && curveVisible) {\n const segs = segmentSamples(state.points, interpolation, ctx);\n const c = hitTestCurve(segs, plot, CURVE_HIT_PX);\n if (c) return { kind: 'curve' as const, payload: { segIdx: c.segIdx, t: c.t } };\n }\n return null;\n }\n\n // ── move constraint, shared by drag and keyboard ────────────────────\n function moveAnchor(state: FunctionLayerState, index: number, model: ModelPoint, ctx: LayerCtx): FunctionLayerState {\n const points = state.points;\n if (index < 0 || index >= points.length) return state;\n const mr = ctx.modelRange;\n const xMin = cfg.xClamp ? cfg.xClamp[0] : mr.xMin;\n const xMax = cfg.xClamp ? cfg.xClamp[1] : mr.xMax;\n let nx = model.x;\n let ny = model.y;\n const isEndpoint = index === 0 || index === points.length - 1;\n\n if (endpoints === 'pinned-both' && isEndpoint) {\n nx = points[index].x;\n ny = points[index].y;\n } else if (endpoints === 'pinned-x' && isEndpoint) {\n nx = index === 0 ? xMin : xMax;\n } else if (constrain === 'function' || domain === '1d') {\n const epsilon = constrain === 'function'\n ? (xMax - xMin) / 1000\n : 0;\n const left = index > 0 ? points[index - 1].x + epsilon : xMin;\n const right = index < points.length - 1 ? points[index + 1].x - epsilon : xMax;\n nx = Math.max(left, Math.min(right, nx));\n }\n\n // Always clamp x to the layer's own range (so free-mode\n // interior anchors of a sub-range layer can't escape it).\n // Normalize bounds for inverted ranges.\n {\n const lo = Math.min(xMin, xMax);\n const hi = Math.max(xMin, xMax);\n nx = Math.max(lo, Math.min(hi, nx));\n }\n const clamped = clampToModelRange({ x: nx, y: ny }, ctx);\n const next = points.slice();\n next[index] = { ...points[index], x: clamped.x, y: clamped.y };\n return { ...state, points: next, activeIndex: index };\n }\n\n // ── drag gesture ────────────────────────────────────────────────────\n function makeDragGesture(index: number): LayerGesture<FunctionLayerState> {\n return {\n onMove(state, model, _e, ctx) { return moveAnchor(state, index, model, ctx); },\n onCommit(state) { return { ...state, activeIndex: null }; },\n onCancel(state) { return { ...state, activeIndex: null }; },\n };\n }\n\n // ── pointerdown on a positive hit ───────────────────────────────────\n function onPointerDown(\n state: FunctionLayerState,\n hit: { kind: string; payload?: unknown },\n e: PointerEvent,\n ctx: LayerCtx,\n extra: EmptyDownArgs<FunctionLayerState>,\n ): LayerGesture<FunctionLayerState> | void {\n if (hit.kind === 'anchor') {\n const { index } = hit.payload as { index: number };\n dlog('function-layer', 'anchor-down', { id, index, shift: ctx.modifiers.shift, button: e.button });\n if (state.points[index]?.locked) return;\n if (ctx.modifiers.shift) {\n if (isPinnedEndpointAt(index, state.points.length, endpoints)) return;\n if (cfg.minPoints !== undefined && state.points.length <= cfg.minPoints) return;\n extra.commit({\n ...state,\n points: state.points.filter((_, i) => i !== index),\n activeIndex: null,\n });\n return;\n }\n if (e.button === 2) return;\n extra.commit({ ...state, activeIndex: index });\n return makeDragGesture(index);\n }\n if (hit.kind === 'curve') {\n const { segIdx } = hit.payload as { segIdx: number; t: number };\n if (cfg.maxPoints !== undefined && state.points.length >= cfg.maxPoints) return;\n const insertIndex = segIdx + 1;\n const modelPt = clampToModelRange(extra.model, ctx);\n\n // function/1d: refuse insert that would be immediately clamped\n // against a neighbor (mouse jitter would otherwise drop a phantom\n // point directly above an existing anchor). Snap to dragging the\n // neighbor instead.\n if (constrain === 'function' || domain === '1d') {\n const epsilon = constrain === 'function'\n ? (ctx.modelRange.xMax - ctx.modelRange.xMin) / 1000\n : 0;\n const left = insertIndex > 0 ? state.points[insertIndex - 1] : null;\n const right = insertIndex < state.points.length ? state.points[insertIndex] : null;\n if (left && Math.abs(modelPt.x - left.x) < epsilon * 2) {\n extra.commit({ ...state, activeIndex: insertIndex - 1 });\n return makeDragGesture(insertIndex - 1);\n }\n if (right && Math.abs(modelPt.x - right.x) < epsilon * 2) {\n extra.commit({ ...state, activeIndex: insertIndex });\n return makeDragGesture(insertIndex);\n }\n }\n\n const nextPoints = [...state.points.slice(0, insertIndex), modelPt, ...state.points.slice(insertIndex)];\n extra.commit({ ...state, points: nextPoints, activeIndex: insertIndex });\n return makeDragGesture(insertIndex);\n }\n }\n\n // ── empty-space click ───────────────────────────────────────────────\n function onEmptyPointerDown(\n state: FunctionLayerState,\n model: ModelPoint,\n _e: PointerEvent,\n ctx: LayerCtx,\n extra: EmptyDownArgs<FunctionLayerState>,\n ): LayerGesture<FunctionLayerState> | void {\n if (!interactive) return;\n if (addPointMode !== 'click-empty') return;\n if (cfg.maxPoints !== undefined && state.points.length >= cfg.maxPoints) return;\n\n const clamped = clampToModelRange(model, ctx);\n let insertIndex = state.points.length;\n if (domain === '1d') {\n for (let i = 0; i < state.points.length; i++) {\n if (state.points[i].x > clamped.x) { insertIndex = i; break; }\n }\n }\n const nextPoints = [...state.points.slice(0, insertIndex), clamped, ...state.points.slice(insertIndex)];\n extra.commit({ ...state, points: nextPoints, activeIndex: null });\n return;\n }\n\n // ── keyboard ────────────────────────────────────────────────────────\n function onKeyDown(\n state: FunctionLayerState,\n e: KeyboardEvent,\n ctx: LayerCtx,\n extra: KeyDownArgs<FunctionLayerState>,\n ): void {\n if (!interactive) return;\n const target = e.target as Element | null;\n if (target?.closest?.('[data-layer-id]')?.getAttribute('data-layer-id') !== id) return;\n const el = target.closest('[data-anchor-index]');\n if (!el) return;\n const dx = e.key === 'ArrowRight' ? 1 : e.key === 'ArrowLeft' ? -1 : 0;\n const dy = e.key === 'ArrowUp' ? 1 : e.key === 'ArrowDown' ? -1 : 0;\n if (dx === 0 && dy === 0) return;\n e.preventDefault();\n const index = Number(el.getAttribute('data-anchor-index'));\n const p = state.points[index];\n if (!p || p.locked) return;\n const m = ctx.modelRange;\n const mult = e.shiftKey ? SHIFT_MULTIPLIER : 1;\n const xSpan = cfg.xClamp ? cfg.xClamp[1] - cfg.xClamp[0] : m.xMax - m.xMin;\n const next = moveAnchor(state, index, {\n x: p.x + dx * Math.abs(xSpan) * KEY_STEP_FRACTION * mult,\n y: p.y + dy * Math.abs(m.yMax - m.yMin) * KEY_STEP_FRACTION * mult,\n }, ctx);\n const moved = next.points[index];\n if (moved.x === p.x && moved.y === p.y) return;\n extra.commit({ ...next, activeIndex: null });\n }\n\n return {\n id,\n render,\n hitTest,\n onPointerDown,\n onEmptyPointerDown,\n onKeyDown,\n };\n}\n\n/** Convenience: build a function-layer state from a points array. */\nexport function functionLayerState(points: readonly ControlPoint[]): FunctionLayerState {\n return { points, activeIndex: null };\n}\n","/**\n * Back-compat wrapper around `LayeredCurveEditor` that preserves the\n * original single-curve API. New consumers wanting multi-layer\n * composition should reach for `LayeredCurveEditor` + `createFunctionLayer`\n * directly.\n */\nimport {\n useCallback, useEffect, useMemo, useRef, useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from 'react';\nimport {\n type GridSettings,\n type AxesSettings,\n type TickSettings,\n} from '../Plot2D';\nimport type { InterpolationMode } from './interpolation';\nimport {\n createFunctionLayer,\n type ControlPoint,\n type CurveDomain,\n type EndpointMode,\n type AddPointMode,\n type CurveSettings,\n type FillSettings,\n type AnchorRenderProps,\n type FunctionLayerState,\n} from './createFunctionLayer';\nimport { LayeredCurveEditor } from './LayeredCurveEditor';\n\nexport type { GridSettings, AxesSettings, TickSettings };\nexport type {\n ControlPoint, CurveDomain, EndpointMode, AddPointMode,\n CurveSettings, FillSettings, AnchorRenderProps,\n};\n\n/**\n * Props for {@link CurveEditor}. `onInput` fires throughout a gesture and\n * `onChange` once at its end, with the pre-gesture points as `prev`.\n */\nexport interface CurveEditorProps {\n value: readonly ControlPoint[];\n onInput: (next: ControlPoint[]) => void;\n onChange?: (next: ControlPoint[], prev: readonly ControlPoint[]) => void;\n domain?: CurveDomain;\n interpolation?: InterpolationMode;\n endpoints?: EndpointMode;\n xRange?: readonly [number, number];\n yRange?: readonly [number, number];\n width: number;\n height: number;\n grid?: GridSettings | false | null;\n axes?: AxesSettings | false | null;\n xTicks?: TickSettings | false | null;\n yTicks?: TickSettings | false | null;\n curve?: CurveSettings | false | null;\n fill?: FillSettings | false | null;\n hideNonInteractive?: boolean;\n constrain?: 'none' | 'function';\n history?: boolean;\n minPoints?: number;\n maxPoints?: number;\n addPointMode?: AddPointMode;\n renderAnchor?: (info: AnchorRenderProps) => ReactNode;\n /** Extra SVG content rendered behind the curve and anchors. */\n decorations?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Editable curve through a list of control points: drag anchors, click to\n * insert, right-click to delete, with optional built-in undo.\n *\n * This is the single-curve API, implemented as one `createFunctionLayer` on\n * a `LayeredCurveEditor`. Reach for those directly to stack several curves\n * on one plot.\n */\nexport function CurveEditor(props: CurveEditorProps) {\n const {\n value, onInput, onChange,\n domain, endpoints, interpolation, constrain, addPointMode,\n minPoints, maxPoints, curve, fill, hideNonInteractive, renderAnchor,\n width, height, xRange, yRange, grid, axes, xTicks, yTicks, history,\n className, style, decorations,\n } = props;\n\n // Layer is config-only; rebuild only when *config* changes.\n const layer = useMemo(() => createFunctionLayer({\n id: 'function',\n domain, endpoints, interpolation, constrain, addPointMode,\n minPoints, maxPoints, curve, fill, hideNonInteractive, renderAnchor,\n }), [\n domain, endpoints, interpolation, constrain, addPointMode,\n minPoints, maxPoints, curve, fill, hideNonInteractive, renderAnchor,\n ]);\n\n // Hybrid controlled-state: the wrapper holds the full FunctionLayerState\n // locally so that consumers using the original CurveEditor API don't\n // have to wire their `value` prop back through on every drag tick to\n // keep the in-flight gesture advancing. We adopt the consumer's\n // `value` prop when it changes externally (and no gesture is active).\n const [layerState, setLayerState] = useState<FunctionLayerState>(\n () => ({ points: value, activeIndex: null }),\n );\n // Ref mirror so the layerChange callback can compare against the\n // freshest state without re-binding on every render.\n const layerStateRef = useRef(layerState);\n layerStateRef.current = layerState;\n\n // Sync from controlled `value` when the consumer updates it externally\n // and we're idle. Skip the update during a gesture so drag-in-flight\n // points aren't clobbered by a stale `value`.\n useEffect(() => {\n if (layerStateRef.current.activeIndex !== null) return;\n if (layerStateRef.current.points === value) return;\n setLayerState({ points: value, activeIndex: null });\n }, [value]);\n\n const handleLayerChange = useCallback((_id: string, nextUnknown: unknown) => {\n const next = nextUnknown as FunctionLayerState;\n const prevPoints = layerStateRef.current.points;\n setLayerState(next);\n if (next.points !== prevPoints) {\n onInput(next.points as ControlPoint[]);\n }\n }, [onInput]);\n\n const handleLayerCommit = useCallback((_id: string, nextUnknown: unknown, prevUnknown: unknown) => {\n if (!onChange) return;\n const next = nextUnknown as FunctionLayerState;\n const prev = prevUnknown as FunctionLayerState;\n if (next.points !== prev.points) {\n onChange?.(next.points as ControlPoint[], prev.points);\n }\n }, [onChange]);\n\n // Right-click on an anchor → delete (preserves original CurveEditor\n // behavior). LayeredCurveEditor doesn't model contextmenu as a\n // gesture; we intercept at the wrapper level by walking the DOM\n // target for `data-anchor-index`.\n const onContextMenu = useCallback((e: ReactMouseEvent<HTMLDivElement>) => {\n const target = e.target as Element | null;\n const node = target?.closest?.('[data-anchor-index]') as Element | null;\n if (!node) return;\n e.preventDefault();\n e.stopPropagation();\n const idxAttr = node.getAttribute('data-anchor-index');\n if (idxAttr === null) return;\n const idx = Number(idxAttr);\n const points = layerStateRef.current.points;\n if (!Number.isInteger(idx) || idx < 0 || idx >= points.length) return;\n if (points[idx]?.locked) return;\n if (endpoints !== undefined && endpoints !== 'free' && (idx === 0 || idx === points.length - 1)) return;\n if (minPoints !== undefined && points.length <= minPoints) return;\n const next = points.filter((_, i) => i !== idx);\n setLayerState({ points: next, activeIndex: null });\n onInput(next as ControlPoint[]);\n onChange?.(next as ControlPoint[], points);\n }, [endpoints, minPoints, onInput, onChange]);\n\n const layers = useMemo(() => [{ layer, state: layerState }], [layer, layerState]);\n\n return (\n <div\n onContextMenu={onContextMenu}\n style={{ display: 'contents' }}\n >\n <LayeredCurveEditor\n layers={layers}\n onLayerChange={handleLayerChange}\n onLayerCommit={handleLayerCommit}\n width={width}\n height={height}\n xRange={xRange}\n yRange={yRange}\n grid={grid}\n axes={axes}\n xTicks={xTicks}\n yTicks={yTicks}\n history={history}\n className={className}\n style={style}\n >\n {decorations}\n </LayeredCurveEditor>\n </div>\n );\n}\n","import type { Op } from '@weasel-js/core';\nimport type { ControlPoint } from './CurveEditor';\n\n/**\n * The adapter contract for {@link createSetCurveOp}. Consumers wire\n * this to whatever state container holds the curve's value — typically\n * a small callback that calls a React state setter or dispatches a\n * Redux/Zustand action.\n */\nexport interface SetCurveAdapter {\n setValue(id: string, next: readonly ControlPoint[]): void;\n}\n\n/**\n * Arguments for {@link createSetCurveOp}. `coalesceKey` merges consecutive\n * edits sharing it into one history entry.\n */\nexport interface CreateSetCurveOpArgs {\n /** Stable id the consumer uses for this curve. Used so a single\n * adapter can handle multiple curves; the op's apply routes by id. */\n id: string;\n from: readonly ControlPoint[];\n to: readonly ControlPoint[];\n label?: string;\n coalesceKey?: string;\n}\n\n/**\n * Op factory for editing a CurveEditor's value through weasel-history.\n *\n * history.applyOps(\n * [createSetCurveOp({ id: 'easing', from, to, label: 'Edit easing' })],\n * 'Edit easing',\n * );\n *\n * The op's `apply(adapter)` calls `adapter.setValue(id, to)`. `invert()`\n * returns a mirror op with `from`/`to` swapped. When `from` and `to`\n * are structurally equal, `apply` returns `false` so history can skip\n * the entry — same convention as `createSetPathOp`.\n */\nexport function createSetCurveOp(args: CreateSetCurveOpArgs): Op {\n const { id, from, to, label, coalesceKey } = args;\n return {\n name: 'setCurve',\n args: { id, from, to, label, coalesceKey },\n label,\n coalesceKey,\n apply(adapter) {\n if (controlPointsEqual(from, to)) return false;\n (adapter as SetCurveAdapter).setValue(id, to);\n return undefined;\n },\n invert() {\n return createSetCurveOp({ id, from: to, to: from, label, coalesceKey });\n },\n };\n}\n\nfunction controlPointsEqual(\n a: readonly ControlPoint[],\n b: readonly ControlPoint[],\n): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i].x !== b[i].x || a[i].y !== b[i].y) return false;\n }\n return true;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DataGrid-CZPrB_3a.js","names":[],"sources":["../../src/components/DataGrid/DataGrid.module.css","../../src/components/DataGrid/DataGrid.tsx"],"sourcesContent":[".grid {\n position: relative;\n width: 100%;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--wzl-font-size-sm);\n}\n\n.table th,\n.table td {\n text-align: left;\n padding: 3px var(--wzl-space-3);\n vertical-align: middle;\n}\n.table tbody tr {\n border-bottom: 1px solid var(--wzl-line-subtle);\n}\n\n.table th {\n font-weight: var(--wzl-font-weight-bold);\n color: var(--wzl-fg-muted);\n position: sticky;\n top: 0;\n background: var(--wzl-surface, #2a2018);\n z-index: 1;\n border-bottom: 1px solid var(--wzl-border);\n}\n\n.sortButton {\n all: unset;\n cursor: pointer;\n user-select: none;\n display: block;\n width: 100%;\n}\n.sortButton:hover { color: var(--wzl-fg, #e6e7e9); }\n.sortButton:focus-visible {\n outline: 2px solid var(--wzl-focus-ring, var(--wzl-accent, #7fb069));\n outline-offset: -2px;\n}\n.sortActive { color: var(--wzl-fg, #e6e7e9); }\n\n.empty {\n color: var(--wzl-fg-muted);\n font-style: italic;\n padding: var(--wzl-space-4) 0;\n text-align: center;\n}\n\n/* Drag-handle column. */\n.handleCol { width: 14px; }\n.handleCell {\n width: 14px;\n cursor: grab;\n color: var(--wzl-fg-muted);\n user-select: none;\n text-align: center;\n}\n.handleCell:active { cursor: grabbing; }\n\n.dragging { opacity: 0.4; }\n\n.dropBefore > td { box-shadow: inset 0 2px 0 0 var(--wzl-accent, #7fb069); }\n.dropAfter > td { box-shadow: inset 0 -2px 0 0 var(--wzl-accent, #7fb069); }\n\n/* Row activation (`onRowClick`). */\n.clickable { cursor: pointer; }\n.clickable:hover > td { background: var(--wzl-surface-hover); }\n.clickable:focus-visible {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: -2px;\n}\n\n/* Disclosure column and the detail row it opens. */\n.detailCol,\n.detailCell {\n width: var(--wzl-control-h-sm);\n padding-inline: 0;\n text-align: center;\n}\n.table .detailCell { padding-block: 0; }\n.detailRow > td {\n padding: var(--wzl-space-2) var(--wzl-space-3) var(--wzl-space-3);\n background: var(--wzl-surface-sunken);\n}\n","/**\n * Lightweight sortable data grid. Use for inspector tables — action\n * registries, route maps, telemetry rows. Intentionally narrow:\n *\n * - Sortable columns (click header to cycle asc → desc → none)\n * - Custom cell render via per-column `render`\n * - Optional drag handles for row reordering (when `onReorder` is set)\n * - Per-row class, row activation, and expandable full-width detail rows\n *\n * Not: virtual scrolling, column resizing, multi-column sort, filtering,\n * inline editing. Reach for a real grid library when you need those.\n */\nimport { Fragment, useId, useMemo, useState } from 'react';\nimport type { KeyboardEvent, MouseEvent, ReactNode } from 'react';\nimport { useReorderDragList } from '../../useReorderDragList';\nimport { Disclosure } from '../Disclosure';\nimport s from './DataGrid.module.css';\n\n/**\n * One column of a {@link DataGrid}. `id` doubles as the default property name\n * read off each row when no `accessor` is given.\n */\nexport interface DataGridColumn<Row> {\n id: string;\n header: ReactNode;\n /** Pull a sortable value from the row. Defaults to `(row as any)[column.id]`. */\n accessor?: (row: Row) => string | number | null | undefined;\n /** Render the cell. Defaults to `String(accessor(row) ?? '')`. */\n render?: (row: Row) => ReactNode;\n /** Default true. Set false to suppress the sort affordance on this column. */\n sortable?: boolean;\n /** Optional CSS class on every <td> in this column. */\n className?: string;\n}\n\n/** Props for {@link DataGrid}. */\nexport interface DataGridProps<Row extends { id: string }> {\n rows: readonly Row[];\n columns: readonly DataGridColumn<Row>[];\n /** Initial sort. Omit for unsorted (rows render in input order). */\n defaultSort?: { columnId: string; direction: 'asc' | 'desc' };\n /** Enable drag handles in a leading column. Receives the reorder spec\n * (the existing `useReorderDragList` semantics — see weasel-ui). */\n onReorder?: (ids: string[], targetIndex: number) => void;\n /** Empty-state row text. Default `'—'`. */\n empty?: ReactNode;\n className?: string;\n /** Extra class on a row's `<tr>`, for row-level state such as a verdict. */\n rowClassName?: (row: Row) => string | undefined;\n /**\n * Activate a row. Makes each row focusable: a click anywhere in it, or\n * Enter/Space while it has focus, calls this. Clicks and keys landing on a\n * control inside a cell (button, link, input, …) are left to that control.\n */\n onRowClick?: (row: Row) => void;\n /**\n * Content for a full-width detail row under `row`, shown while the row is\n * expanded. Setting it adds a leading disclosure column. Return `null` for\n * no detail row.\n */\n renderDetail?: (row: Row) => ReactNode;\n /** Which rows offer the disclosure. Default: every row. */\n rowExpandable?: (row: Row) => boolean;\n /** Expanded row ids, controlled. Pair with `onExpandedChange`. */\n expandedIds?: ReadonlySet<string>;\n /** Initially expanded row ids when uncontrolled. */\n defaultExpandedIds?: Iterable<string>;\n /** Called with the next expanded set when a disclosure toggles. */\n onExpandedChange?: (ids: ReadonlySet<string>) => void;\n}\n\ntype SortState = { columnId: string; direction: 'asc' | 'desc' } | null;\n\nconst INTERACTIVE = 'a[href], button, input, select, textarea, label, summary, [role=\"button\"], [contenteditable=\"true\"]';\n\n/** Did this event start on a control inside the row rather than on the row itself? */\nfunction fromControl(e: MouseEvent | KeyboardEvent): boolean {\n const target = e.target as Element | null;\n const hit = target?.closest?.(INTERACTIVE);\n return !!hit && e.currentTarget.contains(hit);\n}\n\n/**\n * Sortable table for inspector-style data. Rows are keyed by `id`. Clicking a\n * sortable header cycles ascending, descending, unsorted; nullish values sort\n * last regardless of direction. Passing `onReorder` adds a leading drag-handle\n * column — note that the drag indices it reports are into the *sorted* row\n * order, not the input order.\n */\nexport function DataGrid<Row extends { id: string }>(props: DataGridProps<Row>) {\n const {\n rows, columns, defaultSort, onReorder, empty = '—', className,\n rowClassName, onRowClick, renderDetail, rowExpandable, expandedIds, defaultExpandedIds, onExpandedChange,\n } = props;\n const [sort, setSort] = useState<SortState>(defaultSort ?? null);\n const [ownExpanded, setOwnExpanded] = useState<ReadonlySet<string>>(() => new Set(defaultExpandedIds));\n const expanded = expandedIds ?? ownExpanded;\n const detailIdBase = useId();\n\n const toggleExpanded = (id: string) => {\n const next = new Set(expanded);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n if (!expandedIds) setOwnExpanded(next);\n onExpandedChange?.(next);\n };\n\n const sortedRows = useMemo(() => {\n if (!sort) return [...rows];\n const col = columns.find((c) => c.id === sort.columnId);\n if (!col) return [...rows];\n const get = col.accessor ?? ((row: Row) => (row as unknown as Record<string, unknown>)[col.id] as string | number | null | undefined);\n const dir = sort.direction === 'asc' ? 1 : -1;\n return [...rows].sort((a, b) => {\n const av = get(a);\n const bv = get(b);\n if (av == null && bv == null) return 0;\n if (av == null) return 1;\n if (bv == null) return -1;\n if (av < bv) return -1 * dir;\n if (av > bv) return 1 * dir;\n return 0;\n });\n }, [rows, columns, sort]);\n\n const cycleSort = (columnId: string) => {\n setSort((cur) => {\n if (!cur || cur.columnId !== columnId) return { columnId, direction: 'asc' };\n if (cur.direction === 'asc') return { columnId, direction: 'desc' };\n return null;\n });\n };\n\n // Drag handles via useReorderDragList. Adapter: the hook expects\n // `{ id, label }`-shaped items; we map our rows to that shape (label\n // unused — the hook only uses id and locked).\n const drag = useReorderDragList({\n items: sortedRows.map((r) => ({ id: r.id, label: '' })),\n selectedIds: [],\n onReorder: onReorder ?? (() => {}),\n rowSelector: ':not([data-detail-of])',\n });\n const dragEnabled = !!onReorder;\n const detailEnabled = !!renderDetail;\n const colCount = columns.length + (dragEnabled ? 1 : 0) + (detailEnabled ? 1 : 0);\n\n const cls = [s.grid, className].filter(Boolean).join(' ');\n\n return (\n <div\n className={cls}\n >\n <table className={s.table}>\n <thead>\n <tr>\n {dragEnabled && <th className={s.handleCol} aria-label=\"drag\" />}\n {detailEnabled && <th className={s.detailCol} aria-label=\"details\" />}\n {columns.map((col) => {\n const sortable = col.sortable !== false;\n const active = sort?.columnId === col.id;\n const indicator = active ? (sort.direction === 'asc' ? ' ↑' : ' ↓') : '';\n return (\n <th\n key={col.id}\n className={[col.className, active ? s.sortActive : ''].filter(Boolean).join(' ')}\n aria-sort={sortable ? (active ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none') : undefined}\n >\n {sortable ? (\n <button type=\"button\" className={s.sortButton} onClick={() => cycleSort(col.id)}>\n {col.header}{indicator}\n </button>\n ) : (\n <>{col.header}{indicator}</>\n )}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody ref={dragEnabled ? (drag.containerProps.ref as React.RefCallback<HTMLTableSectionElement>) : undefined}>\n {sortedRows.length === 0 && (\n <tr>\n <td colSpan={colCount} className={s.empty}>\n {empty}\n </td>\n </tr>\n )}\n {sortedRows.map((row, i) => {\n const isDragging = drag.state.draggedIds?.includes(row.id) ?? false;\n const target = drag.state.targetIndex;\n const expandable = detailEnabled && (rowExpandable?.(row) ?? true);\n const isExpanded = expandable && expanded.has(row.id);\n const detail = isExpanded ? renderDetail!(row) : null;\n const detailId = `${detailIdBase}-detail-${row.id}`;\n const rowCls = [\n onRowClick && s.clickable,\n isDragging && s.dragging,\n target === i && s.dropBefore,\n target === sortedRows.length && i === sortedRows.length - 1 && s.dropAfter,\n rowClassName?.(row),\n ].filter(Boolean).join(' ');\n return (\n <Fragment key={row.id}>\n <tr\n className={rowCls || undefined}\n data-expanded={isExpanded || undefined}\n tabIndex={onRowClick ? 0 : undefined}\n onClick={onRowClick ? (e) => { if (!fromControl(e)) onRowClick(row); } : undefined}\n onKeyDown={onRowClick ? (e) => {\n if (e.target !== e.currentTarget || (e.key !== 'Enter' && e.key !== ' ')) return;\n e.preventDefault();\n onRowClick(row);\n } : undefined}\n >\n {dragEnabled && (\n <td\n className={s.handleCell}\n onPointerDown={(e) => drag.rowProps(row.id, i).onPointerDown(e)}\n >\n <span aria-hidden=\"true\">⋮⋮</span>\n </td>\n )}\n {detailEnabled && (\n <td className={s.detailCell}>\n {expandable && (\n <Disclosure\n open={isExpanded}\n onToggle={() => toggleExpanded(row.id)}\n label={isExpanded ? 'Hide details' : 'Show details'}\n controls={detail != null ? detailId : undefined}\n />\n )}\n </td>\n )}\n {columns.map((col) => {\n const get = col.accessor ?? ((r: Row) => (r as unknown as Record<string, unknown>)[col.id] as string | number | null | undefined);\n const content = col.render ? col.render(row) : String(get(row) ?? '');\n return (\n <td key={col.id} className={col.className}>\n {content}\n </td>\n );\n })}\n </tr>\n {detail != null && (\n <tr id={detailId} className={s.detailRow} data-detail-of={row.id}>\n <td colSpan={colCount}>{detail}</td>\n </tr>\n )}\n </Fragment>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,43 +0,0 @@
1
- import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
- import { useId as n } from "react";
3
- var r = {
4
- list: "_list_1jpmp_1",
5
- row: "_row_1jpmp_14",
6
- label: "_label_1jpmp_22",
7
- value: "_value_1jpmp_36",
8
- title: "_title_1jpmp_49"
9
- };
10
- //#endregion
11
- //#region src/components/DetailList/DetailList.tsx
12
- function i({ children: i, title: a, layout: o = "inline", className: s }) {
13
- let c = n(), l = /* @__PURE__ */ e("dl", {
14
- className: s && a == null ? `${r.list} ${s}` : r.list,
15
- "data-layout": o,
16
- "aria-labelledby": a == null ? void 0 : c,
17
- children: i
18
- });
19
- return a == null ? l : /* @__PURE__ */ t("section", {
20
- className: s,
21
- children: [/* @__PURE__ */ e("h3", {
22
- id: c,
23
- className: r.title,
24
- children: a
25
- }), l]
26
- });
27
- }
28
- function a({ label: n, children: i, className: a }) {
29
- return /* @__PURE__ */ t("div", {
30
- className: a ? `${r.row} ${a}` : r.row,
31
- children: [/* @__PURE__ */ e("dt", {
32
- className: r.label,
33
- children: n
34
- }), /* @__PURE__ */ e("dd", {
35
- className: r.value,
36
- children: i
37
- })]
38
- });
39
- }
40
- //#endregion
41
- export { a as n, i as t };
42
-
43
- //# sourceMappingURL=DetailList-DHaXX4TG.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DetailList-DHaXX4TG.js","names":[],"sources":["../../src/components/DetailList/DetailList.module.css","../../src/components/DetailList/DetailList.tsx"],"sourcesContent":[".list {\n display: grid;\n grid-template-columns: var(--wzl-params-label-width, auto) minmax(0, 1fr);\n column-gap: var(--wzl-space-6);\n row-gap: var(--wzl-space-1);\n margin: 0;\n font-size: var(--wzl-font-size-md);\n}\n\n.list[data-layout='block'] {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.row {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n /* A label meets the first line of its value, however many lines that runs to. */\n align-items: baseline;\n}\n\n.label {\n display: flex;\n align-items: baseline;\n justify-content: var(--wzl-params-label-align, start);\n gap: var(--wzl-space-2);\n font-family: var(--wzl-font-display);\n font-weight: var(--wzl-font-weight-light);\n font-size: var(--wzl-font-size-sm);\n line-height: var(--wzl-leading-snug);\n color: var(--wzl-fg-muted);\n text-transform: var(--wzl-params-label-case, uppercase);\n letter-spacing: var(--wzl-params-label-tracking, var(--wzl-tracking-wide));\n}\n\n.value {\n margin: 0;\n min-width: 0;\n /* The floor a property row stands on, so the two share a rhythm side by side. */\n min-height: var(--wzl-prop-row-h, var(--wzl-field-h, var(--wzl-control-h)));\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wzl-space-2);\n overflow-wrap: anywhere;\n color: var(--wzl-fg);\n}\n\n.title {\n margin: 0 0 var(--wzl-space-3);\n font-family: var(--wzl-font-display);\n font-weight: var(--wzl-font-weight-light);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n text-transform: var(--wzl-params-label-case, uppercase);\n letter-spacing: var(--wzl-params-label-tracking, var(--wzl-tracking-wide));\n}\n","import { type ReactNode, useId } from 'react';\nimport s from './DetailList.module.css';\n\n/** Whether a row's label sits beside its value or above it. */\nexport type DetailListLayout = 'inline' | 'block';\n\n/** Props for {@link DetailList}. */\nexport interface DetailListProps {\n /** {@link DetailRow}s. */\n children: ReactNode;\n /** Heading drawn above the list, which also names it. */\n title?: ReactNode;\n /**\n * `inline` puts every label in one rail beside the values; `block` stacks\n * each label over its value, for a column too narrow to hold both.\n */\n layout?: DetailListLayout;\n /** Class on the outermost element: the `<dl>`, or the `<section>` holding\n * the heading and the list when there is a `title`. */\n className?: string;\n}\n\n/** Props for {@link DetailRow}. */\nexport interface DetailRowProps {\n label: ReactNode;\n /** The value: text, or any run of elements — code chips, badges, keycaps,\n * links. Several children wrap as a line of items. */\n children: ReactNode;\n className?: string;\n}\n\n/**\n * A read-only list of labelled values — the `<dl>` a property panel would be\n * if its rows held facts instead of controls. Labels take the params label\n * recipe and rail: `--wzl-params-label-width` sets the rail, so a detail list\n * and a property panel beside it line their labels up from one declaration.\n */\nexport function DetailList({ children, title, layout = 'inline', className }: DetailListProps) {\n const titleId = useId();\n const list = (\n <dl\n className={className && title == null ? `${s.list} ${className}` : s.list}\n data-layout={layout}\n aria-labelledby={title != null ? titleId : undefined}\n >\n {children}\n </dl>\n );\n if (title == null) return list;\n return (\n <section className={className}>\n <h3 id={titleId} className={s.title}>{title}</h3>\n {list}\n </section>\n );\n}\n\n/** One label and its value in a {@link DetailList}. */\nexport function DetailRow({ label, children, className }: DetailRowProps) {\n return (\n <div className={className ? `${s.row} ${className}` : s.row}>\n <dt className={s.label}>{label}</dt>\n <dd className={s.value}>{children}</dd>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;ACqCA,SAAgB,EAAW,EAAE,aAAU,UAAO,YAAS,UAAU,gBAA8B;CAC7F,IAAM,IAAU,GAAO,EACjB,IACJ,kBAAC,MAAD;EACE,WAAW,KAAa,KAAS,OAAO,GAAG,EAAE,KAAK,GAAG,MAAc,EAAE;EACrE,eAAa;EACb,mBAAiB,KAAS,OAAiB,KAAA,IAAV;EAEhC;EACE,CAAA;AAGP,QADI,KAAS,OAAa,IAExB,kBAAC,WAAD;EAAoB;YAApB,CACE,kBAAC,MAAD;GAAI,IAAI;GAAS,WAAW,EAAE;aAAQ;GAAW,CAAA,EAChD,EACO;;;AAKd,SAAgB,EAAU,EAAE,UAAO,aAAU,gBAA6B;AACxE,QACE,kBAAC,OAAD;EAAK,WAAW,IAAY,GAAG,EAAE,IAAI,GAAG,MAAc,EAAE;YAAxD,CACE,kBAAC,MAAD;GAAI,WAAW,EAAE;aAAQ;GAAW,CAAA,EACpC,kBAAC,MAAD;GAAI,WAAW,EAAE;GAAQ;GAAc,CAAA,CACnC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DetentSlider-BYyaZha6.js","names":[],"sources":["../../src/components/DetentSlider/DetentSlider.module.css","../../src/components/DetentSlider/DetentSlider.tsx"],"sourcesContent":[".root {\n position: relative;\n /* Read by Slider's track and stop marks. Detents run the full height of the\n * track so they read as notches rather than as tally marks beside it. */\n --rp-tick-inset: 0;\n --rp-tick-width: 1px;\n --rp-tick-color: var(--wzl-border-strong);\n --rp-track-cursor: pointer;\n font-family: var(--wzl-font-ui);\n}\n\n.slider {\n width: 100%;\n}\n\n","import { useEffect, useRef, type ReactElement, type ReactNode } from 'react';\nimport { Slider, type SliderStop, type Thumb } from '../Slider/Slider';\nimport s from './DetentSlider.module.css';\n\n/** What a detent can carry. Narrowed so identity comparison and React keys\n * both work without a keying callback. */\nexport type DetentValue = string | number;\n\n/** One detent on a {@link DetentSlider}. */\nexport type DetentItem<V extends DetentValue = number> = {\n value: V;\n /** Drawn under the detent. Defaults to `formatLabel(value)`, then `value`. */\n label?: ReactNode;\n /** Spoken form, when the drawn label is not the right thing to say. */\n ariaLabel?: string;\n};\n\n/**\n * Props for {@link DetentSlider}.\n *\n * `items` takes bare values or `DetentItem`s interchangeably — a bare value is\n * a detent with no label of its own.\n *\n * `onChange` fires on every detent the control passes through, including\n * mid-drag: each one is a complete, legal choice, so there is no in-flight\n * value to withhold. `onCommit` fires once the gesture that changed things\n * ends, and is the one to write to history.\n */\nexport type DetentSliderProps<V extends DetentValue = number> = {\n items: readonly (V | DetentItem<V>)[];\n value: V;\n onChange: (value: V, index: number) => void;\n onCommit?: (value: V, index: number) => void;\n formatLabel?: (value: V, index: number) => ReactNode;\n labels?: 'all' | 'ends' | 'none';\n trackHeight?: number;\n ariaLabel?: string;\n className?: string;\n};\n\nfunction normalize<V extends DetentValue>(items: readonly (V | DetentItem<V>)[]): DetentItem<V>[] {\n return items.map(it => (typeof it === 'object' && it !== null ? it : ({ value: it } as DetentItem<V>)));\n}\n\n/**\n * The detent `value` selects. An exact match wins; a number that matches none\n * lands on the nearest one, so a value arriving from a numeric field or an\n * older save renders where it belongs rather than silently reading as the\n * first detent.\n */\nfunction resolveIndex<V extends DetentValue>(items: readonly DetentItem<V>[], value: V): number {\n const exact = items.findIndex(it => it.value === value);\n if (exact !== -1) return exact;\n if (typeof value !== 'number') return 0;\n let best = 0;\n let bestGap = Infinity;\n for (let i = 0; i < items.length; i++) {\n const v = items[i].value;\n if (typeof v !== 'number') continue;\n const gap = Math.abs(v - value);\n if (gap < bestGap) {\n bestGap = gap;\n best = i;\n }\n }\n return best;\n}\n\nfunction plainText(label: ReactNode, fallback: DetentValue): string {\n return typeof label === 'string' || typeof label === 'number' ? String(label) : String(fallback);\n}\n\n/**\n * Slider over a fixed list of values: one detent per value, evenly spaced, the\n * thumb resting on one of them.\n *\n * This is the shape to reach for when an option has a small set of allowed\n * values along a line — playback rate, zoom step, quality — in place of a\n * dropdown, which hides the ordering and the extent of the range behind a\n * click. The values need only be ordered, not numeric.\n *\n * It is a strict {@link Slider} over the *index* of `items`, which keeps the\n * detents evenly spaced however the values are distributed. Since the index is\n * meaningless to a screen reader, the value is published as `aria-valuetext`.\n * For numbers that may also rest between the detents, use `Slider` directly\n * with `spacing=\"even\"` and magnetic stops.\n */\nexport function DetentSlider<V extends DetentValue = number>(props: DetentSliderProps<V>): ReactElement {\n const { value, onChange, onCommit, formatLabel, ariaLabel, className } = props;\n const items = normalize(props.items);\n const index = resolveIndex(items, value);\n const lastIndex = Math.max(0, items.length - 1);\n\n const labelOf = (item: DetentItem<V>, i: number): ReactNode =>\n item.label ?? formatLabel?.(item.value, i) ?? String(item.value);\n\n // Deduped separately: `live` suppresses the repeat reports a drag produces\n // while the pointer crosses one detent, `changed` keeps a press that chose\n // nothing from landing a no-op entry in the consumer's history.\n const liveRef = useRef(index);\n const changedRef = useRef(false);\n useEffect(() => {\n liveRef.current = index;\n }, [index]);\n\n const handleInput = (next: Thumb[]) => {\n const i = next[0].value;\n if (i === liveRef.current) return;\n liveRef.current = i;\n changedRef.current = true;\n onChange(items[i].value, i);\n };\n\n const handleCommit = (next: Thumb[]) => {\n if (!changedRef.current) return;\n changedRef.current = false;\n const i = next[0].value;\n onCommit?.(items[i].value, i);\n };\n\n const current = items[index];\n if (!current) return <div className={className ? `${s.root} ${className}` : s.root} />;\n\n const thumbs: Thumb[] = [\n { value: index, valueText: current.ariaLabel ?? plainText(labelOf(current, index), current.value) },\n ];\n\n const stops: SliderStop[] = items.map((item, i) => ({ value: i, label: labelOf(item, i) }));\n\n return (\n <div className={className ? `${s.root} ${className}` : s.root}>\n <Slider\n className={s.slider}\n min={0}\n max={lastIndex}\n stops={stops}\n snap=\"strict\"\n stopLabels={props.labels ?? 'all'}\n trackClick=\"move-nearest\"\n trackHeight={props.trackHeight ?? 8}\n ariaLabel={ariaLabel}\n thumbs={thumbs}\n onInput={handleInput}\n onChange={handleCommit}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;ACwCA,SAAS,EAAiC,GAAwD;AAChG,QAAO,EAAM,KAAI,MAAO,OAAO,KAAO,YAAY,IAAc,IAAM,EAAE,OAAO,GAAI,CAAoB;;AASzG,SAAS,EAAoC,GAAiC,GAAkB;CAC9F,IAAM,IAAQ,EAAM,WAAU,MAAM,EAAG,UAAU,EAAM;AACvD,KAAI,MAAU,GAAI,QAAO;AACzB,KAAI,OAAO,KAAU,SAAU,QAAO;CACtC,IAAI,IAAO,GACP,IAAU;AACd,MAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAAK;EACrC,IAAM,IAAI,EAAM,GAAG;AACnB,MAAI,OAAO,KAAM,SAAU;EAC3B,IAAM,IAAM,KAAK,IAAI,IAAI,EAAM;AAC/B,EAAI,IAAM,MACR,IAAU,GACV,IAAO;;AAGX,QAAO;;AAGT,SAAS,EAAU,GAAkB,GAA+B;AAClE,QAAgE,OAAzD,OAAO,KAAU,YAAY,OAAO,KAAU,WAAkB,IAAgB,EAAS;;AAkBlG,SAAgB,EAA6C,GAA2C;CACtG,IAAM,EAAE,UAAO,aAAU,aAAU,gBAAa,cAAW,iBAAc,GACnE,IAAQ,EAAU,EAAM,MAAM,EAC9B,IAAQ,EAAa,GAAO,EAAM,EAClC,IAAY,KAAK,IAAI,GAAG,EAAM,SAAS,EAAE,EAEzC,KAAW,GAAqB,MACpC,EAAK,SAAS,IAAc,EAAK,OAAO,EAAE,IAAI,OAAO,EAAK,MAAM,EAK5D,IAAU,EAAO,EAAM,EACvB,IAAa,EAAO,GAAM;AAChC,SAAgB;AACd,IAAQ,UAAU;IACjB,CAAC,EAAM,CAAC;CAEX,IAAM,KAAe,MAAkB;EACrC,IAAM,IAAI,EAAK,GAAG;AACd,QAAM,EAAQ,YAClB,EAAQ,UAAU,GAClB,EAAW,UAAU,IACrB,EAAS,EAAM,GAAG,OAAO,EAAE;IAGvB,KAAgB,MAAkB;AACtC,MAAI,CAAC,EAAW,QAAS;AACzB,IAAW,UAAU;EACrB,IAAM,IAAI,EAAK,GAAG;AAClB,MAAW,EAAM,GAAG,OAAO,EAAE;IAGzB,IAAU,EAAM;AACtB,KAAI,CAAC,EAAS,QAAO,kBAAC,OAAD,EAAK,WAAW,IAAY,GAAG,EAAE,KAAK,GAAG,MAAc,EAAE,MAAQ,CAAA;CAEtF,IAAM,IAAkB,CACtB;EAAE,OAAO;EAAO,WAAW,EAAQ,aAAa,EAAU,EAAQ,GAAS,EAAM,EAAE,EAAQ,MAAM;EAAE,CACpG,EAEK,IAAsB,EAAM,KAAK,GAAM,OAAO;EAAE,OAAO;EAAG,OAAO,EAAQ,GAAM,EAAE;EAAE,EAAE;AAE3F,QACE,kBAAC,OAAD;EAAK,WAAW,IAAY,GAAG,EAAE,KAAK,GAAG,MAAc,EAAE;YACvD,kBAAC,GAAD;GACE,WAAW,EAAE;GACb,KAAK;GACL,KAAK;GACE;GACP,MAAK;GACL,YAAY,EAAM,UAAU;GAC5B,YAAW;GACX,aAAa,EAAM,eAAe;GACvB;GACH;GACR,SAAS;GACT,UAAU;GACV,CAAA;EACE,CAAA"}
@@ -1,66 +0,0 @@
1
- import { r as e } from "./portalHost-CjpCnuGU.js";
2
- import { t } from "./stance-CarrcbbP.js";
3
- import { Fragment as n, jsx as r, jsxs as i } from "react/jsx-runtime";
4
- import { Dialog as a, Heading as o, Modal as s, ModalOverlay as c } from "react-aria-components";
5
- var l = {
6
- overlay: "_overlay_122x3_1",
7
- modal: "_modal_122x3_29",
8
- dialog: "_dialog_122x3_223",
9
- header: "_header_122x3_231",
10
- title: "_title_122x3_240",
11
- close: "_close_122x3_251",
12
- body: "_body_122x3_273",
13
- footer: "_footer_122x3_288"
14
- };
15
- //#endregion
16
- //#region src/components/Dialog/Dialog.tsx
17
- function u(u) {
18
- let { title: d, showCloseButton: f, children: p, footer: m, role: h = "dialog", className: g, bodyClassName: _, isOpen: v, onOpenChange: y, portalContainer: b, stance: x, tone: S, ...C } = u, w = t({
19
- stance: x,
20
- tone: S
21
- }), T = f ?? !!y, { anchor: E, portalProps: D } = e(b);
22
- return /* @__PURE__ */ i(n, { children: [E, /* @__PURE__ */ r(c, {
23
- ...C,
24
- isOpen: v,
25
- onOpenChange: y,
26
- className: l.overlay,
27
- "data-weasel-overlay": "",
28
- ...D,
29
- children: /* @__PURE__ */ r(s, {
30
- className: [l.modal, g].filter(Boolean).join(" "),
31
- ...w,
32
- children: /* @__PURE__ */ r(a, {
33
- role: h,
34
- className: l.dialog,
35
- children: ({ close: e }) => /* @__PURE__ */ i(n, { children: [
36
- (d !== void 0 || T) && /* @__PURE__ */ i("header", {
37
- className: l.header,
38
- children: [d !== void 0 && /* @__PURE__ */ r(o, {
39
- slot: "title",
40
- className: l.title,
41
- children: d
42
- }), T && /* @__PURE__ */ r("button", {
43
- type: "button",
44
- className: l.close,
45
- onClick: e,
46
- "aria-label": "Close dialog",
47
- children: "×"
48
- })]
49
- }),
50
- /* @__PURE__ */ r("div", {
51
- className: [l.body, _].filter(Boolean).join(" "),
52
- children: p
53
- }),
54
- m !== void 0 && /* @__PURE__ */ r("footer", {
55
- className: l.footer,
56
- children: m
57
- })
58
- ] })
59
- })
60
- })
61
- })] });
62
- }
63
- //#endregion
64
- export { u as t };
65
-
66
- //# sourceMappingURL=Dialog-GIvjoDQj.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Dialog-GIvjoDQj.js","names":[],"sources":["../../src/components/Dialog/Dialog.module.css","../../src/components/Dialog/Dialog.tsx"],"sourcesContent":[".overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n opacity: 0;\n transition: opacity var(--wzl-motion-fast);\n}\n\n.overlay[data-entering] {\n opacity: 0;\n}\n\n.overlay[data-entering][data-rac] {\n opacity: 1;\n}\n\n.overlay[data-exiting] {\n opacity: 0;\n}\n\n.overlay[data-rac]:not([data-entering]):not([data-exiting]) {\n opacity: 1;\n}\n\n.modal {\n background: var(--_s-fill);\n border: var(--_s-border-width) var(--_s-border-style) var(--_s-border-color);\n border-radius: var(--_s-radius);\n box-shadow: 0 24px 64px rgba(0, 0, 0, 0.45);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n max-width: min(900px, calc(100vw - 32px));\n max-height: calc(100vh - 32px);\n display: flex;\n flex-direction: column;\n outline: none;\n}\n\n/* BEGIN GENERATED stance rules: dialog — `npm run gen:stances`, do not edit. */\n\n.modal {\n --wzl-tone: initial;\n}\n\n.modal {\n --_s-surface: var(--wzl-surface);\n --_s-border-color: var(--wzl-border);\n --_s-border-style: solid;\n --_s-border-width: 1px;\n --_s-radius: var(--wzl-radius-md);\n --_s-tone-mix: var(--wzl-panel-tone-mix);\n --_s-tone: var(--wzl-tone, var(--_s-surface));\n --_s-accent: var(--wzl-tone);\n --_s-title-font: var(--wzl-font-ui);\n --_s-title-weight: var(--wzl-font-weight-bold);\n --_s-title-size: var(--wzl-font-size);\n --_s-title-case: none;\n --_s-title-tracking: normal;\n --_s-title-color: var(--wzl-fg);\n}\n\n.modal[data-stance='scope'] {\n --_s-surface: var(--wzl-stance-scope-surface, var(--wzl-surface));\n --_s-border-color: var(--wzl-stance-scope-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-scope-border-style, solid);\n --_s-border-width: var(--wzl-stance-scope-border-width, 1px);\n --_s-radius: var(--wzl-stance-scope-radius, var(--wzl-radius-md));\n --_s-tone-mix: var(--wzl-stance-scope-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-scope-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-scope-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-scope-title-font, var(--wzl-font-ui));\n --_s-title-weight: var(--wzl-stance-scope-title-weight, var(--wzl-font-weight-bold));\n --_s-title-size: var(--wzl-stance-scope-title-size, var(--wzl-font-size));\n --_s-title-case: var(--wzl-stance-scope-title-case, none);\n --_s-title-tracking: var(--wzl-stance-scope-title-tracking, normal);\n --_s-title-color: var(--wzl-stance-scope-title-color, var(--wzl-fg));\n}\n\n.modal[data-stance='aside'] {\n --_s-surface: var(--wzl-stance-aside-surface, var(--wzl-surface));\n --_s-border-color: var(--wzl-stance-aside-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-aside-border-style, solid);\n --_s-border-width: var(--wzl-stance-aside-border-width, 1px);\n --_s-radius: var(--wzl-stance-aside-radius, var(--wzl-radius-md));\n --_s-tone-mix: var(--wzl-stance-aside-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-aside-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-aside-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-aside-title-font, var(--wzl-font-ui));\n --_s-title-weight: var(--wzl-stance-aside-title-weight, var(--wzl-font-weight-bold));\n --_s-title-size: var(--wzl-stance-aside-title-size, var(--wzl-font-size));\n --_s-title-case: var(--wzl-stance-aside-title-case, none);\n --_s-title-tracking: var(--wzl-stance-aside-title-tracking, normal);\n --_s-title-color: var(--wzl-stance-aside-title-color, var(--wzl-fg));\n}\n\n.modal[data-stance='advanced'] {\n --_s-surface: var(--wzl-stance-advanced-surface, var(--wzl-surface));\n --_s-border-color: var(--wzl-stance-advanced-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-advanced-border-style, solid);\n --_s-border-width: var(--wzl-stance-advanced-border-width, 1px);\n --_s-radius: var(--wzl-stance-advanced-radius, var(--wzl-radius-md));\n --_s-tone-mix: var(--wzl-stance-advanced-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-advanced-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-advanced-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-advanced-title-font, var(--wzl-font-ui));\n --_s-title-weight: var(--wzl-stance-advanced-title-weight, var(--wzl-font-weight-bold));\n --_s-title-size: var(--wzl-stance-advanced-title-size, var(--wzl-font-size));\n --_s-title-case: var(--wzl-stance-advanced-title-case, none);\n --_s-title-tracking: var(--wzl-stance-advanced-title-tracking, normal);\n --_s-title-color: var(--wzl-stance-advanced-title-color, var(--wzl-fg));\n}\n\n.modal[data-stance='debug'] {\n --_s-surface: var(--wzl-stance-debug-surface, var(--wzl-surface));\n --_s-border-color: var(--wzl-stance-debug-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-debug-border-style, solid);\n --_s-border-width: var(--wzl-stance-debug-border-width, 1px);\n --_s-radius: var(--wzl-stance-debug-radius, var(--wzl-radius-md));\n --_s-tone-mix: var(--wzl-stance-debug-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-debug-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-debug-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-debug-title-font, var(--wzl-font-ui));\n --_s-title-weight: var(--wzl-stance-debug-title-weight, var(--wzl-font-weight-bold));\n --_s-title-size: var(--wzl-stance-debug-title-size, var(--wzl-font-size));\n --_s-title-case: var(--wzl-stance-debug-title-case, none);\n --_s-title-tracking: var(--wzl-stance-debug-title-tracking, normal);\n --_s-title-color: var(--wzl-stance-debug-title-color, var(--wzl-fg));\n}\n\n.modal[data-stance='danger'] {\n --_s-surface: var(--wzl-stance-danger-surface, var(--wzl-surface));\n --_s-border-color: var(--wzl-stance-danger-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-danger-border-style, solid);\n --_s-border-width: var(--wzl-stance-danger-border-width, 1px);\n --_s-radius: var(--wzl-stance-danger-radius, var(--wzl-radius-md));\n --_s-tone-mix: var(--wzl-stance-danger-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-danger-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-danger-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-danger-title-font, var(--wzl-font-ui));\n --_s-title-weight: var(--wzl-stance-danger-title-weight, var(--wzl-font-weight-bold));\n --_s-title-size: var(--wzl-stance-danger-title-size, var(--wzl-font-size));\n --_s-title-case: var(--wzl-stance-danger-title-case, none);\n --_s-title-tracking: var(--wzl-stance-danger-title-tracking, normal);\n --_s-title-color: var(--wzl-stance-danger-title-color, var(--wzl-fg));\n}\n\n.modal[data-stance='notice'] {\n --_s-surface: var(--wzl-stance-notice-surface, var(--wzl-surface));\n --_s-border-color: var(--wzl-stance-notice-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-notice-border-style, solid);\n --_s-border-width: var(--wzl-stance-notice-border-width, 1px);\n --_s-radius: var(--wzl-stance-notice-radius, var(--wzl-radius-md));\n --_s-tone-mix: var(--wzl-stance-notice-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-notice-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-notice-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-notice-title-font, var(--wzl-font-ui));\n --_s-title-weight: var(--wzl-stance-notice-title-weight, var(--wzl-font-weight-bold));\n --_s-title-size: var(--wzl-stance-notice-title-size, var(--wzl-font-size));\n --_s-title-case: var(--wzl-stance-notice-title-case, none);\n --_s-title-tracking: var(--wzl-stance-notice-title-tracking, normal);\n --_s-title-color: var(--wzl-stance-notice-title-color, var(--wzl-fg));\n}\n\n.modal[data-stance='important'] {\n --_s-surface: var(--wzl-stance-important-surface, var(--wzl-surface));\n --_s-border-color: var(--wzl-stance-important-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-important-border-style, solid);\n --_s-border-width: var(--wzl-stance-important-border-width, 1px);\n --_s-radius: var(--wzl-stance-important-radius, var(--wzl-radius-md));\n --_s-tone-mix: var(--wzl-stance-important-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-important-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-important-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-important-title-font, var(--wzl-font-ui));\n --_s-title-weight: var(--wzl-stance-important-title-weight, var(--wzl-font-weight-bold));\n --_s-title-size: var(--wzl-stance-important-title-size, var(--wzl-font-size));\n --_s-title-case: var(--wzl-stance-important-title-case, none);\n --_s-title-tracking: var(--wzl-stance-important-title-tracking, normal);\n --_s-title-color: var(--wzl-stance-important-title-color, var(--wzl-fg));\n}\n\n.modal[data-stance='preview'] {\n --_s-surface: var(--wzl-stance-preview-surface, var(--wzl-surface));\n --_s-border-color: var(--wzl-stance-preview-border-color, var(--wzl-border));\n --_s-border-style: var(--wzl-stance-preview-border-style, solid);\n --_s-border-width: var(--wzl-stance-preview-border-width, 1px);\n --_s-radius: var(--wzl-stance-preview-radius, var(--wzl-radius-md));\n --_s-tone-mix: var(--wzl-stance-preview-tone-mix, var(--wzl-panel-tone-mix));\n --_s-tone: var(--wzl-tone, var(--wzl-stance-preview-tone, var(--_s-surface)));\n --_s-accent: var(--wzl-stance-preview-accent, var(--wzl-tone));\n --_s-title-font: var(--wzl-stance-preview-title-font, var(--wzl-font-ui));\n --_s-title-weight: var(--wzl-stance-preview-title-weight, var(--wzl-font-weight-bold));\n --_s-title-size: var(--wzl-stance-preview-title-size, var(--wzl-font-size));\n --_s-title-case: var(--wzl-stance-preview-title-case, none);\n --_s-title-tracking: var(--wzl-stance-preview-title-tracking, normal);\n --_s-title-color: var(--wzl-stance-preview-title-color, var(--wzl-fg));\n}\n\n.modal {\n --_s-fill: var(--_s-surface);\n}\n\n.modal[data-tone],\n.modal[data-stance] {\n --_s-fill: color-mix(in oklab, var(--_s-tone) var(--_s-tone-mix), var(--_s-surface));\n}\n\n.modal[data-tone] {\n --wzl-accent: var(--_s-accent);\n --wzl-accent-base: var(--_s-accent);\n --wzl-accent-strong: color-mix(in oklab, var(--_s-accent) 70%, var(--wzl-fg));\n --wzl-accent-soft: color-mix(in oklab, var(--_s-accent) 45%, var(--wzl-surface));\n --wzl-accent-hover: var(--wzl-accent-strong);\n --wzl-accent-fg: var(--wzl-accent-strong);\n --wzl-focus-ring: var(--wzl-accent-strong);\n}\n\n/* END GENERATED stance rules: dialog */\n\n.dialog {\n display: flex;\n flex-direction: column;\n min-height: 0;\n flex: 1;\n outline: none;\n}\n\n.header {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-6);\n padding: var(--wzl-space-7) var(--wzl-space-8);\n border-bottom: 1px solid var(--wzl-border);\n flex: 0 0 auto;\n}\n\n.title {\n flex: 1;\n margin: 0;\n font-family: var(--_s-title-font);\n font-size: var(--_s-title-size);\n font-weight: var(--_s-title-weight);\n text-transform: var(--_s-title-case);\n letter-spacing: var(--_s-title-tracking);\n color: var(--_s-title-color);\n}\n\n.close {\n flex: 0 0 auto;\n width: var(--wzl-icon-button-size);\n height: var(--wzl-icon-button-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid transparent;\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-fg-muted);\n cursor: pointer;\n padding: 0;\n font-size: var(--wzl-font-size-lg);\n line-height: 1;\n}\n\n.close:hover {\n background: var(--wzl-surface-hover);\n color: var(--wzl-fg);\n}\n\n.body {\n flex: 1;\n}\n\n/* Defaults, not rules: `bodyClassName` exists to turn these off for content\n that scrolls itself, and a plain class would tie with it on specificity and\n be decided by stylesheet order. `min-height` is here for the same reason —\n left in the rule above it silently beat a consumer class asking the body to\n hold a height, and the dialog resized itself around every pane. */\n:where(.body) {\n min-height: 0;\n overflow: auto;\n padding: var(--wzl-space-8);\n}\n\n.footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--wzl-space-4);\n padding: var(--wzl-space-6) var(--wzl-space-8);\n border-top: 1px solid var(--wzl-border);\n flex: 0 0 auto;\n}\n","import type { ReactNode } from 'react';\nimport {\n Modal as RACModal,\n ModalOverlay,\n Dialog as RACDialog,\n Heading,\n type ModalOverlayProps,\n type DialogProps as RACDialogProps,\n} from 'react-aria-components';\nimport { useOverlayPortal, type OverlayPortalProps, type WithoutPortalTarget } from '../../overlays/portalHost';\nimport { type StanceProps, useStance } from '../stance';\nimport s from './Dialog.module.css';\n\n/** Props for {@link Dialog}, on top of React Aria's `ModalOverlay` props. */\nexport type DialogProps = Omit<\n WithoutPortalTarget<ModalOverlayProps>,\n 'children' | 'className'\n> &\n OverlayPortalProps &\n StanceProps & {\n /** Heading rendered in the dialog's default header. Omit when supplying\n * a custom `header` slot via children. */\n title?: ReactNode;\n /** Show the built-in close button. Defaults to true when `onOpenChange`\n * is wired so the user has an escape hatch. */\n showCloseButton?: boolean;\n /** Body content. */\n children?: ReactNode;\n /** Footer slot — typically action buttons. */\n footer?: ReactNode;\n /** ARIA role. Defaults to `dialog`. Use `alertdialog` for confirms. */\n role?: RACDialogProps['role'];\n /** Class applied to the modal box (inside the overlay). */\n className?: string;\n /** Class applied to the scrolling body. For content that owns its own\n * scrolling — a form with a fixed navigation rail beside a scrolling\n * pane — this is where the body's padding and overflow come off. */\n bodyClassName?: string;\n };\n\n/**\n * Modal dialog wrapping React Aria. Supplies a default header (title +\n * close), scrollable body, and footer slot. Pass `isOpen` + `onOpenChange`\n * for controlled visibility, or omit both and use a `<DialogTrigger>` from\n * `react-aria-components` upstream of this component.\n *\n * Escape, click-outside, focus trap, and scroll lock all come from the\n * underlying primitives. `stance` and `tone` work as on `<PropertyPanel>` —\n * a destructive confirm is `stance=\"danger\"`.\n */\nexport function Dialog(props: DialogProps) {\n const {\n title,\n showCloseButton,\n children,\n footer,\n role = 'dialog',\n className,\n bodyClassName,\n isOpen,\n onOpenChange,\n portalContainer,\n stance,\n tone,\n ...rest\n } = props;\n const stanced = useStance({ stance, tone });\n\n const showClose = showCloseButton ?? Boolean(onOpenChange);\n const { anchor, portalProps } = useOverlayPortal(portalContainer);\n\n return (\n <>\n {anchor}\n <ModalOverlay\n {...rest}\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n className={s.overlay}\n data-weasel-overlay=\"\"\n {...portalProps}\n >\n <RACModal className={[s.modal, className].filter(Boolean).join(' ')} {...stanced}>\n <RACDialog role={role} className={s.dialog}>\n {({ close }) => (\n <>\n {(title !== undefined || showClose) && (\n <header className={s.header}>\n {title !== undefined && (\n <Heading slot=\"title\" className={s.title}>{title}</Heading>\n )}\n {showClose && (\n <button\n type=\"button\"\n className={s.close}\n onClick={close}\n aria-label=\"Close dialog\"\n >\n ×\n </button>\n )}\n </header>\n )}\n <div className={[s.body, bodyClassName].filter(Boolean).join(' ')}>{children}</div>\n {footer !== undefined && <footer className={s.footer}>{footer}</footer>}\n </>\n )}\n </RACDialog>\n </RACModal>\n </ModalOverlay>\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;ACkDA,SAAgB,EAAO,GAAoB;CACzC,IAAM,EACJ,UACA,oBACA,aACA,WACA,UAAO,UACP,cACA,kBACA,WACA,iBACA,oBACA,WACA,SACA,GAAG,MACD,GACE,IAAU,EAAU;EAAE;EAAQ;EAAM,CAAC,EAErC,IAAY,KAAmB,EAAQ,GACvC,EAAE,WAAQ,mBAAgB,EAAiB,EAAgB;AAEjE,QACE,kBAAA,GAAA,EAAA,UAAA,CACG,GACD,kBAAC,GAAD;EACE,GAAI;EACI;EACM;EACd,WAAW,EAAE;EACb,uBAAoB;EACpB,GAAI;YAEJ,kBAAC,GAAD;GAAU,WAAW,CAAC,EAAE,OAAO,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;GAAE,GAAI;aACvE,kBAAC,GAAD;IAAiB;IAAM,WAAW,EAAE;eAChC,EAAE,eACF,kBAAA,GAAA,EAAA,UAAA;MACI,MAAU,KAAA,KAAa,MACvB,kBAAC,UAAD;MAAQ,WAAW,EAAE;gBAArB,CACG,MAAU,KAAA,KACT,kBAAC,GAAD;OAAS,MAAK;OAAQ,WAAW,EAAE;iBAAQ;OAAgB,CAAA,EAE5D,KACC,kBAAC,UAAD;OACE,MAAK;OACL,WAAW,EAAE;OACb,SAAS;OACT,cAAW;iBACZ;OAEQ,CAAA,CAEJ;;KAEX,kBAAC,OAAD;MAAK,WAAW,CAAC,EAAE,MAAM,EAAc,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;MAAG;MAAe,CAAA;KAClF,MAAW,KAAA,KAAa,kBAAC,UAAD;MAAQ,WAAW,EAAE;gBAAS;MAAgB,CAAA;KACtE,EAAA,CAAA;IAEK,CAAA;GACH,CAAA;EACE,CAAA,CACd,EAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Disclosure-D79jhmh2.js","names":[],"sources":["../../src/components/Disclosure/Disclosure.module.css","../../src/components/Disclosure/Disclosure.tsx"],"sourcesContent":["/* Every dimension is stated because a host app's bare-element defaults can be\n authored at zero specificity — labkit's `:where(.lk-root) :where(button)`\n sets `height: var(--wzl-control-h)` and horizontal padding, which would\n otherwise stretch a 12px mark into a full-height control. */\n.twisty {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* A floor, not a size: a control sized to a 12px glyph is a 12px target,\n which is under every pointer-size guideline there is. Stated as a minimum\n so a larger mark grows the target with it rather than being shrunk to fit\n — a flex item's default `flex-shrink: 1` would otherwise crush it. */\n min-width: var(--wzl-disclosure-target, var(--wzl-control-h-sm));\n min-height: var(--wzl-disclosure-target, var(--wzl-control-h-sm));\n padding: 0;\n border: 0;\n border-radius: var(--wzl-radius-sm);\n background: none;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n line-height: 1;\n cursor: pointer;\n}\n\n.twisty:focus-visible {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: -2px;\n}\n\n.twisty:disabled {\n cursor: not-allowed;\n}\n\n.mark {\n display: block;\n flex: none;\n}\n\n.lozenge {\n fill: var(--wzl-disclosure-fill, var(--wzl-accent-fg));\n transition: fill var(--wzl-motion-fast, 90ms) var(--wzl-ease-out-cubic);\n}\n\n.twisty:hover:not(:disabled) .lozenge {\n fill: color-mix(in oklab, var(--wzl-disclosure-fill, var(--wzl-accent-fg)), white 15%);\n}\n\n.twisty:disabled .lozenge {\n fill: var(--wzl-fg-subtle);\n}\n\n.sign {\n fill: none;\n stroke: var(--wzl-fg-on-accent);\n stroke-width: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .lozenge {\n transition: none;\n }\n}\n\n.row {\n display: flex;\n align-items: center;\n gap: var(--wzl-disclosure-gap, 4px);\n}\n\n/* The row's content takes the rest and is allowed to shrink; the twisty is\n not, so a long label truncates rather than crushing the control. */\n.rowBody {\n flex: 1 1 auto;\n min-width: 0;\n}\n","import type { ReactNode } from 'react';\nimport s from './Disclosure.module.css';\n\n/** Props for `<DisclosureMark>`. */\nexport interface DisclosureMarkProps {\n /** Whether the section it stands for is open: `−` when open, `+` when shut. */\n open: boolean;\n /** Mark size in px, square. Default 13. */\n size?: number;\n className?: string;\n}\n\n/**\n * The fold mark alone: a dark violet rounded square holding a `+` while its section is\n * shut and a `−` while it is open. Decorative — it carries no role or label —\n * for a row that is itself the control, such as a tree item or a header\n * button. Anywhere the mark has to be the control, use `<Disclosure>`.\n *\n * Deliberately not part of the icon register, on the same grounds as\n * `DragHandleGlyph`: that register is outline strokes at a fixed weight, and\n * this mark is filled.\n */\nexport function DisclosureMark({ open, size = 13, className }: DisclosureMarkProps) {\n return (\n <svg\n className={className ? `${s.mark} ${className}` : s.mark}\n viewBox=\"0 0 13 13\"\n width={size}\n height={size}\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <rect className={s.lozenge} width=\"13\" height=\"13\" rx=\"3\" />\n {/* One-unit bars centered on 6.5 in an odd box, so at the default size\n both edges land on the pixel grid rather than blurring across it. */}\n <path className={s.sign} d={open ? 'M3 6.5 H10' : 'M3 6.5 H10 M6.5 3 V10'} />\n </svg>\n );\n}\n\n/** Props for `<Disclosure>`. */\nexport interface DisclosureProps {\n /** Whether the section it controls is open. The consumer owns this. */\n open: boolean;\n onToggle: () => void;\n /**\n * Names the section, for a screen reader. The control has no text of its\n * own, so without this it announces as an unlabeled button.\n */\n label: string;\n /**\n * `id` of the element this expands. Sets `aria-controls`, which lets a\n * screen reader move to the revealed content.\n */\n controls?: string;\n /** Mark size in px. The hit target is at least 20px and grows with it.\n * Default 13. */\n size?: number;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * The twisty on a collapsible section: a `<DisclosureMark>` in a button.\n *\n * Presentational — it holds no open/closed state and renders no children.\n * The consumer owns the state and the panel; this is the control that toggles\n * it, and `aria-expanded` is what ties the two together.\n *\n * Three things it settles that a hand-rolled twisty keeps getting wrong. The\n * mark is drawn rather than typed, because `--wzl-font-ui` carries no ▸/▾ and\n * a text glyph falls back to whatever the system offers at whatever size that\n * font renders it. The hit target is larger than the mark. And it is a sibling\n * of the row's label rather than a child, so clicking to expand does not\n * actuate the label's own control.\n */\nexport function Disclosure({ open, onToggle, label, controls, size = 13, disabled, className }: DisclosureProps) {\n return (\n <button\n type=\"button\"\n className={className ? `${s.twisty} ${className}` : s.twisty}\n aria-expanded={open}\n aria-controls={controls}\n aria-label={label}\n disabled={disabled}\n onClick={onToggle}\n >\n <DisclosureMark open={open} size={size} />\n </button>\n );\n}\n\n/** Props for `<DisclosureRow>`. */\nexport interface DisclosureRowProps extends Omit<DisclosureProps, 'className'> {\n /** The row's own content — a label, a checkbox, a count. */\n children: ReactNode;\n className?: string;\n}\n\n/**\n * A `<Disclosure>` and a row of content beside it, laid out so the twisty\n * leads and the content takes the rest.\n *\n * The layout is the point: the twisty sits *outside* whatever the row puts in\n * it, so a row whose content is a `<label>` wrapping a checkbox stays\n * clickable as a label without the twisty actuating it.\n */\nexport function DisclosureRow({ children, className, ...twisty }: DisclosureRowProps) {\n return (\n <div className={className ? `${s.row} ${className}` : s.row}>\n <Disclosure {...twisty} />\n <div className={s.rowBody}>{children}</div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;ACsBA,SAAgB,EAAe,EAAE,SAAM,UAAO,IAAI,gBAAkC;AAClF,QACE,kBAAC,OAAD;EACE,WAAW,IAAY,GAAG,EAAE,KAAK,GAAG,MAAc,EAAE;EACpD,SAAQ;EACR,OAAO;EACP,QAAQ;EACR,eAAY;EACZ,WAAU;YANZ,CAQE,kBAAC,QAAD;GAAM,WAAW,EAAE;GAAS,OAAM;GAAK,QAAO;GAAK,IAAG;GAAM,CAAA,EAG5D,kBAAC,QAAD;GAAM,WAAW,EAAE;GAAM,GAAG,IAAO,eAAe;GAA2B,CAAA,CACzE;;;AAwCV,SAAgB,EAAW,EAAE,SAAM,aAAU,UAAO,aAAU,UAAO,IAAI,aAAU,gBAA8B;AAC/G,QACE,kBAAC,UAAD;EACE,MAAK;EACL,WAAW,IAAY,GAAG,EAAE,OAAO,GAAG,MAAc,EAAE;EACtD,iBAAe;EACf,iBAAe;EACf,cAAY;EACF;EACV,SAAS;YAET,kBAAC,GAAD;GAAsB;GAAY;GAAQ,CAAA;EACnC,CAAA;;AAmBb,SAAgB,EAAc,EAAE,aAAU,cAAW,GAAG,KAA8B;AACpF,QACE,kBAAC,OAAD;EAAK,WAAW,IAAY,GAAG,EAAE,IAAI,GAAG,MAAc,EAAE;YAAxD,CACE,kBAAC,GAAD,EAAY,GAAI,GAAU,CAAA,EAC1B,kBAAC,OAAD;GAAK,WAAW,EAAE;GAAU;GAAe,CAAA,CACvC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DragGhost-DcU7cOwy.js","names":[],"sources":["../../src/components/DragGhost/DragGhost.module.css","../../src/components/DragGhost/DragGhost.tsx"],"sourcesContent":[".ghost {\n position: fixed;\n z-index: var(--wzl-z-overlay);\n display: flex;\n flex-direction: column;\n gap: 1px;\n padding: 1px;\n border-radius: var(--wzl-radius-sm);\n background: var(--wzl-surface-raised);\n box-shadow: 0 4px 12px var(--wzl-shadow);\n opacity: 0.85;\n pointer-events: none;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { nearestPortalHost } from '../../overlays/portalHost';\nimport s from './DragGhost.module.css';\n\n/** Props for `<DragGhost>`. */\nexport interface DragGhostProps {\n /** The ghost's top-left in client space, and its width — `useReorderDragList`'s `state.ghost` is one. */\n at: { left: number; top: number; width: number };\n /** An element inside the list being dragged from. The ghost portals to its nearest themed ancestor, so it resolves\n * the list's tokens without being clipped by the list's panel. */\n from: Element;\n /** What to draw: copies of the dragged items, or any stand-in for them. */\n children: ReactNode;\n}\n\n/** Whether `el` is the containing block of its fixed-position descendants rather than the viewport. */\nfunction containsFixed(el: Element): boolean {\n const cs = getComputedStyle(el);\n return (\n cs.transform !== 'none' ||\n cs.filter !== 'none' ||\n cs.backdropFilter !== 'none' ||\n cs.perspective !== 'none' ||\n /paint|layout|strict|content/.test(cs.contain)\n );\n}\n\n/**\n * What follows the pointer during a drag while the dragged items hold their place: `children` on a raised surface at\n * a client-space point. Hidden from assistive tech and from the pointer, so it never becomes the drop target.\n */\nexport function DragGhost({ at, from, children }: DragGhostProps) {\n const host = nearestPortalHost(from) ?? document.body;\n const origin = host !== document.body && containsFixed(host) ? host.getBoundingClientRect() : { left: 0, top: 0 };\n // Pixel positioning: the point is the pointer's, known only at runtime.\n const style: CSSProperties = { left: at.left - origin.left, top: at.top - origin.top, width: at.width };\n return createPortal(\n <div className={s.ghost} style={style} aria-hidden=\"true\">\n {children}\n </div>,\n host,\n );\n}\n"],"mappings":";;;;;;ACiBA,SAAS,EAAc,GAAsB;CAC3C,IAAM,IAAK,iBAAiB,EAAG;AAC/B,QACE,EAAG,cAAc,UACjB,EAAG,WAAW,UACd,EAAG,mBAAmB,UACtB,EAAG,gBAAgB,UACnB,8BAA8B,KAAK,EAAG,QAAQ;;AAQlD,SAAgB,EAAU,EAAE,OAAI,SAAM,eAA4B;CAChE,IAAM,IAAO,EAAkB,EAAK,IAAI,SAAS,MAC3C,IAAS,MAAS,SAAS,QAAQ,EAAc,EAAK,GAAG,EAAK,uBAAuB,GAAG;EAAE,MAAM;EAAG,KAAK;EAAG,EAE3G,IAAuB;EAAE,MAAM,EAAG,OAAO,EAAO;EAAM,KAAK,EAAG,MAAM,EAAO;EAAK,OAAO,EAAG;EAAO;AACvG,QAAO,EACL,kBAAC,OAAD;EAAK,WAAW,EAAE;EAAc;EAAO,eAAY;EAChD;EACG,CAAA,EACN,EACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DragHandleGlyph-BtBxHjZS.js","names":[],"sources":["../../src/components/DragHandleGlyph/DragHandleGlyph.tsx"],"sourcesContent":["/** Props for `<DragHandleGlyph>`. */\nexport interface DragHandleGlyphProps {\n /** Height in px; width scales with it. Default 16. */\n size?: number;\n}\n\n/** The two-column dot grip used on anything draggable by a handle.\n *\n * Deliberately not part of the icon register: that register is outline strokes\n * at a fixed weight, and a grip is filled dots. Forcing it in would either\n * break the register's rule or produce a worse glyph. */\nexport function DragHandleGlyph({ size = 16 }: DragHandleGlyphProps) {\n return (\n <svg\n width={(size * 8) / 16}\n height={size}\n viewBox=\"0 0 8 16\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <circle cx=\"2\" cy=\"3\" r=\"1.1\" />\n <circle cx=\"6\" cy=\"3\" r=\"1.1\" />\n <circle cx=\"2\" cy=\"8\" r=\"1.1\" />\n <circle cx=\"6\" cy=\"8\" r=\"1.1\" />\n <circle cx=\"2\" cy=\"13\" r=\"1.1\" />\n <circle cx=\"6\" cy=\"13\" r=\"1.1\" />\n </svg>\n );\n}\n"],"mappings":";;AAWA,SAAgB,EAAgB,EAAE,UAAO,MAA4B;AACnE,QACE,kBAAC,OAAD;EACE,OAAQ,IAAO,IAAK;EACpB,QAAQ;EACR,SAAQ;EACR,MAAK;EACL,eAAY;YALd;GAOE,kBAAC,UAAD;IAAQ,IAAG;IAAI,IAAG;IAAI,GAAE;IAAQ,CAAA;GAChC,kBAAC,UAAD;IAAQ,IAAG;IAAI,IAAG;IAAI,GAAE;IAAQ,CAAA;GAChC,kBAAC,UAAD;IAAQ,IAAG;IAAI,IAAG;IAAI,GAAE;IAAQ,CAAA;GAChC,kBAAC,UAAD;IAAQ,IAAG;IAAI,IAAG;IAAI,GAAE;IAAQ,CAAA;GAChC,kBAAC,UAAD;IAAQ,IAAG;IAAI,IAAG;IAAK,GAAE;IAAQ,CAAA;GACjC,kBAAC,UAAD;IAAQ,IAAG;IAAI,IAAG;IAAK,GAAE;IAAQ,CAAA;GAC7B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Field-xbqRmjsI.js","names":[],"sources":["../../src/components/Field/Field.module.css","../../src/components/Field/Field.tsx"],"sourcesContent":[".field {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-2);\n font-family: var(--wzl-font-ui);\n color: var(--wzl-fg);\n}\n\n.label {\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-font-weight-medium);\n color: var(--wzl-fg);\n cursor: default;\n}\n\n.hint {\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-subtle);\n line-height: 1.4;\n}\n\n.error {\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-danger);\n line-height: 1.4;\n}\n\n.row {\n flex-direction: row;\n align-items: center;\n gap: var(--wzl-space-4);\n}\n\n.row .label {\n flex: 1;\n min-width: 0;\n}\n","import type { ReactNode } from 'react';\nimport s from './Field.module.css';\n\n/**\n * Whether a {@link Field} stacks its label above the control or sits them\n * side by side.\n */\nexport type FieldOrientation = 'stacked' | 'row';\n\n/** Props for {@link Field}. */\nexport type FieldProps = {\n orientation?: FieldOrientation;\n className?: string;\n children?: ReactNode;\n};\n\n/**\n * Layout primitive that arranges a label, control, hint, and error in the\n * canonical weasel-ui form-row shape. The control itself owns its semantics\n * (RAC `TextField`, `Checkbox`, etc.); this just paints the layout.\n *\n * Most users will instead reach for `Input` / `Checkbox` / `Switch`, which\n * compose Field internally. Use Field directly when you need a custom\n * control to sit in the same visual rhythm.\n */\nexport function Field({ orientation = 'stacked', className, children }: FieldProps) {\n const cls = [s.field, orientation === 'row' && s.row, className].filter(Boolean).join(' ');\n return <div className={cls}>{children}</div>;\n}\n\n/**\n * The class names {@link Field} paints its slots with, so a control composing\n * its own layout can match the same form-row rhythm.\n */\nexport const fieldClasses = {\n root: s.field,\n row: s.row,\n label: s.label,\n hint: s.hint,\n error: s.error,\n};\n"],"mappings":";;;;;;;;;;ACyBA,SAAgB,EAAM,EAAE,iBAAc,WAAW,cAAW,eAAwB;AAElF,QAAO,kBAAC,OAAD;EAAK,WADA;GAAC,EAAE;GAAO,MAAgB,SAAS,EAAE;GAAK;GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAC/D;EAAM;EAAe,CAAA;;AAO9C,IAAa,IAAe;CAC1B,MAAM,EAAE;CACR,KAAK,EAAE;CACP,OAAO,EAAE;CACT,MAAM,EAAE;CACR,OAAO,EAAE;CACV"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"FillStrokeSwatch-BViKXIPx.js","names":[],"sources":["../../src/components/FillStrokeSwatch/FillStrokeSwatch.module.css","../../src/components/FillStrokeSwatch/FillStrokeSwatch.tsx"],"sourcesContent":[".root {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n gap: var(--wzl-space-2);\n}\n\n/* The two chips overlap on a diagonal: fill up-left, behind; stroke\n down-right, in front, so the fill shows through the stroke's hole. */\n.pair {\n --chip: 32px;\n --offset: 12px;\n --ring: 8px;\n position: relative;\n inline-size: calc(var(--chip) + var(--offset));\n block-size: calc(var(--chip) + var(--offset));\n}\n\n.chip {\n position: absolute;\n inline-size: var(--chip);\n block-size: var(--chip);\n box-sizing: border-box;\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n}\n\n.chip[data-slot='fill'] {\n inset-block-start: 0;\n inset-inline-start: 0;\n}\n\n.chip[data-slot='stroke'] {\n inset-block-end: 0;\n inset-inline-end: 0;\n}\n\n.chip[data-focused] {\n border-color: var(--wzl-fg);\n box-shadow: 0 0 0 1px var(--wzl-fg);\n}\n\n.chip:has(.input:focus-visible) {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: 1px;\n}\n\n/* The paint sits over the checker, so a translucent one reads as such. */\n.well {\n position: absolute;\n inset: 0;\n overflow: hidden;\n border-radius: calc(var(--wzl-radius-sm) - var(--wzl-border-w));\n background: repeating-conic-gradient(\n var(--wzl-checker-a) 0% 25%,\n var(--wzl-checker-b) 0% 50%\n )\n 50% / var(--wzl-checker-size) var(--wzl-checker-size);\n}\n\n/* The stroke well is a ring: the mask subtracts the content box from the\n padding box, so whatever is behind the chip shows through its hole. */\n.chip[data-slot='stroke'] .well {\n box-sizing: border-box;\n padding: var(--ring);\n mask:\n linear-gradient(#000, #000) padding-box,\n linear-gradient(#000, #000) content-box;\n mask-composite: exclude;\n}\n\n/* The hole's edge, so a focused stroke reads as focused on both sides. */\n.chip[data-slot='stroke'][data-focused]::before {\n content: '';\n position: absolute;\n inset: calc(var(--ring) - var(--wzl-border-w));\n border: 1px solid var(--wzl-fg);\n border-radius: 1px;\n pointer-events: none;\n}\n\n.paint {\n position: absolute;\n inset: 0;\n}\n\n/* No paint: the surface crossed by the danger diagonal. */\n.chip[data-none] .well {\n background:\n linear-gradient(\n 45deg,\n transparent calc(50% - 1px),\n var(--wzl-danger) calc(50% - 1px),\n var(--wzl-danger) calc(50% + 1px),\n transparent calc(50% + 1px)\n ),\n var(--wzl-surface);\n}\n\n/* The native picker covers its chip, invisible: it takes the click and the\n keyboard focus, and the well draws the paint. */\n.input {\n position: absolute;\n inset: 0;\n inline-size: 100%;\n block-size: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n opacity: 0;\n cursor: pointer;\n}\n\n.buttons {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: var(--wzl-space-1);\n}\n","import { useState, type ReactElement } from 'react';\nimport type { FillStyle } from '@weasel-js/core';\nimport { paintPreviewCss } from '../../paintPreview';\nimport { solidColorOf } from '../paintValue';\nimport { Button } from '../Button';\nimport type { PaintSlot } from '../GradientEditor';\nimport s from './FillStrokeSwatch.module.css';\n\n/** Props for {@link FillStrokeSwatch}. */\nexport interface FillStrokeSwatchProps {\n /** `null` is an explicit \"no paint\". */\n fill: FillStyle | null | undefined;\n stroke: FillStyle | null | undefined;\n /** The slot that edits aimed at \"the current paint\" land on — the None\n * button, a palette click, a keyboard shortcut the app binds. */\n focused: PaintSlot;\n onFocusChange: (slot: PaintSlot) => void;\n /** Every tick of the color picker, as `#rrggbb`. */\n onInput?: (slot: PaintSlot, color: string) => void;\n /** Once when the picker closes, with its last color, if it moved. */\n onChange: (slot: PaintSlot, color: string) => void;\n /** Toggle a slot between no paint and a paint. Given, it adds the None\n * button (acting on `focused`) and shift-click on a chip. */\n onToggleNone?: (slot: PaintSlot) => void;\n /** Given, adds a Swap button that exchanges the two paints. */\n onSwap?: () => void;\n /** Given, adds a Default button that restores the app's default pair. */\n onReset?: () => void;\n /** Key hints for the buttons' tooltips. The app binds the keys itself. */\n shortcuts?: { none?: string; swap?: string; reset?: string };\n 'aria-label'?: string;\n className?: string;\n}\n\nconst SLOT_LABEL: Record<PaintSlot, string> = { fill: 'Fill', stroke: 'Stroke' };\nconst PICKER_FALLBACK: Record<PaintSlot, string> = { fill: '#ffffff', stroke: '#000000' };\n\nfunction Chip(props: {\n slot: PaintSlot;\n paint: FillStyle | null | undefined;\n focused: boolean;\n onFocusChange: (slot: PaintSlot) => void;\n onInput?: (slot: PaintSlot, color: string) => void;\n onChange: (slot: PaintSlot, color: string) => void;\n onToggleNone?: (slot: PaintSlot) => void;\n}): ReactElement {\n const { slot, paint, focused } = props;\n // Tracks the picker through a pick; the prop only catches up on commit.\n const [draft, setDraft] = useState<string | null>(null);\n const none = paint === null;\n const preview = paintPreviewCss(paint);\n const pickerValue = (solidColorOf(paint) ?? PICKER_FALLBACK[slot]).slice(0, 7);\n\n return (\n <span\n className={s.chip}\n data-slot={slot}\n {...(focused ? { 'data-focused': '' } : {})}\n {...(none ? { 'data-none': '' } : {})}\n >\n <span className={s.well} aria-hidden=\"true\">\n {preview && <span className={s.paint} style={{ background: preview }} />}\n </span>\n <input\n type=\"color\"\n className={s.input}\n value={draft ?? pickerValue}\n aria-label={SLOT_LABEL[slot]}\n aria-current={focused ? 'true' : undefined}\n onFocus={() => props.onFocusChange(slot)}\n onClick={(e) => {\n props.onFocusChange(slot);\n // Shift-click is the none toggle; preventing it keeps the OS picker shut.\n if (e.shiftKey && props.onToggleNone) {\n e.preventDefault();\n props.onToggleNone(slot);\n }\n }}\n onInput={(e) => {\n const color = (e.target as HTMLInputElement).value;\n setDraft(color);\n props.onInput?.(slot, color);\n }}\n onBlur={() => {\n if (draft === null) return;\n setDraft(null);\n props.onChange(slot, draft);\n }}\n />\n </span>\n );\n}\n\n/**\n * The active fill and stroke as one overlapping pair, the way drawing apps\n * show the paint the next shape gets: fill a solid square behind, stroke a\n * frame in front of it. Each chip is a native color picker; the focused one\n * is what the None button — and whatever the app binds — acts on.\n *\n * Holds no state of its own: the paints and the focused slot are props, and\n * the chips report picks through `onInput`/`onChange` for the app to route —\n * into its own active-paint state, into the selection through\n * `useOngoingAction`, or both.\n */\nexport function FillStrokeSwatch(props: FillStrokeSwatchProps): ReactElement {\n const {\n fill, stroke, focused, onFocusChange, onInput, onChange,\n onToggleNone, onSwap, onReset, shortcuts, className,\n } = props;\n const focusedPaint = focused === 'fill' ? fill : stroke;\n const chip = { onFocusChange, onInput, onChange, onToggleNone };\n const anyButton = onToggleNone || onSwap || onReset;\n\n return (\n <div\n className={[s.root, className].filter(Boolean).join(' ')}\n role=\"group\"\n aria-label={props['aria-label'] ?? 'Fill and stroke'}\n >\n <div className={s.pair}>\n <Chip slot=\"fill\" paint={fill} focused={focused === 'fill'} {...chip} />\n <Chip slot=\"stroke\" paint={stroke} focused={focused === 'stroke'} {...chip} />\n </div>\n {anyButton && (\n <div className={s.buttons}>\n {onToggleNone && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n pressed={focusedPaint === null}\n onClick={() => onToggleNone(focused)}\n shortcut={shortcuts?.none}\n >\n None\n </Button>\n )}\n {onSwap && (\n <Button variant=\"ghost\" size=\"sm\" onClick={onSwap} shortcut={shortcuts?.swap}>\n Swap\n </Button>\n )}\n {onReset && (\n <Button variant=\"ghost\" size=\"sm\" onClick={onReset} shortcut={shortcuts?.reset}>\n Default\n </Button>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;GCkCM,IAAwC;CAAE,MAAM;CAAQ,QAAQ;CAAU,EAC1E,IAA6C;CAAE,MAAM;CAAW,QAAQ;CAAW;AAEzF,SAAS,EAAK,GAQG;CACf,IAAM,EAAE,SAAM,UAAO,eAAY,GAE3B,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,IAAO,MAAU,MACjB,IAAU,EAAgB,EAAM,EAChC,KAAe,EAAa,EAAM,IAAI,EAAgB,IAAO,MAAM,GAAG,EAAE;AAE9E,QACE,kBAAC,QAAD;EACE,WAAW,EAAE;EACb,aAAW;EACX,GAAK,IAAU,EAAE,gBAAgB,IAAI,GAAG,EAAE;EAC1C,GAAK,IAAO,EAAE,aAAa,IAAI,GAAG,EAAE;YAJtC,CAME,kBAAC,QAAD;GAAM,WAAW,EAAE;GAAM,eAAY;aAClC,KAAW,kBAAC,QAAD;IAAM,WAAW,EAAE;IAAO,OAAO,EAAE,YAAY,GAAS;IAAI,CAAA;GACnE,CAAA,EACP,kBAAC,SAAD;GACE,MAAK;GACL,WAAW,EAAE;GACb,OAAO,KAAS;GAChB,cAAY,EAAW;GACvB,gBAAc,IAAU,SAAS,KAAA;GACjC,eAAe,EAAM,cAAc,EAAK;GACxC,UAAU,MAAM;AAGd,IAFA,EAAM,cAAc,EAAK,EAErB,EAAE,YAAY,EAAM,iBACtB,EAAE,gBAAgB,EAClB,EAAM,aAAa,EAAK;;GAG5B,UAAU,MAAM;IACd,IAAM,IAAS,EAAE,OAA4B;AAE7C,IADA,EAAS,EAAM,EACf,EAAM,UAAU,GAAM,EAAM;;GAE9B,cAAc;AACR,UAAU,SACd,EAAS,KAAK,EACd,EAAM,SAAS,GAAM,EAAM;;GAE7B,CAAA,CACG;;;AAeX,SAAgB,EAAiB,GAA4C;CAC3E,IAAM,EACJ,SAAM,WAAQ,YAAS,kBAAe,YAAS,aAC/C,iBAAc,WAAQ,YAAS,cAAW,iBACxC,GACE,IAAe,MAAY,SAAS,IAAO,GAC3C,IAAO;EAAE;EAAe;EAAS;EAAU;EAAc,EACzD,IAAY,KAAgB,KAAU;AAE5C,QACE,kBAAC,OAAD;EACE,WAAW,CAAC,EAAE,MAAM,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EACxD,MAAK;EACL,cAAY,EAAM,iBAAiB;YAHrC,CAKE,kBAAC,OAAD;GAAK,WAAW,EAAE;aAAlB,CACE,kBAAC,GAAD;IAAM,MAAK;IAAO,OAAO;IAAM,SAAS,MAAY;IAAQ,GAAI;IAAQ,CAAA,EACxE,kBAAC,GAAD;IAAM,MAAK;IAAS,OAAO;IAAQ,SAAS,MAAY;IAAU,GAAI;IAAQ,CAAA,CAC1E;MACL,KACC,kBAAC,OAAD;GAAK,WAAW,EAAE;aAAlB;IACG,KACC,kBAAC,GAAD;KACE,SAAQ;KACR,MAAK;KACL,SAAS,MAAiB;KAC1B,eAAe,EAAa,EAAQ;KACpC,UAAU,GAAW;eACtB;KAEQ,CAAA;IAEV,KACC,kBAAC,GAAD;KAAQ,SAAQ;KAAQ,MAAK;KAAK,SAAS;KAAQ,UAAU,GAAW;eAAM;KAErE,CAAA;IAEV,KACC,kBAAC,GAAD;KAAQ,SAAQ;KAAQ,MAAK;KAAK,SAAS;KAAS,UAAU,GAAW;eAAO;KAEvE,CAAA;IAEP;KAEJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"FontFamilySelect-r9TV_xIH.js","names":[],"sources":["../../src/components/FontFamilySelect/FontFamilySelect.tsx"],"sourcesContent":["/**\n * Font-family picker driven by the live font registry.\n *\n * **What it offers.** Both tiers that can actually paint: `listFonts()` for\n * families with a baked atlas, and `listCanvasFonts()` for families the\n * dynamic canvas-SDF tier will serve. Offer what will render, invent\n * nothing — and `listCanvasFonts` reports service rather than membership,\n * so a family auto-enrolled under a policy that is no longer in force\n * doesn't appear.\n *\n * **What it does with a value it can't offer.** Nothing about the model\n * stops a node from naming a family that was never registered — a pasted\n * node, an imported SVG, a document from a session that loaded more fonts.\n * The control keeps that value visible as its own entry and names what is\n * actually painting instead, read structurally off\n * `resolveFontVariant().substituted`. Dropping the value would silently\n * rewrite the document on the next edit; showing it bare would claim a font\n * is in use that isn't.\n */\nimport { listCanvasFonts, listFonts, resolveFontVariant } from '@weasel-js/font';\nimport { Select } from '../Select';\n\nexport interface FontFamilySelectProps {\n /** Current family, or `undefined` when the sources disagree (`mixed`). */\n value?: string;\n /** Indeterminate presentation — the aggregated sources name different families. */\n mixed?: boolean;\n onChange: (family: string) => void;\n /** The weight / style the text actually renders at, so the substitution\n * probe reports the variant that paints rather than a nominal 400/normal. */\n weight?: number;\n fontStyle?: 'normal' | 'italic';\n 'aria-label'?: string;\n className?: string;\n}\n\n/** Label for a value that isn't in the registry: name the substitute when the\n * fallback chain found one, otherwise say only what is known. */\nfunction unregisteredLabel(family: string, weight: number, style: 'normal' | 'italic'): string {\n const { substituted } = resolveFontVariant(family, weight, style);\n return substituted\n ? `${family} — not loaded, showing ${substituted.resolved}`\n : `${family} — not loaded`;\n}\n\nexport function FontFamilySelect(props: FontFamilySelectProps) {\n const { value, mixed = false, onChange, weight = 400, fontStyle = 'normal', className } = props;\n // Both tiers that actually render: families with a baked atlas, and\n // families the dynamic canvas-SDF tier will serve. Neither list is a guess\n // — `listCanvasFonts` reports what the registry will really route, so a\n // family reaches this menu only if it can paint.\n const baked = listFonts();\n const canvas = listCanvasFonts().filter((c) => !baked.some((f) => f.family === c.family));\n const available = [...baked.map((f) => f.family), ...canvas.map((c) => c.family)];\n const options = available.map((family) => ({ value: family, label: family }));\n if (value !== undefined && !available.includes(value)) {\n options.push({ value, label: unregisteredLabel(value, weight, fontStyle) });\n }\n return (\n <Select<string>\n className={className}\n options={options}\n selectedKey={mixed ? null : (value ?? null)}\n placeholder={mixed ? 'Mixed' : undefined}\n onSelectionChange={onChange}\n aria-label={props['aria-label'] ?? 'Font'}\n />\n );\n}\n"],"mappings":";;;;AAsCA,SAAS,EAAkB,GAAgB,GAAgB,GAAoC;CAC7F,IAAM,EAAE,mBAAgB,EAAmB,GAAQ,GAAQ,EAAM;AACjE,QAAO,IACH,GAAG,EAAO,yBAAyB,EAAY,aAC/C,GAAG,EAAO;;AAGhB,SAAgB,EAAiB,GAA8B;CAC7D,IAAM,EAAE,UAAO,WAAQ,IAAO,aAAU,YAAS,KAAK,eAAY,UAAU,iBAAc,GAKpF,IAAQ,GAAW,EACnB,IAAS,GAAiB,CAAC,QAAQ,MAAM,CAAC,EAAM,MAAM,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EACnF,IAAY,CAAC,GAAG,EAAM,KAAK,MAAM,EAAE,OAAO,EAAE,GAAG,EAAO,KAAK,MAAM,EAAE,OAAO,CAAC,EAC3E,IAAU,EAAU,KAAK,OAAY;EAAE,OAAO;EAAQ,OAAO;EAAQ,EAAE;AAI7E,QAHI,MAAU,KAAA,KAAa,CAAC,EAAU,SAAS,EAAM,IACnD,EAAQ,KAAK;EAAE;EAAO,OAAO,EAAkB,GAAO,GAAQ,EAAU;EAAE,CAAC,EAG3E,kBAAC,GAAD;EACa;EACF;EACT,aAAa,IAAQ,OAAQ,KAAS;EACtC,aAAa,IAAQ,UAAU,KAAA;EAC/B,mBAAmB;EACnB,cAAY,EAAM,iBAAiB;EACnC,CAAA"}