@xsynaptic/sonic-ui 0.18.0 → 0.20.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 (101) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +20 -9
  3. package/dist/default/elements/button.js +0 -5
  4. package/dist/default/elements/dial.js +0 -7
  5. package/dist/default/elements/display-element.js +0 -5
  6. package/dist/default/elements/envelope.js +0 -6
  7. package/dist/default/elements/meter.js +0 -1
  8. package/dist/default/elements/number.js +0 -7
  9. package/dist/default/elements/segmented.js +0 -5
  10. package/dist/default/elements/slider.js +0 -7
  11. package/dist/default/elements/sonic-element.js +3 -1
  12. package/dist/default/elements/switch.js +0 -1
  13. package/dist/default/elements/toggle.js +0 -5
  14. package/dist/default/elements/value-element.js +8 -4
  15. package/dist/default/elements/wave-element.js +7 -8
  16. package/dist/default/elements/xy.js +0 -7
  17. package/dist/default/index.js +2 -1
  18. package/dist/default/lib/canvas-surface.js +5 -1
  19. package/dist/default/lib/clock.js +23 -0
  20. package/dist/default/lib/spoken-duration.js +30 -0
  21. package/dist/default/lib/waveform-buckets.js +7 -1
  22. package/dist/dev/elements/button.js +5 -5
  23. package/dist/dev/elements/button.js.map +1 -1
  24. package/dist/dev/elements/dial.js +4 -7
  25. package/dist/dev/elements/dial.js.map +1 -1
  26. package/dist/dev/elements/display-element.js +1 -5
  27. package/dist/dev/elements/display-element.js.map +1 -1
  28. package/dist/dev/elements/envelope.js +4 -6
  29. package/dist/dev/elements/envelope.js.map +1 -1
  30. package/dist/dev/elements/meter.js +1 -1
  31. package/dist/dev/elements/meter.js.map +1 -1
  32. package/dist/dev/elements/number.js +4 -7
  33. package/dist/dev/elements/number.js.map +1 -1
  34. package/dist/dev/elements/segmented.js +5 -5
  35. package/dist/dev/elements/segmented.js.map +1 -1
  36. package/dist/dev/elements/slider.js +4 -7
  37. package/dist/dev/elements/slider.js.map +1 -1
  38. package/dist/dev/elements/sonic-element.d.ts +6 -16
  39. package/dist/dev/elements/sonic-element.js +54 -29
  40. package/dist/dev/elements/sonic-element.js.map +1 -1
  41. package/dist/dev/elements/split.js.map +1 -1
  42. package/dist/dev/elements/switch.js +4 -1
  43. package/dist/dev/elements/switch.js.map +1 -1
  44. package/dist/dev/elements/toggle.js +5 -5
  45. package/dist/dev/elements/toggle.js.map +1 -1
  46. package/dist/dev/elements/value-element.d.ts +6 -0
  47. package/dist/dev/elements/value-element.js +8 -4
  48. package/dist/dev/elements/value-element.js.map +1 -1
  49. package/dist/dev/elements/wave-element.d.ts +2 -1
  50. package/dist/dev/elements/wave-element.js +11 -8
  51. package/dist/dev/elements/wave-element.js.map +1 -1
  52. package/dist/dev/elements/waveform.d.ts +1 -1
  53. package/dist/dev/elements/xy.js +4 -7
  54. package/dist/dev/elements/xy.js.map +1 -1
  55. package/dist/dev/index.d.ts +3 -2
  56. package/dist/dev/index.js +2 -1
  57. package/dist/dev/lib/canvas-surface.js +5 -1
  58. package/dist/dev/lib/canvas-surface.js.map +1 -1
  59. package/dist/dev/lib/clock.d.ts +5 -0
  60. package/dist/dev/lib/clock.js +24 -0
  61. package/dist/dev/lib/clock.js.map +1 -0
  62. package/dist/dev/lib/mirror-children.js.map +1 -1
  63. package/dist/dev/lib/owned-control.js.map +1 -1
  64. package/dist/dev/lib/spoken-duration.js +31 -0
  65. package/dist/dev/lib/spoken-duration.js.map +1 -0
  66. package/dist/dev/lib/waveform-buckets.d.ts +2 -2
  67. package/dist/dev/lib/waveform-buckets.js +7 -1
  68. package/dist/dev/lib/waveform-buckets.js.map +1 -1
  69. package/dist/styles/button.css +29 -5
  70. package/dist/styles/dial.css +10 -9
  71. package/dist/styles/envelope.css +17 -10
  72. package/dist/styles/led.css +5 -1
  73. package/dist/styles/material/arc.css +3 -2
  74. package/dist/styles/material/bracket.css +3 -3
  75. package/dist/styles/material/cap.css +38 -13
  76. package/dist/styles/material/core.css +4 -0
  77. package/dist/styles/material/glass.css +1 -6
  78. package/dist/styles/material/groove.css +4 -3
  79. package/dist/styles/material/keycap.css +3 -2
  80. package/dist/styles/material/lens.css +1 -1
  81. package/dist/styles/material/pane.css +7 -13
  82. package/dist/styles/material/readout.css +6 -6
  83. package/dist/styles/material/well.css +3 -14
  84. package/dist/styles/meter.css +2 -7
  85. package/dist/styles/number.css +5 -1
  86. package/dist/styles/panel.css +4 -3
  87. package/dist/styles/ring.css +1 -1
  88. package/dist/styles/screen.css +6 -4
  89. package/dist/styles/segmented.css +17 -4
  90. package/dist/styles/slider.css +9 -3
  91. package/dist/styles/spectrum.css +8 -9
  92. package/dist/styles/switch.css +35 -10
  93. package/dist/styles/toggle.css +14 -7
  94. package/dist/styles/waveform.css +17 -18
  95. package/dist/styles/wavestrip.css +12 -25
  96. package/dist/styles/xy.css +46 -25
  97. package/package.json +1 -6
  98. package/dist/default/dat.js +0 -52
  99. package/dist/dev/dat.d.ts +0 -20
  100. package/dist/dev/dat.js +0 -53
  101. package/dist/dev/dat.js.map +0 -1
@@ -35,6 +35,7 @@
35
35
  --_sonic-switch-bat-ratio: var(--sonic-switch-bat-ratio, 0.36);
36
36
  --_sonic-switch-bushing-ratio: var(--sonic-switch-bushing-ratio, 0.62);
37
37
  --_sonic-switch-font-ratio: var(--sonic-switch-font-ratio, 0.4);
38
+ --_sonic-switch-font-own: calc(var(--_sonic-switch-size) * var(--sonic-switch-font-ratio));
38
39
  --_sonic-unit: calc(var(--_sonic-switch-size) / 32);
39
40
  --_sonic-switch-reach: calc(var(--_sonic-switch-size) * var(--_sonic-switch-reach-ratio));
40
41
  --_sonic-switch-ball: calc(var(--_sonic-switch-size) * var(--_sonic-switch-bat-ratio));
@@ -46,12 +47,12 @@
46
47
  --_sonic-switch-metal: color-mix(
47
48
  in oklab,
48
49
  var(--_sonic-switch-cap) calc(100% - 55% * var(--_sonic-relief)),
49
- #fff
50
+ var(--_sonic-shine)
50
51
  );
51
52
  --_sonic-switch-metal-shade: color-mix(
52
53
  in oklab,
53
54
  var(--_sonic-switch-cap) calc(100% - 20% * var(--_sonic-relief)),
54
- #000
55
+ var(--_sonic-shade)
55
56
  );
56
57
 
57
58
  display: inline-grid;
@@ -84,7 +85,13 @@
84
85
  place-self: stretch;
85
86
  padding: 0;
86
87
  font: inherit;
87
- font-size: calc(var(--_sonic-switch-size) * var(--_sonic-switch-font-ratio));
88
+ font-size: var(
89
+ --_sonic-switch-font-own,
90
+ var(
91
+ --sonic-legend-font-size,
92
+ calc(var(--_sonic-switch-size) * var(--_sonic-switch-font-ratio))
93
+ )
94
+ );
88
95
  color: inherit;
89
96
  text-transform: inherit;
90
97
  letter-spacing: inherit;
@@ -241,7 +248,7 @@
241
248
  --_sonic-switch-bushing-shade: color-mix(
242
249
  in oklab,
243
250
  var(--_sonic-cap) calc(100% - 20% * var(--_sonic-relief)),
244
- #000
251
+ var(--_sonic-shade)
245
252
  );
246
253
 
247
254
  inline-size: calc(var(--_sonic-switch-size) * var(--_sonic-switch-bushing-ratio));
@@ -251,10 +258,20 @@
251
258
  --sonic-well,
252
259
  radial-gradient(
253
260
  closest-side,
254
- color-mix(in oklab, var(--_sonic-cap) calc(100% - 70% * var(--_sonic-relief)), #000) 0 42%,
261
+ color-mix(
262
+ in oklab,
263
+ var(--_sonic-cap) calc(100% - 70% * var(--_sonic-relief)),
264
+ var(--_sonic-shade)
265
+ )
266
+ 0 42%,
255
267
  var(--_sonic-switch-bushing-shade) 48%,
256
268
  var(--_sonic-cap) 70%,
257
- color-mix(in oklab, var(--_sonic-cap) calc(100% - 25% * var(--_sonic-relief)), #fff) 88%,
269
+ color-mix(
270
+ in oklab,
271
+ var(--_sonic-cap) calc(100% - 25% * var(--_sonic-relief)),
272
+ var(--_sonic-shine)
273
+ )
274
+ 88%,
258
275
  var(--_sonic-switch-bushing-shade)
259
276
  )
260
277
  );
@@ -266,7 +283,7 @@
266
283
  color-mix(
267
284
  in oklab,
268
285
  var(--_sonic-switch-cap) calc(100% - 60% * var(--_sonic-relief)),
269
- #000
286
+ var(--_sonic-shade)
270
287
  )
271
288
  ),
272
289
  calc(1.5 * var(--_sonic-cast-x)) calc(1.5 * var(--_sonic-cast-y)) calc(2 * var(--_sonic-unit))
@@ -279,7 +296,11 @@
279
296
  --_sonic-switch-pivot: calc((var(--_sonic-switch-size) - var(--_sonic-switch-shaft)) / 2);
280
297
  --_sonic-switch-sheen: linear-gradient(
281
298
  var(--_sonic-light-fall),
282
- color-mix(in oklab, var(--_sonic-switch-metal) calc(100% - 45% * var(--_sonic-relief)), #fff)
299
+ color-mix(
300
+ in oklab,
301
+ var(--_sonic-switch-metal) calc(100% - 45% * var(--_sonic-relief)),
302
+ var(--_sonic-shine)
303
+ )
283
304
  12%,
284
305
  var(--_sonic-switch-metal) 45%,
285
306
  var(--_sonic-switch-metal-shade) 88%
@@ -287,7 +308,11 @@
287
308
  --_sonic-switch-outline: max(1px, round(0.4 * var(--_sonic-unit), var(--_sonic-snap)));
288
309
  --_sonic-switch-rim: var(
289
310
  --sonic-cap-edge,
290
- color-mix(in oklab, var(--_sonic-switch-cap) calc(100% - 30% * var(--_sonic-relief)), #000)
311
+ color-mix(
312
+ in oklab,
313
+ var(--_sonic-switch-cap) calc(100% - 30% * var(--_sonic-relief)),
314
+ var(--_sonic-shade)
315
+ )
291
316
  );
292
317
 
293
318
  position: relative;
@@ -344,7 +369,7 @@
344
369
  calc((var(--_sonic-switch-ball) - var(--_sonic-switch-size)) / 2);
345
370
  box-shadow:
346
371
  inset 0 0 calc(1.5 * var(--_sonic-unit)) calc(0.4 * var(--_sonic-unit))
347
- rgb(0 0 0 / calc(0.3 * var(--_sonic-relief))),
372
+ rgb(from var(--_sonic-shade) r g b / calc(0.3 * var(--_sonic-relief))),
348
373
  0 0 0 var(--_sonic-switch-outline) var(--_sonic-switch-rim),
349
374
  var(--_sonic-focus-shadow);
350
375
  translate: calc(var(--_sonic-switch-along-x) * var(--_sonic-switch-throw))
@@ -52,6 +52,7 @@
52
52
  --_sonic-toggle-bevel-ratio: var(--sonic-toggle-bevel-ratio, 0.075);
53
53
  --_sonic-toggle-depth-ratio: var(--sonic-toggle-depth-ratio, calc(0.03 * var(--_sonic-relief)));
54
54
  --_sonic-toggle-font-ratio: var(--sonic-toggle-font-ratio, 0.26);
55
+ --_sonic-toggle-font-own: calc(var(--_sonic-toggle-size) * var(--sonic-toggle-font-ratio));
55
56
  --_sonic-toggle-press-scale: var(--sonic-toggle-press-scale, 0.985);
56
57
  --_sonic-toggle-icon-ratio: var(--sonic-toggle-icon-ratio, 0.5);
57
58
  --_sonic-toggle-led-ratio: var(--sonic-toggle-led-ratio, 0.25);
@@ -107,7 +108,7 @@
107
108
  user-select: none;
108
109
  transition:
109
110
  --_sonic-toggle-at 120ms cubic-bezier(0.4, 0, 0.2, 1),
110
- --_sonic-toggle-sink 60ms cubic-bezier(0.4, 0, 0.2, 1);
111
+ --_sonic-toggle-sink var(--_sonic-press-duration) cubic-bezier(0.4, 0, 0.2, 1);
111
112
  }
112
113
 
113
114
  [orientation='vertical'] > .sonic-toggle {
@@ -122,7 +123,7 @@
122
123
  }
123
124
 
124
125
  :state(dragging) > .sonic-toggle {
125
- transition: --_sonic-toggle-sink 60ms cubic-bezier(0.4, 0, 0.2, 1);
126
+ transition: --_sonic-toggle-sink var(--_sonic-press-duration) cubic-bezier(0.4, 0, 0.2, 1);
126
127
  }
127
128
 
128
129
  [data-sonic-lit='ok'] > .sonic-toggle:has(> [role='switch']),
@@ -205,7 +206,7 @@
205
206
  box-shadow:
206
207
  var(--_sonic-well),
207
208
  inset 0 0 0 calc(1px * (1 - var(--_sonic-relief))) var(--_sonic-toggle-well-edge);
208
- transition: --_sonic-toggle-well-tint 120ms ease-out;
209
+ transition: --_sonic-toggle-well-tint var(--_sonic-fade-duration) ease-out;
209
210
  }
210
211
 
211
212
  /* The position rides `--_sonic-toggle-at`, which already eases; easing the offset too would trail a drag */
@@ -219,8 +220,8 @@
219
220
  translate: calc(var(--_sonic-toggle-along-x) * var(--_sonic-toggle-throw))
220
221
  calc(var(--_sonic-toggle-along-y) * var(--_sonic-toggle-throw) + var(--_sonic-toggle-sink));
221
222
  transition:
222
- scale 60ms cubic-bezier(0.4, 0, 0.2, 1),
223
- box-shadow 60ms cubic-bezier(0.4, 0, 0.2, 1);
223
+ scale var(--_sonic-press-duration) cubic-bezier(0.4, 0, 0.2, 1),
224
+ box-shadow var(--_sonic-press-duration) cubic-bezier(0.4, 0, 0.2, 1);
224
225
 
225
226
  & > .sonic-led {
226
227
  --_sonic-led-size: var(
@@ -241,7 +242,13 @@
241
242
  position: relative;
242
243
  padding: 0;
243
244
  font: inherit;
244
- font-size: calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-font-ratio));
245
+ font-size: var(
246
+ --_sonic-toggle-font-own,
247
+ var(
248
+ --sonic-legend-font-size,
249
+ calc(var(--_sonic-toggle-size) * var(--_sonic-toggle-font-ratio))
250
+ )
251
+ );
245
252
  line-height: 1;
246
253
  color: inherit;
247
254
  text-transform: inherit;
@@ -304,7 +311,7 @@
304
311
  opacity: 0;
305
312
  translate: calc(var(--_sonic-toggle-along-x) * var(--_sonic-toggle-ride))
306
313
  calc(var(--_sonic-toggle-along-y) * var(--_sonic-toggle-ride) + var(--_sonic-toggle-sink));
307
- transition: opacity 120ms ease-out;
314
+ transition: opacity var(--_sonic-fade-duration) ease-out;
308
315
 
309
316
  & > * {
310
317
  filter: var(--_sonic-engraving);
@@ -91,11 +91,7 @@
91
91
  }
92
92
 
93
93
  .sonic-waveform {
94
- --_sonic-waveform-inset: calc(
95
- var(--_sonic-waveform-size) * var(--sonic-waveform-inset-ratio, 0.06)
96
- );
97
94
  --_sonic-unit: calc(var(--_sonic-waveform-size) / 48);
98
- --_sonic-glass-depth: var(--sonic-glass-depth, calc(0.6 * var(--_sonic-relief)));
99
95
  --_sonic-waveform-line: var(
100
96
  --sonic-waveform-playhead-width,
101
97
  max(1px, round(var(--_sonic-unit), var(--_sonic-snap)))
@@ -104,7 +100,11 @@
104
100
  --_sonic-waveform-wave: var(--_sonic-waveform-lit);
105
101
  --_sonic-waveform-wave-edge: var(
106
102
  --sonic-waveform-edge,
107
- color-mix(in oklab, var(--_sonic-waveform-lit) calc(100% - 55% * var(--_sonic-relief)), #000)
103
+ color-mix(
104
+ in oklab,
105
+ var(--_sonic-waveform-lit) calc(100% - 55% * var(--_sonic-relief)),
106
+ var(--_sonic-shade)
107
+ )
108
108
  );
109
109
  --_sonic-waveform-grid: var(--sonic-waveform-grid, var(--_sonic-etch));
110
110
  --_sonic-waveform-ends: var(--sonic-waveform-ends, var(--_sonic-etch));
@@ -125,21 +125,20 @@
125
125
  var(--_sonic-waveform-label-inset)
126
126
  );
127
127
 
128
+ /* fallow-ignore-next-line code-duplication -- a plain box restated, since sheets never import each other */
129
+ position: relative;
130
+ display: grid;
131
+ flex-shrink: 0;
132
+ grid-template: minmax(0, 1fr) / minmax(0, 1fr);
128
133
  inline-size: var(--_sonic-waveform-length);
129
134
  block-size: var(--_sonic-waveform-size);
130
- padding: var(--_sonic-waveform-inset);
131
135
  container-type: size;
132
136
 
133
137
  /* A label riding in from the far side would otherwise widen the page */
134
138
  overflow: hidden;
135
139
  touch-action: var(--sonic-touch-action, pan-y);
136
140
  cursor: grab;
137
-
138
- --_sonic-glass-radius: calc(
139
- var(--_sonic-waveform-size) * var(--sonic-waveform-radius-ratio, 0.08)
140
- );
141
-
142
- border-radius: var(--_sonic-glass-radius);
141
+ user-select: none;
143
142
  box-shadow: var(--_sonic-focus-shadow);
144
143
  }
145
144
 
@@ -170,15 +169,15 @@
170
169
 
171
170
  .sonic-waveform-scrim {
172
171
  position: absolute;
173
- inset: var(--_sonic-waveform-inset);
172
+ inset: 0;
174
173
  pointer-events: none;
175
174
  background: var(--sonic-waveform-scrim, none);
176
175
  }
177
176
 
178
177
  :is(.sonic-waveform-playhead, .sonic-waveform-ghost) {
179
178
  position: absolute;
180
- inset-block: var(--_sonic-waveform-inset);
181
- inset-inline-start: calc(var(--_sonic-waveform-inset) - var(--_sonic-waveform-line) / 2);
179
+ inset-block: 0;
180
+ inset-inline-start: calc(var(--_sonic-waveform-line) / -2);
182
181
  inline-size: var(--_sonic-waveform-line);
183
182
  pointer-events: none;
184
183
  translate: 50cqi;
@@ -194,8 +193,8 @@
194
193
 
195
194
  .sonic-waveform-label {
196
195
  position: absolute;
197
- inset-block-end: calc(var(--_sonic-waveform-inset) + var(--_sonic-waveform-label-lift));
198
- inset-inline-start: var(--_sonic-waveform-inset);
196
+ inset-block-end: var(--_sonic-waveform-label-lift);
197
+ inset-inline-start: 0;
199
198
  padding: 0.2em 0.35em;
200
199
  margin: -0.2em -0.35em;
201
200
  font-family: var(--sonic-waveform-label-font, inherit);
@@ -216,7 +215,7 @@
216
215
  filter: opacity(0.5);
217
216
  }
218
217
 
219
- /* Opaque, since a system highlight carries alpha that would blend the wave into the glass */
218
+ /* Opaque, since a system highlight carries alpha that would blend the wave into what is behind it */
220
219
  @media (forced-colors: active) {
221
220
  .sonic-waveform {
222
221
  --_sonic-waveform-wave: rgb(from CanvasText r g b / 100%);
@@ -110,9 +110,6 @@
110
110
  --_sonic-wavestrip-groove-ratio: var(--sonic-wavestrip-groove-ratio, 0.15);
111
111
  --_sonic-wavestrip-groove-size: var(--sonic-wavestrip-groove-size, 0px);
112
112
  --_sonic-wavestrip-marker-ratio: var(--sonic-wavestrip-marker-ratio, 0.065);
113
- --_sonic-wavestrip-inset: calc(
114
- var(--_sonic-wavestrip-size) * var(--sonic-wavestrip-inset-ratio, 0.1)
115
- );
116
113
  --_sonic-unit: calc(var(--_sonic-wavestrip-size) / 32);
117
114
  --_sonic-wavestrip-lit: var(--_sonic-lit);
118
115
  --_sonic-marker-size: var(
@@ -136,18 +133,17 @@
136
133
  --_sonic-wavestrip-played: var(--_sonic-wavestrip-lit);
137
134
  --_sonic-wavestrip-scrub: var(--sonic-scrub, color-mix(in oklab, var(--_sonic-lit) 55%, #fff));
138
135
 
136
+ /* fallow-ignore-next-line code-duplication -- a plain box restated, since sheets never import each other */
137
+ position: relative;
138
+ display: grid;
139
+ flex-shrink: 0;
140
+ grid-template: minmax(0, 1fr) / minmax(0, 1fr);
139
141
  inline-size: var(--_sonic-wavestrip-length);
140
142
  block-size: var(--_sonic-wavestrip-size);
141
- padding: var(--_sonic-wavestrip-inset);
142
143
  container-type: size;
143
144
  touch-action: var(--sonic-touch-action, pan-y);
144
145
  cursor: ew-resize;
145
-
146
- --_sonic-glass-radius: calc(
147
- var(--_sonic-wavestrip-size) * var(--sonic-wavestrip-radius-ratio, 0.15)
148
- );
149
-
150
- border-radius: var(--_sonic-glass-radius);
146
+ user-select: none;
151
147
  box-shadow: var(--_sonic-focus-shadow);
152
148
  }
153
149
 
@@ -174,7 +170,7 @@
174
170
 
175
171
  .sonic-wavestrip-markers {
176
172
  position: absolute;
177
- inset: var(--_sonic-wavestrip-inset);
173
+ inset: 0;
178
174
  pointer-events: none;
179
175
  }
180
176
 
@@ -187,7 +183,7 @@
187
183
  --_sonic-marker-colour: color-mix(
188
184
  in oklab,
189
185
  var(--_sonic-marker, var(--_sonic-marker-default)) 45%,
190
- var(--_sonic-glass)
186
+ transparent
191
187
  );
192
188
  }
193
189
  }
@@ -199,12 +195,11 @@
199
195
  block-size: var(--_sonic-marker-size);
200
196
  background: var(--_sonic-marker-colour);
201
197
  border-radius: 50%;
202
- box-shadow: 0 0 0 var(--_sonic-marker-edge) var(--_sonic-glass);
198
+ box-shadow: 0 0 0 var(--_sonic-marker-edge) var(--sonic-wavestrip-marker-edge, transparent);
203
199
  }
204
200
 
205
201
  .sonic-wavestrip-region {
206
- inset: calc(-1 * var(--_sonic-wavestrip-inset)) auto calc(-1 * var(--_sonic-wavestrip-inset))
207
- calc(var(--_sonic-marker-from, 0) * 100%);
202
+ inset: 0 auto 0 calc(var(--_sonic-marker-from, 0) * 100%);
208
203
  box-sizing: border-box;
209
204
  inline-size: calc((var(--_sonic-marker-to, 0) - var(--_sonic-marker-from, 0)) * 100%);
210
205
  background: color-mix(in oklab, var(--_sonic-marker-colour) 16%, transparent);
@@ -214,23 +209,15 @@
214
209
 
215
210
  /* Bare `block-start` spans the viewport; `translate` belongs to the open transition */
216
211
  .sonic-wavestrip-readout {
217
- --_sonic-wavestrip-readout-inset: calc(
218
- var(--_sonic-wavestrip-inset) + var(--_sonic-wavestrip-readout-at, 0) * 100cqi
219
- );
220
-
221
212
  inset-inline: 0;
222
213
  justify-self: start;
223
214
  position-area: block-start center;
224
215
  transform: translateX(
225
- clamp(
226
- 0px,
227
- var(--_sonic-wavestrip-readout-inset) - 50%,
228
- 100cqi + 2 * var(--_sonic-wavestrip-inset) - 100%
229
- )
216
+ clamp(0px, var(--_sonic-wavestrip-readout-at, 0) * 100cqi - 50%, 100cqi - 100%)
230
217
  );
231
218
  }
232
219
 
233
- /* Opaque, since a system highlight carries alpha that would blend the bars into the glass */
220
+ /* Opaque, since a system highlight carries alpha that would blend the bars into what is behind them */
234
221
  @media (forced-colors: active) {
235
222
  .sonic-wavestrip {
236
223
  --_sonic-wavestrip-lit: Highlight;
@@ -25,25 +25,24 @@
25
25
 
26
26
  .sonic-xy {
27
27
  --_sonic-xy-puck-ratio: var(--sonic-xy-puck-ratio, 0.2);
28
- --_sonic-xy-radius-ratio: var(--sonic-xy-radius-ratio, 0.06);
29
- --_sonic-xy-inset-ratio: var(--sonic-xy-inset-ratio, 0.04);
30
28
  --_sonic-unit: calc(var(--_sonic-xy-size) / 96);
31
29
  --_sonic-xy-lit: var(--_sonic-lit);
32
30
  --_sonic-xy-cursor: grab;
33
31
  --_sonic-xy-puck: calc(var(--_sonic-xy-size) * var(--_sonic-xy-puck-ratio));
34
- --_sonic-xy-inset: calc(var(--_sonic-xy-size) * var(--_sonic-xy-inset-ratio));
35
- --_sonic-xy-travel-x: calc(100cqi - 2 * var(--_sonic-xy-inset) - var(--_sonic-xy-puck));
36
- --_sonic-xy-travel-y: calc(100cqb - 2 * var(--_sonic-xy-inset) - var(--_sonic-xy-puck));
32
+ --_sonic-xy-travel-x: calc(100cqi - var(--_sonic-xy-puck));
33
+ --_sonic-xy-travel-y: calc(100cqb - var(--_sonic-xy-puck));
37
34
 
35
+ /* fallow-ignore-next-line code-duplication -- a plain box restated, since sheets never import each other */
36
+ position: relative;
37
+ display: grid;
38
+ flex-shrink: 0;
39
+ grid-template: minmax(0, 1fr) / minmax(0, 1fr);
38
40
  inline-size: calc(var(--_sonic-xy-size) * var(--_sonic-xy-aspect-ratio));
39
41
  block-size: var(--_sonic-xy-size);
40
42
  container-type: size;
41
43
  touch-action: none;
42
44
  cursor: crosshair;
43
-
44
- --_sonic-glass-radius: calc(var(--_sonic-xy-size) * var(--_sonic-xy-radius-ratio));
45
-
46
- border-radius: var(--_sonic-glass-radius);
45
+ user-select: none;
47
46
  }
48
47
 
49
48
  :disabled > .sonic-xy {
@@ -59,9 +58,11 @@
59
58
  --_sonic-xy-x-high: max(var(--_sonic-xy-x-origin, 0), var(--_sonic-xy-x, 0));
60
59
  --_sonic-xy-y-low: min(var(--_sonic-xy-y-origin, 0), var(--_sonic-xy-y, 0));
61
60
  --_sonic-xy-y-high: max(var(--_sonic-xy-y-origin, 0), var(--_sonic-xy-y, 0));
61
+ --_sonic-xy-cut-x: calc(var(--_sonic-xy-x, 0) * var(--_sonic-xy-travel-x));
62
+ --_sonic-xy-cut-y: calc(var(--_sonic-xy-y, 0) * var(--_sonic-xy-travel-y));
62
63
 
63
64
  position: absolute;
64
- inset: var(--_sonic-xy-inset);
65
+ inset: 0;
65
66
  pointer-events: none;
66
67
 
67
68
  &::before,
@@ -70,6 +71,8 @@
70
71
  content: '';
71
72
  }
72
73
 
74
+ /* Each line is cut under the puck, which is see-through while held; the cut ends inside its ring */
75
+
73
76
  &::before {
74
77
  inset: auto 0
75
78
  calc(
@@ -93,6 +96,12 @@
93
96
  transparent 0
94
97
  ),
95
98
  var(--_sonic-unlit);
99
+ mask: linear-gradient(
100
+ to right,
101
+ #000 calc(var(--_sonic-xy-cut-x) + 0.29 * var(--_sonic-xy-puck)),
102
+ transparent 0 calc(var(--_sonic-xy-cut-x) + 0.71 * var(--_sonic-xy-puck)),
103
+ #000 0
104
+ );
96
105
  }
97
106
 
98
107
  &::after {
@@ -118,14 +127,19 @@
118
127
  transparent 0
119
128
  ),
120
129
  var(--_sonic-unlit);
130
+ mask: linear-gradient(
131
+ to top,
132
+ #000 calc(var(--_sonic-xy-cut-y) + 0.29 * var(--_sonic-xy-puck)),
133
+ transparent 0 calc(var(--_sonic-xy-cut-y) + 0.71 * var(--_sonic-xy-puck)),
134
+ #000 0
135
+ );
121
136
  }
122
137
  }
123
138
 
124
139
  :is(.sonic-xy-bracket, .sonic-xy-puck) {
125
140
  position: absolute;
126
- inset: auto auto
127
- calc(var(--_sonic-xy-inset) + var(--_sonic-xy-y, 0) * var(--_sonic-xy-travel-y))
128
- calc(var(--_sonic-xy-inset) + var(--_sonic-xy-x, 0) * var(--_sonic-xy-travel-x));
141
+ inset: auto auto calc(var(--_sonic-xy-y, 0) * var(--_sonic-xy-travel-y))
142
+ calc(var(--_sonic-xy-x, 0) * var(--_sonic-xy-travel-x));
129
143
  inline-size: var(--_sonic-xy-puck);
130
144
  block-size: var(--_sonic-xy-puck);
131
145
  border-radius: 50%;
@@ -140,25 +154,27 @@
140
154
  --_sonic-xy-puck-edge: var(--_sonic-xy-puck-fill);
141
155
  --_sonic-xy-puck-lift: color-mix(in oklab, var(--_sonic-xy-lit) 85%, #fff);
142
156
  --_sonic-xy-puck-glow: transparent;
143
- --_sonic-xy-puck-ring: 0 0 transparent;
157
+ --_sonic-xy-puck-ring: transparent;
158
+ --_sonic-xy-puck-ring-width: max(2px, round(0.08 * var(--_sonic-xy-puck), var(--_sonic-snap)));
144
159
 
145
160
  cursor: var(--_sonic-xy-cursor);
146
161
  filter: drop-shadow(0 0 calc(0.15 * var(--_sonic-xy-puck)) var(--_sonic-xy-puck-glow));
147
- transition: filter 120ms ease-out;
162
+ transition: filter var(--_sonic-fade-duration) ease-out;
148
163
 
149
164
  &::before {
150
165
  position: absolute;
151
166
  inset: 25%;
152
167
  pointer-events: none;
168
+ outline: var(--_sonic-xy-puck-ring-width) solid var(--_sonic-xy-puck-ring);
169
+ outline-offset: var(--_sonic-xy-puck-ring-width);
153
170
  content: '';
154
171
  background: var(--_sonic-xy-puck-fill);
155
172
  border: max(1px, 0.08 * var(--_sonic-xy-puck)) solid var(--_sonic-xy-puck-edge);
156
173
  border-radius: 50%;
157
- box-shadow: var(--_sonic-xy-puck-ring);
158
174
  transition:
159
- background-color 120ms ease-out,
160
- border-color 120ms ease-out,
161
- box-shadow 120ms ease-out;
175
+ background-color var(--_sonic-fade-duration) ease-out,
176
+ border-color var(--_sonic-fade-duration) ease-out,
177
+ outline-color var(--_sonic-fade-duration) ease-out;
162
178
  }
163
179
  }
164
180
 
@@ -170,13 +186,11 @@
170
186
 
171
187
  .sonic-xy-puck:has(> :focus-visible:not([data-sonic-pointer-focus])) {
172
188
  --_sonic-xy-puck-fill: var(--_sonic-xy-puck-lift);
173
- --_sonic-xy-puck-ring:
174
- 0 0 0 max(2px, round(0.08 * var(--_sonic-xy-puck), var(--_sonic-snap))) var(--_sonic-glass),
175
- 0 0 0 max(4px, round(0.16 * var(--_sonic-xy-puck), var(--_sonic-snap))) var(--_sonic-focus);
189
+ --_sonic-xy-puck-ring: var(--_sonic-focus);
176
190
  }
177
191
 
178
192
  :state(dragging) > .sonic-xy > .sonic-xy-puck {
179
- --_sonic-xy-puck-fill: var(--_sonic-glass);
193
+ --_sonic-xy-puck-fill: transparent;
180
194
  --_sonic-xy-puck-edge: var(--_sonic-xy-lit);
181
195
  --_sonic-xy-puck-glow: color-mix(
182
196
  in oklab,
@@ -196,7 +210,6 @@
196
210
  .sonic-xy {
197
211
  --_sonic-lit: Highlight;
198
212
  --_sonic-unlit: GrayText;
199
- --_sonic-glass: Canvas;
200
213
  }
201
214
 
202
215
  .sonic-xy-field {
@@ -207,9 +220,17 @@
207
220
  --_sonic-xy-puck-fill: CanvasText;
208
221
  --_sonic-xy-puck-lift: CanvasText;
209
222
  --_sonic-xy-puck-glow: transparent;
210
- --_sonic-xy-puck-ring: 0 0 transparent;
211
223
 
212
224
  forced-color-adjust: none;
225
+
226
+ /* The axis's own outline is the focus here */
227
+ &::before {
228
+ outline-style: none;
229
+ }
230
+ }
231
+
232
+ :state(dragging) > .sonic-xy > .sonic-xy-puck {
233
+ --_sonic-xy-puck-fill: Canvas;
213
234
  }
214
235
 
215
236
  .sonic-xy-axis {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsynaptic/sonic-ui",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Native custom elements for audio interfaces, skinned with CSS custom properties",
5
5
  "keywords": [
6
6
  "custom-elements",
@@ -38,11 +38,6 @@
38
38
  "development": "./dist/dev/index.js",
39
39
  "import": "./dist/default/index.js"
40
40
  },
41
- "./dat": {
42
- "types": "./dist/dev/dat.d.ts",
43
- "development": "./dist/dev/dat.js",
44
- "import": "./dist/default/dat.js"
45
- },
46
41
  "./define": {
47
42
  "types": "./dist/dev/define.d.ts",
48
43
  "development": "./dist/dev/define.js",
@@ -1,52 +0,0 @@
1
- import { clamp } from "./lib/math.js";
2
-
3
- //#region src/dat.ts
4
- function readVersion(view) {
5
- const version = view.getInt32(0, true);
6
- if (version === 1 || version === 2) return version;
7
- throw new Error(`A .dat file of version ${String(version)} is not one this reads`);
8
- }
9
- function readDatHeader(buffer) {
10
- if (buffer.byteLength < 20) throw new Error("A .dat header takes at least 20 bytes");
11
- const view = new DataView(buffer);
12
- const version = readVersion(view);
13
- const dataOffset = version === 1 ? 20 : 24;
14
- if (buffer.byteLength < dataOffset) throw new Error(`A version ${String(version)} .dat header takes ${String(dataOffset)} bytes`);
15
- const channels = version === 1 ? 1 : view.getInt32(20, true);
16
- if (channels < 1) throw new Error("A .dat header names no channels");
17
- const sampleRate = view.getInt32(8, true);
18
- const samplesPerPixel = view.getInt32(12, true);
19
- if (samplesPerPixel < 1) throw new Error("A .dat header names no samples per pixel");
20
- return {
21
- bits: (view.getUint32(4, true) & 1) === 1 ? 8 : 16,
22
- channels,
23
- dataOffset,
24
- pairs: view.getUint32(16, true),
25
- pairsPerSecond: sampleRate / samplesPerPixel,
26
- sampleRate,
27
- samplesPerPixel,
28
- version
29
- };
30
- }
31
- /** An inclusive byte range for a `Range` header; `undefined` when the pairs asked for are empty */
32
- function datByteRange(header, fromPair, toPair) {
33
- const from = clamp(Math.floor(fromPair), 0, header.pairs);
34
- const to = clamp(Math.ceil(toPair), from, header.pairs);
35
- if (!(to > from)) return void 0;
36
- const pairBytes = header.channels * 2 * header.bits / 8;
37
- return [header.dataOffset + from * pairBytes, header.dataOffset + to * pairBytes - 1];
38
- }
39
- function readDatSamples(header, body, byteOffset = 0) {
40
- return header.bits === 8 ? new Int8Array(body, byteOffset) : new Int16Array(body, byteOffset, Math.floor((body.byteLength - byteOffset) / 2));
41
- }
42
- function readDatPeaks(header, body, byteOffset = 0) {
43
- return {
44
- channels: header.channels,
45
- fullScale: header.bits === 8 ? 128 : 32768,
46
- pairsPerSecond: header.pairsPerSecond,
47
- samples: readDatSamples(header, body, byteOffset)
48
- };
49
- }
50
-
51
- //#endregion
52
- export { datByteRange, readDatHeader, readDatPeaks, readDatSamples };
package/dist/dev/dat.d.ts DELETED
@@ -1,20 +0,0 @@
1
- import { WaveformPeaks } from "./lib/waveform-buckets.js";
2
- //#region src/dat.d.ts
3
- export interface DatHeader {
4
- bits: 8 | 16;
5
- channels: number;
6
- dataOffset: number;
7
- pairs: number;
8
- pairsPerSecond: number;
9
- sampleRate: number;
10
- samplesPerPixel: number;
11
- version: 1 | 2;
12
- }
13
- export declare function readDatHeader(buffer: ArrayBuffer): DatHeader;
14
- /** An inclusive byte range for a `Range` header; `undefined` when the pairs asked for are empty */
15
- export declare function datByteRange(header: DatHeader, fromPair: number, toPair: number): [number, number] | undefined;
16
- export declare function readDatSamples(header: DatHeader, body: ArrayBuffer, byteOffset?: number): Int8Array | Int16Array;
17
- export declare function readDatPeaks(header: DatHeader, body: ArrayBuffer, byteOffset?: number): WaveformPeaks;
18
- //#endregion
19
- export type { WaveformPeaks };
20
- //# sourceMappingURL=dat.d.ts.map
package/dist/dev/dat.js DELETED
@@ -1,53 +0,0 @@
1
- import { clamp } from "./lib/math.js";
2
-
3
- //#region src/dat.ts
4
- function readVersion(view) {
5
- const version = view.getInt32(0, true);
6
- if (version === 1 || version === 2) return version;
7
- throw new Error(`A .dat file of version ${String(version)} is not one this reads`);
8
- }
9
- function readDatHeader(buffer) {
10
- if (buffer.byteLength < 20) throw new Error("A .dat header takes at least 20 bytes");
11
- const view = new DataView(buffer);
12
- const version = readVersion(view);
13
- const dataOffset = version === 1 ? 20 : 24;
14
- if (buffer.byteLength < dataOffset) throw new Error(`A version ${String(version)} .dat header takes ${String(dataOffset)} bytes`);
15
- const channels = version === 1 ? 1 : view.getInt32(20, true);
16
- if (channels < 1) throw new Error("A .dat header names no channels");
17
- const sampleRate = view.getInt32(8, true);
18
- const samplesPerPixel = view.getInt32(12, true);
19
- if (samplesPerPixel < 1) throw new Error("A .dat header names no samples per pixel");
20
- return {
21
- bits: (view.getUint32(4, true) & 1) === 1 ? 8 : 16,
22
- channels,
23
- dataOffset,
24
- pairs: view.getUint32(16, true),
25
- pairsPerSecond: sampleRate / samplesPerPixel,
26
- sampleRate,
27
- samplesPerPixel,
28
- version
29
- };
30
- }
31
- /** An inclusive byte range for a `Range` header; `undefined` when the pairs asked for are empty */
32
- function datByteRange(header, fromPair, toPair) {
33
- const from = clamp(Math.floor(fromPair), 0, header.pairs);
34
- const to = clamp(Math.ceil(toPair), from, header.pairs);
35
- if (!(to > from)) return void 0;
36
- const pairBytes = header.channels * 2 * header.bits / 8;
37
- return [header.dataOffset + from * pairBytes, header.dataOffset + to * pairBytes - 1];
38
- }
39
- function readDatSamples(header, body, byteOffset = 0) {
40
- return header.bits === 8 ? new Int8Array(body, byteOffset) : new Int16Array(body, byteOffset, Math.floor((body.byteLength - byteOffset) / 2));
41
- }
42
- function readDatPeaks(header, body, byteOffset = 0) {
43
- return {
44
- channels: header.channels,
45
- fullScale: header.bits === 8 ? 128 : 32768,
46
- pairsPerSecond: header.pairsPerSecond,
47
- samples: readDatSamples(header, body, byteOffset)
48
- };
49
- }
50
-
51
- //#endregion
52
- export { datByteRange, readDatHeader, readDatPeaks, readDatSamples };
53
- //# sourceMappingURL=dat.js.map