@xsynaptic/sonic-ui 0.10.3 → 0.12.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 (68) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +12 -0
  3. package/dist/default/define/toggle.js +7 -0
  4. package/dist/default/define.js +1 -0
  5. package/dist/default/elements/button.js +2 -0
  6. package/dist/default/elements/position-group.js +163 -0
  7. package/dist/default/elements/radio-group.js +34 -12
  8. package/dist/default/elements/sonic-element.js +11 -2
  9. package/dist/default/elements/switch.js +34 -168
  10. package/dist/default/elements/toggle.js +189 -0
  11. package/dist/default/elements/value-element.js +9 -0
  12. package/dist/default/elements/waveform.js +38 -19
  13. package/dist/default/elements/wavestrip.js +6 -1
  14. package/dist/default/index.js +2 -1
  15. package/dist/default/lib/key-press.js +27 -0
  16. package/dist/default/lib/strip-scene.js +4 -3
  17. package/dist/default/lib/toggle-travel.js +19 -0
  18. package/dist/dev/define/toggle.d.ts +2 -0
  19. package/dist/dev/define/toggle.js +8 -0
  20. package/dist/dev/define/toggle.js.map +1 -0
  21. package/dist/dev/define.d.ts +3 -1
  22. package/dist/dev/define.js +1 -0
  23. package/dist/dev/elements/button.js +2 -0
  24. package/dist/dev/elements/button.js.map +1 -1
  25. package/dist/dev/elements/position-group.d.ts +38 -0
  26. package/dist/dev/elements/position-group.js +164 -0
  27. package/dist/dev/elements/position-group.js.map +1 -0
  28. package/dist/dev/elements/radio-group.d.ts +4 -0
  29. package/dist/dev/elements/radio-group.js +34 -12
  30. package/dist/dev/elements/radio-group.js.map +1 -1
  31. package/dist/dev/elements/sonic-element.d.ts +1 -0
  32. package/dist/dev/elements/sonic-element.js +11 -2
  33. package/dist/dev/elements/sonic-element.js.map +1 -1
  34. package/dist/dev/elements/switch.d.ts +4 -19
  35. package/dist/dev/elements/switch.js +34 -168
  36. package/dist/dev/elements/switch.js.map +1 -1
  37. package/dist/dev/elements/toggle.d.ts +21 -0
  38. package/dist/dev/elements/toggle.js +197 -0
  39. package/dist/dev/elements/toggle.js.map +1 -0
  40. package/dist/dev/elements/value-element.d.ts +3 -0
  41. package/dist/dev/elements/value-element.js +9 -0
  42. package/dist/dev/elements/value-element.js.map +1 -1
  43. package/dist/dev/elements/waveform.d.ts +1 -1
  44. package/dist/dev/elements/waveform.js +38 -19
  45. package/dist/dev/elements/waveform.js.map +1 -1
  46. package/dist/dev/elements/wavestrip.d.ts +3 -0
  47. package/dist/dev/elements/wavestrip.js +6 -1
  48. package/dist/dev/elements/wavestrip.js.map +1 -1
  49. package/dist/dev/index.d.ts +3 -2
  50. package/dist/dev/index.js +2 -1
  51. package/dist/dev/lib/key-press.js +28 -0
  52. package/dist/dev/lib/key-press.js.map +1 -0
  53. package/dist/dev/lib/strip-scene.js +4 -3
  54. package/dist/dev/lib/strip-scene.js.map +1 -1
  55. package/dist/dev/lib/toggle-travel.js +20 -0
  56. package/dist/dev/lib/toggle-travel.js.map +1 -0
  57. package/dist/styles/button.css +2 -2
  58. package/dist/styles/controls.css +1 -0
  59. package/dist/styles/led.css +16 -13
  60. package/dist/styles/material.css +36 -9
  61. package/dist/styles/meter.css +7 -6
  62. package/dist/styles/segmented.css +8 -4
  63. package/dist/styles/spectrum.css +2 -2
  64. package/dist/styles/switch.css +6 -2
  65. package/dist/styles/toggle.css +481 -0
  66. package/dist/styles/waveform.css +5 -2
  67. package/dist/styles/wavestrip.css +7 -0
  68. package/package.json +2 -1
@@ -78,7 +78,7 @@
78
78
  transition: color 120ms ease-out;
79
79
  }
80
80
 
81
- .sonic-segmented-option:where([data-sonic-pressed], :focus-visible:active):not(:disabled),
81
+ .sonic-segmented-option:where([data-sonic-pressed]):not(:disabled),
82
82
  .sonic-segmented-option[aria-checked='true'] {
83
83
  --_sonic-keycap-shift: calc(var(--_sonic-keycap-depth) / 2);
84
84
  --_sonic-keycap-scale: var(--_sonic-segmented-press-scale);
@@ -88,7 +88,7 @@
88
88
  .sonic-segmented-option[aria-checked='true'] {
89
89
  --_sonic-keycap-glow: var(--_sonic-keycap-lit-glow);
90
90
 
91
- color: var(--_sonic-lit);
91
+ color: var(--_sonic-legend-lit, var(--_sonic-lit));
92
92
  background: var(--_sonic-segmented-well-lit);
93
93
  box-shadow: var(--_sonic-well);
94
94
  }
@@ -115,12 +115,16 @@
115
115
  }
116
116
 
117
117
  .sonic-segmented-option[aria-checked='true']:not(:disabled):focus-visible {
118
- color: var(--sonic-lit-hover, var(--_sonic-lit));
118
+ --_sonic-legend-lit-from: var(--sonic-lit-hover, var(--_sonic-lit));
119
+
120
+ color: var(--_sonic-legend-lit, var(--_sonic-legend-lit-from));
119
121
  }
120
122
 
121
123
  @media (hover: hover) {
122
124
  .sonic-segmented-option[aria-checked='true']:not(:disabled):hover {
123
- color: var(--sonic-lit-hover, var(--_sonic-lit));
125
+ --_sonic-legend-lit-from: var(--sonic-lit-hover, var(--_sonic-lit));
126
+
127
+ color: var(--_sonic-legend-lit, var(--_sonic-legend-lit-from));
124
128
  }
125
129
  }
126
130
 
@@ -67,8 +67,8 @@
67
67
  .sonic-spectrum {
68
68
  --_sonic-unit: calc(var(--_sonic-spectrum-size) / 48);
69
69
  --_sonic-spectrum-lit: var(--_sonic-lit);
70
- --_sonic-spectrum-hot: var(--_sonic-hot);
71
- --_sonic-spectrum-clip: var(--_sonic-clip);
70
+ --_sonic-spectrum-hot: var(--_sonic-lit-warning);
71
+ --_sonic-spectrum-clip: var(--_sonic-lit-danger);
72
72
  --_sonic-spectrum-grid: color-mix(in oklab, var(--_sonic-glass-text) 20%, transparent);
73
73
  --_sonic-spectrum-hot-from: var(--sonic-spectrum-hot-from, -12);
74
74
  --_sonic-spectrum-clip-from: var(--sonic-spectrum-clip-from, -3);
@@ -127,6 +127,10 @@
127
127
  }
128
128
  }
129
129
 
130
+ .sonic-switch-position:disabled > .sonic-switch-label {
131
+ color: color-mix(in oklab, currentcolor 30%, transparent);
132
+ }
133
+
130
134
  .sonic-switch[data-sonic-position-count] {
131
135
  & > :is(.sonic-switch-bushing, .sonic-switch-bat) {
132
136
  grid-area: 2 / 1 / -2 / 2;
@@ -350,7 +354,7 @@
350
354
  --_sonic-focus-shadow: var(--_sonic-focus-glow);
351
355
  }
352
356
 
353
- .sonic-switch:has(> .sonic-switch-position:disabled) {
357
+ .sonic-switch:not(:has(> .sonic-switch-position:not(:disabled))) {
354
358
  --_sonic-switch-disabled: color-mix(
355
359
  in oklab,
356
360
  var(--_sonic-ink) 30%,
@@ -371,7 +375,7 @@
371
375
  --_sonic-switch-metal-shade: CanvasText;
372
376
  }
373
377
 
374
- .sonic-switch:has(> .sonic-switch-position:disabled) {
378
+ .sonic-switch:not(:has(> .sonic-switch-position:not(:disabled))) {
375
379
  --_sonic-switch-metal: GrayText;
376
380
  --_sonic-switch-metal-shade: GrayText;
377
381
  }
@@ -0,0 +1,481 @@
1
+ @property --_sonic-toggle-size {
2
+ syntax: '<length>';
3
+ inherits: true;
4
+ initial-value: 32px;
5
+ }
6
+
7
+ @property --_sonic-toggle-at {
8
+ syntax: '<number>';
9
+ inherits: true;
10
+ initial-value: 0;
11
+ }
12
+
13
+ @property --_sonic-toggle-sink {
14
+ syntax: '<length>';
15
+ inherits: true;
16
+ initial-value: 0;
17
+ }
18
+
19
+ @property --_sonic-toggle-well-tint {
20
+ syntax: '<color>';
21
+ inherits: false;
22
+ initial-value: transparent;
23
+ }
24
+
25
+ @layer sonic {
26
+ :is(sonic-toggle, .sonic-toggle) {
27
+ --_sonic-toggle-size: var(--sonic-toggle-size, 2rem);
28
+ }
29
+
30
+ :has(> .sonic-toggle):not([hidden]) {
31
+ display: contents;
32
+ }
33
+
34
+ sonic-toggle:not(:defined, [hidden]) {
35
+ display: block;
36
+ visibility: hidden;
37
+ flex-shrink: 0;
38
+ inline-size: var(--_sonic-toggle-size);
39
+ block-size: var(--_sonic-toggle-size);
40
+ overflow: hidden;
41
+ }
42
+
43
+ .sonic-toggle {
44
+ --_sonic-toggle-travel-ratio: var(--sonic-toggle-travel-ratio, 0.75);
45
+ --_sonic-toggle-gap-ratio: var(
46
+ --sonic-toggle-gap-ratio,
47
+ calc(0.14 - 0.06 * var(--_sonic-relief))
48
+ );
49
+ --_sonic-toggle-radius-ratio: var(--sonic-toggle-radius-ratio, 0.5);
50
+ --_sonic-toggle-bevel-ratio: var(--sonic-toggle-bevel-ratio, 0.075);
51
+ --_sonic-toggle-depth-ratio: var(--sonic-toggle-depth-ratio, calc(0.03 * var(--_sonic-relief)));
52
+ --_sonic-toggle-font-ratio: var(--sonic-toggle-font-ratio, 0.26);
53
+ --_sonic-toggle-press-scale: var(--sonic-toggle-press-scale, 0.985);
54
+ --_sonic-toggle-icon-ratio: var(--sonic-toggle-icon-ratio, 0.5);
55
+ --_sonic-toggle-led-ratio: var(--sonic-toggle-led-ratio, 0.25);
56
+ --_sonic-toggle-well-glow: color-mix(
57
+ in oklab,
58
+ var(--_sonic-lit) calc(100% * var(--_sonic-relief)),
59
+ transparent
60
+ );
61
+ --_sonic-toggle-well-lit: var(--sonic-well-lit, var(--_sonic-toggle-well-glow));
62
+ --_sonic-toggle-well-fill: transparent;
63
+ --_sonic-toggle-sink: 0px;
64
+ --_sonic-toggle-well-forced: Canvas;
65
+ --_sonic-toggle-count: 2;
66
+ --_sonic-toggle-along-x: 1;
67
+ --_sonic-toggle-along-y: 0;
68
+ --_sonic-toggle-disc: var(--_sonic-ink);
69
+ --_sonic-cap: var(--sonic-cap, var(--_sonic-toggle-disc));
70
+ --_sonic-cap-hover: var(--sonic-cap-hover, var(--sonic-cap, var(--_sonic-toggle-disc)));
71
+ --_sonic-toggle-pole: oklch(from var(--_sonic-cap) clamp(0, (0.6 - l) * 1000, 1) 0 0deg / 100%);
72
+ --_sonic-toggle-ink-set: color-mix(in oklab, var(--sonic-cap) 0%, var(--_sonic-ink));
73
+ --_sonic-toggle-legend: var(--_sonic-toggle-ink-set, var(--_sonic-toggle-pole));
74
+ --_sonic-toggle-legend-lit: var(--_sonic-legend-lit, var(--_sonic-toggle-pole));
75
+ --_sonic-toggle-well-edge-off: color-mix(in oklab, var(--sonic-well) 0%, transparent);
76
+ --_sonic-toggle-well-edge: var(--_sonic-toggle-well-edge-off, var(--_sonic-etch));
77
+ --_sonic-toggle-led-ring-off: color-mix(in oklab, var(--sonic-cap) 0%, transparent);
78
+ --_sonic-toggle-led-ring: var(--_sonic-toggle-led-ring-off, var(--_sonic-toggle-pole));
79
+ --_sonic-unit: calc(var(--_sonic-toggle-size) / 32);
80
+ --_sonic-toggle-step: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-travel-ratio));
81
+ --_sonic-toggle-gap: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-gap-ratio));
82
+ --_sonic-toggle-cap-size: calc(var(--_sonic-toggle-size) - 2 * var(--_sonic-toggle-gap));
83
+ --_sonic-toggle-slice: calc(
84
+ (var(--_sonic-toggle-size) + var(--_sonic-toggle-run)) / var(--_sonic-toggle-count)
85
+ );
86
+ --_sonic-toggle-run: calc((var(--_sonic-toggle-count) - 1) * var(--_sonic-toggle-step));
87
+ --_sonic-toggle-mid: calc((var(--_sonic-toggle-count) - 1) / 2);
88
+ --_sonic-toggle-throw: calc(
89
+ (var(--_sonic-toggle-at) - var(--_sonic-toggle-mid)) * var(--_sonic-toggle-step)
90
+ );
91
+ --_sonic-toggle-corner: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-radius-ratio));
92
+ --_sonic-keycap-depth: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-depth-ratio));
93
+ --_sonic-keycap-corner: max(0px, var(--_sonic-toggle-corner) - var(--_sonic-toggle-gap));
94
+ --_sonic-keycap-bevel: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-bevel-ratio));
95
+ --_sonic-keycap-face-corner: max(0px, var(--_sonic-keycap-corner) - var(--_sonic-keycap-bevel));
96
+
97
+ position: relative;
98
+ display: inline-grid;
99
+ flex-shrink: 0;
100
+ grid-template-rows: var(--_sonic-toggle-size);
101
+ grid-auto-columns: var(--_sonic-toggle-slice);
102
+ grid-auto-flow: column;
103
+ line-height: 1;
104
+ touch-action: pan-y;
105
+ user-select: none;
106
+ transition:
107
+ --_sonic-toggle-at 120ms cubic-bezier(0.4, 0, 0.2, 1),
108
+ --_sonic-toggle-sink 60ms cubic-bezier(0.4, 0, 0.2, 1);
109
+ }
110
+
111
+ [orientation='vertical'] > .sonic-toggle {
112
+ --_sonic-toggle-along-x: 0;
113
+ --_sonic-toggle-along-y: 1;
114
+
115
+ grid-template-rows: none;
116
+ grid-template-columns: var(--_sonic-toggle-size);
117
+ grid-auto-rows: var(--_sonic-toggle-slice);
118
+ grid-auto-flow: row;
119
+ touch-action: pan-x;
120
+ }
121
+
122
+ :state(dragging) > .sonic-toggle {
123
+ transition: --_sonic-toggle-sink 60ms cubic-bezier(0.4, 0, 0.2, 1);
124
+ }
125
+
126
+ [data-sonic-lit='ok'] > .sonic-toggle:has(> [role='switch']),
127
+ .sonic-toggle:has(> [aria-checked='true'] [data-sonic-lit='ok']) {
128
+ --_sonic-lit: var(--_sonic-lit-ok);
129
+ }
130
+
131
+ [data-sonic-lit='warning'] > .sonic-toggle:has(> [role='switch']),
132
+ .sonic-toggle:has(> [aria-checked='true'] [data-sonic-lit='warning']) {
133
+ --_sonic-lit: var(--_sonic-lit-warning);
134
+ }
135
+
136
+ [data-sonic-lit='danger'] > .sonic-toggle:has(> [role='switch']),
137
+ .sonic-toggle:has(> [aria-checked='true'] [data-sonic-lit='danger']) {
138
+ --_sonic-lit: var(--_sonic-lit-danger);
139
+ }
140
+
141
+ /* `--sonic-well-lit` holds a skin's one lit colour, so a coloured position takes only whether it is set */
142
+ [data-sonic-lit]:where(:not([data-sonic-lit=''], [data-sonic-lit='idle']))
143
+ > .sonic-toggle:has(> [role='switch']),
144
+ .sonic-toggle:has(
145
+ > [aria-checked='true']
146
+ [data-sonic-lit]:where(:not([data-sonic-lit=''], [data-sonic-lit='idle']))
147
+ ) {
148
+ --_sonic-toggle-well-lit-set: color-mix(in oklab, var(--sonic-well-lit) 0%, var(--_sonic-lit));
149
+ --_sonic-toggle-well-lit: var(--_sonic-toggle-well-lit-set, var(--_sonic-toggle-well-glow));
150
+ }
151
+
152
+ :where([data-sonic-lit]) > .sonic-toggle:has(> [role='switch'][aria-checked='true']),
153
+ .sonic-toggle:has(> [aria-checked='true'] [data-sonic-lit]) {
154
+ --_sonic-toggle-disc: var(--_sonic-lit);
155
+ --_sonic-toggle-well-fill: var(--_sonic-toggle-well-lit);
156
+ --_sonic-toggle-well-forced: var(--_sonic-lit);
157
+ }
158
+
159
+ .sonic-toggle:not(:has(> .sonic-toggle-position:not(:disabled))) {
160
+ --_sonic-lit: var(--_sonic-lit-disabled);
161
+ --_sonic-toggle-disc: var(--_sonic-etch);
162
+ --_sonic-toggle-ink-set: color-mix(in oklab, var(--sonic-cap) 0%, var(--_sonic-etch));
163
+ --_sonic-legend-lit: color-mix(in oklab, var(--sonic-cap) 0%, var(--_sonic-lit));
164
+ }
165
+
166
+ .sonic-toggle:has(> .sonic-toggle-position:focus-visible) {
167
+ --_sonic-cap: var(--_sonic-cap-hover);
168
+ --_sonic-focus-shadow: var(--_sonic-focus-glow);
169
+ }
170
+
171
+ @media (hover: hover) {
172
+ .sonic-toggle:has(> .sonic-toggle-position:not(:disabled):hover) {
173
+ --_sonic-cap: var(--_sonic-cap-hover);
174
+ }
175
+ }
176
+
177
+ /* Held, never resting: the chosen position's cap stands as proud as any other */
178
+ .sonic-toggle:has(> .sonic-toggle-position[data-sonic-pressed]):has(
179
+ > .sonic-toggle-position:not(:disabled)
180
+ ) {
181
+ --_sonic-toggle-sink: calc(var(--_sonic-keycap-depth) / 2);
182
+ --_sonic-keycap-scale: var(--_sonic-toggle-press-scale);
183
+ --_sonic-keycap-drop: var(--_sonic-press-drop);
184
+ }
185
+
186
+ .sonic-toggle-well {
187
+ --_sonic-toggle-well-tint: var(--_sonic-toggle-well-fill);
188
+
189
+ position: absolute;
190
+ inset: 0;
191
+ inline-size: calc(
192
+ var(--_sonic-toggle-size) + var(--_sonic-toggle-along-x) * var(--_sonic-toggle-run)
193
+ );
194
+ block-size: calc(
195
+ var(--_sonic-toggle-size) + var(--_sonic-toggle-along-y) * var(--_sonic-toggle-run)
196
+ );
197
+ margin: auto;
198
+ pointer-events: none;
199
+ background:
200
+ linear-gradient(var(--_sonic-toggle-well-tint), var(--_sonic-toggle-well-tint)),
201
+ var(--_sonic-well-floor);
202
+ border-radius: var(--_sonic-toggle-corner);
203
+ box-shadow:
204
+ var(--_sonic-well),
205
+ inset 0 0 0 calc(1px * (1 - var(--_sonic-relief))) var(--_sonic-toggle-well-edge);
206
+ transition: --_sonic-toggle-well-tint 120ms ease-out;
207
+ }
208
+
209
+ /* The position rides `--_sonic-toggle-at`, which already eases; easing the offset too would trail a drag */
210
+ .sonic-toggle-cap {
211
+ position: absolute;
212
+ inset: 0;
213
+ inline-size: var(--_sonic-toggle-cap-size);
214
+ block-size: var(--_sonic-toggle-cap-size);
215
+ margin: auto;
216
+ pointer-events: none;
217
+ translate: calc(var(--_sonic-toggle-along-x) * var(--_sonic-toggle-throw))
218
+ calc(var(--_sonic-toggle-along-y) * var(--_sonic-toggle-throw) + var(--_sonic-toggle-sink));
219
+ transition:
220
+ scale 60ms cubic-bezier(0.4, 0, 0.2, 1),
221
+ box-shadow 60ms cubic-bezier(0.4, 0, 0.2, 1);
222
+
223
+ & > .sonic-led {
224
+ --_sonic-led-size: var(
225
+ --sonic-led-size,
226
+ calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-led-ratio))
227
+ );
228
+ --_sonic-lit: inherit;
229
+
230
+ box-shadow: inset 0 0 0 max(1px, 0.1 * var(--_sonic-led-size)) var(--_sonic-toggle-led-ring);
231
+ }
232
+
233
+ & > * {
234
+ color: var(--_sonic-toggle-legend);
235
+ }
236
+ }
237
+
238
+ .sonic-toggle-position {
239
+ position: relative;
240
+ padding: 0;
241
+ font: inherit;
242
+ font-size: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-font-ratio));
243
+ line-height: 1;
244
+ color: inherit;
245
+ text-transform: inherit;
246
+ letter-spacing: inherit;
247
+ cursor: pointer;
248
+ background: transparent;
249
+ border: 0;
250
+ }
251
+
252
+ .sonic-toggle-position:focus-visible {
253
+ outline: 2px solid transparent;
254
+ outline-offset: -2px;
255
+ }
256
+
257
+ .sonic-toggle-position:disabled {
258
+ cursor: default;
259
+ }
260
+
261
+ .sonic-toggle-position:has([data-sonic-momentary]),
262
+ .sonic-toggle[data-sonic-position-count='2']:has([data-sonic-momentary])
263
+ > .sonic-toggle-position {
264
+ touch-action: none;
265
+ }
266
+
267
+ .sonic-toggle-position::after {
268
+ inset-inline: 0;
269
+ }
270
+
271
+ [orientation='vertical'] > .sonic-toggle > .sonic-toggle-position::after {
272
+ inset-block: 0;
273
+ inset-inline: var(--_sonic-target-outset);
274
+ }
275
+
276
+ .sonic-toggle-position[role='switch'] {
277
+ grid-column: span 2;
278
+ }
279
+
280
+ [orientation='vertical'] > .sonic-toggle > .sonic-toggle-position[role='switch'] {
281
+ grid-row: span 2;
282
+ grid-column: auto;
283
+ }
284
+
285
+ /* Every legend sits at the cap, so a press must fall through to the position under it */
286
+ .sonic-toggle-legend {
287
+ --_sonic-toggle-ride: calc(
288
+ var(--_sonic-toggle-throw) - (var(--_sonic-toggle-index, 0) - var(--_sonic-toggle-mid)) *
289
+ var(--_sonic-toggle-slice)
290
+ );
291
+
292
+ position: absolute;
293
+ inset: 0;
294
+ display: grid;
295
+ place-items: center;
296
+ inline-size: var(--_sonic-toggle-cap-size);
297
+ block-size: var(--_sonic-toggle-cap-size);
298
+ margin: auto;
299
+ color: var(--_sonic-toggle-legend);
300
+ white-space: nowrap;
301
+ pointer-events: none;
302
+ opacity: 0;
303
+ translate: calc(var(--_sonic-toggle-along-x) * var(--_sonic-toggle-ride))
304
+ calc(var(--_sonic-toggle-along-y) * var(--_sonic-toggle-ride) + var(--_sonic-toggle-sink));
305
+ transition: opacity 120ms ease-out;
306
+
307
+ & > * {
308
+ filter: var(--_sonic-engraving);
309
+ }
310
+ }
311
+
312
+ :is(.sonic-toggle-cap, .sonic-toggle-legend) > svg {
313
+ display: block;
314
+ inline-size: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-icon-ratio));
315
+ block-size: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-icon-ratio));
316
+ }
317
+
318
+ .sonic-toggle-position[aria-checked='true'] > .sonic-toggle-legend {
319
+ opacity: 1;
320
+ }
321
+
322
+ .sonic-toggle-position[aria-checked='true']:has([data-sonic-lit]) > .sonic-toggle-legend {
323
+ color: var(--_sonic-toggle-legend-lit);
324
+
325
+ & > * {
326
+ filter: var(--_sonic-engraving) var(--_sonic-legend-glow);
327
+ }
328
+ }
329
+
330
+ [legends='outside'] > .sonic-toggle[data-sonic-position-count] {
331
+ & > :is(.sonic-toggle-well, .sonic-toggle-cap) {
332
+ grid-area: 1 / 2 / 2 / -2;
333
+ }
334
+
335
+ & > .sonic-toggle-position {
336
+ display: grid;
337
+ grid-area: 1 / 1 / 2 / 3;
338
+ grid-template: subgrid / subgrid;
339
+ place-items: center;
340
+ }
341
+
342
+ & > .sonic-toggle-position > .sonic-toggle-legend {
343
+ position: static;
344
+ display: block;
345
+ inline-size: auto;
346
+ block-size: auto;
347
+ padding: calc(var(--_sonic-toggle-size) * 0.12);
348
+ margin: 0;
349
+ color: inherit;
350
+ pointer-events: auto;
351
+ opacity: 1;
352
+ translate: none;
353
+
354
+ & > * {
355
+ filter: none;
356
+ }
357
+ }
358
+
359
+ & > .sonic-toggle-position:disabled > .sonic-toggle-legend {
360
+ color: color-mix(in oklab, currentcolor 30%, transparent);
361
+ }
362
+
363
+ & > .sonic-toggle-position:last-child > .sonic-toggle-legend {
364
+ grid-column: 2;
365
+ }
366
+ }
367
+
368
+ [legends='outside'][orientation='vertical'] > .sonic-toggle[data-sonic-position-count] {
369
+ & > :is(.sonic-toggle-well, .sonic-toggle-cap) {
370
+ grid-area: 2 / 1 / -2 / 2;
371
+ }
372
+
373
+ & > .sonic-toggle-position {
374
+ grid-area: 1 / 1 / 3 / 2;
375
+ }
376
+
377
+ & > .sonic-toggle-position:last-child > .sonic-toggle-legend {
378
+ grid-area: 2 / 1;
379
+ }
380
+ }
381
+
382
+ [legends='outside'] > .sonic-toggle[data-sonic-position-count='2'] {
383
+ grid-template: var(--_sonic-toggle-size) / auto repeat(2, var(--_sonic-toggle-slice)) auto;
384
+
385
+ & > .sonic-toggle-position:last-child {
386
+ grid-area: 1 / 3 / 2 / 5;
387
+ }
388
+ }
389
+
390
+ [legends='outside'] > .sonic-toggle[data-sonic-position-count='3'] {
391
+ grid-template: var(--_sonic-toggle-size) auto / auto repeat(3, var(--_sonic-toggle-slice)) auto;
392
+
393
+ & > .sonic-toggle-position:last-child {
394
+ grid-area: 1 / 4 / 2 / 6;
395
+ }
396
+
397
+ & > .sonic-toggle-position:nth-child(2 of .sonic-toggle-position) {
398
+ grid-area: 1 / 3 / 3 / 4;
399
+
400
+ & > .sonic-toggle-legend {
401
+ grid-row: 2;
402
+ }
403
+ }
404
+ }
405
+
406
+ [legends='outside'][orientation='vertical'] > .sonic-toggle[data-sonic-position-count='2'] {
407
+ grid-template:
408
+ auto repeat(2, var(--_sonic-toggle-slice)) auto /
409
+ minmax(var(--_sonic-toggle-size), auto);
410
+
411
+ & > .sonic-toggle-position:last-child {
412
+ grid-area: 3 / 1 / 5 / 2;
413
+ }
414
+ }
415
+
416
+ [legends='outside'][orientation='vertical'] > .sonic-toggle[data-sonic-position-count='3'] {
417
+ grid-template:
418
+ auto repeat(3, var(--_sonic-toggle-slice)) auto /
419
+ minmax(var(--_sonic-toggle-size), auto) auto;
420
+
421
+ & > .sonic-toggle-position:last-child {
422
+ grid-area: 4 / 1 / 6 / 2;
423
+ }
424
+
425
+ & > .sonic-toggle-position:nth-child(2 of .sonic-toggle-position) {
426
+ grid-area: 3 / 1 / 4 / 3;
427
+
428
+ & > .sonic-toggle-legend {
429
+ grid-area: 1 / 2;
430
+ }
431
+ }
432
+ }
433
+
434
+ @media (prefers-reduced-motion: reduce) {
435
+ .sonic-toggle,
436
+ :state(dragging) > .sonic-toggle,
437
+ .sonic-toggle-well,
438
+ .sonic-toggle-cap,
439
+ .sonic-toggle-legend {
440
+ transition: none;
441
+ }
442
+ }
443
+
444
+ @media (forced-colors: active) {
445
+ .sonic-toggle {
446
+ --_sonic-skirt: CanvasText;
447
+ --_sonic-face: CanvasText;
448
+ --_sonic-rim: 0 0 0 var(--_sonic-rim-width) Canvas;
449
+ --_sonic-toggle-legend: Canvas;
450
+ --_sonic-toggle-legend-lit: Canvas;
451
+ --_sonic-toggle-led-ring: transparent;
452
+ }
453
+
454
+ .sonic-toggle:not(:has(> .sonic-toggle-position:not(:disabled))) {
455
+ --_sonic-skirt: GrayText;
456
+ --_sonic-face: GrayText;
457
+ }
458
+
459
+ .sonic-toggle-well {
460
+ forced-color-adjust: none;
461
+ background: var(--_sonic-toggle-well-forced);
462
+ box-shadow: inset 0 0 0 1px CanvasText;
463
+ }
464
+
465
+ .sonic-toggle-position:focus-visible {
466
+ outline-offset: 2px;
467
+ }
468
+
469
+ .sonic-toggle-legend {
470
+ forced-color-adjust: none;
471
+ }
472
+
473
+ [legends='outside'] > .sonic-toggle > .sonic-toggle-position > .sonic-toggle-legend {
474
+ forced-color-adjust: auto;
475
+ }
476
+
477
+ .sonic-toggle-position > .sonic-toggle-legend > * {
478
+ filter: none;
479
+ }
480
+ }
481
+ }
@@ -190,8 +190,11 @@
190
190
  padding: 0.2em 0.35em;
191
191
  margin: -0.2em -0.35em;
192
192
  font-family: var(--sonic-waveform-label-font, inherit);
193
- font-size: calc(var(--_sonic-waveform-size) * var(--sonic-waveform-label-font-ratio, 0.13));
194
- line-height: 1;
193
+ font-size: var(
194
+ --sonic-waveform-label-font-size,
195
+ calc(var(--_sonic-waveform-size) * var(--sonic-waveform-label-font-ratio, 0.13))
196
+ );
197
+ line-height: var(--sonic-waveform-label-line-height, 1);
195
198
  color: var(--_sonic-marker, var(--_sonic-waveform-label));
196
199
  white-space: nowrap;
197
200
  text-shadow: var(--sonic-waveform-label-shadow, none);
@@ -34,6 +34,12 @@
34
34
  initial-value: 0.15;
35
35
  }
36
36
 
37
+ @property --_sonic-wavestrip-groove-size {
38
+ syntax: '<length>';
39
+ inherits: true;
40
+ initial-value: 0;
41
+ }
42
+
37
43
  @property --_sonic-wavestrip-wave {
38
44
  syntax: '<color>';
39
45
  inherits: true;
@@ -100,6 +106,7 @@
100
106
  --_sonic-wavestrip-bar-gap-ratio: var(--sonic-wavestrip-bar-gap-ratio, 0.33);
101
107
  --_sonic-wavestrip-bar-radius-ratio: var(--sonic-wavestrip-bar-radius-ratio, 0.5);
102
108
  --_sonic-wavestrip-groove-ratio: var(--sonic-wavestrip-groove-ratio, 0.15);
109
+ --_sonic-wavestrip-groove-size: var(--sonic-wavestrip-groove-size, 0px);
103
110
  --_sonic-wavestrip-marker-ratio: var(--sonic-wavestrip-marker-ratio, 0.065);
104
111
  --_sonic-wavestrip-inset: calc(
105
112
  var(--_sonic-wavestrip-size) * var(--sonic-wavestrip-inset-ratio, 0.1)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsynaptic/sonic-ui",
3
- "version": "0.10.3",
3
+ "version": "0.12.0",
4
4
  "description": "Native custom elements for audio interfaces, skinned with CSS custom properties",
5
5
  "keywords": [
6
6
  "custom-elements",
@@ -68,6 +68,7 @@
68
68
  "./slider.css": "./dist/styles/slider.css",
69
69
  "./spectrum.css": "./dist/styles/spectrum.css",
70
70
  "./switch.css": "./dist/styles/switch.css",
71
+ "./toggle.css": "./dist/styles/toggle.css",
71
72
  "./waveform.css": "./dist/styles/waveform.css",
72
73
  "./wavestrip.css": "./dist/styles/wavestrip.css",
73
74
  "./xy.css": "./dist/styles/xy.css",