@weasel-js/ui 0.5.1 → 0.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 (127) hide show
  1. package/dist/chunks/ActionBar-CiKvEvXi.js +63 -0
  2. package/dist/chunks/ActionBar-CiKvEvXi.js.map +1 -0
  3. package/dist/chunks/ActionsBar-CzU6Of3B.js +94 -0
  4. package/dist/chunks/ActionsBar-CzU6Of3B.js.map +1 -0
  5. package/dist/chunks/Badge-DU8ihE7Z.js +2942 -0
  6. package/dist/chunks/Badge-DU8ihE7Z.js.map +1 -0
  7. package/dist/chunks/Button-9QNIYugK.js +87 -0
  8. package/dist/chunks/Button-9QNIYugK.js.map +1 -0
  9. package/dist/chunks/Callout-Dt0kBIls.js +114 -0
  10. package/dist/chunks/Callout-Dt0kBIls.js.map +1 -0
  11. package/dist/chunks/Checkbox-CtK8H_OQ.js +47 -0
  12. package/dist/chunks/Checkbox-CtK8H_OQ.js.map +1 -0
  13. package/dist/chunks/ColorField-sGLnThpB.js +60 -0
  14. package/dist/chunks/ColorField-sGLnThpB.js.map +1 -0
  15. package/dist/chunks/ComboBox-pH8aDEL2.js +88 -0
  16. package/dist/chunks/ComboBox-pH8aDEL2.js.map +1 -0
  17. package/dist/chunks/CurveEditor-DrORWShU.js +786 -0
  18. package/dist/chunks/CurveEditor-DrORWShU.js.map +1 -0
  19. package/dist/chunks/DataGrid-mUq38k0Q.js +186 -0
  20. package/dist/chunks/DataGrid-mUq38k0Q.js.map +1 -0
  21. package/dist/chunks/Dialog-CQymDCAl.js +58 -0
  22. package/dist/chunks/Dialog-CQymDCAl.js.map +1 -0
  23. package/dist/chunks/Field-BHSu2F3E.js +31 -0
  24. package/dist/chunks/Field-BHSu2F3E.js.map +1 -0
  25. package/dist/chunks/Input-D_Xzgr2b.js +55 -0
  26. package/dist/chunks/Input-D_Xzgr2b.js.map +1 -0
  27. package/dist/chunks/Keycaps-B9dJMYx_.js +397 -0
  28. package/dist/chunks/Keycaps-B9dJMYx_.js.map +1 -0
  29. package/dist/chunks/NumberField-BQmELz32.js +59 -0
  30. package/dist/chunks/NumberField-BQmELz32.js.map +1 -0
  31. package/dist/chunks/OptionsBar-CHOP_CiW.js +98 -0
  32. package/dist/chunks/OptionsBar-CHOP_CiW.js.map +1 -0
  33. package/dist/chunks/Plot2D-CEnhzodm.js +168 -0
  34. package/dist/chunks/Plot2D-CEnhzodm.js.map +1 -0
  35. package/dist/chunks/PointPlotter-D528sBdT.js +16 -0
  36. package/dist/chunks/PointPlotter-D528sBdT.js.map +1 -0
  37. package/dist/chunks/Powerline-C8rddbbK.js +36 -0
  38. package/dist/chunks/Powerline-C8rddbbK.js.map +1 -0
  39. package/dist/chunks/Prefs-snBejOzK.js +238 -0
  40. package/dist/chunks/Prefs-snBejOzK.js.map +1 -0
  41. package/dist/chunks/RadioGroup-Ci-I9NEx.js +49 -0
  42. package/dist/chunks/RadioGroup-Ci-I9NEx.js.map +1 -0
  43. package/dist/chunks/RangeSlider-CW-edtNx.js +52 -0
  44. package/dist/chunks/RangeSlider-CW-edtNx.js.map +1 -0
  45. package/dist/chunks/Select-l7pAkVEG.js +97 -0
  46. package/dist/chunks/Select-l7pAkVEG.js.map +1 -0
  47. package/dist/chunks/SelectionPanel-CMglTgEf.js +303 -0
  48. package/dist/chunks/SelectionPanel-CMglTgEf.js.map +1 -0
  49. package/dist/chunks/Sidebar-BFcBx8QV.js +26 -0
  50. package/dist/chunks/Sidebar-BFcBx8QV.js.map +1 -0
  51. package/dist/chunks/SidebarPanel-CRnSlvee.js +59 -0
  52. package/dist/chunks/SidebarPanel-CRnSlvee.js.map +1 -0
  53. package/dist/chunks/Slider-sUJGgmKR.js +221 -0
  54. package/dist/chunks/Slider-sUJGgmKR.js.map +1 -0
  55. package/dist/chunks/Switch-DxJLMYki.js +27 -0
  56. package/dist/chunks/Switch-DxJLMYki.js.map +1 -0
  57. package/dist/chunks/Tabs-DelDecks.js +41 -0
  58. package/dist/chunks/Tabs-DelDecks.js.map +1 -0
  59. package/dist/chunks/Toast-Bw3XQxmV.js +128 -0
  60. package/dist/chunks/Toast-Bw3XQxmV.js.map +1 -0
  61. package/dist/chunks/ToggleBar-Defj6Asn.js +129 -0
  62. package/dist/chunks/ToggleBar-Defj6Asn.js.map +1 -0
  63. package/dist/chunks/ToolButton-Dk_uJf7N.js +53 -0
  64. package/dist/chunks/ToolButton-Dk_uJf7N.js.map +1 -0
  65. package/dist/chunks/ToolGroup-D8-qdtuw.js +25 -0
  66. package/dist/chunks/ToolGroup-D8-qdtuw.js.map +1 -0
  67. package/dist/chunks/ToolOptionsBar-ChiL-HVA.js +27 -0
  68. package/dist/chunks/ToolOptionsBar-ChiL-HVA.js.map +1 -0
  69. package/dist/chunks/ToolPalette-xKHzPKYf.js +117 -0
  70. package/dist/chunks/ToolPalette-xKHzPKYf.js.map +1 -0
  71. package/dist/chunks/Tooltip-Clgn4trm.js +39 -0
  72. package/dist/chunks/Tooltip-Clgn4trm.js.map +1 -0
  73. package/dist/chunks/keyGlyph-BDH5fqkO.js +22 -0
  74. package/dist/chunks/keyGlyph-BDH5fqkO.js.map +1 -0
  75. package/dist/components/ActionBar/index.js +2 -0
  76. package/dist/components/ActionsBar/index.js +2 -0
  77. package/dist/components/Badge/index.js +2 -0
  78. package/dist/components/Button/index.js +2 -0
  79. package/dist/components/Callout/index.js +2 -0
  80. package/dist/components/Checkbox/index.js +2 -0
  81. package/dist/components/ColorField/index.js +2 -0
  82. package/dist/components/ComboBox/index.js +2 -0
  83. package/dist/components/CurveEditor/index.js +2 -0
  84. package/dist/components/DataGrid/index.js +2 -0
  85. package/dist/components/Dialog/index.js +2 -0
  86. package/dist/components/Field/index.js +2 -0
  87. package/dist/components/Input/index.js +2 -0
  88. package/dist/components/Keycaps/index.js +3 -0
  89. package/dist/components/NumberField/index.js +2 -0
  90. package/dist/components/OptionsBar/index.js +2 -0
  91. package/dist/components/Plot2D/index.js +2 -0
  92. package/dist/components/PointPlotter/index.js +2 -0
  93. package/dist/components/Powerline/index.js +3 -0
  94. package/dist/components/Prefs/index.js +2 -0
  95. package/dist/components/RadioGroup/index.js +2 -0
  96. package/dist/components/RangeSlider/index.js +2 -0
  97. package/dist/components/Select/index.js +2 -0
  98. package/dist/components/SelectionPanel/SelectionPanel.d.ts.map +1 -1
  99. package/dist/components/SelectionPanel/index.d.ts +1 -1
  100. package/dist/components/SelectionPanel/index.d.ts.map +1 -1
  101. package/dist/components/SelectionPanel/index.js +2 -0
  102. package/dist/components/SelectionPanel/model.d.ts +13 -11
  103. package/dist/components/SelectionPanel/model.d.ts.map +1 -1
  104. package/dist/components/Sidebar/index.js +2 -0
  105. package/dist/components/SidebarPanel/index.js +2 -0
  106. package/dist/components/Slider/index.js +2 -0
  107. package/dist/components/Switch/index.js +2 -0
  108. package/dist/components/Tabs/index.js +2 -0
  109. package/dist/components/Toast/index.js +2 -0
  110. package/dist/components/ToggleBar/ToggleBar.d.ts +17 -0
  111. package/dist/components/ToggleBar/ToggleBar.d.ts.map +1 -1
  112. package/dist/components/ToggleBar/index.js +2 -0
  113. package/dist/components/ToolButton/index.js +2 -0
  114. package/dist/components/ToolGroup/index.js +2 -0
  115. package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts +44 -0
  116. package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts.map +1 -0
  117. package/dist/components/ToolOptionsBar/index.d.ts +3 -0
  118. package/dist/components/ToolOptionsBar/index.d.ts.map +1 -0
  119. package/dist/components/ToolOptionsBar/index.js +2 -0
  120. package/dist/components/ToolPalette/index.js +2 -0
  121. package/dist/components/Tooltip/index.js +2 -0
  122. package/dist/index.d.ts +1 -0
  123. package/dist/index.d.ts.map +1 -1
  124. package/dist/index.js +50 -6749
  125. package/dist/index.js.map +1 -1
  126. package/dist/style.css +1 -1
  127. package/package.json +8 -4
@@ -0,0 +1,397 @@
1
+ import { Fragment as e } from "react";
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ var r = {
4
+ keys: "_keys_1ve0i_2",
5
+ keysEmpty: "_keysEmpty_1ve0i_16",
6
+ sep: "_sep_1ve0i_20",
7
+ key: "_key_1ve0i_2"
8
+ }, i = new Set([
9
+ "⌘",
10
+ "⇪",
11
+ "⌥",
12
+ "⌃",
13
+ "⇧"
14
+ ]), a = new Set([
15
+ "⇥",
16
+ "↵",
17
+ "␣"
18
+ ]);
19
+ function o(e) {
20
+ return i.has(e) ? "modifier" : a.has(e) || e.length > 1 ? "wide" : "square";
21
+ }
22
+ function s({ label: e, inverted: n = !1, variant: i = "default", className: a, style: s, font: c }) {
23
+ let l = c ? {
24
+ ...s,
25
+ fontFamily: c
26
+ } : s;
27
+ return /* @__PURE__ */ t("kbd", {
28
+ className: [r.key, a].filter(Boolean).join(" "),
29
+ "data-kind": o(e),
30
+ "data-variant": i === "default" ? void 0 : i,
31
+ "data-inverted": n || void 0,
32
+ style: l,
33
+ children: e
34
+ });
35
+ }
36
+ //#endregion
37
+ //#region src/components/Keycaps/Keycaps.tsx
38
+ function c({ keys: i, separator: a = "+", variant: c = "default", font: l, className: u }) {
39
+ if (!i || i.length === 0) return /* @__PURE__ */ t("span", {
40
+ className: [r.keysEmpty, u].filter(Boolean).join(" "),
41
+ children: "—"
42
+ });
43
+ let d = i.map((e, t) => ({
44
+ k: e,
45
+ i: t
46
+ })).sort((e, t) => (o(e.k.label) === "modifier" ? 0 : 1) - (o(t.k.label) === "modifier" ? 0 : 1) || e.i - t.i).map(({ k: e }) => e), f = d.findIndex((e) => o(e.label) !== "modifier"), p = !!a && f > 0 && f < d.length;
47
+ return /* @__PURE__ */ t("span", {
48
+ className: [r.keys, u].filter(Boolean).join(" "),
49
+ children: d.map((i, o) => /* @__PURE__ */ n(e, { children: [p && o === f ? /* @__PURE__ */ t("span", {
50
+ className: r.sep,
51
+ children: a
52
+ }) : null, /* @__PURE__ */ t(s, {
53
+ label: i.label,
54
+ inverted: i.optional ?? !1,
55
+ variant: c,
56
+ font: l
57
+ })] }, o))
58
+ });
59
+ }
60
+ //#endregion
61
+ //#region src/components/Keycaps/keySpecsFromMods.ts
62
+ var l = {
63
+ mod: {
64
+ macos: {
65
+ auto: "⌘",
66
+ symbol: "⌘",
67
+ text: "Cmd"
68
+ },
69
+ windows: {
70
+ auto: "Ctrl",
71
+ symbol: "Ctrl",
72
+ text: "Ctrl"
73
+ },
74
+ linux: {
75
+ auto: "Ctrl",
76
+ symbol: "Ctrl",
77
+ text: "Ctrl"
78
+ }
79
+ },
80
+ shift: {
81
+ macos: {
82
+ auto: "⇧",
83
+ symbol: "⇧",
84
+ text: "Shift"
85
+ },
86
+ windows: {
87
+ auto: "⇧",
88
+ symbol: "⇧",
89
+ text: "Shift"
90
+ },
91
+ linux: {
92
+ auto: "⇧",
93
+ symbol: "⇧",
94
+ text: "Shift"
95
+ }
96
+ },
97
+ alt: {
98
+ macos: {
99
+ auto: "⌥",
100
+ symbol: "⌥",
101
+ text: "Option"
102
+ },
103
+ windows: {
104
+ auto: "Alt",
105
+ symbol: "Alt",
106
+ text: "Alt"
107
+ },
108
+ linux: {
109
+ auto: "Alt",
110
+ symbol: "Alt",
111
+ text: "Alt"
112
+ }
113
+ },
114
+ ctrl: {
115
+ macos: {
116
+ auto: "⌃",
117
+ symbol: "⌃",
118
+ text: "Control"
119
+ },
120
+ windows: {
121
+ auto: "Ctrl",
122
+ symbol: "Ctrl",
123
+ text: "Ctrl"
124
+ },
125
+ linux: {
126
+ auto: "Ctrl",
127
+ symbol: "Ctrl",
128
+ text: "Ctrl"
129
+ }
130
+ },
131
+ meta: {
132
+ macos: {
133
+ auto: "⌘",
134
+ symbol: "⌘",
135
+ text: "Cmd"
136
+ },
137
+ windows: {
138
+ auto: "⊞",
139
+ symbol: "⊞",
140
+ text: "Win"
141
+ },
142
+ linux: {
143
+ auto: "⊞",
144
+ symbol: "⊞",
145
+ text: "Super"
146
+ }
147
+ }
148
+ };
149
+ function u() {
150
+ if (typeof navigator > "u") return "macos";
151
+ let e = (navigator.userAgentData?.platform ?? navigator.userAgent ?? "").toLowerCase();
152
+ return e.includes("mac") || e.includes("darwin") || e.includes("iphone") || e.includes("ipad") ? "macos" : e.includes("win") ? "windows" : e.includes("linux") || e.includes("x11") ? "linux" : "macos";
153
+ }
154
+ function d(e, t = {}) {
155
+ let n = t.platform ?? u(), r = t.legend ?? "auto";
156
+ return e.map((e) => {
157
+ let t = l[e.name][n][r];
158
+ return e.optional ? {
159
+ label: t,
160
+ optional: !0
161
+ } : { label: t };
162
+ });
163
+ }
164
+ var f = {
165
+ Escape: {
166
+ macos: {
167
+ auto: "⎋",
168
+ symbol: "⎋",
169
+ text: "Esc"
170
+ },
171
+ windows: {
172
+ auto: "Esc",
173
+ symbol: "Esc",
174
+ text: "Esc"
175
+ },
176
+ linux: {
177
+ auto: "Esc",
178
+ symbol: "Esc",
179
+ text: "Esc"
180
+ }
181
+ },
182
+ Enter: {
183
+ macos: {
184
+ auto: "↵",
185
+ symbol: "↵",
186
+ text: "Return"
187
+ },
188
+ windows: {
189
+ auto: "Enter",
190
+ symbol: "Enter",
191
+ text: "Enter"
192
+ },
193
+ linux: {
194
+ auto: "Enter",
195
+ symbol: "Enter",
196
+ text: "Enter"
197
+ }
198
+ },
199
+ Return: {
200
+ macos: {
201
+ auto: "↵",
202
+ symbol: "↵",
203
+ text: "Return"
204
+ },
205
+ windows: {
206
+ auto: "Enter",
207
+ symbol: "Enter",
208
+ text: "Enter"
209
+ },
210
+ linux: {
211
+ auto: "Enter",
212
+ symbol: "Enter",
213
+ text: "Enter"
214
+ }
215
+ },
216
+ Tab: {
217
+ macos: {
218
+ auto: "⇥",
219
+ symbol: "⇥",
220
+ text: "Tab"
221
+ },
222
+ windows: {
223
+ auto: "Tab",
224
+ symbol: "Tab",
225
+ text: "Tab"
226
+ },
227
+ linux: {
228
+ auto: "Tab",
229
+ symbol: "Tab",
230
+ text: "Tab"
231
+ }
232
+ },
233
+ Space: {
234
+ macos: {
235
+ auto: "␣",
236
+ symbol: "␣",
237
+ text: "Space"
238
+ },
239
+ windows: {
240
+ auto: "Space",
241
+ symbol: "Space",
242
+ text: "Space"
243
+ },
244
+ linux: {
245
+ auto: "Space",
246
+ symbol: "Space",
247
+ text: "Space"
248
+ }
249
+ },
250
+ " ": {
251
+ macos: {
252
+ auto: "␣",
253
+ symbol: "␣",
254
+ text: "Space"
255
+ },
256
+ windows: {
257
+ auto: "Space",
258
+ symbol: "Space",
259
+ text: "Space"
260
+ },
261
+ linux: {
262
+ auto: "Space",
263
+ symbol: "Space",
264
+ text: "Space"
265
+ }
266
+ },
267
+ Backspace: {
268
+ macos: {
269
+ auto: "⌫",
270
+ symbol: "⌫",
271
+ text: "Backspace"
272
+ },
273
+ windows: {
274
+ auto: "Backspace",
275
+ symbol: "Backspace",
276
+ text: "Backspace"
277
+ },
278
+ linux: {
279
+ auto: "Backspace",
280
+ symbol: "Backspace",
281
+ text: "Backspace"
282
+ }
283
+ },
284
+ Delete: {
285
+ macos: {
286
+ auto: "⌦",
287
+ symbol: "⌦",
288
+ text: "Delete"
289
+ },
290
+ windows: {
291
+ auto: "Delete",
292
+ symbol: "Delete",
293
+ text: "Delete"
294
+ },
295
+ linux: {
296
+ auto: "Delete",
297
+ symbol: "Delete",
298
+ text: "Delete"
299
+ }
300
+ },
301
+ ContextMenu: {
302
+ macos: {
303
+ auto: "Menu",
304
+ symbol: "Menu",
305
+ text: "Menu"
306
+ },
307
+ windows: {
308
+ auto: "▤",
309
+ symbol: "▤",
310
+ text: "Menu"
311
+ },
312
+ linux: {
313
+ auto: "▤",
314
+ symbol: "▤",
315
+ text: "Menu"
316
+ }
317
+ },
318
+ ArrowUp: {
319
+ macos: {
320
+ auto: "↑",
321
+ symbol: "↑",
322
+ text: "↑"
323
+ },
324
+ windows: {
325
+ auto: "↑",
326
+ symbol: "↑",
327
+ text: "↑"
328
+ },
329
+ linux: {
330
+ auto: "↑",
331
+ symbol: "↑",
332
+ text: "↑"
333
+ }
334
+ },
335
+ ArrowDown: {
336
+ macos: {
337
+ auto: "↓",
338
+ symbol: "↓",
339
+ text: "↓"
340
+ },
341
+ windows: {
342
+ auto: "↓",
343
+ symbol: "↓",
344
+ text: "↓"
345
+ },
346
+ linux: {
347
+ auto: "↓",
348
+ symbol: "↓",
349
+ text: "↓"
350
+ }
351
+ },
352
+ ArrowLeft: {
353
+ macos: {
354
+ auto: "←",
355
+ symbol: "←",
356
+ text: "←"
357
+ },
358
+ windows: {
359
+ auto: "←",
360
+ symbol: "←",
361
+ text: "←"
362
+ },
363
+ linux: {
364
+ auto: "←",
365
+ symbol: "←",
366
+ text: "←"
367
+ }
368
+ },
369
+ ArrowRight: {
370
+ macos: {
371
+ auto: "→",
372
+ symbol: "→",
373
+ text: "→"
374
+ },
375
+ windows: {
376
+ auto: "→",
377
+ symbol: "→",
378
+ text: "→"
379
+ },
380
+ linux: {
381
+ auto: "→",
382
+ symbol: "→",
383
+ text: "→"
384
+ }
385
+ }
386
+ };
387
+ function p(e, t = {}) {
388
+ let n = t.platform ?? u(), r = t.legend ?? "auto", i = f[e], a = i ? i[n][r] : e.length === 1 ? e.toUpperCase() : e;
389
+ return t.optional ? {
390
+ label: a,
391
+ optional: !0
392
+ } : { label: a };
393
+ }
394
+ //#endregion
395
+ export { s as a, c as i, p as n, o, d as r, u as t };
396
+
397
+ //# sourceMappingURL=Keycaps-B9dJMYx_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Keycaps-B9dJMYx_.js","names":[],"sources":["../../src/components/Keycaps/Keycaps.module.css","../../src/components/Keycaps/Keycap.tsx","../../src/components/Keycaps/Keycaps.tsx","../../src/components/Keycaps/keySpecsFromMods.ts"],"sourcesContent":["/* Keystroke \"key cap\" styling — each modifier and key in its own bordered chip. */\n.keys {\n display: inline-flex;\n gap: 3px;\n /* Bottom-align so chips with text labels and chips with icon glyphs\n (arrows, modifier symbols) line up at the same bottom edge. Baseline\n drifts because text baselines sit above icon centers. */\n align-items: flex-end;\n /* When this whole sequence sits inline in surrounding text (e.g.\n \"Press <KeySequence> to confirm.\"), the row anchors to the\n surrounding line's bottom edge, not its baseline. */\n vertical-align: bottom;\n flex-wrap: wrap;\n}\n\n.keysEmpty {\n color: var(--wzl-muted, #9ea1a8);\n}\n\n.sep {\n color: var(--wzl-muted, #9ea1a8);\n font-size: 11px;\n line-height: 1;\n}\n\n.key {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n height: 18px;\n padding: 0 4px;\n /* Light face, slightly-darker-than-face border, dark glyph — reads as\n a real keycap rather than a recessed slot in the panel. */\n background: var(--wzl-fg, #e6e7e9);\n border: 1px solid #25272c;\n border-bottom-width: 2px;\n border-radius: 3px;\n color: var(--wzl-bg, #181a1e);\n /* Keycaps are a deliberate exception to the site theme — the design-\n system UI font (often a display face like Oswald) is wrong for\n keyboard chips. Use a neutral sans stack so labels read like real\n key legends. Consumers wanting a specific face per chip pass the\n `font` prop on KeyCap. */\n font-family: ui-sans-serif, system-ui, sans-serif;\n font-size: 11px;\n font-weight: 700;\n line-height: 1;\n}\n\n/* Default chip is square — letters, digits, and single glyphs (⎋ ⌫ ↑ etc.)\n sit in a uniform key-cap box. */\n.key[data-kind='square'] {\n width: 18px;\n padding: 0;\n}\n\n/* Modifiers (⌘ ⇪ ⌥ ⌃) are wider to match the visual weight of how they\n appear on a real keyboard — and to differentiate them from the keys\n they modify in a stack. */\n.key[data-kind='modifier'] {\n min-width: 26px;\n padding: 0 6px;\n}\n\n/* Tab / Enter / Space — actual wide keys on a real keyboard. */\n.key[data-kind='wide'] {\n min-width: 32px;\n padding: 0 8px;\n}\n\n/* Optional/inverted (default variant): face flips to dark; legend drops\n to 60% opacity; dotted border drops to 40% opacity. Three soft cues\n stacked for \"may be held but isn't required.\" */\n.key[data-inverted] {\n background: var(--wzl-bg, #181a1e);\n color: color-mix(in srgb, var(--wzl-fg, #e6e7e9) 60%, transparent);\n border-style: dotted;\n border-color: color-mix(in srgb, var(--wzl-fg, #e6e7e9) 40%, transparent);\n border-width: 1.5px;\n border-bottom-width: 1.5px;\n}\n\n/* Minimal variant — no fill, borders and legend follow currentColor.\n Useful inline in colored prose / next to colored badges where the\n chip should take the surrounding text color. */\n.key[data-variant='minimal'] {\n background: transparent;\n border-color: currentColor;\n color: currentColor;\n}\n\n/* Optional + minimal: dotted border at full currentColor, legend at full\n currentColor. The dotted pattern alone carries the \"optional\" cue here\n — minimal's whole point is to defer color to the surrounding context,\n so dimming would fight that. (Default variant uses graded opacity as a\n stacked cue; minimal keeps it crisp.) */\n.key[data-variant='minimal'][data-inverted] {\n border-style: dotted;\n border-color: currentColor;\n color: currentColor;\n border-width: 1.5px;\n border-bottom-width: 1.5px;\n}\n","import type { CSSProperties } from 'react';\nimport s from './Keycaps.module.css';\n\nconst MODIFIER_GLYPHS = new Set(['⌘', '⇪', '⌥', '⌃', '⇧']);\nconst WIDE_GLYPHS = new Set(['⇥', '↵', '␣']);\n\nexport type KeycapKind = 'modifier' | 'wide' | 'square';\n\nexport function inferKeycapKind(label: string): KeycapKind {\n if (MODIFIER_GLYPHS.has(label)) return 'modifier';\n if (WIDE_GLYPHS.has(label)) return 'wide';\n if (label.length > 1) return 'wide';\n return 'square';\n}\n\nexport type KeyCapVariant = 'default' | 'minimal';\n\nexport interface KeyCapProps {\n /** Glyph rendered in the chip (modifier or key). */\n label: string;\n /** Marks the chip as not required to trigger the action. In the default\n * variant the chip face inverts (dark face / light glyph) for\n * emphasis. In the `'minimal'` variant the chip's border becomes\n * dotted to read as \"may be held, but isn't required.\" */\n inverted?: boolean;\n /** Visual style. `'default'` (default) renders a filled chip; `'minimal'`\n * renders an unfilled chip whose border and legend are `currentColor`\n * — useful inline in colored prose / next to colored badges where the\n * chip should take the surrounding text color. */\n variant?: KeyCapVariant;\n className?: string;\n /** Optional inline style. Useful for one-off width overrides (e.g.\n * building a keyboard-layout where the space bar spans several\n * standard-key widths). The component sets no inline styles of its\n * own — everything else comes from the CSS module. */\n style?: CSSProperties;\n /** Override the chip's font-family. Accepts any CSS font-family\n * string. When omitted, the chip inherits from the design-system\n * UI font token (`--wzl-font-ui`). Useful for one-off cases where\n * a different face is desired — though the canonical move is to\n * override the CSS variable at the consumer's scope, not the prop. */\n font?: string;\n}\n\n/** Single bordered keycap chip for one glyph (modifier or key). Use\n * `KeySequence` to render a full shortcut. */\nexport function KeyCap({ label, inverted = false, variant = 'default', className, style, font }: KeyCapProps) {\n const resolvedStyle = font ? { ...style, fontFamily: font } : style;\n return (\n <kbd\n className={[s.key, className].filter(Boolean).join(' ')}\n data-kind={inferKeycapKind(label)}\n data-variant={variant === 'default' ? undefined : variant}\n data-inverted={inverted || undefined}\n style={resolvedStyle}\n >\n {label}\n </kbd>\n );\n}\n","import { Fragment } from 'react';\nimport s from './Keycaps.module.css';\nimport { KeyCap, inferKeycapKind, type KeyCapVariant } from './Keycap';\n\nexport interface KeySpec {\n /** Glyph rendered in the chip (modifier or key). */\n label: string;\n /** When true, the chip renders inverted to mark it as not required to\n * trigger the action (e.g. an optional modifier). Defaults to false. */\n optional?: boolean;\n}\n\nexport interface KeySequenceProps {\n /** Keys to render. `undefined` or empty renders a muted em-dash.\n * Modifiers are always rendered first regardless of input order; relative\n * order within each group is preserved. */\n keys: readonly KeySpec[] | undefined;\n /** Character inserted between the trailing modifier chip and the first\n * non-modifier chip (e.g. `'+'` renders `⌘ + K`). `null` or `''`\n * suppresses it. Defaults to `'+'`. */\n separator?: string | null;\n /** Forwarded to every `KeyCap` in the sequence. `'minimal'` renders\n * unfilled chips whose border + legend are `currentColor`. */\n variant?: KeyCapVariant;\n /** Forwarded to every `KeyCap` in the sequence. Overrides the design-\n * system UI font for that chip only. */\n font?: string;\n className?: string;\n}\n\n/** Renders a shortcut as a row of `KeyCap` chips, one per key. Optional\n * keys render inverted to distinguish them from required ones. */\nexport function KeySequence({ keys, separator = '+', variant = 'default', font, className }: KeySequenceProps) {\n if (!keys || keys.length === 0) {\n return <span className={[s.keysEmpty, className].filter(Boolean).join(' ')}>—</span>;\n }\n const ordered = keys\n .map((k, i) => ({ k, i }))\n .sort((a, b) => {\n const am = inferKeycapKind(a.k.label) === 'modifier' ? 0 : 1;\n const bm = inferKeycapKind(b.k.label) === 'modifier' ? 0 : 1;\n return am - bm || a.i - b.i;\n })\n .map(({ k }) => k);\n const sepIdx = ordered.findIndex((k) => inferKeycapKind(k.label) !== 'modifier');\n const showSep = !!separator && sepIdx > 0 && sepIdx < ordered.length;\n return (\n <span className={[s.keys, className].filter(Boolean).join(' ')}>\n {ordered.map((k, i) => (\n <Fragment key={i}>\n {showSep && i === sepIdx ? <span className={s.sep}>{separator}</span> : null}\n <KeyCap label={k.label} inverted={k.optional ?? false} variant={variant} font={font} />\n </Fragment>\n ))}\n </span>\n );\n}\n","import type { KeySpec } from './Keycaps';\n\n/** Logical modifier name. Matches the kit's `ModifierKey` in shape — kept as a\n * local type so `weasel-ui` stays independent of `@weasel-js/core`. */\nexport type LogicalMod = 'mod' | 'shift' | 'alt' | 'ctrl' | 'meta';\n\n/** Detected (or overridden) platform. `'mod'` resolves to ⌘ on macOS,\n * Ctrl on Windows / Linux. */\nexport type Platform = 'macos' | 'windows' | 'linux';\n\n/** Visual form of a modifier or named-key label.\n *\n * - `'auto'` (default): the per-entry, per-platform default — whatever\n * label is actually printed on the physical key. macOS keys show the\n * Apple glyphs (⌘ ⌥ ⌃ ⇧ ⎋ ↵ ⇥). Windows keys mostly show text\n * (Ctrl, Alt, Shift) BUT the Win key shows its logo (⊞) and the\n * context-menu key shows ▤. Linux mirrors Windows with Super (⊞).\n * - `'symbol'` forces the Apple-style glyph everywhere a symbolic form\n * exists. Entries without a widely-recognized symbol still fall\n * back to text.\n * - `'text'` always spells the label out (Cmd / Option / Esc / Enter). */\nexport type LegendStyle = 'auto' | 'symbol' | 'text';\n\nexport interface LogicalModSpec {\n name: LogicalMod;\n /** Marks this modifier as optional (may be held but isn't required).\n * Forwarded as the resulting `KeySpec.optional`. */\n optional?: boolean;\n}\n\nexport interface KeySpecsFromModsOptions {\n /** Override OS detection. Defaults to the detected platform, or\n * `'macos'` when detection is unavailable (e.g. in tests, or when\n * `navigator` is missing). */\n platform?: Platform;\n /** Defaults to `'auto'` (symbol on macOS, text everywhere else). Pass\n * `'symbol'` or `'text'` to force a specific style regardless of\n * platform. */\n legend?: LegendStyle;\n}\n\nconst MOD_BY_PLATFORM: Record<LogicalMod, Record<Platform, Record<LegendStyle, string>>> = {\n mod: {\n macos: { auto: '⌘', symbol: '⌘', text: 'Cmd' },\n windows: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n linux: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n },\n shift: {\n macos: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n windows: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n linux: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n },\n alt: {\n macos: { auto: '⌥', symbol: '⌥', text: 'Option' },\n windows: { auto: 'Alt', symbol: 'Alt', text: 'Alt' },\n linux: { auto: 'Alt', symbol: 'Alt', text: 'Alt' },\n },\n ctrl: {\n macos: { auto: '⌃', symbol: '⌃', text: 'Control' },\n windows: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n linux: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n },\n // Windows/Linux Meta has a recognized symbol on the physical key (⊞ Win\n // logo / Super logo), so `auto` shows it. Use `text` for Win / Super.\n meta: {\n macos: { auto: '⌘', symbol: '⌘', text: 'Cmd' },\n windows: { auto: '⊞', symbol: '⊞', text: 'Win' },\n linux: { auto: '⊞', symbol: '⊞', text: 'Super' },\n },\n};\n\n/** Detect the user's OS from the browser environment. UA sniffing — not\n * 100% reliable, but adequate for picking a modifier-glyph convention.\n * Falls back to `'macos'` (matches the kit's docs convention) when\n * `navigator` is unavailable. */\nexport function detectPlatform(): Platform {\n if (typeof navigator === 'undefined') return 'macos';\n // Prefer the modern userAgentData when available (Chromium-only today).\n const uaData = (navigator as Navigator & { userAgentData?: { platform?: string } }).userAgentData;\n const raw = (uaData?.platform ?? navigator.userAgent ?? '').toLowerCase();\n if (raw.includes('mac') || raw.includes('darwin') || raw.includes('iphone') || raw.includes('ipad')) return 'macos';\n if (raw.includes('win')) return 'windows';\n if (raw.includes('linux') || raw.includes('x11')) return 'linux';\n return 'macos';\n}\n\n/**\n * Map a list of **logical** modifiers (`'mod'`, `'shift'`, …) to **visual**\n * `KeySpec`s appropriate for the current platform.\n *\n * The kit-side gesture grammar uses logical names so the same route reads\n * correctly on every OS — `'mod'` means \"Cmd on Mac, Ctrl on Win/Linux\".\n * `KeySequence` is purely visual and renders the labels you give it; this\n * helper is the bridge.\n *\n * ```ts\n * <KeySequence\n * keys={keySpecsFromMods([{ name: 'mod' }, { name: 'shift', optional: true }])}\n * />\n * ```\n *\n * On a Mac: renders `⌘ ⇧`. On Windows: renders `Ctrl Shift`. Pass an\n * explicit `platform` to override detection (e.g. for docs that always\n * show the macOS form). Pass `legend: 'text'` to force \"Cmd\" over \"⌘\"\n * even on macOS.\n */\nexport function keySpecsFromMods(\n mods: readonly LogicalModSpec[],\n opts: KeySpecsFromModsOptions = {},\n): readonly KeySpec[] {\n const platform = opts.platform ?? detectPlatform();\n const legend = opts.legend ?? 'auto';\n return mods.map((m) => {\n const label = MOD_BY_PLATFORM[m.name][platform][legend];\n return m.optional ? { label, optional: true } : { label };\n });\n}\n\n/** Per-platform × per-legend table for named, non-modifier keys. `auto`\n * is whatever's printed on the physical key for that platform. Arrows\n * are universal symbols on every platform. */\nconst NAMED_KEY: Record<string, Record<Platform, Record<LegendStyle, string>>> = {\n Escape: { macos: { auto: '⎋', symbol: '⎋', text: 'Esc' }, windows: { auto: 'Esc', symbol: 'Esc', text: 'Esc' }, linux: { auto: 'Esc', symbol: 'Esc', text: 'Esc' } },\n Enter: { macos: { auto: '↵', symbol: '↵', text: 'Return' }, windows: { auto: 'Enter', symbol: 'Enter', text: 'Enter' }, linux: { auto: 'Enter', symbol: 'Enter', text: 'Enter' } },\n Return: { macos: { auto: '↵', symbol: '↵', text: 'Return' }, windows: { auto: 'Enter', symbol: 'Enter', text: 'Enter' }, linux: { auto: 'Enter', symbol: 'Enter', text: 'Enter' } },\n Tab: { macos: { auto: '⇥', symbol: '⇥', text: 'Tab' }, windows: { auto: 'Tab', symbol: 'Tab', text: 'Tab' }, linux: { auto: 'Tab', symbol: 'Tab', text: 'Tab' } },\n Space: { macos: { auto: '␣', symbol: '␣', text: 'Space' }, windows: { auto: 'Space', symbol: 'Space', text: 'Space' }, linux: { auto: 'Space', symbol: 'Space', text: 'Space' } },\n ' ': { macos: { auto: '␣', symbol: '␣', text: 'Space' }, windows: { auto: 'Space', symbol: 'Space', text: 'Space' }, linux: { auto: 'Space', symbol: 'Space', text: 'Space' } },\n Backspace: { macos: { auto: '⌫', symbol: '⌫', text: 'Backspace' }, windows: { auto: 'Backspace', symbol: 'Backspace', text: 'Backspace' }, linux: { auto: 'Backspace', symbol: 'Backspace', text: 'Backspace' } },\n Delete: { macos: { auto: '⌦', symbol: '⌦', text: 'Delete' }, windows: { auto: 'Delete', symbol: 'Delete', text: 'Delete' }, linux: { auto: 'Delete', symbol: 'Delete', text: 'Delete' } },\n // Context-menu key (the right-Ctrl-area key on Windows / Linux keyboards\n // with a ▤ icon). Mac has no equivalent; falls back to text 'Menu'.\n ContextMenu: { macos: { auto: 'Menu', symbol: 'Menu', text: 'Menu' }, windows: { auto: '▤', symbol: '▤', text: 'Menu' }, linux: { auto: '▤', symbol: '▤', text: 'Menu' } },\n ArrowUp: { macos: { auto: '↑', symbol: '↑', text: '↑' }, windows: { auto: '↑', symbol: '↑', text: '↑' }, linux: { auto: '↑', symbol: '↑', text: '↑' } },\n ArrowDown: { macos: { auto: '↓', symbol: '↓', text: '↓' }, windows: { auto: '↓', symbol: '↓', text: '↓' }, linux: { auto: '↓', symbol: '↓', text: '↓' } },\n ArrowLeft: { macos: { auto: '←', symbol: '←', text: '←' }, windows: { auto: '←', symbol: '←', text: '←' }, linux: { auto: '←', symbol: '←', text: '←' } },\n ArrowRight: { macos: { auto: '→', symbol: '→', text: '→' }, windows: { auto: '→', symbol: '→', text: '→' }, linux: { auto: '→', symbol: '→', text: '→' } },\n};\n\n/**\n * Render a raw `KeyboardEvent.key` value as a platform-appropriate\n * `KeySpec`. Named non-modifier keys (Esc, Enter, Tab, Space, Backspace,\n * Delete, arrows) get the platform's conventional form. Letter / digit /\n * other keys pass through upper-cased.\n *\n * ```ts\n * keySpecFromKey('Escape', { platform: 'macos' }) // { label: '⎋' }\n * keySpecFromKey('Escape', { platform: 'windows' }) // { label: 'Esc' }\n * keySpecFromKey('p') // { label: 'P' }\n * ```\n *\n * Symbol mode is only meaningful on macOS — Windows / Linux keyboards\n * print the text form on the physical key, so symbol mode there falls\n * back to text.\n */\nexport function keySpecFromKey(\n raw: string,\n opts: KeySpecsFromModsOptions & { optional?: boolean } = {},\n): KeySpec {\n const platform = opts.platform ?? detectPlatform();\n const legend = opts.legend ?? 'auto';\n const entry = NAMED_KEY[raw];\n const label = entry ? entry[platform][legend] : raw.length === 1 ? raw.toUpperCase() : raw;\n return opts.optional ? { label, optional: true } : { label };\n}\n"],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { n as e } from "./Field-BHSu2F3E.js";
2
+ import { forwardRef as t } from "react";
3
+ import { Button as n, FieldError as r, Group as i, Input as a, Label as o, NumberField as s, Text as c } from "react-aria-components";
4
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
+ var d = {
6
+ field: "_field_14yuu_1",
7
+ frame: "_frame_14yuu_9",
8
+ steppers: "_steppers_14yuu_57",
9
+ stepper: "_stepper_14yuu_57"
10
+ }, f = t(function(t, f) {
11
+ let { label: p, description: m, errorMessage: h, hideSteppers: g, placeholder: _, className: v, ...y } = t;
12
+ return /* @__PURE__ */ u(s, {
13
+ ...y,
14
+ className: [
15
+ d.field,
16
+ e.root,
17
+ v
18
+ ].filter(Boolean).join(" "),
19
+ children: [
20
+ p !== void 0 && /* @__PURE__ */ l(o, {
21
+ className: e.label,
22
+ children: p
23
+ }),
24
+ /* @__PURE__ */ u(i, {
25
+ className: d.frame,
26
+ children: [/* @__PURE__ */ l(a, {
27
+ ref: f,
28
+ placeholder: _
29
+ }), !g && /* @__PURE__ */ u("div", {
30
+ className: d.steppers,
31
+ children: [/* @__PURE__ */ l(n, {
32
+ slot: "increment",
33
+ className: d.stepper,
34
+ "aria-label": "Increment",
35
+ children: "▲"
36
+ }), /* @__PURE__ */ l(n, {
37
+ slot: "decrement",
38
+ className: d.stepper,
39
+ "aria-label": "Decrement",
40
+ children: "▼"
41
+ })]
42
+ })]
43
+ }),
44
+ m !== void 0 && /* @__PURE__ */ l(c, {
45
+ slot: "description",
46
+ className: e.hint,
47
+ children: m
48
+ }),
49
+ /* @__PURE__ */ l(r, {
50
+ className: e.error,
51
+ children: h
52
+ })
53
+ ]
54
+ });
55
+ });
56
+ //#endregion
57
+ export { f as t };
58
+
59
+ //# sourceMappingURL=NumberField-BQmELz32.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberField-BQmELz32.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: 24px;\n background: var(--wzl-input-bg);\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: 13px;\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, #ff5b5b);\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 8px;\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: 9px;\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: color-mix(in srgb, var(--wzl-fg) 10%, transparent);\n color: var(--wzl-fg);\n}\n\n.stepper[data-pressed]:not([data-disabled]) {\n background: color-mix(in srgb, var(--wzl-fg) 18%, transparent);\n}\n\n.stepper[data-disabled] {\n opacity: 0.4;\n cursor: not-allowed;\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\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 /** Native input placeholder — e.g. `'Mixed'` for a multi-selection\n * editor with no shared value. */\n placeholder?: string;\n className?: string;\n};\n\nexport const NumberField = forwardRef(function NumberField(\n props: NumberFieldProps,\n ref: Ref<HTMLInputElement>,\n) {\n const { label, description, errorMessage, hideSteppers, placeholder, className, ...rest } = 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={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":";;;;;;;;;GC2Ba,IAAc,EAAW,SACpC,GACA,GACA;CACA,IAAM,EAAE,UAAO,gBAAa,iBAAc,iBAAc,gBAAa,cAAW,GAAG,MAAS;CAC5F,OACE,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,EAAE;cAApB,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"}
@@ -0,0 +1,98 @@
1
+ import { useRef as e } from "react";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ var n = {
4
+ root: "_root_13y7a_6",
5
+ segment: "_segment_13y7a_28",
6
+ segmentSelected: "_segmentSelected_13y7a_75",
7
+ size_sm: "_size_sm_13y7a_133",
8
+ variant_minimal: "_variant_minimal_13y7a_146"
9
+ };
10
+ //#endregion
11
+ //#region src/components/OptionsBar/OptionsBar.tsx
12
+ function r(e) {
13
+ for (let t = 0; t < e.length; t++) if (!e[t].disabled) return t;
14
+ return -1;
15
+ }
16
+ function i(e) {
17
+ for (let t = e.length - 1; t >= 0; t--) if (!e[t].disabled) return t;
18
+ return -1;
19
+ }
20
+ function a(e, t) {
21
+ let n = e.length;
22
+ for (let r = 1; r <= n; r++) {
23
+ let i = (t + r + n) % n;
24
+ if (!e[i].disabled) return i;
25
+ }
26
+ return t;
27
+ }
28
+ function o(e, t) {
29
+ let n = e.length;
30
+ for (let r = 1; r <= n; r++) {
31
+ let i = (t - r + n) % n;
32
+ if (!e[i].disabled) return i;
33
+ }
34
+ return t;
35
+ }
36
+ function s(s) {
37
+ let { items: c, ariaLabel: l, className: u, height: d, size: f, variant: p } = s, m = e(null), h = r(c), g = (e) => {
38
+ let t = c[e];
39
+ t.disabled || t.onChange(!t.selected);
40
+ }, _ = (e) => {
41
+ let t = m.current;
42
+ t && t.querySelectorAll(`.${n.segment}`)[e]?.focus();
43
+ }, v = (e) => (t) => {
44
+ let n = -1;
45
+ switch (t.key) {
46
+ case "ArrowLeft":
47
+ case "ArrowUp":
48
+ n = o(c, e);
49
+ break;
50
+ case "ArrowRight":
51
+ case "ArrowDown":
52
+ n = a(c, e);
53
+ break;
54
+ case "Home":
55
+ n = r(c);
56
+ break;
57
+ case "End":
58
+ n = i(c);
59
+ break;
60
+ case " ":
61
+ case "Enter":
62
+ t.preventDefault(), g(e);
63
+ return;
64
+ default: return;
65
+ }
66
+ n < 0 || n === e || (t.preventDefault(), _(n));
67
+ }, y = d === void 0 ? void 0 : { "--wzl-tb-height": `${d}px` };
68
+ return /* @__PURE__ */ t("div", {
69
+ ref: m,
70
+ className: [
71
+ n.root,
72
+ f && n[`size_${f}`],
73
+ p && n[`variant_${p}`],
74
+ u
75
+ ].filter(Boolean).join(" "),
76
+ role: "group",
77
+ "aria-label": l,
78
+ style: y,
79
+ children: c.map((e, r) => {
80
+ let i = `${n.segment}${e.selected ? ` ${n.segmentSelected}` : ""}`;
81
+ return /* @__PURE__ */ t("button", {
82
+ type: "button",
83
+ "aria-pressed": e.selected,
84
+ "aria-label": e.ariaLabel,
85
+ disabled: e.disabled,
86
+ tabIndex: r === h ? 0 : -1,
87
+ className: i,
88
+ onClick: () => g(r),
89
+ onKeyDown: v(r),
90
+ children: e.label
91
+ }, e.value);
92
+ })
93
+ });
94
+ }
95
+ //#endregion
96
+ export { s as t };
97
+
98
+ //# sourceMappingURL=OptionsBar-CHOP_CiW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OptionsBar-CHOP_CiW.js","names":[],"sources":["../../src/components/OptionsBar/OptionsBar.module.css","../../src/components/OptionsBar/OptionsBar.tsx"],"sourcesContent":["/* Aqua-glass segmented control. The track is a pill-shaped well; the\n selected segment becomes a tinted glass cylinder that reads as the same\n \"lozenge\" family as the standalone Button. Visual params come from the\n `--btn-*` custom properties (see Button.module.css) so the Button Lab\n can tune both surfaces with one set of sliders. */\n.root {\n display: inline-flex;\n height: var(--wzl-tb-height, 28px);\n padding: 2px;\n background: linear-gradient(\n 180deg,\n rgba(0, 0, 0, 0.18) 0%,\n rgba(0, 0, 0, 0.05) 100%\n );\n border-radius: 999px;\n /* Clip segments to the track outline so interior corners read crisp and\n the selected segment's glass treatment doesn't paint over the rounded\n outer pixels. */\n overflow: hidden;\n box-shadow:\n inset 0 1px 2px rgba(0, 0, 0, 0.4),\n 0 1px 0 rgba(255, 255, 255, 0.06);\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n}\n\n.segment {\n position: relative;\n flex: 1 1 0;\n min-width: 0;\n padding: 0 12px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n margin: 0;\n font-family: var(--wzl-font-ui);\n font-weight: 300;\n font-size: var(--btn-fontsize, 14px);\n line-height: 1;\n color: var(--wzl-fg-muted);\n cursor: pointer;\n /* Only round the outer corners of the bar — middle segments stay square\n so the seams between them don't render as facing parentheses. */\n border-radius: 0;\n isolation: isolate;\n overflow: hidden;\n transition: color var(--wzl-motion-fast);\n}\n\n.segment:first-child {\n border-radius: 999px 0 0 999px;\n}\n\n.segment:last-child {\n border-radius: 0 999px 999px 0;\n}\n\n.segment:only-child {\n border-radius: 999px;\n}\n\n.segment:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: -2px;\n}\n\n.segment:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.segment:hover:not(:disabled):not(.segmentSelected) {\n color: var(--wzl-fg);\n}\n\n/* Selected segment — full Aqua glass cylinder. Mirrors Button.variant_primary. */\n.segmentSelected {\n background: linear-gradient(\n 180deg,\n color-mix(in srgb, var(--wzl-accent) var(--btn-top-alpha, 45%), transparent) 0%,\n color-mix(in srgb, var(--wzl-accent) var(--btn-upper-alpha, 70%), transparent) calc(var(--btn-equator, 52%) - var(--btn-equator-spread, 12%)),\n color-mix(in srgb, var(--wzl-accent) var(--btn-equator-tint, 95%), white) var(--btn-equator, 52%),\n var(--wzl-accent) calc(var(--btn-equator, 52%) + var(--btn-equator-spread, 12%) * 1.6),\n color-mix(in srgb, var(--wzl-accent) var(--btn-base-tint, 70%), black) 100%\n );\n backdrop-filter: blur(var(--btn-blur, 6px)) saturate(var(--btn-saturate, 1.3));\n -webkit-backdrop-filter: blur(var(--btn-blur, 6px)) saturate(var(--btn-saturate, 1.3));\n color: var(--wzl-fg-on-accent);\n text-shadow:\n 0 1px 0 rgba(0, 0, 0, var(--btn-text-shadow, 0.35)),\n var(--btn-text-inset-x, 0px) var(--btn-text-inset-y, 1px) 0 rgba(0, 0, 0, var(--btn-text-inset, 0.55)),\n 0 0 6px rgba(0, 0, 0, calc(var(--btn-text-shadow, 0.35) * 0.5));\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, var(--btn-inset-hi, 0.42)),\n inset 0 -1px 2px rgba(0, 0, 0, var(--btn-inset-lo, 0.3)),\n 0 0 0 1px rgba(0, 0, 0, var(--btn-rim, 0.22)),\n 0 1px 2px rgba(0, 0, 0, var(--btn-drop-near, 0.3)),\n 0 2px 4px rgba(0, 0, 0, calc(var(--btn-drop-far, 0.18) * 0.8));\n}\n\n/* Specular gloss on the selected segment. Top corners inherit the\n segment's radius so they hug the upper edge cleanly; bottom corners\n are flattened so the gloss ends in a straight line at the equator\n instead of two little curves that read as `)(` brackets. */\n.segmentSelected::before {\n content: '';\n position: absolute;\n inset: 1px 1px var(--btn-gloss-bottom, 50%) 1px;\n border-radius: inherit;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, var(--btn-gloss-top, 0.42)) 0%,\n rgba(255, 255, 255, var(--btn-gloss-mid, 0.12)) 60%,\n rgba(255, 255, 255, 0) 100%\n );\n pointer-events: none;\n z-index: 1;\n}\n\n.segmentSelected > * {\n position: relative;\n z-index: 2;\n}\n\n/* Small variant — ~60% of the default height, with proportionally reduced\n padding and font. Sized for dense surfaces (lab control panels, inline\n filters, etc.). */\n.size_sm {\n height: 17px;\n padding: 1px;\n}\n\n.size_sm .segment {\n padding: 0 8px;\n font-size: 11px;\n}\n\n/* Minimal variant — strips the pill track, glass selected state, inset\n shadows, and outer padding. Used in dense diagnostic surfaces (dispatch\n trace, lab inspectors) where the bar must read as plain text controls. */\n.variant_minimal {\n height: auto;\n padding: 0;\n background: none;\n border-radius: 0;\n box-shadow: none;\n gap: 2px;\n}\n\n.variant_minimal .segment {\n padding: 0 4px;\n font-size: 11px;\n font-weight: 400;\n line-height: 1.4;\n border-radius: 2px;\n color: var(--wzl-fg-muted);\n transition: none;\n}\n\n.variant_minimal .segment:first-child,\n.variant_minimal .segment:last-child,\n.variant_minimal .segment:only-child {\n border-radius: 2px;\n}\n\n.variant_minimal .segment:hover:not(:disabled):not(.segmentSelected) {\n color: var(--wzl-fg);\n background: rgba(255, 255, 255, 0.06);\n}\n\n.variant_minimal .segmentSelected {\n background: none;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n color: var(--wzl-accent-fg, var(--wzl-accent));\n text-shadow: none;\n box-shadow: none;\n font-weight: 500;\n}\n\n.variant_minimal .segmentSelected::before {\n content: none;\n}\n","import { useRef, type CSSProperties, type KeyboardEvent as ReactKeyboardEvent, type ReactElement, type ReactNode } from 'react';\nimport s from './OptionsBar.module.css';\n\nexport type OptionsBarItem<V extends string | number = string> = {\n value: V;\n label?: ReactNode;\n ariaLabel?: string;\n disabled?: boolean;\n selected: boolean;\n onChange: (next: boolean) => void;\n};\n\nexport type OptionsBarSize = 'sm' | 'md';\nexport type OptionsBarVariant = 'default' | 'minimal';\n\nexport type OptionsBarProps<V extends string | number = string> = {\n items: readonly OptionsBarItem<V>[];\n ariaLabel?: string;\n className?: string;\n height?: number;\n /** Size variant. `sm` is ~60% of the default height with reduced padding\n * and font size — sized for dense surfaces like lab control panels. */\n size?: OptionsBarSize;\n /** Visual variant. `minimal` strips the pill track and glass treatment;\n * selection becomes a flat accent. For dense diagnostic surfaces. */\n variant?: OptionsBarVariant;\n};\n\nfunction firstEnabledIndex(items: readonly OptionsBarItem<string | number>[]): number {\n for (let i = 0; i < items.length; i++) if (!items[i].disabled) return i;\n return -1;\n}\n\nfunction lastEnabledIndex(items: readonly OptionsBarItem<string | number>[]): number {\n for (let i = items.length - 1; i >= 0; i--) if (!items[i].disabled) return i;\n return -1;\n}\n\nfunction nextEnabledIndex(items: readonly OptionsBarItem<string | number>[], from: number): number {\n const n = items.length;\n for (let k = 1; k <= n; k++) {\n const i = (from + k + n) % n;\n if (!items[i].disabled) return i;\n }\n return from;\n}\n\nfunction prevEnabledIndex(items: readonly OptionsBarItem<string | number>[], from: number): number {\n const n = items.length;\n for (let k = 1; k <= n; k++) {\n const i = (from - k + n) % n;\n if (!items[i].disabled) return i;\n }\n return from;\n}\n\nexport function OptionsBar<V extends string | number = string>(props: OptionsBarProps<V>): ReactElement {\n const { items, ariaLabel, className, height, size, variant } = props;\n const rootRef = useRef<HTMLDivElement | null>(null);\n\n const tabStopIndex = firstEnabledIndex(items);\n\n const toggle = (index: number) => {\n const item = items[index];\n if (item.disabled) return;\n item.onChange(!item.selected);\n };\n\n const focusSegment = (index: number) => {\n const root = rootRef.current;\n if (!root) return;\n const buttons = root.querySelectorAll<HTMLButtonElement>(`.${s.segment}`);\n buttons[index]?.focus();\n };\n\n const handleKeyDown = (index: number) => (e: ReactKeyboardEvent<HTMLButtonElement>) => {\n let nextIndex = -1;\n switch (e.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n nextIndex = prevEnabledIndex(items, index);\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n nextIndex = nextEnabledIndex(items, index);\n break;\n case 'Home':\n nextIndex = firstEnabledIndex(items);\n break;\n case 'End':\n nextIndex = lastEnabledIndex(items);\n break;\n case ' ':\n case 'Enter':\n e.preventDefault();\n toggle(index);\n return;\n default:\n return;\n }\n if (nextIndex < 0 || nextIndex === index) return;\n e.preventDefault();\n focusSegment(nextIndex);\n };\n\n const style: CSSProperties | undefined = height !== undefined\n ? ({ ['--wzl-tb-height' as string]: `${height}px` } as CSSProperties)\n : undefined;\n\n const rootCls = [\n s.root,\n size && s[`size_${size}`],\n variant && s[`variant_${variant}`],\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <div\n ref={rootRef}\n className={rootCls}\n role=\"group\"\n aria-label={ariaLabel}\n style={style}\n >\n {items.map((item, i) => {\n const cls = `${s.segment}${item.selected ? ` ${s.segmentSelected}` : ''}`;\n return (\n <button\n key={item.value}\n type=\"button\"\n aria-pressed={item.selected}\n aria-label={item.ariaLabel}\n disabled={item.disabled}\n tabIndex={i === tabStopIndex ? 0 : -1}\n className={cls}\n onClick={() => toggle(i)}\n onKeyDown={handleKeyDown(i)}\n >\n {item.label}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;AC4BA,SAAS,EAAkB,GAA2D;CACpF,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAAK,IAAI,CAAC,EAAM,GAAG,UAAU,OAAO;CACtE,OAAO;;AAGT,SAAS,EAAiB,GAA2D;CACnF,KAAK,IAAI,IAAI,EAAM,SAAS,GAAG,KAAK,GAAG,KAAK,IAAI,CAAC,EAAM,GAAG,UAAU,OAAO;CAC3E,OAAO;;AAGT,SAAS,EAAiB,GAAmD,GAAsB;CACjG,IAAM,IAAI,EAAM;CAChB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC3B,IAAM,KAAK,IAAO,IAAI,KAAK;EAC3B,IAAI,CAAC,EAAM,GAAG,UAAU,OAAO;;CAEjC,OAAO;;AAGT,SAAS,EAAiB,GAAmD,GAAsB;CACjG,IAAM,IAAI,EAAM;CAChB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC3B,IAAM,KAAK,IAAO,IAAI,KAAK;EAC3B,IAAI,CAAC,EAAM,GAAG,UAAU,OAAO;;CAEjC,OAAO;;AAGT,SAAgB,EAA+C,GAAyC;CACtG,IAAM,EAAE,UAAO,cAAW,cAAW,WAAQ,SAAM,eAAY,GACzD,IAAU,EAA8B,KAAK,EAE7C,IAAe,EAAkB,EAAM,EAEvC,KAAU,MAAkB;EAChC,IAAM,IAAO,EAAM;EACf,EAAK,YACT,EAAK,SAAS,CAAC,EAAK,SAAS;IAGzB,KAAgB,MAAkB;EACtC,IAAM,IAAO,EAAQ;EAChB,KAEL,EADqB,iBAAoC,IAAI,EAAE,UAC/D,CAAQ,IAAQ,OAAO;IAGnB,KAAiB,OAAmB,MAA6C;EACrF,IAAI,IAAY;EAChB,QAAQ,EAAE,KAAV;GACE,KAAK;GACL,KAAK;IACH,IAAY,EAAiB,GAAO,EAAM;IAC1C;GACF,KAAK;GACL,KAAK;IACH,IAAY,EAAiB,GAAO,EAAM;IAC1C;GACF,KAAK;IACH,IAAY,EAAkB,EAAM;IACpC;GACF,KAAK;IACH,IAAY,EAAiB,EAAM;IACnC;GACF,KAAK;GACL,KAAK;IAEH,AADA,EAAE,gBAAgB,EAClB,EAAO,EAAM;IACb;GACF,SACE;;EAEA,IAAY,KAAK,MAAc,MACnC,EAAE,gBAAgB,EAClB,EAAa,EAAU;IAGnB,IAAmC,MAAW,KAAA,IAEhD,KAAA,IADC,EAAG,mBAA8B,GAAG,EAAO,KAAK;CAUrD,OACE,kBAAC,OAAD;EACE,KAAK;EACL,WAVY;GACd,EAAE;GACF,KAAQ,EAAE,QAAQ;GAClB,KAAW,EAAE,WAAW;GACxB;GACD,CAAC,OAAO,QAAQ,CAAC,KAAK,IAKR;EACX,MAAK;EACL,cAAY;EACL;YAEN,EAAM,KAAK,GAAM,MAAM;GACtB,IAAM,IAAM,GAAG,EAAE,UAAU,EAAK,WAAW,IAAI,EAAE,oBAAoB;GACrE,OACE,kBAAC,UAAD;IAEE,MAAK;IACL,gBAAc,EAAK;IACnB,cAAY,EAAK;IACjB,UAAU,EAAK;IACf,UAAU,MAAM,IAAe,IAAI;IACnC,WAAW;IACX,eAAe,EAAO,EAAE;IACxB,WAAW,EAAc,EAAE;cAE1B,EAAK;IACC,EAXF,EAAK,MAWH;IAEX;EACE,CAAA"}