@weasel-js/ui 1.4.1 → 1.4.3

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 (230) hide show
  1. package/dist/chunks/{ActionBar-D4N1o4LB.js → ActionBar-DxGp3WuZ.js} +2 -2
  2. package/dist/chunks/{ActionBar-D4N1o4LB.js.map → ActionBar-DxGp3WuZ.js.map} +1 -1
  3. package/dist/chunks/{ActionsBar-B-gWm0NE.js → ActionsBar-D1VFreoj.js} +3 -3
  4. package/dist/chunks/{ActionsBar-B-gWm0NE.js.map → ActionsBar-D1VFreoj.js.map} +1 -1
  5. package/dist/chunks/{Badge-7yQseqZb.js → Badge-Bf8Rd1R6.js} +1 -1
  6. package/dist/chunks/{Badge-7yQseqZb.js.map → Badge-Bf8Rd1R6.js.map} +1 -1
  7. package/dist/chunks/{BandEditor-DjOi4ldl.js → BandEditor-CUlbOlJi.js} +1 -1
  8. package/dist/chunks/{BandEditor-DjOi4ldl.js.map → BandEditor-CUlbOlJi.js.map} +1 -1
  9. package/dist/chunks/{Button-0OdcoOMx.js → Button-Cq5LBUMD.js} +1 -1
  10. package/dist/chunks/{Button-0OdcoOMx.js.map → Button-Cq5LBUMD.js.map} +1 -1
  11. package/dist/chunks/Callout-Dvt6lqVn.js +122 -0
  12. package/dist/chunks/Callout-Dvt6lqVn.js.map +1 -0
  13. package/dist/chunks/{Checkbox-D_GCnoJ0.js → Checkbox-D-pVpobU.js} +1 -1
  14. package/dist/chunks/{Checkbox-D_GCnoJ0.js.map → Checkbox-D-pVpobU.js.map} +1 -1
  15. package/dist/chunks/{ColorField-pEkaSppg.js → ColorField-D0OxUlvu.js} +2 -2
  16. package/dist/chunks/{ColorField-pEkaSppg.js.map → ColorField-D0OxUlvu.js.map} +1 -1
  17. package/dist/chunks/ComboBox-BBRRWvdc.js +107 -0
  18. package/dist/chunks/ComboBox-BBRRWvdc.js.map +1 -0
  19. package/dist/chunks/{CurveEditor-DoX5Q0_V.js → CurveEditor-DtjdpJVB.js} +2 -2
  20. package/dist/chunks/{CurveEditor-DoX5Q0_V.js.map → CurveEditor-DtjdpJVB.js.map} +1 -1
  21. package/dist/chunks/{DataGrid-DHV0chfL.js → DataGrid-BVdDMZkQ.js} +2 -2
  22. package/dist/chunks/{DataGrid-DHV0chfL.js.map → DataGrid-BVdDMZkQ.js.map} +1 -1
  23. package/dist/chunks/{DetentSlider-Cd5360U3.js → DetentSlider-BVWKdRyC.js} +2 -2
  24. package/dist/chunks/{DetentSlider-Cd5360U3.js.map → DetentSlider-BVWKdRyC.js.map} +1 -1
  25. package/dist/chunks/Dialog-CYBLjwbd.js +61 -0
  26. package/dist/chunks/Dialog-CYBLjwbd.js.map +1 -0
  27. package/dist/chunks/Disclosure-DiA6UKdM.js +47 -0
  28. package/dist/chunks/Disclosure-DiA6UKdM.js.map +1 -0
  29. package/dist/chunks/{DragHandleGlyph--2zsZzA2.js → DragHandleGlyph-CppAz4_8.js} +1 -1
  30. package/dist/chunks/{DragHandleGlyph--2zsZzA2.js.map → DragHandleGlyph-CppAz4_8.js.map} +1 -1
  31. package/dist/chunks/{Field-Bc6Nuc3p.js → Field-dzlxOGxT.js} +1 -1
  32. package/dist/chunks/{Field-Bc6Nuc3p.js.map → Field-dzlxOGxT.js.map} +1 -1
  33. package/dist/chunks/{FontFamilySelect-CvrXKVwv.js → FontFamilySelect-DIJ4phXz.js} +2 -2
  34. package/dist/chunks/{FontFamilySelect-CvrXKVwv.js.map → FontFamilySelect-DIJ4phXz.js.map} +1 -1
  35. package/dist/chunks/{GradientEditor-CPeTbkFE.js → GradientEditor-C5NVILLk.js} +4 -4
  36. package/dist/chunks/{GradientEditor-CPeTbkFE.js.map → GradientEditor-C5NVILLk.js.map} +1 -1
  37. package/dist/chunks/{InlineRange-CBt_SBsC.js → InlineRange-50ulExCL.js} +2 -2
  38. package/dist/chunks/{InlineRange-CBt_SBsC.js.map → InlineRange-50ulExCL.js.map} +1 -1
  39. package/dist/chunks/{Input-CSAECs_T.js → Input-CoKOtyD0.js} +2 -2
  40. package/dist/chunks/{Input-CSAECs_T.js.map → Input-CoKOtyD0.js.map} +1 -1
  41. package/dist/chunks/{ItemList-POiCvUDx.js → ItemList-BZJQReXD.js} +1 -1
  42. package/dist/chunks/{ItemList-POiCvUDx.js.map → ItemList-BZJQReXD.js.map} +1 -1
  43. package/dist/chunks/{Keycaps-DszN5Dwl.js → Keycaps-DSeq6QWH.js} +1 -1
  44. package/dist/chunks/{Keycaps-DszN5Dwl.js.map → Keycaps-DSeq6QWH.js.map} +1 -1
  45. package/dist/chunks/{LayerStack-BVdwhAhG.js → LayerStack-DOylrQcm.js} +23 -23
  46. package/dist/chunks/LayerStack-DOylrQcm.js.map +1 -0
  47. package/dist/chunks/{NumberField-Byw1iaIJ.js → NumberField-DBowmOfe.js} +12 -10
  48. package/dist/chunks/NumberField-DBowmOfe.js.map +1 -0
  49. package/dist/chunks/{OptionsBar-efIwfqYe.js → OptionsBar-D_Cd3ZYs.js} +3 -3
  50. package/dist/chunks/{OptionsBar-efIwfqYe.js.map → OptionsBar-D_Cd3ZYs.js.map} +1 -1
  51. package/dist/chunks/{PaintInput-6HTUAFL1.js → PaintInput-67U-COE4.js} +5 -5
  52. package/dist/chunks/{PaintInput-6HTUAFL1.js.map → PaintInput-67U-COE4.js.map} +1 -1
  53. package/dist/chunks/{PatternPicker-G9e0CU5H.js → PatternPicker-Ba22Bf4L.js} +2 -2
  54. package/dist/chunks/{PatternPicker-G9e0CU5H.js.map → PatternPicker-Ba22Bf4L.js.map} +1 -1
  55. package/dist/chunks/{Plot2D-D63D5w6c.js → Plot2D-C97pO13t.js} +1 -1
  56. package/dist/chunks/{Plot2D-D63D5w6c.js.map → Plot2D-C97pO13t.js.map} +1 -1
  57. package/dist/chunks/{PointPlotter-CZJE8Ccu.js → PointPlotter-CbDKVggs.js} +2 -2
  58. package/dist/chunks/{PointPlotter-CZJE8Ccu.js.map → PointPlotter-CbDKVggs.js.map} +1 -1
  59. package/dist/chunks/{Powerline-BY_ADnqq.js → Powerline-BaHDJlcO.js} +2 -2
  60. package/dist/chunks/{Powerline-BY_ADnqq.js.map → Powerline-BaHDJlcO.js.map} +1 -1
  61. package/dist/chunks/Prefs-D0l0PXLF.js +294 -0
  62. package/dist/chunks/Prefs-D0l0PXLF.js.map +1 -0
  63. package/dist/chunks/Properties-CMLua9mU.js +746 -0
  64. package/dist/chunks/Properties-CMLua9mU.js.map +1 -0
  65. package/dist/chunks/{RadioGroup-XjbfUb7S.js → RadioGroup-B2_LUgDp.js} +2 -2
  66. package/dist/chunks/{RadioGroup-XjbfUb7S.js.map → RadioGroup-B2_LUgDp.js.map} +1 -1
  67. package/dist/chunks/{RangeSlider-D0hFbx_Z.js → RangeSlider-C3to8A52.js} +1 -1
  68. package/dist/chunks/{RangeSlider-D0hFbx_Z.js.map → RangeSlider-C3to8A52.js.map} +1 -1
  69. package/dist/chunks/{ResizeHandle-DfqqfaZz.js → ResizeHandle-BrCO0JrH.js} +1 -1
  70. package/dist/chunks/{ResizeHandle-DfqqfaZz.js.map → ResizeHandle-BrCO0JrH.js.map} +1 -1
  71. package/dist/chunks/Select-CacMfs4v.js +124 -0
  72. package/dist/chunks/Select-CacMfs4v.js.map +1 -0
  73. package/dist/chunks/{SelectionPanel-BU2cmRtp.js → SelectionPanel-BWXU8BqW.js} +203 -202
  74. package/dist/chunks/SelectionPanel-BWXU8BqW.js.map +1 -0
  75. package/dist/chunks/{Sidebar-Du0yp1S0.js → Sidebar-BvwjZiFm.js} +1 -1
  76. package/dist/chunks/{Sidebar-Du0yp1S0.js.map → Sidebar-BvwjZiFm.js.map} +1 -1
  77. package/dist/chunks/{SidebarPanel-Cuq__FIC.js → SidebarPanel-D5Ua2vyP.js} +2 -2
  78. package/dist/chunks/{SidebarPanel-Cuq__FIC.js.map → SidebarPanel-D5Ua2vyP.js.map} +1 -1
  79. package/dist/chunks/{Slider-BE6jaxyU.js → Slider-Bk_G5sSW.js} +15 -15
  80. package/dist/chunks/Slider-Bk_G5sSW.js.map +1 -0
  81. package/dist/chunks/{StatusBar-DLYwh5sb.js → StatusBar-Bqv4D0dW.js} +1 -1
  82. package/dist/chunks/{StatusBar-DLYwh5sb.js.map → StatusBar-Bqv4D0dW.js.map} +1 -1
  83. package/dist/chunks/{Switch-B521iN3m.js → Switch-C4NU-me1.js} +1 -1
  84. package/dist/chunks/{Switch-B521iN3m.js.map → Switch-C4NU-me1.js.map} +1 -1
  85. package/dist/chunks/{Tabs-BuifAv0p.js → Tabs-BT3CDkoQ.js} +1 -1
  86. package/dist/chunks/{Tabs-BuifAv0p.js.map → Tabs-BT3CDkoQ.js.map} +1 -1
  87. package/dist/chunks/{Timeline-CWuh0nV0.js → Timeline-BmYwYjXd.js} +2 -2
  88. package/dist/chunks/{Timeline-CWuh0nV0.js.map → Timeline-BmYwYjXd.js.map} +1 -1
  89. package/dist/chunks/{Toast-B75V2gqL.js → Toast-B7ylq7fz.js} +1 -1
  90. package/dist/chunks/{Toast-B75V2gqL.js.map → Toast-B7ylq7fz.js.map} +1 -1
  91. package/dist/chunks/{ToggleBar-D0veW91s.js → ToggleBar-Bxwv6xvj.js} +2 -2
  92. package/dist/chunks/{ToggleBar-D0veW91s.js.map → ToggleBar-Bxwv6xvj.js.map} +1 -1
  93. package/dist/chunks/{ToolButton-D5VwD47i.js → ToolButton-CtDkqUIc.js} +2 -2
  94. package/dist/chunks/{ToolButton-D5VwD47i.js.map → ToolButton-CtDkqUIc.js.map} +1 -1
  95. package/dist/chunks/{ToolGroup-B2PlMKQ-.js → ToolGroup-zDtqt0QJ.js} +1 -1
  96. package/dist/chunks/{ToolGroup-B2PlMKQ-.js.map → ToolGroup-zDtqt0QJ.js.map} +1 -1
  97. package/dist/chunks/{ToolOptionsBar-ByHX7y1M.js → ToolOptionsBar-B2xPWzJf.js} +1 -1
  98. package/dist/chunks/{ToolOptionsBar-ByHX7y1M.js.map → ToolOptionsBar-B2xPWzJf.js.map} +1 -1
  99. package/dist/chunks/{ToolPalette-Bi5ezkO6.js → ToolPalette-BbrMHfQ9.js} +5 -5
  100. package/dist/chunks/{ToolPalette-Bi5ezkO6.js.map → ToolPalette-BbrMHfQ9.js.map} +1 -1
  101. package/dist/chunks/Tooltip-BHre_vbI.js +42 -0
  102. package/dist/chunks/Tooltip-BHre_vbI.js.map +1 -0
  103. package/dist/chunks/{keyGlyph-BLFMKZgF.js → keyGlyph-Bp0wnLHn.js} +1 -1
  104. package/dist/chunks/{keyGlyph-BLFMKZgF.js.map → keyGlyph-Bp0wnLHn.js.map} +1 -1
  105. package/dist/chunks/{number-D3TDawLC.js → number-Bv1nbhOJ.js} +1 -1
  106. package/dist/chunks/{number-D3TDawLC.js.map → number-Bv1nbhOJ.js.map} +1 -1
  107. package/dist/chunks/portalHost-CjpCnuGU.js +28 -0
  108. package/dist/chunks/portalHost-CjpCnuGU.js.map +1 -0
  109. package/dist/chunks/{range.module-CttzfN6a.js → range.module-CgURq-Ua.js} +1 -1
  110. package/dist/chunks/{range.module-CttzfN6a.js.map → range.module-CgURq-Ua.js.map} +1 -1
  111. package/dist/chunks/schema-CtWwGbqJ.js +41 -0
  112. package/dist/chunks/schema-CtWwGbqJ.js.map +1 -0
  113. package/dist/chunks/{segmentedControl.module-XADeq9e5.js → segmentedControl.module-BgvAPkSZ.js} +1 -1
  114. package/dist/chunks/{segmentedControl.module-XADeq9e5.js.map → segmentedControl.module-BgvAPkSZ.js.map} +1 -1
  115. package/dist/chunks/{useReorderDragList-UvHJFjTZ.js → useReorderDragList-CSQGd7zQ.js} +26 -30
  116. package/dist/chunks/useReorderDragList-CSQGd7zQ.js.map +1 -0
  117. package/dist/chunks/{useRovingTabIndex-ByjY4lnw.js → useRovingTabIndex-Dkpf_KhN.js} +1 -1
  118. package/dist/chunks/{useRovingTabIndex-ByjY4lnw.js.map → useRovingTabIndex-Dkpf_KhN.js.map} +1 -1
  119. package/dist/components/ActionBar/index.js +1 -1
  120. package/dist/components/ActionsBar/index.js +1 -1
  121. package/dist/components/Badge/index.js +1 -1
  122. package/dist/components/BandEditor/index.js +1 -1
  123. package/dist/components/Button/index.js +1 -1
  124. package/dist/components/Callout/Callout.d.ts +2 -1
  125. package/dist/components/Callout/Callout.d.ts.map +1 -1
  126. package/dist/components/Callout/index.js +1 -1
  127. package/dist/components/Checkbox/index.js +1 -1
  128. package/dist/components/ColorField/index.js +1 -1
  129. package/dist/components/ComboBox/ComboBox.d.ts +9 -2
  130. package/dist/components/ComboBox/ComboBox.d.ts.map +1 -1
  131. package/dist/components/ComboBox/index.js +1 -1
  132. package/dist/components/CurveEditor/index.js +1 -1
  133. package/dist/components/DataGrid/index.js +1 -1
  134. package/dist/components/DetentSlider/index.js +1 -1
  135. package/dist/components/Dialog/Dialog.d.ts +2 -1
  136. package/dist/components/Dialog/Dialog.d.ts.map +1 -1
  137. package/dist/components/Dialog/index.js +1 -1
  138. package/dist/components/Disclosure/Disclosure.d.ts +64 -0
  139. package/dist/components/Disclosure/Disclosure.d.ts.map +1 -0
  140. package/dist/components/Disclosure/index.d.ts +3 -0
  141. package/dist/components/Disclosure/index.d.ts.map +1 -0
  142. package/dist/components/Disclosure/index.js +2 -0
  143. package/dist/components/DragHandleGlyph/index.js +1 -1
  144. package/dist/components/Field/index.js +1 -1
  145. package/dist/components/FontFamilySelect/index.js +1 -1
  146. package/dist/components/GradientEditor/index.js +1 -1
  147. package/dist/components/InlineRange/index.js +1 -1
  148. package/dist/components/Input/index.js +1 -1
  149. package/dist/components/ItemList/index.js +1 -1
  150. package/dist/components/Keycaps/index.js +2 -2
  151. package/dist/components/LayerStack/LayerStack.d.ts +22 -9
  152. package/dist/components/LayerStack/LayerStack.d.ts.map +1 -1
  153. package/dist/components/LayerStack/index.js +1 -1
  154. package/dist/components/NumberField/NumberField.d.ts +12 -0
  155. package/dist/components/NumberField/NumberField.d.ts.map +1 -1
  156. package/dist/components/NumberField/index.js +1 -1
  157. package/dist/components/OptionsBar/index.js +1 -1
  158. package/dist/components/PaintInput/index.js +1 -1
  159. package/dist/components/PatternPicker/index.js +1 -1
  160. package/dist/components/Plot2D/index.js +1 -1
  161. package/dist/components/PointPlotter/index.js +1 -1
  162. package/dist/components/Powerline/index.js +2 -2
  163. package/dist/components/Prefs/PrefsForm.d.ts.map +1 -1
  164. package/dist/components/Prefs/index.d.ts +1 -1
  165. package/dist/components/Prefs/index.d.ts.map +1 -1
  166. package/dist/components/Prefs/index.js +3 -2
  167. package/dist/components/Prefs/schema.d.ts +17 -1
  168. package/dist/components/Prefs/schema.d.ts.map +1 -1
  169. package/dist/components/Properties/EffectCard.d.ts +3 -2
  170. package/dist/components/Properties/EffectCard.d.ts.map +1 -1
  171. package/dist/components/Properties/PropertyGroup.d.ts +24 -10
  172. package/dist/components/Properties/PropertyGroup.d.ts.map +1 -1
  173. package/dist/components/Properties/PropertyPanel.d.ts +68 -24
  174. package/dist/components/Properties/PropertyPanel.d.ts.map +1 -1
  175. package/dist/components/Properties/index.d.ts +1 -1
  176. package/dist/components/Properties/index.d.ts.map +1 -1
  177. package/dist/components/Properties/index.js +2 -2
  178. package/dist/components/RadioGroup/index.js +1 -1
  179. package/dist/components/RangeSlider/index.js +1 -1
  180. package/dist/components/ResizeHandle/index.js +1 -1
  181. package/dist/components/Select/Select.d.ts +9 -2
  182. package/dist/components/Select/Select.d.ts.map +1 -1
  183. package/dist/components/Select/index.js +1 -1
  184. package/dist/components/SelectionPanel/SelectionPanel.d.ts.map +1 -1
  185. package/dist/components/SelectionPanel/index.js +1 -1
  186. package/dist/components/Sidebar/index.js +1 -1
  187. package/dist/components/SidebarPanel/index.js +1 -1
  188. package/dist/components/Slider/index.js +1 -1
  189. package/dist/components/StatusBar/index.js +1 -1
  190. package/dist/components/Switch/index.js +1 -1
  191. package/dist/components/Tabs/index.js +1 -1
  192. package/dist/components/Timeline/index.js +1 -1
  193. package/dist/components/Toast/index.js +1 -1
  194. package/dist/components/ToggleBar/index.js +1 -1
  195. package/dist/components/ToolButton/index.js +1 -1
  196. package/dist/components/ToolGroup/index.js +1 -1
  197. package/dist/components/ToolOptionsBar/index.js +1 -1
  198. package/dist/components/ToolPalette/index.js +1 -1
  199. package/dist/components/Tooltip/Tooltip.d.ts +2 -1
  200. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
  201. package/dist/components/Tooltip/index.js +1 -1
  202. package/dist/index.d.ts +2 -0
  203. package/dist/index.d.ts.map +1 -1
  204. package/dist/index.js +63 -60
  205. package/dist/index.js.map +1 -1
  206. package/dist/overlays/portalHost.d.ts +55 -0
  207. package/dist/overlays/portalHost.d.ts.map +1 -0
  208. package/dist/style.css +1 -1
  209. package/dist/useReorderDragList.d.ts +1 -1
  210. package/dist/useReorderDragList.d.ts.map +1 -1
  211. package/package.json +6 -6
  212. package/dist/chunks/Callout-wRyevt8I.js +0 -116
  213. package/dist/chunks/Callout-wRyevt8I.js.map +0 -1
  214. package/dist/chunks/ComboBox-inno5gt1.js +0 -89
  215. package/dist/chunks/ComboBox-inno5gt1.js.map +0 -1
  216. package/dist/chunks/Dialog-CX2B8PIp.js +0 -59
  217. package/dist/chunks/Dialog-CX2B8PIp.js.map +0 -1
  218. package/dist/chunks/LayerStack-BVdwhAhG.js.map +0 -1
  219. package/dist/chunks/NumberField-Byw1iaIJ.js.map +0 -1
  220. package/dist/chunks/Prefs-ByKG3ylD.js +0 -300
  221. package/dist/chunks/Prefs-ByKG3ylD.js.map +0 -1
  222. package/dist/chunks/Properties-BuNzy7Hb.js +0 -662
  223. package/dist/chunks/Properties-BuNzy7Hb.js.map +0 -1
  224. package/dist/chunks/Select-D1uP21db.js +0 -103
  225. package/dist/chunks/Select-D1uP21db.js.map +0 -1
  226. package/dist/chunks/SelectionPanel-BU2cmRtp.js.map +0 -1
  227. package/dist/chunks/Slider-BE6jaxyU.js.map +0 -1
  228. package/dist/chunks/Tooltip-Bq8Hvj4r.js +0 -40
  229. package/dist/chunks/Tooltip-Bq8Hvj4r.js.map +0 -1
  230. package/dist/chunks/useReorderDragList-UvHJFjTZ.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"Callout-wRyevt8I.js","names":[],"sources":["../../src/components/Callout/Callout.module.css","../../src/components/Callout/Callout.tsx"],"sourcesContent":[".anchor {\n position: fixed;\n pointer-events: none;\n}\n\n.popover {\n /* Above Dialog overlay (1000) and ToastRegion (1100) — RAC sets no z-index. */\n z-index: 1200;\n --callout-accent: var(--wzl-accent-strong);\n background: var(--wzl-surface);\n border: 1px solid var(--callout-accent);\n border-radius: var(--wzl-radius-md);\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n max-width: 320px;\n transition: opacity var(--wzl-motion-fast);\n}\n\n.popover[data-entering],\n.popover[data-exiting] {\n opacity: 0;\n}\n\n.toneWarning {\n --callout-accent: var(--wzl-warning, #d99a3f);\n}\n\n.toneDanger {\n --callout-accent: var(--wzl-danger);\n}\n\n.arrow svg {\n display: block;\n fill: var(--wzl-surface);\n stroke: var(--callout-accent);\n stroke-width: 1;\n}\n\n.arrow[data-placement='bottom'] svg {\n transform: rotate(180deg);\n}\n\n.arrow[data-placement='left'] svg {\n transform: rotate(-90deg);\n}\n\n.arrow[data-placement='right'] svg {\n transform: rotate(90deg);\n}\n\n.dialog {\n outline: none;\n max-height: inherit;\n display: flex;\n flex-direction: column;\n}\n\n.header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 0;\n}\n\n.title {\n margin: 0;\n flex: 1;\n font-size: var(--wzl-font-size);\n font-weight: var(--wzl-font-weight-bold);\n}\n\n.close {\n flex: 0 0 auto;\n background: none;\n border: none;\n color: var(--wzl-fg-muted);\n font-size: var(--wzl-font-size-lg);\n line-height: 1;\n padding: 2px 4px;\n cursor: pointer;\n border-radius: var(--wzl-radius-sm);\n}\n\n.close:hover {\n color: var(--wzl-fg);\n}\n\n.body {\n padding: 8px 12px 10px;\n font-size: var(--wzl-font-size);\n line-height: 1.4;\n overflow-y: auto;\n}\n\n.footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 0 12px 10px;\n}\n","import { useCallback, useEffect, useId, useRef, type ReactNode, type RefObject } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n DialogTrigger,\n Popover as RACPopover,\n OverlayArrow,\n Dialog as RACDialog,\n Heading,\n type PopoverProps as RACPopoverProps,\n} from 'react-aria-components';\nimport s from './Callout.module.css';\n\n/** Accent color of a {@link Callout}'s border and arrow. */\nexport type CalloutTone = 'info' | 'warning' | 'danger';\n\n/**\n * Composition wrapper for press-to-open callouts:\n * `<CalloutTrigger><Pressable>…</Pressable><Callout>…</Callout></CalloutTrigger>`.\n * Re-exported RAC DialogTrigger — non-RAC trigger elements must be wrapped\n * in `<Pressable>` from react-aria-components.\n * In composed mode, put `defaultOpen` on `CalloutTrigger`, not `Callout` —\n * RAC detaches to local open state on the trigger, not the popover.\n */\nexport { DialogTrigger as CalloutTrigger };\n\n/** Props for {@link Callout}, on top of React Aria's `Popover` props. */\nexport type CalloutProps = Omit<\n RACPopoverProps,\n 'children' | 'className' | 'isNonModal' | 'triggerRef'\n> & {\n children?: ReactNode;\n className?: string;\n /** Optional heading rendered above the body. */\n title?: ReactNode;\n /** Footer slot — typically action buttons. */\n footer?: ReactNode;\n /** Accent tone for border + arrow. Default `info`. */\n tone?: CalloutTone;\n /**\n * `true` — blocks interaction with the rest of the app until dismissed;\n * inner dialog is `role=\"alertdialog\"`. `false` (default) — non-blocking:\n * the app stays interactive; Esc / outside click / close button dismiss.\n */\n modal?: boolean;\n /**\n * Show the × button. Defaults to `!modal`. In programmatic\n * `triggerRef`/`anchorRect` modes the close button needs controlled open\n * (`isOpen` + `onOpenChange`); with only `defaultOpen` it has no open-state\n * setter to call and cannot close.\n */\n showCloseButton?: boolean;\n /**\n * The user asked for this callout to go away — the × button or Escape.\n *\n * Distinct from `onOpenChange`, which a non-modal popover *also* fires when\n * interaction or focus merely leaves it. On a canvas that's every click on\n * the artwork, so a consumer that pins `isOpen` and treats `onOpenChange`\n * as dismissal retires messages nobody read. Use this instead: it fires\n * only on a deliberate act, and never on incidental focus loss.\n */\n onDismiss?: () => void;\n /** Anchor to an arbitrary element (programmatic use, with `isOpen`). */\n triggerRef?: RefObject<Element | null>;\n /**\n * Anchor to a client-coordinate rect — e.g. a scene node's on-screen box.\n * The callout re-anchors whenever this rect changes, so a consumer that\n * recomputes it on pan, zoom, or scene edits keeps the arrow on its target.\n * Takes precedence over `triggerRef`.\n */\n anchorRect?: { x: number; y: number; width: number; height: number };\n};\n\nconst toneClass: Record<CalloutTone, string> = {\n info: s.toneInfo,\n warning: s.toneWarning,\n danger: s.toneDanger,\n};\n\n/**\n * Anchored callout with an arrow pointing at its source — a trigger\n * element, an arbitrary `triggerRef`, or a client-space `anchorRect`.\n * Wraps React Aria Popover + Dialog; positioning, collision flipping,\n * dismissal, and focus behavior come from the underlying primitives.\n */\nexport function Callout(props: CalloutProps) {\n const {\n children,\n className,\n title,\n footer,\n tone = 'info',\n modal = false,\n showCloseButton,\n onDismiss,\n triggerRef,\n anchorRect,\n placement = 'top',\n offset = 12,\n maxHeight = 400,\n onOpenChange,\n shouldCloseOnInteractOutside,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...rest\n } = props;\n const anchorRef = useRef<HTMLSpanElement>(null);\n const showClose = showCloseButton ?? !modal;\n // Escape is a dismissal like the × is. It can't ride on a React `onKeyDown`:\n // RAC's Dialog runs its props through filterDOMProps, which drops handlers\n // it doesn't know, so the listener goes on the section itself. RAC's own\n // Escape handling is untouched — this only adds the signal.\n const onDismissRef = useRef(onDismiss);\n onDismissRef.current = onDismiss;\n const escapeListener = useRef((e: KeyboardEvent) => {\n if (e.key === 'Escape') onDismissRef.current?.();\n });\n const listeningTo = useRef<HTMLElement | null>(null);\n const dialogRef = useCallback((node: HTMLElement | null) => {\n listeningTo.current?.removeEventListener('keydown', escapeListener.current);\n listeningTo.current = node;\n node?.addEventListener('keydown', escapeListener.current);\n }, []);\n const titleId = useId();\n // RAC positions on open and recomputes on scroll, resize, and a\n // ResizeObserver on the anchor — none of which fire when `anchorRect` is\n // merely *translated*, as it is when a consumer tracks a scene node across a\n // pan. (Zoom happens to work, since scaling also changes the anchor's size.)\n // Nudging RAC's own resize listener is the supported way to make it\n // recompute; there's no public updatePosition on Popover.\n const hasAnchorRect = anchorRect !== undefined;\n useEffect(() => {\n if (!hasAnchorRect || typeof window === 'undefined') return;\n window.dispatchEvent(new Event('resize'));\n }, [hasAnchorRect, anchorRect?.x, anchorRect?.y, anchorRect?.width, anchorRect?.height]);\n // RAC's popover role-heuristic misses alertdialog; label the outer role\n // it stamps. Upstream: react-spectrum Popover.mjs querySelector('[role=dialog]').\n const popoverAriaLabelledby =\n modal && title !== undefined ? titleId : ariaLabelledby;\n const popoverAriaLabel = modal ? ariaLabel : undefined;\n return (\n <>\n {/* Harmless while closed — RAC reads the ref only when the popover is open. */}\n {anchorRect !== undefined &&\n createPortal(\n <span\n ref={anchorRef}\n data-callout-anchor=\"\"\n className={s.anchor}\n aria-hidden=\"true\"\n // Dynamic geometry — inline style is the mechanism here, not styling.\n style={{\n left: anchorRect.x,\n top: anchorRect.y,\n width: anchorRect.width,\n height: anchorRect.height,\n }}\n />,\n document.body,\n )}\n <RACPopover\n {...rest}\n triggerRef={anchorRect !== undefined ? anchorRef : triggerRef}\n isNonModal={!modal}\n placement={placement}\n offset={offset}\n maxHeight={maxHeight}\n onOpenChange={onOpenChange}\n shouldCloseOnInteractOutside={\n shouldCloseOnInteractOutside ?? (modal ? () => false : undefined)\n }\n aria-label={popoverAriaLabel}\n aria-labelledby={popoverAriaLabelledby}\n className={[s.popover, toneClass[tone], className].filter(Boolean).join(' ')}\n data-weasel-overlay=\"\"\n >\n <OverlayArrow className={s.arrow}>\n <svg width={12} height={12} viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n <path d=\"M0 0 L6 6 L12 0\" />\n </svg>\n </OverlayArrow>\n <RACDialog\n role={modal ? 'alertdialog' : 'dialog'}\n className={s.dialog}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n ref={dialogRef}\n >\n {({ close }) => (\n <>\n {(title !== undefined || showClose) && (\n <header className={s.header}>\n {title !== undefined && (\n <Heading id={titleId} slot=\"title\" className={s.title}>\n {title}\n </Heading>\n )}\n {showClose && (\n <button\n type=\"button\"\n className={s.close}\n onClick={() => {\n // `close()` resolves OverlayTriggerStateContext, only\n // provided by DialogTrigger (composed mode). In\n // triggerRef/anchorRect modes there is no such\n // context, so `close()` is a no-op there — the\n // controlled-open fallback below does the work.\n close();\n onOpenChange?.(false);\n onDismiss?.();\n }}\n aria-label=\"Close callout\"\n >\n ×\n </button>\n )}\n </header>\n )}\n <div className={s.body}>{children}</div>\n {footer !== undefined && <footer className={s.footer}>{footer}</footer>}\n </>\n )}\n </RACDialog>\n </RACPopover>\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;GCwEM,IAAyC;CAC7C,MAAM,EAAE;CACR,SAAS,EAAE;CACX,QAAQ,EAAE;CACX;AAQD,SAAgB,EAAQ,GAAqB;CAC3C,IAAM,EACJ,aACA,cACA,UACA,WACA,UAAO,QACP,WAAQ,IACR,oBACA,cACA,eACA,eACA,eAAY,OACZ,YAAS,IACT,eAAY,KACZ,iBACA,iCACA,cAAc,GACd,mBAAmB,GACnB,GAAG,MACD,GACE,IAAY,EAAwB,KAAK,EACzC,IAAY,KAAmB,CAAC,GAKhC,IAAe,EAAO,EAAU;AACtC,GAAa,UAAU;CACvB,IAAM,IAAiB,GAAQ,MAAqB;AAClD,EAAI,EAAE,QAAQ,YAAU,EAAa,WAAW;GAChD,EACI,IAAc,EAA2B,KAAK,EAC9C,IAAY,GAAa,MAA6B;AAG1D,EAFA,EAAY,SAAS,oBAAoB,WAAW,EAAe,QAAQ,EAC3E,EAAY,UAAU,GACtB,GAAM,iBAAiB,WAAW,EAAe,QAAQ;IACxD,EAAE,CAAC,EACA,IAAU,GAAO,EAOjB,IAAgB,MAAe,KAAA;AACrC,SAAgB;AACV,GAAC,KAAiB,OAAO,SAAW,OACxC,OAAO,cAAc,IAAI,MAAM,SAAS,CAAC;IACxC;EAAC;EAAe,GAAY;EAAG,GAAY;EAAG,GAAY;EAAO,GAAY;EAAO,CAAC;CAGxF,IAAM,IACJ,KAAS,MAAU,KAAA,IAAY,IAAU,GACrC,IAAmB,IAAQ,IAAY,KAAA;AAC7C,QACE,kBAAA,GAAA,EAAA,UAAA,CAEG,MAAe,KAAA,KACd,EACE,kBAAC,QAAD;EACE,KAAK;EACL,uBAAoB;EACpB,WAAW,EAAE;EACb,eAAY;EAEZ,OAAO;GACL,MAAM,EAAW;GACjB,KAAK,EAAW;GAChB,OAAO,EAAW;GAClB,QAAQ,EAAW;GACpB;EACD,CAAA,EACF,SAAS,KACV,EACH,kBAAC,GAAD;EACE,GAAI;EACJ,YAAY,MAAe,KAAA,IAAwB,IAAZ;EACvC,YAAY,CAAC;EACF;EACH;EACG;EACG;EACd,8BACE,MAAiC,UAAc,KAAQ,KAAA;EAEzD,cAAY;EACZ,mBAAiB;EACjB,WAAW;GAAC,EAAE;GAAS,EAAU;GAAO;GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EAC5E,uBAAoB;YAdtB,CAgBE,kBAAC,GAAD;GAAc,WAAW,EAAE;aACzB,kBAAC,OAAD;IAAK,OAAO;IAAI,QAAQ;IAAI,SAAQ;IAAY,eAAY;cAC1D,kBAAC,QAAD,EAAM,GAAE,mBAAoB,CAAA;IACxB,CAAA;GACO,CAAA,EACf,kBAAC,GAAD;GACE,MAAM,IAAQ,gBAAgB;GAC9B,WAAW,EAAE;GACb,cAAY;GACZ,mBAAiB;GACjB,KAAK;cAEH,EAAE,eACF,kBAAA,GAAA,EAAA,UAAA;KACI,MAAU,KAAA,KAAa,MACvB,kBAAC,UAAD;KAAQ,WAAW,EAAE;eAArB,CACG,MAAU,KAAA,KACT,kBAAC,GAAD;MAAS,IAAI;MAAS,MAAK;MAAQ,WAAW,EAAE;gBAC7C;MACO,CAAA,EAEX,KACC,kBAAC,UAAD;MACE,MAAK;MACL,WAAW,EAAE;MACb,eAAe;AAQb,OAFA,GAAO,EACP,IAAe,GAAM,EACrB,KAAa;;MAEf,cAAW;gBACZ;MAEQ,CAAA,CAEJ;;IAEX,kBAAC,OAAD;KAAK,WAAW,EAAE;KAAO;KAAe,CAAA;IACvC,MAAW,KAAA,KAAa,kBAAC,UAAD;KAAQ,WAAW,EAAE;eAAS;KAAgB,CAAA;IACtE,EAAA,CAAA;GAEK,CAAA,CACD;IACZ,EAAA,CAAA"}
@@ -1,89 +0,0 @@
1
- import { n as e } from "./Field-Bc6Nuc3p.js";
2
- import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
- import { Button as r, ComboBox as i, FieldError as a, Input as o, Label as s, ListBox as c, ListBoxItem as l, Popover as u, Text as d } from "react-aria-components";
4
- var f = {
5
- field: "_field_148rf_1",
6
- frame: "_frame_148rf_9",
7
- openButton: "_openButton_148rf_53",
8
- popover: "_popover_148rf_75",
9
- listbox: "_listbox_148rf_80",
10
- option: "_option_148rf_93",
11
- empty: "_empty_148rf_116"
12
- };
13
- //#endregion
14
- //#region src/components/ComboBox/ComboBox.tsx
15
- function p(l) {
16
- let { label: p, description: h, errorMessage: g, placeholder: _, options: v, children: y, selectedKey: b, defaultSelectedKey: x, onSelectionChange: S, emptyLabel: C = "No matches", className: w, ...T } = l;
17
- return /* @__PURE__ */ n(i, {
18
- ...T,
19
- selectedKey: b,
20
- defaultSelectedKey: x,
21
- onSelectionChange: S ? (e) => S(e) : void 0,
22
- className: [
23
- f.field,
24
- e.root,
25
- w
26
- ].filter(Boolean).join(" "),
27
- children: [
28
- p !== void 0 && /* @__PURE__ */ t(s, {
29
- className: e.label,
30
- children: p
31
- }),
32
- /* @__PURE__ */ n("div", {
33
- className: f.frame,
34
- children: [/* @__PURE__ */ t(o, { placeholder: _ }), /* @__PURE__ */ t(r, {
35
- className: f.openButton,
36
- "aria-label": "Show options",
37
- children: /* @__PURE__ */ t("svg", {
38
- viewBox: "0 0 10 10",
39
- "aria-hidden": "true",
40
- children: /* @__PURE__ */ t("path", {
41
- d: "M2 4 L5 7 L8 4",
42
- fill: "none",
43
- stroke: "currentColor",
44
- strokeWidth: "1.5",
45
- strokeLinecap: "round",
46
- strokeLinejoin: "round"
47
- })
48
- })
49
- })]
50
- }),
51
- h !== void 0 && /* @__PURE__ */ t(d, {
52
- slot: "description",
53
- className: e.hint,
54
- children: h
55
- }),
56
- /* @__PURE__ */ t(a, {
57
- className: e.error,
58
- children: g
59
- }),
60
- /* @__PURE__ */ t(u, {
61
- className: f.popover,
62
- "data-weasel-overlay": "",
63
- children: /* @__PURE__ */ t(c, {
64
- className: f.listbox,
65
- renderEmptyState: () => /* @__PURE__ */ t("div", {
66
- className: f.empty,
67
- children: C
68
- }),
69
- children: v === void 0 ? y : v.map((e) => /* @__PURE__ */ t(m, {
70
- id: e.value,
71
- textValue: e.textValue,
72
- isDisabled: e.isDisabled,
73
- children: e.label
74
- }, String(e.value)))
75
- })
76
- })
77
- ]
78
- });
79
- }
80
- function m({ className: e, ...n }) {
81
- return /* @__PURE__ */ t(l, {
82
- ...n,
83
- className: [f.option, e].filter(Boolean).join(" ")
84
- });
85
- }
86
- //#endregion
87
- export { m as n, p as t };
88
-
89
- //# sourceMappingURL=ComboBox-inno5gt1.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ComboBox-inno5gt1.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: 4px;\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.openButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\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: 4px;\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: 4px 8px;\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: 6px 8px;\n color: var(--wzl-fg-subtle);\n font-size: var(--wzl-font-size-sm);\n}\n","import type { ReactNode } from 'react';\nimport {\n ComboBox as RACComboBox,\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 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 * 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 className?: string;\n};\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 className,\n ...rest\n } = props;\n\n return (\n <RACComboBox\n {...rest}\n selectedKey={selectedKey}\n defaultSelectedKey={defaultSelectedKey}\n onSelectionChange={onSelectionChange ? (k) => onSelectionChange(k as T | null) : undefined}\n className={[s.field, fieldClasses.root, className].filter(Boolean).join(' ')}\n >\n {label !== undefined && <Label className={fieldClasses.label}>{label}</Label>}\n <div className={s.frame}>\n <RACInput placeholder={placeholder} />\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 {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=\"\">\n <RACListBox className={s.listbox} renderEmptyState={() => <div className={s.empty}>{emptyLabel}</div>}>\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/** 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":";;;;;;;;;;;;;;ACuDA,SAAgB,EAAiC,GAAyB;CACxE,IAAM,EACJ,UACA,gBACA,iBACA,gBACA,YACA,aACA,gBACA,uBACA,sBACA,gBAAa,cACb,cACA,GAAG,MACD;AAEJ,QACE,kBAAC,GAAD;EACE,GAAI;EACS;EACO;EACpB,mBAAmB,KAAqB,MAAM,EAAkB,EAAc,GAAG,KAAA;EACjF,WAAW;GAAC,EAAE;GAAO,EAAa;GAAM;GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;YAL9E;GAOG,MAAU,KAAA,KAAa,kBAAC,GAAD;IAAO,WAAW,EAAa;cAAQ;IAAc,CAAA;GAC7E,kBAAC,OAAD;IAAK,WAAW,EAAE;cAAlB,CACE,kBAAC,GAAD,EAAuB,gBAAe,CAAA,EACtC,kBAAC,GAAD;KAAW,WAAW,EAAE;KAAY,cAAW;eAC7C,kBAAC,OAAD;MAAK,SAAQ;MAAY,eAAY;gBACnC,kBAAC,QAAD;OAAM,GAAE;OAAiB,MAAK;OAAO,QAAO;OAAe,aAAY;OAAM,eAAc;OAAQ,gBAAe;OAAU,CAAA;MACxH,CAAA;KACI,CAAA,CACR;;GACL,MAAgB,KAAA,KACf,kBAAC,GAAD;IAAM,MAAK;IAAc,WAAW,EAAa;cAC9C;IACI,CAAA;GAET,kBAAC,GAAD;IAAY,WAAW,EAAa;cAAQ;IAA0B,CAAA;GACtE,kBAAC,GAAD;IAAY,WAAW,EAAE;IAAS,uBAAoB;cACpD,kBAAC,GAAD;KAAY,WAAW,EAAE;KAAS,wBAAwB,kBAAC,OAAD;MAAK,WAAW,EAAE;gBAAQ;MAAiB,CAAA;eAClG,MAAY,KAAA,IAMT,IALA,EAAQ,KAAK,MACX,kBAAC,GAAD;MAAoC,IAAI,EAAE;MAAO,WAAW,EAAE;MAAW,YAAY,EAAE;gBACpF,EAAE;MACU,EAFI,OAAO,EAAE,MAAM,CAEnB,CACf;KAEK,CAAA;IACF,CAAA;GACD;;;AAUlB,SAAgB,EAAa,EAAE,cAAW,GAAG,KAA2B;AACtE,QAAO,kBAAC,GAAD;EAAgB,GAAI;EAAM,WAAW,CAAC,EAAE,QAAQ,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EAAI,CAAA"}
@@ -1,59 +0,0 @@
1
- import { Fragment as e, jsx as t, jsxs as n } from "react/jsx-runtime";
2
- import { Dialog as r, Heading as i, Modal as a, ModalOverlay as o } from "react-aria-components";
3
- var s = {
4
- overlay: "_overlay_1og89_1",
5
- modal: "_modal_1og89_29",
6
- dialog: "_dialog_1og89_43",
7
- header: "_header_1og89_51",
8
- title: "_title_1og89_60",
9
- close: "_close_1og89_68",
10
- body: "_body_1og89_90",
11
- footer: "_footer_1og89_97"
12
- };
13
- //#endregion
14
- //#region src/components/Dialog/Dialog.tsx
15
- function c(c) {
16
- let { title: l, showCloseButton: u, children: d, footer: f, role: p = "dialog", className: m, isOpen: h, onOpenChange: g, ..._ } = c, v = u ?? !!g;
17
- return /* @__PURE__ */ t(o, {
18
- ..._,
19
- isOpen: h,
20
- onOpenChange: g,
21
- className: s.overlay,
22
- "data-weasel-overlay": "",
23
- children: /* @__PURE__ */ t(a, {
24
- className: [s.modal, m].filter(Boolean).join(" "),
25
- children: /* @__PURE__ */ t(r, {
26
- role: p,
27
- className: s.dialog,
28
- children: ({ close: r }) => /* @__PURE__ */ n(e, { children: [
29
- (l !== void 0 || v) && /* @__PURE__ */ n("header", {
30
- className: s.header,
31
- children: [l !== void 0 && /* @__PURE__ */ t(i, {
32
- slot: "title",
33
- className: s.title,
34
- children: l
35
- }), v && /* @__PURE__ */ t("button", {
36
- type: "button",
37
- className: s.close,
38
- onClick: r,
39
- "aria-label": "Close dialog",
40
- children: "×"
41
- })]
42
- }),
43
- /* @__PURE__ */ t("div", {
44
- className: s.body,
45
- children: d
46
- }),
47
- f !== void 0 && /* @__PURE__ */ t("footer", {
48
- className: s.footer,
49
- children: f
50
- })
51
- ] })
52
- })
53
- })
54
- });
55
- }
56
- //#endregion
57
- export { c as t };
58
-
59
- //# sourceMappingURL=Dialog-CX2B8PIp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Dialog-CX2B8PIp.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(--wzl-surface);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-md);\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.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: 12px;\n padding: 14px 16px;\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-size: var(--wzl-font-size);\n font-weight: var(--wzl-font-weight-bold);\n color: var(--wzl-fg);\n}\n\n.close {\n flex: 0 0 auto;\n width: 22px;\n height: 22px;\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 min-height: 0;\n overflow: auto;\n padding: 16px;\n}\n\n.footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 16px;\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 s from './Dialog.module.css';\n\n/** Props for {@link Dialog}, on top of React Aria's `ModalOverlay` props. */\nexport type DialogProps = Omit<ModalOverlayProps, 'children' | 'className'> & {\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};\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.\n */\nexport function Dialog(props: DialogProps) {\n const {\n title,\n showCloseButton,\n children,\n footer,\n role = 'dialog',\n className,\n isOpen,\n onOpenChange,\n ...rest\n } = props;\n\n const showClose = showCloseButton ?? Boolean(onOpenChange);\n\n return (\n <ModalOverlay {...rest} isOpen={isOpen} onOpenChange={onOpenChange} className={s.overlay} data-weasel-overlay=\"\">\n <RACModal className={[s.modal, className].filter(Boolean).join(' ')}>\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}>{children}</div>\n {footer !== undefined && <footer className={s.footer}>{footer}</footer>}\n </>\n )}\n </RACDialog>\n </RACModal>\n </ModalOverlay>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;ACsCA,SAAgB,EAAO,GAAoB;CACzC,IAAM,EACJ,UACA,oBACA,aACA,WACA,UAAO,UACP,cACA,WACA,iBACA,GAAG,MACD,GAEE,IAAY,KAAmB,EAAQ;AAE7C,QACE,kBAAC,GAAD;EAAc,GAAI;EAAc;EAAsB;EAAc,WAAW,EAAE;EAAS,uBAAoB;YAC5G,kBAAC,GAAD;GAAU,WAAW,CAAC,EAAE,OAAO,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;aACjE,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,EAAE;MAAO;MAAe,CAAA;KACvC,MAAW,KAAA,KAAa,kBAAC,UAAD;MAAQ,WAAW,EAAE;gBAAS;MAAgB,CAAA;KACtE,EAAA,CAAA;IAEK,CAAA;GACH,CAAA;EACE,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"LayerStack-BVdwhAhG.js","names":[],"sources":["../../src/components/LayerStack/LayerStack.module.css","../../src/components/LayerStack/LayerStack.tsx"],"sourcesContent":["/* Authored against labkit's `.lk-root`, which supplied a border-box reset and a\n set of bare-button defaults. weasel-ui has neither, so the stack restates\n both over its own subtree rather than depending on an ancestor class. */\n.stack,\n.stack * {\n box-sizing: border-box;\n}\n\n.stack {\n display: grid;\n gap: 8px;\n}\n\n.head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.title {\n margin: 0;\n font-family: var(--wzl-font-display);\n font-weight: var(--wzl-font-weight-light);\n font-size: var(--wzl-font-size-lg);\n color: var(--wzl-fg);\n}\n\n.palette {\n display: flex;\n gap: 4px;\n}\n\n.add {\n font: inherit;\n height: var(--wzl-control-h);\n background: transparent;\n border: 1px dashed var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n padding: 2px 8px;\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-subtle);\n cursor: pointer;\n}\n\n.add:hover {\n background: var(--wzl-surface-raised);\n color: var(--wzl-fg);\n}\n\n.list {\n display: grid;\n gap: 6px;\n}\n\n.dropHint {\n height: 2px;\n background: var(--wzl-accent);\n border-radius: var(--wzl-radius-sm);\n}\n\n.empty {\n color: var(--wzl-fg-subtle);\n font-size: var(--wzl-font-size);\n padding: 8px;\n text-align: center;\n}\n\n.card {\n background: var(--wzl-surface-raised);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-md);\n overflow: hidden;\n}\n\n.cardAccented {\n /* Re-bind --wzl-accent inside the card so descendant controls (slider tracks\n and thumbs, readouts, etc.) tint to the per-card accent instead of the\n global theme accent. Mirrors EffectCard's behavior. */\n --wzl-accent: var(--wzl-layer-stack-accent);\n border-left: 3px solid var(--wzl-layer-stack-accent);\n}\n\n.cardDragging {\n opacity: 0.5;\n}\n\n.cardHead {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 8px;\n}\n\n.handle {\n font: inherit;\n background: transparent;\n border: 0;\n color: var(--wzl-fg-subtle);\n padding: 2px 4px;\n cursor: grab;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n border-radius: var(--wzl-radius-sm);\n font-weight: var(--wzl-font-weight-bold);\n font-size: var(--wzl-font-size);\n}\n\n.cardAccented .handle {\n background: var(--wzl-layer-stack-accent);\n color: white;\n}\n\n.handle:active {\n cursor: grabbing;\n}\n\n.kind,\n.primary {\n flex: 1;\n font-size: var(--wzl-font-size);\n}\n\n.primary {\n background: transparent;\n border: 0;\n color: var(--wzl-fg);\n font: inherit;\n text-transform: uppercase;\n letter-spacing: var(--wzl-tracking-wide);\n}\n\n.remove {\n font: inherit;\n height: var(--wzl-control-h);\n background: transparent;\n border: 0;\n color: var(--wzl-fg-subtle);\n font-size: var(--wzl-font-size-lg);\n cursor: pointer;\n padding: 2px 6px;\n}\n\n.remove:hover {\n color: var(--wzl-fg);\n}\n\n.cardBody {\n padding: 8px;\n border-top: 1px solid var(--wzl-border);\n}\n","import { type CSSProperties, type ReactNode, type RefCallback, useEffect, useState } from 'react';\nimport { dlog } from '../../dlog';\nimport { useReorderDragList } from '../../useReorderDragList';\nimport { DragHandleGlyph } from '../DragHandleGlyph';\nimport s from './LayerStack.module.css';\n\n/** One card in a layer stack: its identity, the label shown when collapsed,\n * and the optional select hoisted into its header. */\nexport interface LayerStackItem {\n /** Stable id used for keys, onRemove, onReorder. Numeric to match\n * common id-from-nextId conventions; string ids also work. */\n id: number | string;\n /** Short kind label rendered in the header when no primary select\n * is hoisted (e.g. \"shadow\", \"stroke\"). */\n kind: string;\n /** When present, hoist this select into the card header so the user\n * can switch mode/shape without expanding. */\n primaryValue?: string;\n primaryOptions?: string[];\n /** Accent CSS color used as the left border / index-badge fill. Sets\n * --wzl-layer-stack-accent on the card, which re-binds --wzl-accent\n * for everything inside it. */\n accent?: string;\n /** Optional badge text rendered before the primary control\n * (e.g. tail index \"1\", \"2\", \"3\"). When omitted a drag handle\n * glyph renders in its place. */\n badge?: string;\n /** Initial expanded state. Defaults to true for newly-added items. */\n defaultExpanded?: boolean;\n}\n\n/** Props for `<LayerStack>`. */\nexport interface LayerStackProps {\n title: string;\n items: LayerStackItem[];\n /** Kinds the user can add via the header palette. */\n paletteKinds: string[];\n onAdd: (kind: string) => void;\n onRemove: (id: number | string) => void;\n onReorder: (orderedIds: Array<number | string>) => void;\n onPrimaryChange: (id: number | string, nextValue: string) => void;\n /** Render the body controls for each item. */\n renderBody: (item: LayerStackItem) => ReactNode;\n /** Hide the title + palette row (used when an outer wrap renders its\n * own head — see speech-balloons Tails panel). */\n hideHead?: boolean;\n /** Appended to the root element's class list. The module's own class names\n * are hashed, so this is the supported way to reach the stack from a\n * consumer stylesheet. */\n className?: string;\n}\n\n/** A drag-reorderable stack of expandable cards, with a palette in the header\n * for adding more. The body of each card is the caller's to render. */\nexport function LayerStack({\n className,\n title,\n items,\n paletteKinds,\n onAdd,\n onRemove,\n onReorder,\n onPrimaryChange,\n renderBody,\n hideHead,\n}: LayerStackProps) {\n const [expandedIds, setExpandedIds] = useState<Set<number | string>>(\n () => new Set(items.filter((i) => i.defaultExpanded !== false).map((i) => i.id)),\n );\n\n useEffect(() => {\n setExpandedIds((prev) => {\n let next: Set<number | string> | null = null;\n for (const item of items) {\n if (item.defaultExpanded === false) continue;\n if (prev.has(item.id)) continue;\n if (next === null) next = new Set(prev);\n next.add(item.id);\n }\n return next ?? prev;\n });\n }, [items]);\n\n const dragItems = items.map((it) => ({ id: String(it.id), label: it.kind }));\n const drag = useReorderDragList({\n items: dragItems,\n selectedIds: [],\n onReorder: (ids, targetIndex) => {\n dlog('layer-stack', 'onReorder', { ids, targetIndex });\n const orig = items.map((i) => i.id);\n const moving = new Set(ids);\n const remaining = orig.filter((id) => !moving.has(String(id)));\n const movedIds = items.map((i) => i.id).filter((id) => moving.has(String(id)));\n // weasel reports targetIndex against the original list (which includes\n // the dragged row). Each moved item that originally sat before\n // targetIndex needs to shift the insertion point left by one.\n const shift = orig.filter((id, idx) => moving.has(String(id)) && idx < targetIndex).length;\n const adjusted = targetIndex - shift;\n const out = [...remaining];\n out.splice(adjusted, 0, ...movedIds);\n onReorder(out);\n },\n });\n\n const toggleExpanded = (id: number | string) => {\n setExpandedIds((current) => {\n const n = new Set(current);\n if (n.has(id)) n.delete(id);\n else n.add(id);\n return n;\n });\n };\n\n return (\n <div className={className ? `${s.stack} ${className}` : s.stack}>\n {!hideHead && (\n <div className={s.head}>\n <h2 className={s.title}>{title}</h2>\n <div className={s.palette}>\n {paletteKinds.map((k) => (\n <button\n key={k}\n type=\"button\"\n className={s.add}\n onClick={() => {\n dlog('layer-stack', 'onAdd', { kind: k });\n onAdd(k);\n }}\n aria-label={`Add ${k}`}\n >\n {k}\n </button>\n ))}\n </div>\n </div>\n )}\n <div\n className={s.list}\n ref={drag.containerProps.ref as RefCallback<HTMLDivElement>}\n >\n {items.map((item, i) => {\n const expanded = expandedIds.has(item.id);\n const draggedId = drag.state.draggedIds?.[0];\n const isDragging = draggedId === String(item.id);\n const showHintBefore = drag.state.targetIndex === i && draggedId !== String(item.id);\n const showHintAfter = drag.state.targetIndex === items.length && i === items.length - 1;\n const cardCls = [\n s.card,\n isDragging ? s.cardDragging : '',\n item.accent ? s.cardAccented : '',\n ]\n .filter(Boolean)\n .join(' ');\n const cardStyle = item.accent\n ? ({ '--wzl-layer-stack-accent': item.accent } as CSSProperties)\n : undefined;\n const { onPointerDown } = drag.rowProps(String(item.id), i);\n return (\n <div key={item.id}>\n {showHintBefore && <div className={s.dropHint} />}\n <div className={cardCls} data-testid={`layer-card-${item.id}`} style={cardStyle}>\n <div className={s.cardHead}>\n <button\n type=\"button\"\n className={s.handle}\n aria-label={`Drag to reorder layer ${item.id}`}\n onPointerDown={onPointerDown}\n onClick={() => toggleExpanded(item.id)}\n >\n {item.badge ?? <DragHandleGlyph />}\n </button>\n {item.primaryValue !== undefined && item.primaryOptions ? (\n <select\n className={s.primary}\n value={item.primaryValue}\n aria-label={`Primary select for layer ${item.id}`}\n onChange={(e) => onPrimaryChange(item.id, e.target.value)}\n onClick={(e) => e.stopPropagation()}\n >\n {item.primaryOptions.map((o) => (\n <option key={o} value={o}>\n {o}\n </option>\n ))}\n </select>\n ) : (\n <span className={s.kind}>{item.kind}</span>\n )}\n <button\n type=\"button\"\n className={s.remove}\n aria-label=\"Remove layer\"\n onClick={(e) => {\n e.stopPropagation();\n onRemove(item.id);\n }}\n >\n ✕\n </button>\n </div>\n {expanded && <div className={s.cardBody}>{renderBody(item)}</div>}\n </div>\n {showHintAfter && <div className={s.dropHint} />}\n </div>\n );\n })}\n {items.length === 0 && (\n <div className={s.empty}>No layers — add one above.</div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"NumberField-Byw1iaIJ.js","names":[],"sources":["../../src/components/NumberField/NumberField.module.css","../../src/components/NumberField/NumberField.tsx"],"sourcesContent":[".field {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-width: 0;\n gap: 4px;\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 text-align: right;\n -moz-appearance: textfield;\n}\n\n.frame input::-webkit-outer-spin-button,\n.frame input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.steppers {\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--wzl-border);\n}\n\n.stepper {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n flex: 1;\n background: transparent;\n border: none;\n color: var(--wzl-fg-muted);\n cursor: pointer;\n padding: 0;\n font-size: var(--wzl-font-size-2xs);\n line-height: 1;\n}\n\n.stepper:not(:last-child) {\n border-bottom: 1px solid var(--wzl-border);\n}\n\n.stepper[data-hovered]:not([data-disabled]) {\n background: var(--wzl-surface-hover);\n color: var(--wzl-fg);\n}\n\n.stepper[data-pressed]:not([data-disabled]) {\n background: var(--wzl-surface-pressed);\n}\n\n.stepper[data-disabled] {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* Mirrors the property rows' editable readout (`.readoutInput`), so a number\n sitting inside other chrome does not draw a second box around itself. */\n.ghost {\n height: auto;\n background: transparent;\n border-color: transparent;\n color: var(--wzl-accent);\n font-weight: var(--wzl-font-weight-medium);\n}\n\n.ghost input {\n padding: 1px 0;\n}\n\n.ghost:hover {\n background: color-mix(in srgb, currentColor 8%, transparent);\n}\n\n.ghost:focus-within {\n background: var(--wzl-surface-sunken);\n border-color: var(--wzl-focus-ring);\n box-shadow: none;\n}\n","import { forwardRef, type ReactNode, type Ref } from 'react';\nimport {\n NumberField as RACNumberField,\n Label,\n Input as RACInput,\n Group,\n Button as RACButton,\n Text,\n FieldError,\n type NumberFieldProps as RACNumberFieldProps,\n type ValidationResult,\n} from 'react-aria-components';\nimport { fieldClasses } from '../Field/Field';\nimport s from './NumberField.module.css';\n\n/** Props for {@link NumberField}, on top of React Aria's `NumberField` props. */\nexport type NumberFieldProps = Omit<RACNumberFieldProps, 'children' | 'className'> & {\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);\n /** Hide the up/down stepper buttons. Defaults to false. */\n hideSteppers?: boolean;\n /** Render with no box until focused — the readout treatment the property\n * rows use, for a value that sits inside other chrome rather than in a form. */\n ghost?: boolean;\n /** Native input placeholder — e.g. `'Mixed'` for a multi-selection\n * editor with no shared value. */\n placeholder?: string;\n className?: string;\n};\n\n/**\n * Numeric input with stepper buttons, wrapping React Aria's NumberField and\n * supplying the same label / description / errorMessage slots as `Input`.\n * Arrow keys and scroll step the value; parsing and formatting are React\n * Aria's.\n *\n * `ref` forwards to the underlying `<input>`.\n */\nexport const NumberField = forwardRef(function NumberField(\n props: NumberFieldProps,\n ref: Ref<HTMLInputElement>,\n) {\n const { label, description, errorMessage, hideSteppers, ghost, placeholder, className, ...rest } =\n props;\n return (\n <RACNumberField\n {...rest}\n className={[s.field, fieldClasses.root, className].filter(Boolean).join(' ')}\n >\n {label !== undefined && <Label className={fieldClasses.label}>{label}</Label>}\n <Group className={ghost ? `${s.frame} ${s.ghost}` : s.frame}>\n <RACInput ref={ref} placeholder={placeholder} />\n {!hideSteppers && (\n <div className={s.steppers}>\n <RACButton slot=\"increment\" className={s.stepper} aria-label=\"Increment\">▲</RACButton>\n <RACButton slot=\"decrement\" className={s.stepper} aria-label=\"Decrement\">▼</RACButton>\n </div>\n )}\n </Group>\n {description !== undefined && (\n <Text slot=\"description\" className={fieldClasses.hint}>\n {description}\n </Text>\n )}\n <FieldError className={fieldClasses.error}>{errorMessage}</FieldError>\n </RACNumberField>\n );\n});\n"],"mappings":";;;;;;;;;;GCuCa,IAAc,EAAW,SACpC,GACA,GACA;CACA,IAAM,EAAE,UAAO,gBAAa,iBAAc,iBAAc,UAAO,gBAAa,cAAW,GAAG,MACxF;AACF,QACE,kBAAC,GAAD;EACE,GAAI;EACJ,WAAW;GAAC,EAAE;GAAO,EAAa;GAAM;GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;YAF9E;GAIG,MAAU,KAAA,KAAa,kBAAC,GAAD;IAAO,WAAW,EAAa;cAAQ;IAAc,CAAA;GAC7E,kBAAC,GAAD;IAAO,WAAW,IAAQ,GAAG,EAAE,MAAM,GAAG,EAAE,UAAU,EAAE;cAAtD,CACE,kBAAC,GAAD;KAAe;KAAkB;KAAe,CAAA,EAC/C,CAAC,KACA,kBAAC,OAAD;KAAK,WAAW,EAAE;eAAlB,CACE,kBAAC,GAAD;MAAW,MAAK;MAAY,WAAW,EAAE;MAAS,cAAW;gBAAY;MAAa,CAAA,EACtF,kBAAC,GAAD;MAAW,MAAK;MAAY,WAAW,EAAE;MAAS,cAAW;gBAAY;MAAa,CAAA,CAClF;OAEF;;GACP,MAAgB,KAAA,KACf,kBAAC,GAAD;IAAM,MAAK;IAAc,WAAW,EAAa;cAC9C;IACI,CAAA;GAET,kBAAC,GAAD;IAAY,WAAW,EAAa;cAAQ;IAA0B,CAAA;GACvD;;EAEnB"}
@@ -1,300 +0,0 @@
1
- import { n as e, t } from "./Tooltip-Bq8Hvj4r.js";
2
- import { t as n } from "./ColorField-pEkaSppg.js";
3
- import { t as r } from "./Checkbox-D_GCnoJ0.js";
4
- import { t as i } from "./Input-CSAECs_T.js";
5
- import { t as a } from "./NumberField-Byw1iaIJ.js";
6
- import { n as o, t as s } from "./RadioGroup-XjbfUb7S.js";
7
- import { t as c } from "./RangeSlider-D0hFbx_Z.js";
8
- import { t as l } from "./Select-D1uP21db.js";
9
- import { t as u } from "./Switch-B521iN3m.js";
10
- import { t as d } from "./Dialog-CX2B8PIp.js";
11
- import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
12
- import { isBuiltinToolPref as h } from "@weasel-js/core";
13
- import { useMemo as g } from "react";
14
- import { Focusable as _ } from "react-aria-components";
15
- //#region src/components/paintValue.ts
16
- function v(e) {
17
- if (typeof e != "object" || !e) return;
18
- let t = e;
19
- if (!(t.fill !== void 0 && t.fill !== "solid")) return typeof t.color == "string" ? t.color : void 0;
20
- }
21
- function y(e) {
22
- if (!(typeof e != "object" || !e || !("paint" in e))) return v(e.paint);
23
- }
24
- //#endregion
25
- //#region src/components/Prefs/schema.ts
26
- function b(e) {
27
- return "kind" in e;
28
- }
29
- function x(e, t) {
30
- let n = e;
31
- for (let e of t.split(".")) {
32
- if (typeof n != "object" || !n) return;
33
- n = n[e];
34
- }
35
- return n;
36
- }
37
- function S(e, t) {
38
- if (b(e)) return e.hidden && !t ? null : e;
39
- let n = e, r = {};
40
- for (let [e, i] of Object.entries(n.children)) {
41
- let n = S(i, t);
42
- n && (r[e] = n);
43
- }
44
- return Object.keys(r).length === 0 ? null : {
45
- ...e,
46
- children: r
47
- };
48
- }
49
- var C = {
50
- columns: "_columns_i4hcs_5",
51
- column: "_column_i4hcs_5",
52
- panel: "_panel_i4hcs_23",
53
- subpanel: "_subpanel_i4hcs_33",
54
- groupHeader: "_groupHeader_i4hcs_44",
55
- groupTitle: "_groupTitle_i4hcs_57",
56
- groupDesc: "_groupDesc_i4hcs_72",
57
- rows: "_rows_i4hcs_79",
58
- row: "_row_i4hcs_79",
59
- rowLabel: "_rowLabel_i4hcs_95",
60
- help: "_help_i4hcs_104",
61
- rowControl: "_rowControl_i4hcs_128",
62
- textarea: "_textarea_i4hcs_135",
63
- unrenderable: "_unrenderable_i4hcs_147",
64
- titleRow: "_titleRow_i4hcs_154",
65
- objectLeaf: "_objectLeaf_i4hcs_168",
66
- objectRow: "_objectRow_i4hcs_175",
67
- objectLabel: "_objectLabel_i4hcs_182",
68
- objectGroup: "_objectGroup_i4hcs_187"
69
- };
70
- //#endregion
71
- //#region src/components/Prefs/PrefsForm.tsx
72
- function w(e) {
73
- let { schema: t, values: n, onChange: r, renderers: i, showHidden: a = !1, className: o } = e, s = g(() => S(t, a), [t, a]), c = {
74
- values: n,
75
- onChange: r,
76
- renderers: i
77
- };
78
- return /* @__PURE__ */ p("div", {
79
- className: [C.columns, o].filter(Boolean).join(" "),
80
- children: Object.entries(s?.children ?? {}).map(([e, t]) => /* @__PURE__ */ p("div", {
81
- className: C.column,
82
- children: b(t) ? /* @__PURE__ */ p(E, {
83
- ctx: c,
84
- path: e,
85
- pref: t
86
- }) : /* @__PURE__ */ p(T, {
87
- ctx: c,
88
- group: t,
89
- path: e,
90
- depth: 0
91
- })
92
- }, e))
93
- });
94
- }
95
- function T({ ctx: e, group: t, path: n, depth: r }) {
96
- return /* @__PURE__ */ m("div", {
97
- className: r === 0 ? C.panel : C.subpanel,
98
- children: [/* @__PURE__ */ m("div", {
99
- className: C.groupHeader,
100
- children: [/* @__PURE__ */ p("h3", {
101
- className: C.groupTitle,
102
- children: t.name
103
- }), t.description !== void 0 && /* @__PURE__ */ p("p", {
104
- className: C.groupDesc,
105
- children: t.description
106
- })]
107
- }), /* @__PURE__ */ p("div", {
108
- className: C.rows,
109
- children: Object.entries(t.children).map(([t, i]) => {
110
- let a = `${n}.${t}`;
111
- return b(i) ? /* @__PURE__ */ p(E, {
112
- ctx: e,
113
- path: a,
114
- pref: i
115
- }, t) : /* @__PURE__ */ p(T, {
116
- ctx: e,
117
- group: i,
118
- path: a,
119
- depth: r + 1
120
- }, t);
121
- })
122
- })]
123
- });
124
- }
125
- function E({ ctx: n, path: r, pref: i }) {
126
- let a = x(n.values, r), o = {
127
- path: r,
128
- pref: i,
129
- value: a === void 0 ? i.default : a,
130
- setValue: (e) => n.onChange(r, e)
131
- }, s = n.renderers?.[i.kind], c = s ? s(o) : D(o);
132
- return s && c === null ? null : i.block ? /* @__PURE__ */ p(f, { children: c }) : /* @__PURE__ */ m("label", {
133
- className: C.row,
134
- children: [/* @__PURE__ */ m("span", {
135
- className: C.rowLabel,
136
- children: [i.name, i.description ? /* @__PURE__ */ m(e, { children: [/* @__PURE__ */ p(_, { children: /* @__PURE__ */ p("button", {
137
- type: "button",
138
- className: C.help,
139
- "aria-label": `About ${i.name}`,
140
- children: "ⓘ"
141
- }) }), /* @__PURE__ */ p(t, { children: i.description })] }) : null]
142
- }), /* @__PURE__ */ p("span", {
143
- className: C.rowControl,
144
- children: c
145
- })]
146
- });
147
- }
148
- function D(e, t) {
149
- let { pref: d, value: f, setValue: g } = e;
150
- if (!h(d)) return /* @__PURE__ */ m("span", {
151
- className: C.unrenderable,
152
- children: [
153
- "(",
154
- d.kind,
155
- ": no renderer)"
156
- ]
157
- });
158
- switch (d.kind) {
159
- case "boolean": {
160
- let e = !!f;
161
- return d.control === "switch" ? /* @__PURE__ */ p(u, {
162
- isSelected: e,
163
- onChange: g,
164
- "aria-label": d.name
165
- }) : /* @__PURE__ */ p(r, {
166
- isSelected: e,
167
- onChange: g,
168
- "aria-label": d.name
169
- });
170
- }
171
- case "number": {
172
- let e = typeof f == "number" && Number.isFinite(f) ? f : 0;
173
- return d.control === "slider" ? /* @__PURE__ */ p(c, {
174
- value: e,
175
- onChange: (e) => g(typeof e == "number" ? e : e[0]),
176
- minValue: d.min,
177
- maxValue: d.max,
178
- step: d.step ?? 1,
179
- "aria-label": d.name
180
- }) : /* @__PURE__ */ p(a, {
181
- value: e,
182
- onChange: g,
183
- minValue: d.min,
184
- maxValue: d.max,
185
- step: d.step ?? 1,
186
- "aria-label": d.name
187
- });
188
- }
189
- case "string": {
190
- let e = typeof f == "string" ? f : "";
191
- return d.control === "textarea" ? /* @__PURE__ */ p("textarea", {
192
- className: C.textarea,
193
- value: e,
194
- onChange: (e) => g(e.target.value),
195
- "aria-label": d.name,
196
- rows: 3
197
- }) : /* @__PURE__ */ p(i, {
198
- value: e,
199
- onChange: g,
200
- "aria-label": d.name
201
- });
202
- }
203
- case "enum": {
204
- let e = d.encoding, n = e ? e.read(f, t) : typeof f == "string" ? f : d.default, r = (n) => g(e ? e.write(n, t) : n);
205
- return d.control === "radio" ? /* @__PURE__ */ p(o, {
206
- value: n ?? null,
207
- onChange: r,
208
- "aria-label": d.name,
209
- children: d.options.map((e) => /* @__PURE__ */ p(s, {
210
- value: e.value,
211
- isDisabled: e.disabled,
212
- children: e.label
213
- }, e.value))
214
- }) : /* @__PURE__ */ p(l, {
215
- options: d.options.map((e) => ({
216
- value: e.value,
217
- label: e.label,
218
- isDisabled: e.disabled
219
- })),
220
- selectedKey: n ?? null,
221
- onSelectionChange: r,
222
- "aria-label": d.name
223
- });
224
- }
225
- case "color": return /* @__PURE__ */ p(n, {
226
- value: typeof f == "string" ? f : d.default,
227
- alpha: d.alpha,
228
- onChange: g,
229
- "aria-label": d.name
230
- });
231
- case "paint": return /* @__PURE__ */ p(n, {
232
- value: v(f) ?? v(d.default),
233
- alpha: d.alpha,
234
- onChange: (e) => g({
235
- fill: "solid",
236
- color: e
237
- }),
238
- "aria-label": d.name
239
- });
240
- case "object": {
241
- let t = d, n = typeof f == "object" && f ? f : void 0, r = (i) => {
242
- let a = [];
243
- for (let [o, s] of Object.entries(i)) {
244
- if (!b(s)) {
245
- let e = r(s.children);
246
- if (e.length === 0) continue;
247
- a.push(/* @__PURE__ */ p("h4", {
248
- className: C.objectGroup,
249
- children: s.name
250
- }, `group:${o}`), ...e);
251
- continue;
252
- }
253
- a.push(/* @__PURE__ */ m("label", {
254
- className: C.objectRow,
255
- children: [/* @__PURE__ */ p("span", {
256
- className: C.objectLabel,
257
- children: s.name
258
- }), D({
259
- path: `${e.path}.${o}`,
260
- pref: s,
261
- value: n?.[o],
262
- setValue: (e) => {
263
- g({
264
- ...n ?? t.fromScalar?.(f) ?? {},
265
- [o]: e
266
- });
267
- }
268
- }, n)]
269
- }, o));
270
- }
271
- return a;
272
- };
273
- return /* @__PURE__ */ p("div", {
274
- className: C.objectLeaf,
275
- children: r(t.children)
276
- });
277
- }
278
- default: throw Error(`PrefsForm: no control for built-in pref kind "${d.kind}"`);
279
- }
280
- }
281
- //#endregion
282
- //#region src/components/Prefs/PrefsDialog.tsx
283
- function O(e) {
284
- let { isOpen: t, onOpenChange: n, title: r, headerExtra: i, dialogClassName: a, ...o } = e;
285
- return /* @__PURE__ */ p(d, {
286
- isOpen: t,
287
- onOpenChange: n,
288
- "aria-label": typeof r == "string" ? r : o.schema.name,
289
- className: a,
290
- title: i === void 0 ? r ?? o.schema.name : /* @__PURE__ */ m("span", {
291
- className: C.titleRow,
292
- children: [/* @__PURE__ */ p("span", { children: r ?? o.schema.name }), i]
293
- }),
294
- children: /* @__PURE__ */ p(w, { ...o })
295
- });
296
- }
297
- //#endregion
298
- export { S as a, x as i, w as n, v as o, b as r, y as s, O as t };
299
-
300
- //# sourceMappingURL=Prefs-ByKG3ylD.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Prefs-ByKG3ylD.js","names":[],"sources":["../../src/components/paintValue.ts","../../src/components/Prefs/schema.ts","../../src/components/Prefs/Prefs.module.css","../../src/components/Prefs/PrefsForm.tsx","../../src/components/Prefs/PrefsDialog.tsx"],"sourcesContent":["// Reading and writing the paint objects a property control may be pointed at.\n//\n// `data.fill` is a `FillStyle` and `data.stroke` a `Stroke`, so a control that\n// assumes either is a hex string reads `undefined` off it and writes a bare\n// string back over it. These helpers are what keep a control honest about the\n// shape it is holding.\n\n/** The color of a solid paint, or `undefined` for anything else — including a\n * value that isn't a paint at all. `fill` is optional on the solid member of\n * the union, so the tag alone can't decide it. */\nexport function solidColorOf(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const paint = value as { fill?: string; color?: unknown };\n if (paint.fill !== undefined && paint.fill !== 'solid') return undefined;\n return typeof paint.color === 'string' ? paint.color : undefined;\n}\n\n/** The single color a stroke shows, or `undefined` when it has none to show —\n * a gradient or pattern stroke, or no stroke at all. */\nexport function strokeColorOf(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null || !('paint' in value)) return undefined;\n return solidColorOf((value as { paint: unknown }).paint);\n}\n","// Preference-schema vocabulary for PrefsForm / PrefsDialog / SelectionPanel:\n// core's `ToolPref*` family under this package's names. Never re-declare them\n// here — this was a hand-kept structural copy until it drifted, and the\n// independence from `@weasel-js/core` it bought is long gone anyway.\n\nexport type {\n ToolPref as BuiltinPref,\n ToolPrefBoolean as PrefBoolean,\n ToolPrefBooleanControl as PrefBooleanControl,\n ToolPrefColor as PrefColor,\n ToolPrefCustom as PrefCustom,\n ToolPrefEnum as PrefEnum,\n ToolPrefEnumControl as PrefEnumControl,\n ToolPrefEnumEncoding as PrefEnumEncoding,\n ToolPrefGroup as PrefGroup,\n ToolPrefKind as PrefKind,\n ToolPrefLeaf as PrefLeaf,\n ToolPrefNumber as PrefNumber,\n ToolPrefNumberControl as PrefNumberControl,\n ToolPrefNumberUnit as PrefNumberUnit,\n ToolPrefObject as PrefObject,\n ToolPrefPaint as PrefPaint,\n ToolPrefString as PrefString,\n ToolPrefStringControl as PrefStringControl,\n} from '@weasel-js/core';\n\nimport type { ToolPrefGroup, ToolPrefLeaf } from '@weasel-js/core';\n\n/** Distinguishes a leaf from a group while walking a schema tree. */\nexport function isPrefLeaf(node: ToolPrefLeaf | ToolPrefGroup): node is ToolPrefLeaf {\n return 'kind' in node;\n}\n\n/** Get the value at a dotted path inside a nested value tree. Returns\n * `undefined` when a segment is missing or hits a non-object. */\nexport function prefValueAtPath(values: unknown, path: string): unknown {\n let cur: unknown = values;\n for (const seg of path.split('.')) {\n if (cur == null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[seg];\n }\n return cur;\n}\n\n/**\n * Recursively drop `hidden` leaves (unless `showHidden`), pruning groups\n * that end up empty. Returns null when the entire subtree is hidden.\n */\nexport function visiblePrefSubtree<T extends ToolPrefLeaf | ToolPrefGroup>(\n node: T,\n showHidden: boolean,\n): T | null {\n if (isPrefLeaf(node)) return node.hidden && !showHidden ? null : node;\n const group = node as ToolPrefGroup;\n const children: Record<string, ToolPrefLeaf | ToolPrefGroup> = {};\n for (const [key, child] of Object.entries(group.children)) {\n const kept = visiblePrefSubtree(child, showHidden);\n if (kept) children[key] = kept;\n }\n if (Object.keys(children).length === 0) return null;\n return { ...node, children };\n}\n","/* Ported from WeaselDraw's wd-prefs-* rules (apps/draw/src/app.css),\n * generalized onto theme tokens. Column width is overridable via\n * --wzl-prefs-column-width at any ancestor scope. */\n\n.columns {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: 12px;\n overflow-y: auto;\n padding-right: 4px;\n}\n\n.column {\n flex: 0 0 var(--wzl-prefs-column-width, 300px);\n width: var(--wzl-prefs-column-width, 300px);\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.panel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n background: var(--wzl-surface-sunken);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n}\n\n.subpanel {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 6px;\n padding: 8px 8px 8px 10px;\n background: var(--wzl-surface-sunken);\n border-left: 2px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n}\n\n.groupHeader {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding-bottom: 4px;\n border-bottom: 1px solid var(--wzl-border);\n}\n\n.subpanel .groupHeader {\n border-bottom: none;\n padding-bottom: 2px;\n}\n\n.groupTitle {\n margin: 0;\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-font-weight-bold);\n color: var(--wzl-fg);\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n.subpanel .groupTitle {\n font-size: var(--wzl-font-size-sm);\n text-transform: none;\n letter-spacing: 0;\n}\n\n.groupDesc {\n margin: 0;\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-subtle);\n line-height: 1.35;\n}\n\n.rows {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg);\n cursor: default;\n}\n\n.rowLabel {\n flex: 1 1 auto;\n min-width: 0;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n/* Description affordance — quiet until hovered/focused. */\n.help {\n flex: 0 0 auto;\n padding: 0;\n border: none;\n background: none;\n color: var(--wzl-fg-subtle);\n font-size: var(--wzl-font-size-sm);\n line-height: 1;\n cursor: help;\n border-radius: var(--wzl-radius-sm);\n}\n\n.help:hover {\n color: var(--wzl-fg);\n}\n\n.help:focus-visible {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: 1px;\n color: var(--wzl-fg);\n}\n\n/* Control slot — fixed width so the label can take the rest of the row.\n * Kit form controls render as block-level flex columns that fill it. */\n.rowControl {\n flex: 0 0 110px;\n min-width: 0;\n display: flex;\n align-items: center;\n}\n\n.textarea {\n width: 100%;\n padding: 4px 8px;\n background: var(--wzl-surface-sunken);\n color: var(--wzl-fg);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n font: inherit;\n font-size: var(--wzl-font-size-sm);\n resize: vertical;\n}\n\n.unrenderable {\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-subtle);\n}\n\n/* PrefsDialog header row: title text + optional headerExtra chrome. */\n.titleRow {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.titleRow > span:first-child {\n flex: 1;\n min-width: 0;\n}\n\n/* An object leaf renders its fields as its own rows. */\n.objectLeaf {\n display: flex;\n flex-direction: column;\n gap: 6px;\n inline-size: 100%;\n}\n\n.objectRow {\n display: grid;\n grid-template-columns: 96px 1fr;\n gap: 8px;\n align-items: center;\n}\n\n.objectLabel {\n font-size: var(--wzl-font-size-sm);\n opacity: 0.75;\n}\n\n.objectGroup {\n margin: 4px 0 0;\n font-size: var(--wzl-font-size-xs);\n font-weight: var(--wzl-font-weight-bold);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n opacity: 0.55;\n}\n","import { useMemo, type ReactNode } from 'react';\nimport { Focusable } from 'react-aria-components';\nimport { Checkbox } from '../Checkbox';\nimport { ColorField } from '../ColorField';\nimport { solidColorOf } from '../paintValue';\nimport { Input } from '../Input';\nimport { NumberField } from '../NumberField';\nimport { RadioGroup, Radio } from '../RadioGroup';\nimport { RangeSlider } from '../RangeSlider';\nimport { Select } from '../Select';\nimport { Switch } from '../Switch';\nimport { Tooltip, TooltipTrigger } from '../Tooltip';\nimport { isBuiltinToolPref } from '@weasel-js/core';\nimport {\n isPrefLeaf,\n prefValueAtPath,\n visiblePrefSubtree,\n type PrefGroup,\n type PrefLeaf,\n} from './schema';\nimport s from './Prefs.module.css';\n\n/** What a {@link PrefRenderer} is given for the leaf it is rendering. */\nexport interface PrefRenderContext {\n /** Dotted path of the leaf within the schema root. */\n path: string;\n /** The schema node. App renderers narrow this to their own kind shape. */\n pref: PrefLeaf;\n /** Current value — `values` at `path`, falling back to `pref.default`. */\n value: unknown;\n setValue: (value: unknown) => void;\n}\n\n/**\n * Renders the control cell for one preference leaf. Returning `null`\n * collapses the row.\n */\nexport type PrefRenderer = (ctx: PrefRenderContext) => ReactNode;\n\n/** Props for {@link PrefsForm}. */\nexport interface PrefsFormProps {\n /** Root of the schema tree. Core `ToolPrefGroup`s assign structurally. */\n schema: PrefGroup;\n /** Nested value tree (shape mirrors the schema). Sparse is fine —\n * missing leaves fall back to their schema `default`. */\n values?: unknown;\n /** Change callback with the leaf's dotted path. Values apply live;\n * there is no dirty/commit state. */\n onChange: (path: string, value: unknown) => void;\n /**\n * Per-kind renderers for app-defined kinds. Entries also override the\n * built-in kinds when keys collide. A renderer owns the control cell\n * (the label/tooltip row chrome stays with the form, unless the leaf\n * sets `block`); returning `null` collapses the row entirely. Unknown\n * kinds with no renderer show a labeled placeholder instead of\n * crashing.\n */\n renderers?: Record<string, PrefRenderer>;\n /** Reveal `hidden` leaves (dev tooling). Default false. */\n showHidden?: boolean;\n className?: string;\n}\n\n/**\n * Schema-driven preferences form. Top-level groups render as columns,\n * nested groups as indented sub-panels, leaves as label + control rows.\n * Storage-agnostic: pair with `PrefsDialog` for the modal composition,\n * and persist however the app likes via `onChange`.\n */\nexport function PrefsForm(props: PrefsFormProps) {\n const { schema, values, onChange, renderers, showHidden = false, className } = props;\n const visibleRoot = useMemo(\n () => visiblePrefSubtree(schema, showHidden),\n [schema, showHidden],\n );\n const ctx: WalkCtx = { values, onChange, renderers };\n return (\n <div className={[s.columns, className].filter(Boolean).join(' ')}>\n {Object.entries(visibleRoot?.children ?? {}).map(([key, child]) => (\n <div key={key} className={s.column}>\n {isPrefLeaf(child) ? (\n // Top-level leaves are unusual but legal — give each its own\n // column for symmetry with grouped siblings.\n <PrefRow ctx={ctx} path={key} pref={child} />\n ) : (\n <GroupBody ctx={ctx} group={child} path={key} depth={0} />\n )}\n </div>\n ))}\n </div>\n );\n}\n\ninterface WalkCtx {\n values: unknown;\n onChange: (path: string, value: unknown) => void;\n renderers?: Record<string, PrefRenderer>;\n}\n\nfunction GroupBody({ ctx, group, path, depth }: {\n ctx: WalkCtx;\n group: PrefGroup;\n path: string;\n depth: number;\n}) {\n return (\n <div className={depth === 0 ? s.panel : s.subpanel}>\n <div className={s.groupHeader}>\n <h3 className={s.groupTitle}>{group.name}</h3>\n {group.description !== undefined && (\n <p className={s.groupDesc}>{group.description}</p>\n )}\n </div>\n <div className={s.rows}>\n {Object.entries(group.children).map(([key, child]) => {\n const childPath = `${path}.${key}`;\n return isPrefLeaf(child) ? (\n <PrefRow key={key} ctx={ctx} path={childPath} pref={child} />\n ) : (\n <GroupBody key={key} ctx={ctx} group={child} path={childPath} depth={depth + 1} />\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction PrefRow({ ctx, path, pref }: { ctx: WalkCtx; path: string; pref: PrefLeaf }) {\n const stored = prefValueAtPath(ctx.values, path);\n const renderCtx: PrefRenderContext = {\n path,\n pref,\n value: stored !== undefined ? stored : pref.default,\n setValue: (v) => ctx.onChange(path, v),\n };\n\n const custom = ctx.renderers?.[pref.kind];\n const control = custom ? custom(renderCtx) : renderBuiltin(renderCtx);\n if (custom && control === null) return null;\n\n // `block` leaves own their chrome (embedded editors with their own\n // header) — no label/tooltip row.\n if (pref.block) return <>{control}</>;\n\n return (\n <label className={s.row}>\n <span className={s.rowLabel}>\n {pref.name}\n {pref.description ? (\n // Help affordance carries the description tooltip. A tooltip\n // trigger must be interactive (keyboard-reachable), so this is\n // a real button — a bare label span would be neither focusable\n // nor announced.\n <TooltipTrigger>\n <Focusable>\n <button type=\"button\" className={s.help} aria-label={`About ${pref.name}`}>\n ⓘ\n </button>\n </Focusable>\n <Tooltip>{pref.description}</Tooltip>\n </TooltipTrigger>\n ) : null}\n </span>\n <span className={s.rowControl}>{control}</span>\n </label>\n );\n}\n\nfunction renderBuiltin(\n ctx: PrefRenderContext,\n // The object a nested leaf is a field of — what an enum `encoding` reads\n // and writes against. Undefined for a top-level leaf, which has none.\n siblings?: Record<string, unknown>,\n): ReactNode {\n const { pref, value, setValue } = ctx;\n if (!isBuiltinToolPref(pref)) {\n // App-defined kind with no `renderers` entry: labeled placeholder, not a\n // crash — a missing wiring should be visible and recoverable.\n return <span className={s.unrenderable}>({pref.kind}: no renderer)</span>;\n }\n switch (pref.kind) {\n case 'boolean': {\n const checked = Boolean(value);\n return pref.control === 'switch' ? (\n <Switch isSelected={checked} onChange={setValue} aria-label={pref.name} />\n ) : (\n <Checkbox isSelected={checked} onChange={setValue} aria-label={pref.name} />\n );\n }\n case 'number': {\n const n = typeof value === 'number' && Number.isFinite(value) ? value : 0;\n if (pref.control === 'slider') {\n return (\n <RangeSlider\n value={n}\n onChange={(v) => setValue(typeof v === 'number' ? v : v[0])}\n minValue={pref.min}\n maxValue={pref.max}\n step={pref.step ?? 1}\n aria-label={pref.name}\n />\n );\n }\n return (\n <NumberField\n value={n}\n onChange={setValue}\n minValue={pref.min}\n maxValue={pref.max}\n step={pref.step ?? 1}\n aria-label={pref.name}\n />\n );\n }\n case 'string': {\n const text = typeof value === 'string' ? value : '';\n if (pref.control === 'textarea') {\n return (\n <textarea\n className={s.textarea}\n value={text}\n onChange={(e) => setValue(e.target.value)}\n aria-label={pref.name}\n rows={3}\n />\n );\n }\n return <Input value={text} onChange={setValue} aria-label={pref.name} />;\n }\n case 'enum': {\n const encoding = pref.encoding;\n // An encoded leaf stores something other than the option string (a dash\n // array), so reading the raw value selects nothing and writing one\n // replaces the stored form with the option string.\n const option = encoding\n ? encoding.read(value, siblings)\n : typeof value === 'string'\n ? value\n : pref.default;\n const choose = (next: string): void =>\n setValue(encoding ? encoding.write(next, siblings) : next);\n if (pref.control === 'radio') {\n return (\n <RadioGroup value={option ?? null} onChange={choose} aria-label={pref.name}>\n {pref.options.map((o) => (\n <Radio key={o.value} value={o.value} isDisabled={o.disabled}>\n {o.label}\n </Radio>\n ))}\n </RadioGroup>\n );\n }\n return (\n <Select<string>\n options={pref.options.map((o) => ({\n value: o.value,\n label: o.label,\n isDisabled: o.disabled,\n }))}\n selectedKey={option ?? null}\n onSelectionChange={choose}\n aria-label={pref.name}\n />\n );\n }\n case 'color': {\n const hex = typeof value === 'string' ? value : pref.default;\n return (\n <ColorField\n value={hex}\n alpha={pref.alpha}\n onChange={setValue}\n aria-label={pref.name}\n />\n );\n }\n case 'paint': {\n // A whole `FillStyle`. A gradient or pattern has no single color to\n // show, so the field goes blank rather than claiming one, and an edit\n // writes a whole solid union member rather than grafting a `color` key\n // onto the gradient.\n const solid = solidColorOf(value) ?? solidColorOf(pref.default);\n return (\n <ColorField\n value={solid}\n alpha={pref.alpha}\n onChange={(color) => setValue({ fill: 'solid', color })}\n aria-label={pref.name}\n />\n );\n }\n case 'object': {\n // One value with its fields hanging off it: each child renders its own\n // control and commits the parent object whole.\n const p = pref;\n const held = typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n const objectRows = (children: Record<string, PrefLeaf | PrefGroup>): ReactNode[] => {\n const out: ReactNode[] = [];\n for (const [key, child] of Object.entries(children)) {\n if (!isPrefLeaf(child)) {\n const inner = objectRows(child.children);\n if (inner.length === 0) continue;\n out.push(<h4 key={`group:${key}`} className={s.objectGroup}>{child.name}</h4>, ...inner);\n continue;\n }\n out.push(\n <label key={key} className={s.objectRow}>\n <span className={s.objectLabel}>{child.name}</span>\n {renderBuiltin({\n path: `${ctx.path}.${key}`,\n pref: child,\n value: held?.[key],\n setValue: (v) => {\n const base = held ?? p.fromScalar?.(value) ?? {};\n setValue({ ...base, [key]: v });\n },\n }, held)}\n </label>,\n );\n }\n return out;\n };\n return <div className={s.objectLeaf}>{objectRows(p.children)}</div>;\n }\n default: {\n // Not reachable while every built-in kind has an arm — and a new kind\n // that lacks one is a compile error here, never a blank row.\n const _exhaustive: never = pref;\n throw new Error(\n `PrefsForm: no control for built-in pref kind \"${(_exhaustive as { kind: string }).kind}\"`,\n );\n }\n }\n}\n","import type { ReactNode } from 'react';\nimport { Dialog } from '../Dialog';\nimport { PrefsForm, type PrefsFormProps } from './PrefsForm';\nimport s from './Prefs.module.css';\n\n/**\n * Props for {@link PrefsDialog} — everything {@link PrefsForm} takes, plus\n * the dialog's own open state and chrome.\n */\nexport interface PrefsDialogProps extends PrefsFormProps {\n isOpen: boolean;\n onOpenChange: (open: boolean) => void;\n /** Dialog heading. Defaults to the schema root's `name`. */\n title?: ReactNode;\n /** Extra chrome rendered inline with the title (e.g. a dev-mode\n * \"Show hidden\" switch). */\n headerExtra?: ReactNode;\n /** Class applied to the dialog's modal box. */\n dialogClassName?: string;\n}\n\n/**\n * The kit's preferences dialog: `Dialog` + `PrefsForm`. Changes apply\n * live through `onChange` — there is no OK/Cancel staging. For custom\n * placement (sidebar, popover, inline page), compose `PrefsForm`\n * directly; this wrapper is intentionally thin.\n */\nexport function PrefsDialog(props: PrefsDialogProps) {\n const { isOpen, onOpenChange, title, headerExtra, dialogClassName, ...form } = props;\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n aria-label={typeof title === 'string' ? title : form.schema.name}\n className={dialogClassName}\n title={\n headerExtra !== undefined ? (\n <span className={s.titleRow}>\n <span>{title ?? form.schema.name}</span>\n {headerExtra}\n </span>\n ) : (\n title ?? form.schema.name\n )\n }\n >\n <PrefsForm {...form} />\n </Dialog>\n );\n}\n"],"mappings":"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"}