@xsynaptic/sonic-ui 0.24.1 → 0.26.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.
- package/CHANGELOG.md +42 -2
- package/README.md +6 -4
- package/dist/default/define/region.js +7 -0
- package/dist/default/define.js +1 -0
- package/dist/default/elements/button.js +3 -0
- package/dist/default/elements/dial.js +3 -0
- package/dist/default/elements/envelope.js +14 -11
- package/dist/default/elements/form-element.js +10 -0
- package/dist/default/elements/meter.js +3 -0
- package/dist/default/elements/number.js +3 -0
- package/dist/default/elements/radio-group.js +4 -1
- package/dist/default/elements/readout.js +1 -1
- package/dist/default/elements/region-layer.js +253 -0
- package/dist/default/elements/region.js +161 -0
- package/dist/default/elements/slider.js +3 -0
- package/dist/default/elements/sonic-element.js +7 -9
- package/dist/default/elements/split.js +2 -2
- package/dist/default/elements/toggle.js +4 -4
- package/dist/default/elements/value-element.js +21 -3
- package/dist/default/elements/value-gestures.js +7 -5
- package/dist/default/elements/wave-element.js +15 -3
- package/dist/default/elements/waveform.js +38 -2
- package/dist/default/elements/wavestrip.js +90 -17
- package/dist/default/elements/xy.js +6 -11
- package/dist/default/index.js +2 -1
- package/dist/default/lib/canvas-surface.js +22 -1
- package/dist/default/lib/clock.js +1 -0
- package/dist/default/lib/drag-step.js +1 -1
- package/dist/default/lib/key-press.js +2 -2
- package/dist/default/lib/marker-band.js +40 -29
- package/dist/default/lib/region-drag.js +48 -0
- package/dist/dev/define/region.d.ts +2 -0
- package/dist/dev/define/region.js +8 -0
- package/dist/dev/define/region.js.map +1 -0
- package/dist/dev/define.d.ts +3 -1
- package/dist/dev/define.js +1 -0
- package/dist/dev/elements/button.d.ts +1 -0
- package/dist/dev/elements/button.js +3 -0
- package/dist/dev/elements/button.js.map +1 -1
- package/dist/dev/elements/dial.d.ts +1 -0
- package/dist/dev/elements/dial.js +3 -0
- package/dist/dev/elements/dial.js.map +1 -1
- package/dist/dev/elements/envelope.d.ts +1 -0
- package/dist/dev/elements/envelope.js +14 -11
- package/dist/dev/elements/envelope.js.map +1 -1
- package/dist/dev/elements/form-element.d.ts +1 -0
- package/dist/dev/elements/form-element.js +10 -0
- package/dist/dev/elements/form-element.js.map +1 -1
- package/dist/dev/elements/meter.d.ts +1 -0
- package/dist/dev/elements/meter.js +3 -0
- package/dist/dev/elements/meter.js.map +1 -1
- package/dist/dev/elements/number.d.ts +1 -0
- package/dist/dev/elements/number.js +3 -0
- package/dist/dev/elements/number.js.map +1 -1
- package/dist/dev/elements/radio-group.d.ts +1 -0
- package/dist/dev/elements/radio-group.js +4 -1
- package/dist/dev/elements/radio-group.js.map +1 -1
- package/dist/dev/elements/readout.js +1 -1
- package/dist/dev/elements/readout.js.map +1 -1
- package/dist/dev/elements/region-layer.js +254 -0
- package/dist/dev/elements/region-layer.js.map +1 -0
- package/dist/dev/elements/region.d.ts +30 -0
- package/dist/dev/elements/region.js +169 -0
- package/dist/dev/elements/region.js.map +1 -0
- package/dist/dev/elements/slider.d.ts +1 -0
- package/dist/dev/elements/slider.js +3 -0
- package/dist/dev/elements/slider.js.map +1 -1
- package/dist/dev/elements/sonic-element.d.ts +2 -0
- package/dist/dev/elements/sonic-element.js +8 -10
- package/dist/dev/elements/sonic-element.js.map +1 -1
- package/dist/dev/elements/split.js +2 -2
- package/dist/dev/elements/split.js.map +1 -1
- package/dist/dev/elements/toggle.js +4 -4
- package/dist/dev/elements/toggle.js.map +1 -1
- package/dist/dev/elements/value-element.d.ts +3 -1
- package/dist/dev/elements/value-element.js +21 -3
- package/dist/dev/elements/value-element.js.map +1 -1
- package/dist/dev/elements/value-gestures.js +7 -5
- package/dist/dev/elements/value-gestures.js.map +1 -1
- package/dist/dev/elements/wave-element.d.ts +8 -1
- package/dist/dev/elements/wave-element.js +15 -3
- package/dist/dev/elements/wave-element.js.map +1 -1
- package/dist/dev/elements/waveform.d.ts +7 -0
- package/dist/dev/elements/waveform.js +38 -2
- package/dist/dev/elements/waveform.js.map +1 -1
- package/dist/dev/elements/wavestrip.d.ts +17 -1
- package/dist/dev/elements/wavestrip.js +90 -17
- package/dist/dev/elements/wavestrip.js.map +1 -1
- package/dist/dev/elements/xy.d.ts +1 -0
- package/dist/dev/elements/xy.js +6 -11
- package/dist/dev/elements/xy.js.map +1 -1
- package/dist/dev/index.d.ts +3 -2
- package/dist/dev/index.js +2 -1
- package/dist/dev/lib/canvas-surface.js +22 -1
- package/dist/dev/lib/canvas-surface.js.map +1 -1
- package/dist/dev/lib/clock.js +1 -0
- package/dist/dev/lib/clock.js.map +1 -1
- package/dist/dev/lib/drag-step.js +1 -1
- package/dist/dev/lib/drag-step.js.map +1 -1
- package/dist/dev/lib/key-press.js +2 -2
- package/dist/dev/lib/key-press.js.map +1 -1
- package/dist/dev/lib/marker-band.d.ts +7 -0
- package/dist/dev/lib/marker-band.js +40 -29
- package/dist/dev/lib/marker-band.js.map +1 -1
- package/dist/dev/lib/region-drag.js +49 -0
- package/dist/dev/lib/region-drag.js.map +1 -0
- package/dist/styles/button.css +23 -13
- package/dist/styles/controls.css +1 -0
- package/dist/styles/dial.css +41 -24
- package/dist/styles/envelope.css +12 -5
- package/dist/styles/led.css +8 -8
- package/dist/styles/material/arc.css +2 -2
- package/dist/styles/material/cap.css +34 -13
- package/dist/styles/material/glass.css +1 -1
- package/dist/styles/material/groove.css +3 -3
- package/dist/styles/material/keycap.css +2 -2
- package/dist/styles/material/lens.css +1 -1
- package/dist/styles/material/pane.css +20 -6
- package/dist/styles/material/readout.css +14 -5
- package/dist/styles/material/{bracket.css → reticle.css} +15 -8
- package/dist/styles/material/well.css +2 -2
- package/dist/styles/material.css +1 -1
- package/dist/styles/meter.css +29 -16
- package/dist/styles/number.css +3 -2
- package/dist/styles/panel.css +3 -3
- package/dist/styles/region.css +94 -0
- package/dist/styles/ring.css +2 -1
- package/dist/styles/screen.css +7 -5
- package/dist/styles/segmented.css +5 -4
- package/dist/styles/slider.css +24 -15
- package/dist/styles/spectrum.css +9 -1
- package/dist/styles/switch.css +9 -2
- package/dist/styles/toggle.css +5 -4
- package/dist/styles/waveform.css +10 -3
- package/dist/styles/wavestrip.css +17 -8
- package/dist/styles/xy.css +24 -11
- package/package.json +3 -2
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { clampProportion } from "../lib/math.js";
|
|
1
|
+
import { clamp, clampProportion } from "../lib/math.js";
|
|
2
2
|
import { requireChild, template } from "../lib/render.js";
|
|
3
3
|
import { readPxProperty } from "../lib/read-px-property.js";
|
|
4
4
|
import { scrubRegions } from "../lib/scrub.js";
|
|
5
5
|
import { sortedRegions } from "../lib/time-regions.js";
|
|
6
6
|
import { SonicWaveElement } from "./wave-element.js";
|
|
7
7
|
import { createMarkerBand } from "../lib/marker-band.js";
|
|
8
|
+
import { RegionLayer } from "./region-layer.js";
|
|
8
9
|
import { stripBars, stripGroove, stripRegions } from "../lib/strip-scene.js";
|
|
9
10
|
|
|
10
11
|
//#region src/elements/wavestrip.ts
|
|
@@ -23,9 +24,10 @@ const lengths = {
|
|
|
23
24
|
};
|
|
24
25
|
const cancelZonePx = 48;
|
|
25
26
|
const renderWavestrip = template(`
|
|
26
|
-
<div class="sonic-wavestrip"
|
|
27
|
-
<canvas class="sonic-wavestrip-canvas"
|
|
27
|
+
<div class="sonic-wavestrip">
|
|
28
|
+
<canvas class="sonic-wavestrip-canvas" role="slider" tabindex="0"></canvas>
|
|
28
29
|
<div class="sonic-wavestrip-markers" aria-hidden="true"></div>
|
|
30
|
+
<div class="sonic-wavestrip-regions"></div>
|
|
29
31
|
<div class="sonic-wavestrip-readout" popover="manual">
|
|
30
32
|
<span></span>
|
|
31
33
|
<input
|
|
@@ -63,6 +65,14 @@ var SonicWavestrip = class extends SonicWaveElement {
|
|
|
63
65
|
set cancellable(isCancellable) {
|
|
64
66
|
this.reflect("cancellable", isCancellable);
|
|
65
67
|
}
|
|
68
|
+
/** Words a region's `aria-valuetext`; unset, a region speaks its start as the strip speaks a time */
|
|
69
|
+
get formatSpokenRegion() {
|
|
70
|
+
return this.#formatSpokenRegion;
|
|
71
|
+
}
|
|
72
|
+
set formatSpokenRegion(format) {
|
|
73
|
+
this.#formatSpokenRegion = format;
|
|
74
|
+
this.#regions?.render();
|
|
75
|
+
}
|
|
66
76
|
/** One amplitude from 0 to 1 per slice of the whole track, any length; resampled to the bars and never normalised */
|
|
67
77
|
get peaks() {
|
|
68
78
|
return this.#peaks;
|
|
@@ -72,6 +82,25 @@ var SonicWavestrip = class extends SonicWaveElement {
|
|
|
72
82
|
this.renderEmpty();
|
|
73
83
|
this.surface()?.invalidate();
|
|
74
84
|
}
|
|
85
|
+
/** A time a release will seek to, drawn as a scrub's edge; a hold or a hover of the strip's own is drawn instead */
|
|
86
|
+
get preview() {
|
|
87
|
+
return this.#preview;
|
|
88
|
+
}
|
|
89
|
+
set preview(seconds) {
|
|
90
|
+
this.#preview = Number.isFinite(seconds) ? seconds ?? void 0 : void 0;
|
|
91
|
+
this.render();
|
|
92
|
+
}
|
|
93
|
+
/** Runs once per point marker on each `markers` or `renderMarker` write; the element lasts until the next */
|
|
94
|
+
get renderMarker() {
|
|
95
|
+
return this.#renderMarker;
|
|
96
|
+
}
|
|
97
|
+
set renderMarker(render) {
|
|
98
|
+
this.#renderMarker = render;
|
|
99
|
+
this.#drawMarker = render && ((marker, element) => {
|
|
100
|
+
render({ ...marker }, element);
|
|
101
|
+
});
|
|
102
|
+
if (this.isBound()) this.renderMarkers();
|
|
103
|
+
}
|
|
75
104
|
control = renderWavestrip();
|
|
76
105
|
canvas = requireChild(this.control, ".sonic-wavestrip-canvas", HTMLCanvasElement);
|
|
77
106
|
colours = colours;
|
|
@@ -81,43 +110,75 @@ var SonicWavestrip = class extends SonicWaveElement {
|
|
|
81
110
|
sizeProperty = "--_sonic-wavestrip-size";
|
|
82
111
|
#bars;
|
|
83
112
|
#buffered = [];
|
|
113
|
+
#drawMarker;
|
|
114
|
+
#formatSpokenRegion;
|
|
84
115
|
#markerBand = createMarkerBand(requireChild(this.control, ".sonic-wavestrip-markers", HTMLDivElement));
|
|
85
116
|
#paintedKey = "";
|
|
86
117
|
#peaks;
|
|
118
|
+
#preview;
|
|
119
|
+
#regions;
|
|
120
|
+
#renderMarker;
|
|
87
121
|
/** Viewport x of a time, clamped to the strip */
|
|
88
122
|
clientXOf(value) {
|
|
89
123
|
const { startPx, travelPx } = this.#axis();
|
|
90
124
|
return startPx + this.mapping().proportionOf(value) * travelPx;
|
|
91
125
|
}
|
|
92
126
|
connectedCallback() {
|
|
93
|
-
this.upgradeProperties("buffered", "cancellable", "peaks");
|
|
127
|
+
this.upgradeProperties("buffered", "cancellable", "formatSpokenRegion", "peaks", "preview", "renderMarker");
|
|
94
128
|
super.connectedCallback();
|
|
95
129
|
}
|
|
130
|
+
valueFromPoint(clientX, _clientY) {
|
|
131
|
+
const { startPx, travelPx } = this.#axis();
|
|
132
|
+
const mapping = this.mapping();
|
|
133
|
+
return clamp(mapping.valueAt(clampProportion((clientX - startPx) / travelPx)), ...mapping.bounds);
|
|
134
|
+
}
|
|
96
135
|
connect(signal) {
|
|
97
136
|
const { control } = this;
|
|
137
|
+
this.#regions = new RegionLayer({
|
|
138
|
+
axis: () => this.#axis(),
|
|
139
|
+
control,
|
|
140
|
+
element: this,
|
|
141
|
+
isDisabled: () => this.isDisabled(),
|
|
142
|
+
layer: requireChild(control, ".sonic-wavestrip-regions", HTMLDivElement),
|
|
143
|
+
mapping: () => this.mapping(),
|
|
144
|
+
outside: () => this.#outside(),
|
|
145
|
+
seek: (event) => {
|
|
146
|
+
if (this.input(this.valueFromPoint(event.clientX, event.clientY))) this.dispatchEvent(new Event("change", { bubbles: true }));
|
|
147
|
+
},
|
|
148
|
+
speak: ({ end, start }) => this.#formatSpokenRegion?.(start, end) ?? this.spokenText(start) ?? this.notation.format(start)
|
|
149
|
+
}, signal);
|
|
98
150
|
super.connect(signal);
|
|
99
151
|
this.bindHover(control, signal, {
|
|
152
|
+
changed: () => {
|
|
153
|
+
if (this.#preview !== void 0) this.render();
|
|
154
|
+
},
|
|
100
155
|
place: () => {
|
|
101
156
|
this.#placeReadout();
|
|
102
157
|
},
|
|
103
|
-
valueAt: (event) =>
|
|
104
|
-
const axis = this.#axis();
|
|
105
|
-
const at = clampProportion((event.clientX - axis.startPx) / axis.travelPx);
|
|
106
|
-
const mapping = this.mapping();
|
|
107
|
-
return this.#markerAt(event, axis) ?? mapping.snap(mapping.valueAt(at));
|
|
108
|
-
}
|
|
158
|
+
valueAt: (event) => this.#markerStartAt(event, this.#axis()) ?? this.mapping().snap(this.valueFromPoint(event.clientX, event.clientY))
|
|
109
159
|
});
|
|
110
160
|
this.bindGestures(control, signal, (event) => this.#grab(event));
|
|
111
161
|
}
|
|
112
162
|
draw() {
|
|
113
163
|
const surface = this.surface();
|
|
114
164
|
this.#placeReadout();
|
|
165
|
+
this.#regions?.follow();
|
|
115
166
|
this.showCurrentMarker(this.scrubState().played);
|
|
116
167
|
if (surface && this.#stripRegions(surface.size.width).key !== this.#paintedKey) surface.requestFrame();
|
|
117
168
|
}
|
|
169
|
+
focusTarget() {
|
|
170
|
+
return this.canvas;
|
|
171
|
+
}
|
|
118
172
|
isEmpty() {
|
|
119
173
|
return !this.#peaks || this.#peaks.length === 0;
|
|
120
174
|
}
|
|
175
|
+
/** The first point marker is the one a press there snaps to */
|
|
176
|
+
markersInReach(point, widthPx) {
|
|
177
|
+
const regions = this.markerProportions().flatMap(([from, to], index) => {
|
|
178
|
+
return this.markerList()[index]?.end !== void 0 && point.x >= from * widthPx && point.x <= to * widthPx ? [index] : [];
|
|
179
|
+
});
|
|
180
|
+
return [...this.#markerBand.inReach(point, widthPx), ...regions];
|
|
181
|
+
}
|
|
121
182
|
paint(context, frame) {
|
|
122
183
|
const { look, size } = frame;
|
|
123
184
|
const strip = this.#stripRegions(size.width);
|
|
@@ -134,11 +195,14 @@ var SonicWavestrip = class extends SonicWaveElement {
|
|
|
134
195
|
]);
|
|
135
196
|
}
|
|
136
197
|
renderMarkers() {
|
|
137
|
-
this.#markerBand.render(this.markerList(), this.markerProportions());
|
|
198
|
+
this.#markerBand.render(this.markerList(), this.markerProportions(), this.#drawMarker);
|
|
138
199
|
}
|
|
139
200
|
scrubsKeyRepeat() {
|
|
140
201
|
return true;
|
|
141
202
|
}
|
|
203
|
+
usesChild(child) {
|
|
204
|
+
return child instanceof Element && child.localName === "sonic-region";
|
|
205
|
+
}
|
|
142
206
|
#axis() {
|
|
143
207
|
const box = this.canvas.getBoundingClientRect();
|
|
144
208
|
return {
|
|
@@ -163,6 +227,13 @@ var SonicWavestrip = class extends SonicWaveElement {
|
|
|
163
227
|
}
|
|
164
228
|
#grab(event) {
|
|
165
229
|
const axis = this.#axis();
|
|
230
|
+
const marker = this.#markerStartAt(event, axis);
|
|
231
|
+
const regions = this.#regions;
|
|
232
|
+
if (regions?.isHeld() === true) {
|
|
233
|
+
regions.abandon();
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (marker === void 0 && regions?.take(event) === true) return void 0;
|
|
166
237
|
const at = (event.clientX - axis.startPx) / axis.travelPx;
|
|
167
238
|
const outside = this.#outside();
|
|
168
239
|
const grabbed = {
|
|
@@ -170,16 +241,16 @@ var SonicWavestrip = class extends SonicWaveElement {
|
|
|
170
241
|
position: axis.position,
|
|
171
242
|
travelPx: axis.travelPx
|
|
172
243
|
};
|
|
173
|
-
this.input(
|
|
244
|
+
this.input(marker ?? this.valueFromPoint(event.clientX, event.clientY));
|
|
174
245
|
return outside ? {
|
|
175
246
|
...grabbed,
|
|
176
247
|
outside
|
|
177
248
|
} : grabbed;
|
|
178
249
|
}
|
|
179
|
-
#
|
|
180
|
-
const index = this.#markerBand.
|
|
181
|
-
x:
|
|
182
|
-
y:
|
|
250
|
+
#markerStartAt({ clientX, clientY }, { startPx, topPx, travelPx }) {
|
|
251
|
+
const [index] = this.#markerBand.inReach({
|
|
252
|
+
x: clientX - startPx,
|
|
253
|
+
y: clientY - topPx
|
|
183
254
|
}, travelPx);
|
|
184
255
|
return index === void 0 ? void 0 : this.markerList()[index]?.start;
|
|
185
256
|
}
|
|
@@ -196,7 +267,9 @@ var SonicWavestrip = class extends SonicWaveElement {
|
|
|
196
267
|
#stripRegions(width) {
|
|
197
268
|
const mapping = this.mapping();
|
|
198
269
|
const { proportionOf } = mapping;
|
|
199
|
-
const
|
|
270
|
+
const state = this.scrubState();
|
|
271
|
+
const preview = state.from !== void 0 || this.hoverValue !== void 0 || this.#preview === void 0 ? void 0 : proportionOf(this.#preview);
|
|
272
|
+
const { played, scrub = preview } = scrubRegions(state, this.value, mapping);
|
|
200
273
|
return stripRegions({
|
|
201
274
|
buffered: this.#buffered.map(([start, end]) => [proportionOf(start), proportionOf(end)]),
|
|
202
275
|
played,
|
|
@@ -30,7 +30,7 @@ const orientations = {
|
|
|
30
30
|
};
|
|
31
31
|
const renderXy = template(`
|
|
32
32
|
<div class="sonic-xy">
|
|
33
|
-
<div class="sonic-xy-
|
|
33
|
+
<div class="sonic-xy-reticle" aria-hidden="true"></div>
|
|
34
34
|
<div class="sonic-xy-field" aria-hidden="true"></div>
|
|
35
35
|
<div class="sonic-xy-puck">
|
|
36
36
|
<div class="sonic-xy-axis" data-sonic-axis="x" role="slider" tabindex="0"></div>
|
|
@@ -265,6 +265,9 @@ var SonicXy = class extends SonicFormElement {
|
|
|
265
265
|
this.x = x;
|
|
266
266
|
this.y = y;
|
|
267
267
|
}
|
|
268
|
+
stateTarget() {
|
|
269
|
+
return this.#xy;
|
|
270
|
+
}
|
|
268
271
|
#axisText(axis) {
|
|
269
272
|
const { value } = this.#models[axis];
|
|
270
273
|
return `${this.getAttribute(`${axis}-label`) ?? axis.toUpperCase()} ${this.#formatValue?.(value, axis) ?? String(value)}`;
|
|
@@ -404,16 +407,8 @@ var SonicXy = class extends SonicFormElement {
|
|
|
404
407
|
}
|
|
405
408
|
}
|
|
406
409
|
#renderForm() {
|
|
407
|
-
const {
|
|
408
|
-
|
|
409
|
-
if (name === "") {
|
|
410
|
-
this.writeFormValue(null, state);
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
const fields = new FormData();
|
|
414
|
-
fields.set(`${name}.x`, String(x));
|
|
415
|
-
fields.set(`${name}.y`, String(y));
|
|
416
|
-
this.writeFormValue(fields, state);
|
|
410
|
+
const { x, y } = this;
|
|
411
|
+
this.writeFormFields([["x", x], ["y", y]], `${String(x)},${String(y)}`);
|
|
417
412
|
}
|
|
418
413
|
#renderReadout() {
|
|
419
414
|
const { isRevealed } = this.#claim;
|
package/dist/default/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { envelopeCurve } from "./lib/envelope-curve.js";
|
|
|
4
4
|
import { SonicEnvelope } from "./elements/envelope.js";
|
|
5
5
|
import { SonicMeter } from "./elements/meter.js";
|
|
6
6
|
import { SonicNumber } from "./elements/number.js";
|
|
7
|
+
import { SonicRegion } from "./elements/region.js";
|
|
7
8
|
import { SonicSegmented } from "./elements/segmented.js";
|
|
8
9
|
import { SonicSlider } from "./elements/slider.js";
|
|
9
10
|
import { SonicSpectrum } from "./elements/spectrum.js";
|
|
@@ -17,4 +18,4 @@ import { SonicXy } from "./elements/xy.js";
|
|
|
17
18
|
import { crossfadeGains } from "./lib/crossfade.js";
|
|
18
19
|
import { formatPercent, parsePercent } from "./lib/percent.js";
|
|
19
20
|
|
|
20
|
-
export { SonicButton, SonicDial, SonicEnvelope, SonicMeter, SonicNumber, SonicSegmented, SonicSlider, SonicSpectrum, SonicSplit, SonicSwitch, SonicToggle, SonicWaveform, SonicWavestrip, SonicXy, crossfadeGains, envelopeCurve, formatClock, formatPercent, parseClock, parsePercent };
|
|
21
|
+
export { SonicButton, SonicDial, SonicEnvelope, SonicMeter, SonicNumber, SonicRegion, SonicSegmented, SonicSlider, SonicSpectrum, SonicSplit, SonicSwitch, SonicToggle, SonicWaveform, SonicWavestrip, SonicXy, crossfadeGains, envelopeCurve, formatClock, formatPercent, parseClock, parsePercent };
|
|
@@ -10,6 +10,17 @@ function deviceBox(entry, css) {
|
|
|
10
10
|
if (!device || Math.abs(device.inlineSize - css.inlineSize * dpr) > 1) return void 0;
|
|
11
11
|
return Math.abs(device.blockSize - css.blockSize * dpr) > 1 ? void 0 : device;
|
|
12
12
|
}
|
|
13
|
+
function canTakeColour(context, colour) {
|
|
14
|
+
const kept = context.fillStyle;
|
|
15
|
+
const isKept = (sentinel) => {
|
|
16
|
+
context.fillStyle = sentinel;
|
|
17
|
+
context.fillStyle = colour;
|
|
18
|
+
return context.fillStyle === sentinel;
|
|
19
|
+
};
|
|
20
|
+
const isRefused = isKept("#000000") && isKept("#ffffff");
|
|
21
|
+
context.fillStyle = kept;
|
|
22
|
+
return !isRefused;
|
|
23
|
+
}
|
|
13
24
|
function readEach(properties, read) {
|
|
14
25
|
return Object.fromEntries(Object.entries(properties).flatMap(([name, property]) => property === void 0 ? [] : [[name, read(property)]]));
|
|
15
26
|
}
|
|
@@ -181,7 +192,7 @@ var CanvasSurface = class {
|
|
|
181
192
|
const { canvas, colours, lengths = {}, numbers = {} } = this.#options;
|
|
182
193
|
const styles = getComputedStyle(canvas);
|
|
183
194
|
return {
|
|
184
|
-
colours: readEach(colours, (property) => styles.getPropertyValue(property).trim().replaceAll("currentcolor", () => styles.color)),
|
|
195
|
+
colours: readEach(colours, (property) => this.#resolve(styles.getPropertyValue(property).trim().replaceAll("currentcolor", () => styles.color))),
|
|
185
196
|
isReducedMotion: this.#reducedMotion.matches,
|
|
186
197
|
lengths: readEach(lengths, (property) => readPxProperty(styles, property, 0)),
|
|
187
198
|
numbers: readEach(numbers, (property) => readPxProperty(styles, property, 0))
|
|
@@ -209,6 +220,16 @@ var CanvasSurface = class {
|
|
|
209
220
|
if (previous.width === 0 || previous.height === 0) this.rebuild();
|
|
210
221
|
else this.invalidate();
|
|
211
222
|
}
|
|
223
|
+
#resolve(colour) {
|
|
224
|
+
const context = this.#context;
|
|
225
|
+
if (!context || canTakeColour(context, colour)) return colour;
|
|
226
|
+
const probe = document.createElement("span");
|
|
227
|
+
probe.style.color = colour;
|
|
228
|
+
this.#options.canvas.append(probe);
|
|
229
|
+
const resolved = getComputedStyle(probe).color;
|
|
230
|
+
probe.remove();
|
|
231
|
+
return resolved;
|
|
232
|
+
}
|
|
212
233
|
#schedule() {
|
|
213
234
|
if (this.#options.signal.aborted || this.#frame !== void 0 || !this.#isVisible) return;
|
|
214
235
|
this.#frame = requestAnimationFrame((frameMs) => {
|
|
@@ -3,7 +3,7 @@ function bindKeyPress(root, signal) {
|
|
|
3
3
|
let pressed;
|
|
4
4
|
const release = () => {
|
|
5
5
|
if (!pressed) return;
|
|
6
|
-
delete pressed.dataset.
|
|
6
|
+
delete pressed.dataset.sonicActive;
|
|
7
7
|
pressed = void 0;
|
|
8
8
|
};
|
|
9
9
|
root.addEventListener("keydown", (event) => {
|
|
@@ -12,7 +12,7 @@ function bindKeyPress(root, signal) {
|
|
|
12
12
|
if (!(part instanceof HTMLButtonElement) || part.disabled) return;
|
|
13
13
|
release();
|
|
14
14
|
pressed = part;
|
|
15
|
-
part.dataset.
|
|
15
|
+
part.dataset.sonicActive = "";
|
|
16
16
|
}, { signal });
|
|
17
17
|
root.addEventListener("keyup", (event) => {
|
|
18
18
|
if (event.key === " " || event.key === "Meta") release();
|
|
@@ -2,7 +2,7 @@ import { readPxProperty } from "./read-px-property.js";
|
|
|
2
2
|
|
|
3
3
|
//#region src/lib/marker-band.ts
|
|
4
4
|
const kindPattern = /^[a-z][a-z0-9-]*$/;
|
|
5
|
-
const
|
|
5
|
+
const snapMarginPx = 4;
|
|
6
6
|
function isKind(kind) {
|
|
7
7
|
return kind !== void 0 && kindPattern.test(kind);
|
|
8
8
|
}
|
|
@@ -13,45 +13,61 @@ function writeKind(part, kind, fallback) {
|
|
|
13
13
|
}
|
|
14
14
|
part.style.setProperty("--_sonic-marker", `var(--sonic-marker-${kind}, var(${fallback}))`);
|
|
15
15
|
}
|
|
16
|
-
function
|
|
16
|
+
function createPart(marker) {
|
|
17
17
|
const part = document.createElement("div");
|
|
18
|
-
part.className =
|
|
19
|
-
if (lane !== void 0) part.style.setProperty("--_sonic-marker-lane", String(lane));
|
|
20
|
-
part.style.setProperty("--_sonic-marker-from", String(from));
|
|
21
|
-
part.style.setProperty("--_sonic-marker-to", String(to));
|
|
18
|
+
part.className = marker.end === void 0 ? "sonic-wavestrip-marker" : "sonic-wavestrip-region";
|
|
22
19
|
writeKind(part, marker.kind, "--_sonic-marker-default");
|
|
23
20
|
if (marker.dimmed === true) part.dataset.sonicDimmed = "";
|
|
24
21
|
return part;
|
|
25
22
|
}
|
|
26
23
|
function createMarkerBand(band) {
|
|
27
|
-
let
|
|
24
|
+
let built;
|
|
25
|
+
let placed = [];
|
|
28
26
|
const px = (property) => readPxProperty(getComputedStyle(band), property, 0);
|
|
27
|
+
function build(markers, draw) {
|
|
28
|
+
const parts = markers.map((marker) => {
|
|
29
|
+
const part = createPart(marker);
|
|
30
|
+
if (draw && marker.end === void 0) {
|
|
31
|
+
part.style.setProperty("--_sonic-marker-paint", "transparent");
|
|
32
|
+
draw(marker, part);
|
|
33
|
+
}
|
|
34
|
+
return part;
|
|
35
|
+
});
|
|
36
|
+
band.replaceChildren(...parts);
|
|
37
|
+
built = {
|
|
38
|
+
draw,
|
|
39
|
+
markers,
|
|
40
|
+
parts
|
|
41
|
+
};
|
|
42
|
+
return parts;
|
|
43
|
+
}
|
|
29
44
|
return {
|
|
30
|
-
|
|
45
|
+
inReach: (point, widthPx) => {
|
|
31
46
|
const size = px("--_sonic-marker-size");
|
|
32
47
|
const step = px("--_sonic-marker-step");
|
|
33
|
-
|
|
34
|
-
x,
|
|
35
|
-
y
|
|
36
|
-
}, dots.map(({ at, lane }) => ({
|
|
48
|
+
return centersInReach(point, placed.map(({ at, lane }) => ({
|
|
37
49
|
x: at * widthPx,
|
|
38
50
|
y: size / 2 + lane * step
|
|
39
|
-
})), size / 2 +
|
|
40
|
-
return nearest === void 0 ? void 0 : dots[nearest]?.index;
|
|
51
|
+
})), size / 2 + snapMarginPx).flatMap((order) => placed[order]?.index ?? []);
|
|
41
52
|
},
|
|
42
|
-
render: (markers, proportions) => {
|
|
53
|
+
render: (markers, proportions, draw) => {
|
|
43
54
|
const widthPx = band.getBoundingClientRect().width;
|
|
44
55
|
const points = markers.flatMap((marker, index) => marker.end === void 0 ? [{
|
|
45
56
|
at: proportions[index]?.[0] ?? 0,
|
|
46
57
|
index
|
|
47
58
|
}] : []);
|
|
48
59
|
const lanes = markerLanes(points.map(({ at }) => at * widthPx), px("--_sonic-marker-step"));
|
|
49
|
-
|
|
60
|
+
const parts = built?.markers === markers && built.draw === draw ? built.parts : build(markers, draw);
|
|
61
|
+
placed = points.map((point, order) => ({
|
|
50
62
|
...point,
|
|
51
63
|
lane: lanes[order] ?? 0
|
|
52
64
|
}));
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
for (const [index, part] of parts.entries()) {
|
|
66
|
+
const [from, to] = proportions[index] ?? [0, 0];
|
|
67
|
+
part.style.setProperty("--_sonic-marker-from", String(from));
|
|
68
|
+
part.style.setProperty("--_sonic-marker-to", String(to));
|
|
69
|
+
}
|
|
70
|
+
for (const { index, lane } of placed) parts[index]?.style.setProperty("--_sonic-marker-lane", String(lane));
|
|
55
71
|
}
|
|
56
72
|
};
|
|
57
73
|
}
|
|
@@ -64,17 +80,12 @@ function markerLanes(positions, minDistance) {
|
|
|
64
80
|
return lane;
|
|
65
81
|
});
|
|
66
82
|
}
|
|
67
|
-
function
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (distance > nearestDistance) continue;
|
|
73
|
-
nearest = index;
|
|
74
|
-
nearestDistance = distance;
|
|
75
|
-
}
|
|
76
|
-
return nearest;
|
|
83
|
+
function centersInReach(point, centers, reach) {
|
|
84
|
+
return centers.map((center, index) => ({
|
|
85
|
+
distance: (center.x - point.x) ** 2 + (center.y - point.y) ** 2,
|
|
86
|
+
index
|
|
87
|
+
})).filter(({ distance }) => distance <= reach * reach).toSorted((first, second) => first.distance - second.distance || second.index - first.index).map(({ index }) => index);
|
|
77
88
|
}
|
|
78
89
|
|
|
79
90
|
//#endregion
|
|
80
|
-
export { createMarkerBand, isKind, markerLanes,
|
|
91
|
+
export { centersInReach, createMarkerBand, isKind, markerLanes, writeKind };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { clamp, clampProportion, trimFloat } from "./math.js";
|
|
2
|
+
import { fineFactor } from "./drag-step.js";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/region-drag.ts
|
|
5
|
+
function regionAt(bodies, x) {
|
|
6
|
+
const index = bodies.findLastIndex((body) => body !== void 0 && x >= body[0] && x <= body[1]);
|
|
7
|
+
return index === -1 ? void 0 : index;
|
|
8
|
+
}
|
|
9
|
+
function regionTravel({ end, start }, [low, high]) {
|
|
10
|
+
return [low, Math.max(low, trimFloat(high - (end - start)))];
|
|
11
|
+
}
|
|
12
|
+
function moveRegionTo(mapping, span, start) {
|
|
13
|
+
const moved = clamp(mapping.snap(start), ...regionTravel(span, mapping.bounds));
|
|
14
|
+
return {
|
|
15
|
+
end: trimFloat(moved + (span.end - span.start)),
|
|
16
|
+
start: moved
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function startRegionDrag({ position, ...fixed }) {
|
|
20
|
+
return {
|
|
21
|
+
...fixed,
|
|
22
|
+
isEngaged: false,
|
|
23
|
+
lastPosition: position,
|
|
24
|
+
startPosition: position,
|
|
25
|
+
travelPx: 0
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function stepRegionDrag(mapping, state, move) {
|
|
29
|
+
if (!(state.isEngaged || Math.abs(move.position - state.startPosition) >= state.thresholdPx)) return {
|
|
30
|
+
span: void 0,
|
|
31
|
+
state
|
|
32
|
+
};
|
|
33
|
+
const pace = move.isFine ? fineFactor : 1;
|
|
34
|
+
const travelPx = state.travelPx + (move.position - state.lastPosition) * pace;
|
|
35
|
+
const at = mapping.proportionOf(state.from.start) + travelPx / state.widthPx;
|
|
36
|
+
return {
|
|
37
|
+
span: moveRegionTo(mapping, state.from, mapping.valueAt(clampProportion(at))),
|
|
38
|
+
state: {
|
|
39
|
+
...state,
|
|
40
|
+
isEngaged: true,
|
|
41
|
+
lastPosition: move.position,
|
|
42
|
+
travelPx
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
export { moveRegionTo, regionAt, regionTravel, startRegionDrag, stepRegionDrag };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region.js","names":[],"sources":["../../../src/define/region.ts"],"sourcesContent":["import { defineOnce } from '#elements/define-once.ts';\nimport { SonicRegion } from '#elements/region.ts';\n\ndefineOnce('sonic-region', SonicRegion);\n\nexport type { SonicRegion } from '#elements/region.ts';\n"],"mappings":";;;;AAGA,WAAW,gBAAgB,WAAW"}
|
package/dist/dev/define.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ import { SonicMeter } from "./elements/meter.js";
|
|
|
8
8
|
import "./define/meter.js";
|
|
9
9
|
import { SonicNumber } from "./elements/number.js";
|
|
10
10
|
import "./define/number.js";
|
|
11
|
+
import { SonicRegion } from "./elements/region.js";
|
|
12
|
+
import "./define/region.js";
|
|
11
13
|
import { SonicSegmented } from "./elements/segmented.js";
|
|
12
14
|
import "./define/segmented.js";
|
|
13
15
|
import { SonicSlider } from "./elements/slider.js";
|
|
@@ -26,4 +28,4 @@ import { SonicWavestrip } from "./elements/wavestrip.js";
|
|
|
26
28
|
import "./define/wavestrip.js";
|
|
27
29
|
import { SonicXy } from "./elements/xy.js";
|
|
28
30
|
import "./define/xy.js";
|
|
29
|
-
export type { SonicButton, SonicDial, SonicEnvelope, SonicMeter, SonicNumber, SonicSegmented, SonicSlider, SonicSpectrum, SonicSplit, SonicSwitch, SonicToggle, SonicWaveform, SonicWavestrip, SonicXy };
|
|
31
|
+
export type { SonicButton, SonicDial, SonicEnvelope, SonicMeter, SonicNumber, SonicRegion, SonicSegmented, SonicSlider, SonicSpectrum, SonicSplit, SonicSwitch, SonicToggle, SonicWaveform, SonicWavestrip, SonicXy };
|
package/dist/dev/define.js
CHANGED
|
@@ -35,6 +35,7 @@ export declare class SonicButton extends SonicFormElement {
|
|
|
35
35
|
protected focusTarget(): HTMLElement;
|
|
36
36
|
protected render(): void;
|
|
37
37
|
protected restoreState(state: string): void;
|
|
38
|
+
protected stateTarget(): HTMLElement;
|
|
38
39
|
}
|
|
39
40
|
//#endregion
|
|
40
41
|
//# sourceMappingURL=button.d.ts.map
|
|
@@ -154,6 +154,9 @@ var SonicButton = class extends SonicFormElement {
|
|
|
154
154
|
restoreState(state) {
|
|
155
155
|
if (this.latching) this.pressed = state === "true";
|
|
156
156
|
}
|
|
157
|
+
stateTarget() {
|
|
158
|
+
return this.#button;
|
|
159
|
+
}
|
|
157
160
|
#bindMomentary(button, signal) {
|
|
158
161
|
const holding = bindHold(button, {
|
|
159
162
|
canHold: () => !this.isDisabled() && !this.#isSoftDisabled(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","names":[],"sources":["../../../src/elements/button.ts"],"sourcesContent":["import type { Hold } from '#lib/hold.ts';\n\nimport { SonicFormElement } from '#elements/form-element.ts';\nimport { copyNode } from '#lib/copy-node.ts';\nimport { bindHold } from '#lib/hold.ts';\nimport { bindKeyPress } from '#lib/key-press.ts';\nimport { mirrorChildren } from '#lib/mirror-children.ts';\nimport { capturePointer } from '#lib/pointer-drag.ts';\nimport { placeChildren, requireChild, template } from '#lib/render.ts';\nimport { writeAttribute } from '#lib/write-attribute.ts';\n\ndeclare const __DEV__: boolean;\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'sonic-button': SonicButton;\n\t}\n}\n\nconst renderButton = template(\n\t/* HTML */ `\n\t\t<button class=\"sonic-button\" type=\"button\"><span class=\"sonic-button-cap\"></span></button>\n\t`,\n\tHTMLButtonElement,\n);\n\nconst holdKeys = new Set([' ', 'Enter']);\n\nconst popupAttributes = {\n\tcontrols: 'aria-controls',\n\texpanded: 'aria-expanded',\n\tpopup: 'aria-haspopup',\n} as const;\n\nconst pressWhens = new Set(['pressed', 'released']);\n\nexport class SonicButton extends SonicFormElement {\n\tstatic override readonly observedAttributes = [\n\t\t...SonicFormElement.observedAttributes,\n\t\t...Object.keys(popupAttributes),\n\t\t'busy',\n\t\t'legend',\n\t\t'momentary',\n\t\t'pressed',\n\t\t'soft-disabled',\n\t\t'latching',\n\t\t'value',\n\t];\n\n\tget armed(): boolean {\n\t\treturn this.hasAttribute('armed');\n\t}\n\n\tset armed(isArmed: boolean) {\n\t\tthis.reflect('armed', isArmed);\n\t}\n\n\tget busy(): boolean {\n\t\treturn this.hasAttribute('busy');\n\t}\n\n\tset busy(isBusy: boolean) {\n\t\tthis.reflect('busy', isBusy);\n\t}\n\n\tget defaultPressed(): boolean {\n\t\treturn this.hasAttribute('pressed');\n\t}\n\n\tset defaultPressed(isPressed: boolean) {\n\t\tthis.reflect('pressed', isPressed);\n\t}\n\n\tget latching(): boolean {\n\t\treturn this.hasAttribute('latching');\n\t}\n\n\tset latching(isLatching: boolean) {\n\t\tthis.reflect('latching', isLatching);\n\t}\n\n\t/** Shows the legend child whose `data-sonic-when` has this name */\n\tget legend(): string | undefined {\n\t\treturn this.getAttribute('legend') ?? undefined;\n\t}\n\n\tset legend(name: string | undefined) {\n\t\tthis.reflect('legend', name);\n\t}\n\n\tget momentary(): boolean {\n\t\treturn this.hasAttribute('momentary');\n\t}\n\n\tset momentary(isMomentary: boolean) {\n\t\tthis.reflect('momentary', isMomentary);\n\t}\n\n\tget pressed(): boolean {\n\t\treturn this.#isDirty ? this.#pressed : this.defaultPressed;\n\t}\n\n\tset pressed(isPressed: boolean | undefined) {\n\t\tthis.#isDirty = true;\n\t\tthis.#pressed = isPressed === true;\n\t\tthis.render();\n\t}\n\n\tget softDisabled(): boolean {\n\t\treturn this.hasAttribute('soft-disabled');\n\t}\n\n\tset softDisabled(isSoftDisabled: boolean) {\n\t\tthis.reflect('soft-disabled', isSoftDisabled);\n\t}\n\n\t/** Submitted with the form while a latching button is pressed */\n\tget value(): string {\n\t\treturn this.getAttribute('value') ?? 'on';\n\t}\n\n\tset value(value: string | undefined) {\n\t\tthis.reflect('value', value);\n\t}\n\n\treadonly #button = renderButton();\n\n\t#holding: Hold | undefined;\n\n\t#isDirty = false;\n\n\t#pressed = false;\n\n\tattributeChangedCallback(name: string): void {\n\t\tif (name === 'pressed') this.#isDirty = false;\n\t\tif (this.isDisabled() || this.#isSoftDisabled()) this.#holding?.release();\n\t\tthis.render();\n\t}\n\n\toverride formResetCallback(): void {\n\t\tthis.attributeChangedCallback('pressed');\n\t}\n\n\tprotected override activate(): void {\n\t\tthis.#button.click();\n\t}\n\n\tprotected connect(signal: AbortSignal): void {\n\t\tconst button = this.#button;\n\t\tconst cap = requireChild(button, '.sonic-button-cap', HTMLSpanElement);\n\n\t\tthis.upgradeProperties(\n\t\t\t'armed',\n\t\t\t'busy',\n\t\t\t'defaultPressed',\n\t\t\t'legend',\n\t\t\t'momentary',\n\t\t\t'softDisabled',\n\t\t\t'latching',\n\t\t\t'pressed',\n\t\t\t'value',\n\t\t);\n\t\tmirrorChildren(\n\t\t\tthis,\n\t\t\t{\n\t\t\t\tcontrol: button,\n\t\t\t\tcopy: copyNode,\n\t\t\t\tplace: (copies) => {\n\t\t\t\t\tplaceChildren(cap, copies);\n\t\t\t\t\tthis.#showLegend();\n\t\t\t\t},\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t\tthis.render();\n\t\tif (__DEV__)\n\t\t\tthis.checkStyles(button, 'button.css', {\n\t\t\t\tproperty: 'padding-inline-start',\n\t\t\t\tratio: '--_sonic-button-padding-ratio',\n\t\t\t\tselector: '.sonic-button-cap > :not(svg, .sonic-led)',\n\t\t\t});\n\n\t\tbutton.addEventListener(\n\t\t\t'click',\n\t\t\t(event) => {\n\t\t\t\t// A native disabled button fires no click at all\n\t\t\t\tif (this.#isSoftDisabled()) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!this.latching) return;\n\n\t\t\t\tthis.pressed = !this.pressed;\n\t\t\t\tthis.dispatchEvent(new Event('change', { bubbles: true }));\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t\tthis.#bindMomentary(button, signal);\n\t\tbindKeyPress(button, signal);\n\t}\n\n\tprotected override focusTarget(): HTMLElement {\n\t\treturn this.#button;\n\t}\n\n\tprotected render(): void {\n\t\tif (!this.isBound()) return;\n\n\t\tconst button = this.#button;\n\n\t\twriteAttribute(button, 'disabled', this.isDisabled() ? '' : undefined);\n\t\twriteAttribute(button, 'aria-disabled', this.#isSoftDisabled() ? 'true' : undefined);\n\t\twriteAttribute(button, 'aria-busy', this.busy ? 'true' : undefined);\n\t\twriteAttribute(button, 'aria-pressed', this.latching ? String(this.pressed) : undefined);\n\t\tthis.toggleState('pressed', this.pressed);\n\t\tthis.forwardNaming(button, true);\n\t\tthis.#forwardPopup(button);\n\t\tthis.#showLegend();\n\n\t\t// eslint-disable-next-line unicorn/no-null -- `null` submits nothing\n\t\tconst submitted = this.latching && this.pressed ? this.value : null;\n\n\t\tthis.writeFormValue(submitted, String(this.pressed));\n\t}\n\n\tprotected restoreState(state: string): void {\n\t\tif (this.latching) this.pressed = state === 'true';\n\t}\n\n\t#bindMomentary(button: HTMLButtonElement, signal: AbortSignal): void {\n\t\tconst holding = bindHold(\n\t\t\tbutton,\n\t\t\t{\n\t\t\t\tcanHold: () => !this.isDisabled() && !this.#isSoftDisabled(),\n\t\t\t\tleave: 'blur',\n\t\t\t\tonHold: () => {\n\t\t\t\t\tthis.#press(true);\n\t\t\t\t},\n\t\t\t\tonRelease: () => {\n\t\t\t\t\tthis.#press(false);\n\t\t\t\t},\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\n\t\tthis.#holding = holding;\n\t\tbutton.addEventListener(\n\t\t\t'pointerdown',\n\t\t\t(event) => {\n\t\t\t\tif (event.button !== 0 || !this.#isMomentary()) return;\n\n\t\t\t\tcapturePointer(button, event.pointerId);\n\t\t\t\tholding.hold(event.pointerId);\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t\tbutton.addEventListener(\n\t\t\t'keydown',\n\t\t\t(event) => {\n\t\t\t\tif (event.repeat || event.defaultPrevented) return;\n\t\t\t\tif (!holdKeys.has(event.key) || !this.#isMomentary()) return;\n\n\t\t\t\tholding.hold(event.key);\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t}\n\n\t#forwardPopup(button: HTMLButtonElement): void {\n\t\tfor (const [name, aria] of Object.entries(popupAttributes)) {\n\t\t\twriteAttribute(button, aria, this.getAttribute(name) ?? undefined);\n\t\t}\n\t}\n\n\t#isMomentary(): boolean {\n\t\treturn this.momentary && !this.latching;\n\t}\n\n\t#isSoftDisabled(): boolean {\n\t\treturn this.softDisabled && !this.isDisabled();\n\t}\n\n\t#press(isPressed: boolean): void {\n\t\tthis.pressed = isPressed;\n\t\tthis.dispatchEvent(new Event('change', { bubbles: true }));\n\t}\n\n\t#showLegend(): void {\n\t\tconst legend = this.legend;\n\n\t\tfor (const part of this.#button.querySelectorAll<HTMLElement | SVGElement>(\n\t\t\t':scope > .sonic-button-cap > [data-sonic-when]',\n\t\t)) {\n\t\t\tconst when = part.dataset.sonicWhen ?? '';\n\n\t\t\tpart.toggleAttribute('data-sonic-hidden', !pressWhens.has(when) && when !== legend);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"button.js","names":[],"sources":["../../../src/elements/button.ts"],"sourcesContent":["import type { Hold } from '#lib/hold.ts';\n\nimport { SonicFormElement } from '#elements/form-element.ts';\nimport { copyNode } from '#lib/copy-node.ts';\nimport { bindHold } from '#lib/hold.ts';\nimport { bindKeyPress } from '#lib/key-press.ts';\nimport { mirrorChildren } from '#lib/mirror-children.ts';\nimport { capturePointer } from '#lib/pointer-drag.ts';\nimport { placeChildren, requireChild, template } from '#lib/render.ts';\nimport { writeAttribute } from '#lib/write-attribute.ts';\n\ndeclare const __DEV__: boolean;\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'sonic-button': SonicButton;\n\t}\n}\n\nconst renderButton = template(\n\t/* HTML */ `\n\t\t<button class=\"sonic-button\" type=\"button\"><span class=\"sonic-button-cap\"></span></button>\n\t`,\n\tHTMLButtonElement,\n);\n\nconst holdKeys = new Set([' ', 'Enter']);\n\nconst popupAttributes = {\n\tcontrols: 'aria-controls',\n\texpanded: 'aria-expanded',\n\tpopup: 'aria-haspopup',\n} as const;\n\nconst pressWhens = new Set(['pressed', 'released']);\n\nexport class SonicButton extends SonicFormElement {\n\tstatic override readonly observedAttributes = [\n\t\t...SonicFormElement.observedAttributes,\n\t\t...Object.keys(popupAttributes),\n\t\t'busy',\n\t\t'legend',\n\t\t'momentary',\n\t\t'pressed',\n\t\t'soft-disabled',\n\t\t'latching',\n\t\t'value',\n\t];\n\n\tget armed(): boolean {\n\t\treturn this.hasAttribute('armed');\n\t}\n\n\tset armed(isArmed: boolean) {\n\t\tthis.reflect('armed', isArmed);\n\t}\n\n\tget busy(): boolean {\n\t\treturn this.hasAttribute('busy');\n\t}\n\n\tset busy(isBusy: boolean) {\n\t\tthis.reflect('busy', isBusy);\n\t}\n\n\tget defaultPressed(): boolean {\n\t\treturn this.hasAttribute('pressed');\n\t}\n\n\tset defaultPressed(isPressed: boolean) {\n\t\tthis.reflect('pressed', isPressed);\n\t}\n\n\tget latching(): boolean {\n\t\treturn this.hasAttribute('latching');\n\t}\n\n\tset latching(isLatching: boolean) {\n\t\tthis.reflect('latching', isLatching);\n\t}\n\n\t/** Shows the legend child whose `data-sonic-when` has this name */\n\tget legend(): string | undefined {\n\t\treturn this.getAttribute('legend') ?? undefined;\n\t}\n\n\tset legend(name: string | undefined) {\n\t\tthis.reflect('legend', name);\n\t}\n\n\tget momentary(): boolean {\n\t\treturn this.hasAttribute('momentary');\n\t}\n\n\tset momentary(isMomentary: boolean) {\n\t\tthis.reflect('momentary', isMomentary);\n\t}\n\n\tget pressed(): boolean {\n\t\treturn this.#isDirty ? this.#pressed : this.defaultPressed;\n\t}\n\n\tset pressed(isPressed: boolean | undefined) {\n\t\tthis.#isDirty = true;\n\t\tthis.#pressed = isPressed === true;\n\t\tthis.render();\n\t}\n\n\tget softDisabled(): boolean {\n\t\treturn this.hasAttribute('soft-disabled');\n\t}\n\n\tset softDisabled(isSoftDisabled: boolean) {\n\t\tthis.reflect('soft-disabled', isSoftDisabled);\n\t}\n\n\t/** Submitted with the form while a latching button is pressed */\n\tget value(): string {\n\t\treturn this.getAttribute('value') ?? 'on';\n\t}\n\n\tset value(value: string | undefined) {\n\t\tthis.reflect('value', value);\n\t}\n\n\treadonly #button = renderButton();\n\n\t#holding: Hold | undefined;\n\n\t#isDirty = false;\n\n\t#pressed = false;\n\n\tattributeChangedCallback(name: string): void {\n\t\tif (name === 'pressed') this.#isDirty = false;\n\t\tif (this.isDisabled() || this.#isSoftDisabled()) this.#holding?.release();\n\t\tthis.render();\n\t}\n\n\toverride formResetCallback(): void {\n\t\tthis.attributeChangedCallback('pressed');\n\t}\n\n\tprotected override activate(): void {\n\t\tthis.#button.click();\n\t}\n\n\tprotected connect(signal: AbortSignal): void {\n\t\tconst button = this.#button;\n\t\tconst cap = requireChild(button, '.sonic-button-cap', HTMLSpanElement);\n\n\t\tthis.upgradeProperties(\n\t\t\t'armed',\n\t\t\t'busy',\n\t\t\t'defaultPressed',\n\t\t\t'legend',\n\t\t\t'momentary',\n\t\t\t'softDisabled',\n\t\t\t'latching',\n\t\t\t'pressed',\n\t\t\t'value',\n\t\t);\n\t\tmirrorChildren(\n\t\t\tthis,\n\t\t\t{\n\t\t\t\tcontrol: button,\n\t\t\t\tcopy: copyNode,\n\t\t\t\tplace: (copies) => {\n\t\t\t\t\tplaceChildren(cap, copies);\n\t\t\t\t\tthis.#showLegend();\n\t\t\t\t},\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t\tthis.render();\n\t\tif (__DEV__)\n\t\t\tthis.checkStyles(button, 'button.css', {\n\t\t\t\tproperty: 'padding-inline-start',\n\t\t\t\tratio: '--_sonic-button-padding-ratio',\n\t\t\t\tselector: '.sonic-button-cap > :not(svg, .sonic-led)',\n\t\t\t});\n\n\t\tbutton.addEventListener(\n\t\t\t'click',\n\t\t\t(event) => {\n\t\t\t\t// A native disabled button fires no click at all\n\t\t\t\tif (this.#isSoftDisabled()) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!this.latching) return;\n\n\t\t\t\tthis.pressed = !this.pressed;\n\t\t\t\tthis.dispatchEvent(new Event('change', { bubbles: true }));\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t\tthis.#bindMomentary(button, signal);\n\t\tbindKeyPress(button, signal);\n\t}\n\n\tprotected override focusTarget(): HTMLElement {\n\t\treturn this.#button;\n\t}\n\n\tprotected render(): void {\n\t\tif (!this.isBound()) return;\n\n\t\tconst button = this.#button;\n\n\t\twriteAttribute(button, 'disabled', this.isDisabled() ? '' : undefined);\n\t\twriteAttribute(button, 'aria-disabled', this.#isSoftDisabled() ? 'true' : undefined);\n\t\twriteAttribute(button, 'aria-busy', this.busy ? 'true' : undefined);\n\t\twriteAttribute(button, 'aria-pressed', this.latching ? String(this.pressed) : undefined);\n\t\tthis.toggleState('pressed', this.pressed);\n\t\tthis.forwardNaming(button, true);\n\t\tthis.#forwardPopup(button);\n\t\tthis.#showLegend();\n\n\t\t// eslint-disable-next-line unicorn/no-null -- `null` submits nothing\n\t\tconst submitted = this.latching && this.pressed ? this.value : null;\n\n\t\tthis.writeFormValue(submitted, String(this.pressed));\n\t}\n\n\tprotected restoreState(state: string): void {\n\t\tif (this.latching) this.pressed = state === 'true';\n\t}\n\n\tprotected override stateTarget(): HTMLElement {\n\t\treturn this.#button;\n\t}\n\n\t#bindMomentary(button: HTMLButtonElement, signal: AbortSignal): void {\n\t\tconst holding = bindHold(\n\t\t\tbutton,\n\t\t\t{\n\t\t\t\tcanHold: () => !this.isDisabled() && !this.#isSoftDisabled(),\n\t\t\t\tleave: 'blur',\n\t\t\t\tonHold: () => {\n\t\t\t\t\tthis.#press(true);\n\t\t\t\t},\n\t\t\t\tonRelease: () => {\n\t\t\t\t\tthis.#press(false);\n\t\t\t\t},\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\n\t\tthis.#holding = holding;\n\t\tbutton.addEventListener(\n\t\t\t'pointerdown',\n\t\t\t(event) => {\n\t\t\t\tif (event.button !== 0 || !this.#isMomentary()) return;\n\n\t\t\t\tcapturePointer(button, event.pointerId);\n\t\t\t\tholding.hold(event.pointerId);\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t\tbutton.addEventListener(\n\t\t\t'keydown',\n\t\t\t(event) => {\n\t\t\t\tif (event.repeat || event.defaultPrevented) return;\n\t\t\t\tif (!holdKeys.has(event.key) || !this.#isMomentary()) return;\n\n\t\t\t\tholding.hold(event.key);\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t}\n\n\t#forwardPopup(button: HTMLButtonElement): void {\n\t\tfor (const [name, aria] of Object.entries(popupAttributes)) {\n\t\t\twriteAttribute(button, aria, this.getAttribute(name) ?? undefined);\n\t\t}\n\t}\n\n\t#isMomentary(): boolean {\n\t\treturn this.momentary && !this.latching;\n\t}\n\n\t#isSoftDisabled(): boolean {\n\t\treturn this.softDisabled && !this.isDisabled();\n\t}\n\n\t#press(isPressed: boolean): void {\n\t\tthis.pressed = isPressed;\n\t\tthis.dispatchEvent(new Event('change', { bubbles: true }));\n\t}\n\n\t#showLegend(): void {\n\t\tconst legend = this.legend;\n\n\t\tfor (const part of this.#button.querySelectorAll<HTMLElement | SVGElement>(\n\t\t\t':scope > .sonic-button-cap > [data-sonic-when]',\n\t\t)) {\n\t\t\tconst when = part.dataset.sonicWhen ?? '';\n\n\t\t\tpart.toggleAttribute('data-sonic-hidden', !pressWhens.has(when) && when !== legend);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@ export declare class SonicDial extends SonicValueElement {
|
|
|
21
21
|
protected draw(): void;
|
|
22
22
|
protected focusTarget(): HTMLElement;
|
|
23
23
|
protected isWrapping(): boolean;
|
|
24
|
+
protected stateTarget(): HTMLElement;
|
|
24
25
|
}
|
|
25
26
|
//#endregion
|
|
26
27
|
//# sourceMappingURL=dial.d.ts.map
|