@swiftwc/ui 0.0.0-dev.97 → 0.0.0-dev.99
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/generated/components/label-view.d.ts +1 -1
- package/generated/components/label-view.js +1 -1
- package/generated/components/picker-view.d.ts +1 -1
- package/generated/components/picker-view.js +1 -1
- package/generated/components/progress-view.d.ts +0 -1
- package/generated/components/progress-view.js +2 -2
- package/generated/components/text-field.d.ts +1 -1
- package/generated/components/text-field.js +1 -1
- package/generated/components/toggle-view.d.ts +1 -1
- package/generated/components/toggle-view.js +157 -36
- package/generated/components/tool-bar-item.js +2 -2
- package/generated/components/v-stack.d.ts +1 -0
- package/generated/components/v-stack.js +1 -0
- package/generated/css/index.css +1459 -207
- package/package.json +1 -1
- package/scss/components/_index.scss +1 -0
- package/scss/components/_toggle-view.scss +66 -28
- package/scss/final/_touch-glass.scss +7 -0
- package/scss/utils/_frame.scss +24 -47
- package/scss/utils/_stacks.scss +14 -3
- package/web-components.html-data/en.json +844 -67
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* @slot icon — Use the `slot="icon"` attribute to place childen in the icon block.
|
|
13
13
|
*
|
|
14
14
|
* @cssprop --label-gap — The gap between the icon and the title.
|
|
15
|
-
* @cssprop --label-image-size — The size of the icon.
|
|
15
|
+
* @cssprop {number} --label-image-size — The size of the icon.
|
|
16
16
|
* @cssprop --label-padding-inline — The padding inline of the label.
|
|
17
17
|
*
|
|
18
18
|
*/
|
|
@@ -15,7 +15,7 @@ import { html } from '../tpl';
|
|
|
15
15
|
* @slot icon — Use the `slot="icon"` attribute to place childen in the icon block.
|
|
16
16
|
*
|
|
17
17
|
* @cssprop --label-gap — The gap between the icon and the title.
|
|
18
|
-
* @cssprop --label-image-size — The size of the icon.
|
|
18
|
+
* @cssprop {number} --label-image-size — The size of the icon.
|
|
19
19
|
* @cssprop --label-padding-inline — The padding inline of the label.
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
@@ -23,7 +23,7 @@ export type Dictionary = DictEntry[];
|
|
|
23
23
|
* @slot — The default slot.
|
|
24
24
|
* @slot label
|
|
25
25
|
* @slot list
|
|
26
|
-
* @slot validity-options
|
|
26
|
+
* @slot {HTMLOptionElement[]} validity-options
|
|
27
27
|
*/
|
|
28
28
|
export declare class PickerView extends FormAssociatedBase {
|
|
29
29
|
#private;
|
|
@@ -129,7 +129,7 @@ const collectLeafValues = (node) => (node.children.length ? node.children.flatMa
|
|
|
129
129
|
* @slot — The default slot.
|
|
130
130
|
* @slot label
|
|
131
131
|
* @slot list
|
|
132
|
-
* @slot validity-options
|
|
132
|
+
* @slot {HTMLOptionElement[]} validity-options
|
|
133
133
|
*/
|
|
134
134
|
export class PickerView extends FormAssociatedBase {
|
|
135
135
|
static get ATTR() {
|
|
@@ -8,7 +8,6 @@ export declare class ProgressView extends HTMLElement {
|
|
|
8
8
|
#private;
|
|
9
9
|
static get observedAttributes(): string[];
|
|
10
10
|
get progressViewStyle(): "circular" | "linear";
|
|
11
|
-
get template(): DocumentFragment;
|
|
12
11
|
constructor();
|
|
13
12
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
14
13
|
disconnectedCallback(): void;
|
|
@@ -25,7 +25,7 @@ export class ProgressView extends HTMLElement {
|
|
|
25
25
|
get progressViewStyle() {
|
|
26
26
|
return this.#progressViewStyle ?? 'circular';
|
|
27
27
|
}
|
|
28
|
-
get template() {
|
|
28
|
+
get #template() {
|
|
29
29
|
if (!_a.#templates.has(this.progressViewStyle))
|
|
30
30
|
switch (this.progressViewStyle) {
|
|
31
31
|
case 'linear':
|
|
@@ -109,7 +109,7 @@ export class ProgressView extends HTMLElement {
|
|
|
109
109
|
if (this.#lastRenderedStyle === this.#progressViewStyle)
|
|
110
110
|
return; // skip if already applied
|
|
111
111
|
this.#lastRenderedStyle = this.#progressViewStyle;
|
|
112
|
-
this.#shadowRoot.replaceChildren(document.importNode(this
|
|
112
|
+
this.#shadowRoot.replaceChildren(document.importNode(this.#template, true)); // clear shadow DOM
|
|
113
113
|
CleanupRegistry.unregister(this, 'slots');
|
|
114
114
|
for (const slot of this.#shadowRoot.querySelectorAll('slot'))
|
|
115
115
|
this.#slots?.set(slot.name, slot);
|
|
@@ -7,7 +7,7 @@ export type KeyboardType = (typeof keyboardTypes)[number];
|
|
|
7
7
|
* @fires {{ detail: { text: string } }} commit — Triggered when user interacts with the input area
|
|
8
8
|
*
|
|
9
9
|
* @slot label
|
|
10
|
-
* @slot validity-options
|
|
10
|
+
* @slot {HTMLOptionElement[]} validity-options
|
|
11
11
|
*/
|
|
12
12
|
export declare class TextField extends FormAssociatedBase {
|
|
13
13
|
#private;
|
|
@@ -13,7 +13,7 @@ const keyboardTypes = ['decimal-pad', 'number-pad', 'default'];
|
|
|
13
13
|
* @fires {{ detail: { text: string } }} commit — Triggered when user interacts with the input area
|
|
14
14
|
*
|
|
15
15
|
* @slot label
|
|
16
|
-
* @slot validity-options
|
|
16
|
+
* @slot {HTMLOptionElement[]} validity-options
|
|
17
17
|
*/
|
|
18
18
|
export class TextField extends FormAssociatedBase {
|
|
19
19
|
static get observedAttributes() {
|
|
@@ -7,7 +7,7 @@ export type ToggleStyle = (typeof toggleStyles)[number];
|
|
|
7
7
|
* @fires toggle:change — User toggled the control
|
|
8
8
|
*
|
|
9
9
|
* @slot label
|
|
10
|
-
* @slot validity-options
|
|
10
|
+
* @slot {HTMLOptionElement[]} validity-options
|
|
11
11
|
*/
|
|
12
12
|
export declare class ToggleView extends FormAssociatedBase {
|
|
13
13
|
#private;
|
|
@@ -2,7 +2,7 @@ var _a;
|
|
|
2
2
|
import { CleanupRegistry } from '../internal/class/cleanup-registry';
|
|
3
3
|
import { FormAssociatedBase, getInternals } from '../internal/class/form-associated-base';
|
|
4
4
|
import { MutationObserverSet } from '../internal/class/mutation-observer-set';
|
|
5
|
-
import { $, devFlags, kebabCase, onoff } from '../internal/utils';
|
|
5
|
+
import { $, devFlags, kebabCase, onoff, touchGlass } from '../internal/utils';
|
|
6
6
|
import { queryMorph } from '../morphdom';
|
|
7
7
|
import { html } from '../tpl';
|
|
8
8
|
const toggleStyles = ['switch', 'button'];
|
|
@@ -12,7 +12,7 @@ const toggleStyles = ['switch', 'button'];
|
|
|
12
12
|
* @fires toggle:change — User toggled the control
|
|
13
13
|
*
|
|
14
14
|
* @slot label
|
|
15
|
-
* @slot validity-options
|
|
15
|
+
* @slot {HTMLOptionElement[]} validity-options
|
|
16
16
|
*/
|
|
17
17
|
export class ToggleView extends FormAssociatedBase {
|
|
18
18
|
static get observedAttributes() {
|
|
@@ -24,7 +24,6 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
24
24
|
* @type {boolean}
|
|
25
25
|
*/
|
|
26
26
|
'is-on',
|
|
27
|
-
'keyboard-type',
|
|
28
27
|
/**
|
|
29
28
|
* @type {boolean}
|
|
30
29
|
*/
|
|
@@ -42,8 +41,7 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
42
41
|
<slot name="label"></slot>
|
|
43
42
|
</div>
|
|
44
43
|
<div part="root toggle-input-stack">
|
|
45
|
-
|
|
46
|
-
<div part="root toggle-form-input" tabindex="0"></div>
|
|
44
|
+
<div part="root toggle-track" tabindex="0"></div>
|
|
47
45
|
</div>
|
|
48
46
|
<slot name="validity-options" hidden></slot>
|
|
49
47
|
</label>`));
|
|
@@ -57,10 +55,30 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
57
55
|
#customValidity = '';
|
|
58
56
|
#slots = new Map();
|
|
59
57
|
#validityObservers = new MutationObserverSet(this.#renderValidityMsgs);
|
|
60
|
-
#
|
|
58
|
+
#track;
|
|
61
59
|
#value = 'on';
|
|
62
60
|
#isOn = false;
|
|
63
|
-
#
|
|
61
|
+
#didDrag = false;
|
|
62
|
+
#trackWidth = 0;
|
|
63
|
+
#dotSize = 0;
|
|
64
|
+
get #trackMinX() {
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
get #trackMaxX() {
|
|
68
|
+
return this.#trackWidth - this.#dotSize;
|
|
69
|
+
}
|
|
70
|
+
#handleMeasure = ([{ target, borderBoxSize }]) => {
|
|
71
|
+
if (devFlags.debug)
|
|
72
|
+
console.debug(`${_a.name} ⚡️ measure`);
|
|
73
|
+
if (!(target instanceof HTMLElement))
|
|
74
|
+
return;
|
|
75
|
+
this.#trackWidth = borderBoxSize.at(0)?.inlineSize ?? 0;
|
|
76
|
+
this.#dotSize = borderBoxSize.at(0)?.blockSize ?? 0;
|
|
77
|
+
};
|
|
78
|
+
#resizeObserver = new ResizeObserver(this.#handleMeasure);
|
|
79
|
+
get #isDragging() {
|
|
80
|
+
return '0ms' === this.#track?.style.getPropertyValue('--toggle--dot-transition-duration');
|
|
81
|
+
}
|
|
64
82
|
get #internals() {
|
|
65
83
|
return getInternals(this);
|
|
66
84
|
}
|
|
@@ -75,14 +93,18 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
75
93
|
});
|
|
76
94
|
CleanupRegistry.unregister(this, 'validities');
|
|
77
95
|
CleanupRegistry.register(this, onoff('slotchange', this.#handleValiditiesSlotchange, this.#slots?.get('validity-options')).on(), 'validities');
|
|
78
|
-
this.#
|
|
79
|
-
this.#input?.addEventListener('click', () => {
|
|
80
|
-
this.isOn = !this.isOn;
|
|
81
|
-
this.#sendValueToForm(this.#connected);
|
|
82
|
-
});
|
|
96
|
+
this.#track = this.#shadowRoot.querySelector('[part*=toggle-track]') ?? undefined;
|
|
83
97
|
CleanupRegistry.register(this, onoff([{ types: 'focusin', listener: this.#handleFocusin }], this).on());
|
|
84
|
-
CleanupRegistry.register(this, onoff([
|
|
85
|
-
|
|
98
|
+
CleanupRegistry.register(this, onoff([
|
|
99
|
+
{ types: 'keydown', listener: this.#handleTrackKeydown },
|
|
100
|
+
{ types: 'click', listener: this.#handleTrackClick },
|
|
101
|
+
{ types: 'pointerdown', listener: this.#handleTrackPointerdown },
|
|
102
|
+
{ types: 'pointerup', listener: this.#handleTrackPointerup },
|
|
103
|
+
{ types: 'pointercancel', listener: this.#handleTrackPointercancel },
|
|
104
|
+
{ types: 'pointermove', listener: this.#handleTrackPointermove },
|
|
105
|
+
{ types: 'lostpointercapture', listener: this.#handleTrackPointercancel },
|
|
106
|
+
], this.#track).on());
|
|
107
|
+
CleanupRegistry.register(this, onoff([{ types: 'blur', listener: this.#handleWindowBlur }], self).on());
|
|
86
108
|
}
|
|
87
109
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
88
110
|
if (devFlags.debug)
|
|
@@ -90,18 +112,18 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
90
112
|
switch (name) {
|
|
91
113
|
case 'value':
|
|
92
114
|
this.value = String(newValue); // this.#input?.setAttribute('checked', newValue ?? '')
|
|
93
|
-
this.#sendValueToForm(
|
|
115
|
+
this.#sendValueToForm(false);
|
|
94
116
|
break;
|
|
95
117
|
case 'is-on':
|
|
96
118
|
this.isOn = newValue !== null; // this.#input?.setAttribute('checked', newValue ?? '')
|
|
97
|
-
this.#sendValueToForm(
|
|
119
|
+
this.#sendValueToForm(false);
|
|
98
120
|
break;
|
|
99
121
|
case 'required':
|
|
100
122
|
// this.#input?.setAttribute(name, newValue ?? '')
|
|
101
|
-
this.#sendValueToForm(
|
|
123
|
+
this.#sendValueToForm(false);
|
|
102
124
|
break;
|
|
103
125
|
case 'name':
|
|
104
|
-
this.#sendValueToForm(
|
|
126
|
+
this.#sendValueToForm(false);
|
|
105
127
|
break;
|
|
106
128
|
case 'label':
|
|
107
129
|
queryMorph('[slot=label]', html `<label-view slot="label">${newValue ? html `<span>${newValue}</span>` : null}</label-view>`, this);
|
|
@@ -114,16 +136,18 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
114
136
|
}
|
|
115
137
|
disconnectedCallback() {
|
|
116
138
|
super.disconnectedCallback();
|
|
139
|
+
if (this.#track)
|
|
140
|
+
this.#resizeObserver.unobserve(this.#track);
|
|
117
141
|
this.#validityObservers.unobserveAll();
|
|
118
142
|
}
|
|
119
143
|
connectedCallback() {
|
|
120
144
|
super.connectedCallback();
|
|
121
|
-
// finally
|
|
122
|
-
// if (this.hasAttribute('value')) this.value = this.getAttribute('value') ?? ''
|
|
123
145
|
if (this.hasAttribute('is-on'))
|
|
124
146
|
this.isOn = this.hasAttribute('is-on');
|
|
125
147
|
this.#sendValueToForm(false);
|
|
126
|
-
this.#
|
|
148
|
+
if (this.#track)
|
|
149
|
+
this.#resizeObserver.observe(this.#track);
|
|
150
|
+
CleanupRegistry.register(this, onoff(touchGlass(this, (t) => t, ({ clientX, clientY }) => this.#measurePointerIsOverDot(clientX, clientY) ?? false), this).on());
|
|
127
151
|
}
|
|
128
152
|
get toggleStyle() {
|
|
129
153
|
return toggleStyles.includes(this.getAttribute('toggle-style') ?? '') ? this.getAttribute('toggle-style') : 'switch';
|
|
@@ -149,7 +173,116 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
149
173
|
if (devFlags.debug)
|
|
150
174
|
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
151
175
|
if (target === this)
|
|
152
|
-
this.#
|
|
176
|
+
this.#track?.focus();
|
|
177
|
+
};
|
|
178
|
+
#handleTrackClick = ({ type }) => {
|
|
179
|
+
if (devFlags.debug)
|
|
180
|
+
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
181
|
+
if (this.#didDrag)
|
|
182
|
+
return (this.#didDrag = false);
|
|
183
|
+
this.#applyIsOnWithFlip(!this.isOn);
|
|
184
|
+
this.#sendValueToForm(true);
|
|
185
|
+
};
|
|
186
|
+
#measurePointerIsOverDot = (clientX, clientY) => {
|
|
187
|
+
if (!this.#track)
|
|
188
|
+
return;
|
|
189
|
+
const { left, top, height } = this.#track.getBoundingClientRect();
|
|
190
|
+
const dotLeft = left + parseFloat(self.getComputedStyle(this.#track, '::before').left);
|
|
191
|
+
const dotCenterX = dotLeft + this.#dotSize / 2;
|
|
192
|
+
const dotCenterY = top + height / 2;
|
|
193
|
+
return Math.hypot(clientX - dotCenterX, clientY - dotCenterY) <= this.#dotSize / 2;
|
|
194
|
+
};
|
|
195
|
+
#dragOffsetX = 0;
|
|
196
|
+
get #baseX() {
|
|
197
|
+
return this.isOn ? this.#trackMaxX : this.#trackMinX;
|
|
198
|
+
}
|
|
199
|
+
#handleTrackPointerdown = ({ type, pointerId, clientX, clientY }) => {
|
|
200
|
+
if (devFlags.debug)
|
|
201
|
+
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
202
|
+
if (!this.#track)
|
|
203
|
+
return;
|
|
204
|
+
if (!this.#measurePointerIsOverDot(clientX, clientY))
|
|
205
|
+
return; // ignore taps elsewhere on the track
|
|
206
|
+
this.#didDrag = true; // dot was engaged — settle() will own the outcome, click must be swallowed
|
|
207
|
+
const currentDelta = parseFloat(self.getComputedStyle(this.#track).getPropertyValue('--toggle--dot-x')) || 0;
|
|
208
|
+
const currentAbsoluteX = this.#baseX + currentDelta;
|
|
209
|
+
this.#dragOffsetX = clientX - this.#track.getBoundingClientRect().left - currentAbsoluteX;
|
|
210
|
+
this.#track.style.setProperty('--toggle--dot-transition-duration', '0ms');
|
|
211
|
+
this.#track.setPointerCapture(pointerId);
|
|
212
|
+
// this.#updateFromEvent(clientX)
|
|
213
|
+
};
|
|
214
|
+
#handleTrackPointermove = ({ type, clientX }) => {
|
|
215
|
+
if (devFlags.debug)
|
|
216
|
+
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
217
|
+
if (!this.#isDragging)
|
|
218
|
+
return;
|
|
219
|
+
this.#updateFromEvent(clientX);
|
|
220
|
+
};
|
|
221
|
+
#handleTrackPointerup = ({ type, pointerId }) => {
|
|
222
|
+
if (devFlags.debug)
|
|
223
|
+
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
224
|
+
if (!this.#isDragging)
|
|
225
|
+
return; // pointerdown never engaged (missed the dot) — plain click, nothing to settle
|
|
226
|
+
this.#track?.style.removeProperty('--toggle--dot-transition-duration');
|
|
227
|
+
this.#track?.releasePointerCapture(pointerId);
|
|
228
|
+
this.#settle();
|
|
229
|
+
};
|
|
230
|
+
#handleTrackPointercancel = ({ type }) => {
|
|
231
|
+
if (devFlags.debug)
|
|
232
|
+
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
233
|
+
if (!this.#isDragging)
|
|
234
|
+
return; // already settled via pointerup, or nothing to settle
|
|
235
|
+
this.#track?.style.removeProperty('--toggle--dot-transition-duration');
|
|
236
|
+
this.#settle();
|
|
237
|
+
};
|
|
238
|
+
#handleWindowBlur = () => {
|
|
239
|
+
if (!this.#isDragging)
|
|
240
|
+
return;
|
|
241
|
+
this.#track?.style.removeProperty('--toggle--dot-transition-duration');
|
|
242
|
+
this.#settle();
|
|
243
|
+
};
|
|
244
|
+
#updateFromEvent = (clientX) => {
|
|
245
|
+
if (!this.#track)
|
|
246
|
+
return;
|
|
247
|
+
const { left } = this.#track.getBoundingClientRect();
|
|
248
|
+
const absoluteX = Math.min(Math.max(clientX - left - this.#dragOffsetX, this.#trackMinX), this.#trackMaxX);
|
|
249
|
+
this.#track.style.setProperty('--toggle--dot-x', `${Math.round(absoluteX - this.#baseX)}px`);
|
|
250
|
+
};
|
|
251
|
+
#settle = () => {
|
|
252
|
+
if (!this.#track)
|
|
253
|
+
return;
|
|
254
|
+
const deltaX = parseFloat(self.getComputedStyle(this.#track).getPropertyValue('--toggle--dot-x')) || 0;
|
|
255
|
+
const absoluteX = this.#baseX + deltaX;
|
|
256
|
+
const nextIsOn = absoluteX > this.#trackMaxX / 2;
|
|
257
|
+
if (nextIsOn === this.isOn)
|
|
258
|
+
return this.#track.style.removeProperty('--toggle--dot-x'); // pure transform animation back to rest, inset untouched
|
|
259
|
+
this.#applyIsOnWithFlip(nextIsOn);
|
|
260
|
+
this.#sendValueToForm(true);
|
|
261
|
+
};
|
|
262
|
+
#handleTrackKeydown = (evt) => {
|
|
263
|
+
if (devFlags.debug)
|
|
264
|
+
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
265
|
+
if (' ' !== evt.key)
|
|
266
|
+
return;
|
|
267
|
+
evt.preventDefault();
|
|
268
|
+
this.#applyIsOnWithFlip(!this.isOn);
|
|
269
|
+
this.#sendValueToForm(true);
|
|
270
|
+
};
|
|
271
|
+
#applyIsOnWithFlip = (nextIsOn) => {
|
|
272
|
+
if (!this.#track || nextIsOn === this.isOn)
|
|
273
|
+
return;
|
|
274
|
+
// capture current visual position under the OLD base, before flipping state
|
|
275
|
+
const deltaX = parseFloat(self.getComputedStyle(this.#track).getPropertyValue('--toggle--dot-x')) || 0, oldAbsoluteX = this.#baseX + deltaX;
|
|
276
|
+
this.isOn = nextIsOn; // changes --toggle--dot-inset-inline-start/-end via aria-checked
|
|
277
|
+
const compensationX = oldAbsoluteX - this.#baseX; // baseX now reflects the NEW state
|
|
278
|
+
// make inset + transform jump together, instantly, so nothing is visibly out of sync
|
|
279
|
+
this.#track.style.setProperty('--toggle--dot-transition-duration', '0ms');
|
|
280
|
+
this.#track.style.setProperty('--toggle--dot-x', `${Math.round(compensationX)}px`);
|
|
281
|
+
void this.#track.offsetWidth; // force reflow so the instant jump is committed before re-enabling transitions
|
|
282
|
+
this.#track.style.removeProperty('--toggle--dot-transition-duration');
|
|
283
|
+
self.requestAnimationFrame(() => {
|
|
284
|
+
this.#track?.style.removeProperty('--toggle--dot-x'); // only transform animates from here — single source of motion
|
|
285
|
+
});
|
|
153
286
|
};
|
|
154
287
|
#sendValueToForm = (dispatchEvent = true) => {
|
|
155
288
|
// input.value has already been updated/synced !!
|
|
@@ -158,9 +291,8 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
158
291
|
if (this.hasAttribute('required') && !this.isOn) {
|
|
159
292
|
this.setValidity({ valueMissing: true });
|
|
160
293
|
}
|
|
161
|
-
else
|
|
294
|
+
else
|
|
162
295
|
this.setValidity({});
|
|
163
|
-
}
|
|
164
296
|
const entries = new FormData();
|
|
165
297
|
if (this.value)
|
|
166
298
|
entries.append(this.name, this.value);
|
|
@@ -168,17 +300,6 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
168
300
|
if (dispatchEvent)
|
|
169
301
|
this.dispatchEvent(new CustomEvent('toggle:change', { detail: { value: this.value, isOn: this.isOn }, bubbles: true, composed: true }));
|
|
170
302
|
};
|
|
171
|
-
#handleInputKeydown = (evt) => {
|
|
172
|
-
if (devFlags.debug)
|
|
173
|
-
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
174
|
-
this.isOn = !this.isOn;
|
|
175
|
-
this.#sendValueToForm();
|
|
176
|
-
};
|
|
177
|
-
#handleInputInput = (evt) => {
|
|
178
|
-
if (devFlags.debug)
|
|
179
|
-
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
180
|
-
this.#sendValueToForm();
|
|
181
|
-
};
|
|
182
303
|
/**
|
|
183
304
|
* Form participation property
|
|
184
305
|
*/
|
|
@@ -222,7 +343,7 @@ export class ToggleView extends FormAssociatedBase {
|
|
|
222
343
|
}
|
|
223
344
|
if (devFlags.debug)
|
|
224
345
|
console.debug(`${_a.name} ⚡️ validity-change`);
|
|
225
|
-
return this.#internals.setValidity(flags, this.#customValidity || message, anchor ?? this.#
|
|
346
|
+
return this.#internals.setValidity(flags, this.#customValidity || message, anchor ?? this.#track);
|
|
226
347
|
};
|
|
227
348
|
setCustomValidity = (message) => {
|
|
228
349
|
this.#customValidity = message;
|
|
@@ -31,11 +31,11 @@ let ToolBarItem = ToolBarItem_1 = class ToolBarItem extends HTMLElement {
|
|
|
31
31
|
const role = this.getAttribute('data-previous-slot') ?? this.getAttribute('slot') ?? '', tKey = this.getAttribute('title-key');
|
|
32
32
|
if (['confirmation-action', 'cancellation-action'].includes(role))
|
|
33
33
|
Snapshot.waitReady.then(() => {
|
|
34
|
-
ensurePlaceholder(this.querySelector(':scope>button'), role, tKey, Snapshot.config);
|
|
34
|
+
ensurePlaceholder(this.querySelector(':scope>button:not(:has(> :not([slot])))'), role, tKey, Snapshot.config);
|
|
35
35
|
this.#mutationObserver = new MutationObserver((mutations) => {
|
|
36
36
|
for (const { target } of mutations)
|
|
37
37
|
if (target instanceof HTMLElement)
|
|
38
|
-
ensurePlaceholder(this.querySelector(':scope>button'), role, tKey, Snapshot.config);
|
|
38
|
+
ensurePlaceholder(this.querySelector(':scope>button:not(:has(> :not([slot])))'), role, tKey, Snapshot.config);
|
|
39
39
|
});
|
|
40
40
|
this.#mutationObserver.observe(this, {
|
|
41
41
|
childList: true,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @summary A view that arranges its children one on top of the other.
|
|
3
3
|
*
|
|
4
|
+
* @attr {@FrameInlineLength} readable — Shortcut for `placement="leading fill" frame:alignment="center" frame:width="infinity" frame:max-width="{length}"`
|
|
4
5
|
* @attr {leading|"leading fill"|center|trailing|fill|space-between} distribution — The distribution of cols
|
|
5
6
|
*
|
|
6
7
|
* @attr {@Template} template — The main-axis grid template
|
|
@@ -2,6 +2,7 @@ import { devFlags } from '../internal/utils';
|
|
|
2
2
|
/**
|
|
3
3
|
* @summary A view that arranges its children one on top of the other.
|
|
4
4
|
*
|
|
5
|
+
* @attr {@FrameInlineLength} readable — Shortcut for `placement="leading fill" frame:alignment="center" frame:width="infinity" frame:max-width="{length}"`
|
|
5
6
|
* @attr {leading|"leading fill"|center|trailing|fill|space-between} distribution — The distribution of cols
|
|
6
7
|
*
|
|
7
8
|
* @attr {@Template} template — The main-axis grid template
|