@fusion.dev/helix-headless 0.26.0 → 0.30.1
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/custom-elements.json +4966 -755
- package/dist/accordion/root/accordion-root.d.ts +5 -6
- package/dist/accordion/root/accordion-root.js +13 -36
- package/dist/announcement/root/announcement-root.js +1 -1
- package/dist/avatar/root/avatar-root.d.ts +17 -3
- package/dist/avatar/root/avatar-root.js +27 -8
- package/dist/blockquote/root/blockquote-root.js +1 -1
- package/dist/button/root/button-root.js +1 -1
- package/dist/carousel/root/carousel-root.js +2 -2
- package/dist/chat/root/chat-root.js +1 -1
- package/dist/checkbox/root/checkbox-root.js +2 -2
- package/dist/checkbox-group/root/checkbox-group-root.js +2 -2
- package/dist/color-input/root/color-input-root.d.ts +12 -14
- package/dist/color-input/root/color-input-root.js +4 -52
- package/dist/color-picker/root/color-picker-root.js +2 -2
- package/dist/combobox/root/combobox-root.js +11 -14
- package/dist/command/root/command-root.js +2 -3
- package/dist/data-table/root/data-table-root.js +1 -1
- package/dist/date-input/root/date-input-root.d.ts +5 -77
- package/dist/date-input/root/date-input-root.js +16 -108
- package/dist/date-picker/root/date-picker-root.js +2 -2
- package/dist/divider/root/divider-root.js +1 -1
- package/dist/drawer/root/drawer-root.js +1 -1
- package/dist/drilldown/item/drilldown-item.js +1 -1
- package/dist/file-input/root/file-input-root.js +4 -7
- package/dist/filter-input/field/filter-field.d.ts +1 -1
- package/dist/filter-input/root/filter-input-root.d.ts +2 -2
- package/dist/filter-input/root/filter-input-root.js +12 -15
- package/dist/heatmap/root/heatmap-root.js +1 -1
- package/dist/image/root/image-root.d.ts +7 -0
- package/dist/image/root/image-root.js +6 -2
- package/dist/input/root/input-root.js +3 -3
- package/dist/listbox/root/listbox-root.js +3 -3
- package/dist/megamenu/root/megamenu-root.d.ts +12 -2
- package/dist/megamenu/root/megamenu-root.js +20 -15
- package/dist/menu/item/menu-item.js +1 -1
- package/dist/menu/root/menu-root.js +3 -10
- package/dist/navigation/root/navigation-root.d.ts +1 -2
- package/dist/navigation/root/navigation-root.js +3 -9
- package/dist/number-input/root/number-input-root.js +5 -5
- package/dist/object-inspector/root/object-inspector-root.js +4 -4
- package/dist/outline/root/outline-root.d.ts +0 -1
- package/dist/outline/root/outline-root.js +6 -12
- package/dist/pin-input/root/pin-input-root.js +2 -2
- package/dist/popover/root/popover-root.js +2 -10
- package/dist/radio/root/radio-root.js +1 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +1 -1
- package/dist/scroll-area/root/scroll-area-root.js +1 -1
- package/dist/select/root/select-root.js +8 -9
- package/dist/slider/root/slider-root.js +2 -2
- package/dist/sparkline/root/sparkline-root.d.ts +2 -1
- package/dist/sparkline/root/sparkline-root.js +2 -2
- package/dist/speed-dial/item/speed-dial-item.js +1 -1
- package/dist/speed-dial/root/speed-dial-root.d.ts +2 -2
- package/dist/speed-dial/root/speed-dial-root.js +4 -7
- package/dist/switch/root/switch-root.js +3 -3
- package/dist/table/column/table-column.js +1 -1
- package/dist/tabs/root/tabs-root.d.ts +2 -17
- package/dist/tabs/root/tabs-root.js +3 -21
- package/dist/tabs/tab/tab.js +1 -1
- package/dist/textarea/root/textarea-root.js +3 -3
- package/dist/time-input/root/time-input-root.d.ts +5 -64
- package/dist/time-input/root/time-input-root.js +15 -107
- package/dist/time-picker/root/time-picker-root.js +2 -2
- package/dist/toggle/group/toggle-group.d.ts +0 -13
- package/dist/toggle/group/toggle-group.js +3 -23
- package/dist/toggle/root/toggle-root.js +1 -1
- package/dist/tooltip/root/tooltip-root.d.ts +0 -13
- package/dist/tooltip/root/tooltip-root.js +8 -16
- package/dist/tour/root/tour-root.js +6 -6
- package/dist/tour/stop/tour-stop.js +2 -2
- package/dist/video/root/captions.d.ts +85 -0
- package/dist/video/root/captions.js +45 -0
- package/dist/video/root/fullscreen.d.ts +28 -0
- package/dist/video/root/fullscreen.js +28 -0
- package/dist/video/root/idle.d.ts +34 -0
- package/dist/video/root/idle.js +24 -0
- package/dist/video/root/media-session.d.ts +54 -0
- package/dist/video/root/media-session.js +49 -0
- package/dist/video/root/remote-playback.d.ts +34 -0
- package/dist/video/root/remote-playback.js +38 -0
- package/dist/video/root/video-root.d.ts +11 -89
- package/dist/video/root/video-root.js +45 -139
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +2 -1
- package/dist/video-playlist/menu/video-playlist-menu.js +8 -10
- package/dist/virtual-list/root/virtual-list-root.js +1 -1
- package/package.json +8 -7
- package/types/jsx.d.ts +264 -192
- package/types/vue.d.ts +78 -69
|
@@ -64,8 +64,6 @@ export declare class HelixHeadlessTabs extends HelixHeadlessTabs_base {
|
|
|
64
64
|
* consumer's server markup does not already have.
|
|
65
65
|
*/
|
|
66
66
|
variant?: 'segmented' | 'underlined';
|
|
67
|
-
/** Watches for anything that moves a tab, since none of it is a property. */
|
|
68
|
-
private observer;
|
|
69
67
|
private get tabs();
|
|
70
68
|
private get panels();
|
|
71
69
|
private readonly handleSelection;
|
|
@@ -74,23 +72,10 @@ export declare class HelixHeadlessTabs extends HelixHeadlessTabs_base {
|
|
|
74
72
|
connectedCallback(): void;
|
|
75
73
|
disconnectedCallback(): void;
|
|
76
74
|
protected firstUpdated(changed: PropertyValues): void;
|
|
77
|
-
/** The host's own size, which moves every tab and therefore the mark. */
|
|
78
|
-
private measure;
|
|
79
75
|
/**
|
|
80
|
-
*
|
|
76
|
+
* The set changed: pair it up and measure it.
|
|
81
77
|
*
|
|
82
|
-
*
|
|
83
|
-
* and filters on `instanceof`, so it is empty until the tab elements upgrade.
|
|
84
|
-
* At `firstUpdated` it frequently is empty, and observing nothing is silent.
|
|
85
|
-
*
|
|
86
|
-
* `observe` is idempotent per element, so re-running this costs nothing and
|
|
87
|
-
* needs no bookkeeping about which tabs are already watched.
|
|
88
|
-
*/
|
|
89
|
-
private watch;
|
|
90
|
-
/**
|
|
91
|
-
* The set changed: pair it up, watch it, and measure it.
|
|
92
|
-
*
|
|
93
|
-
* All three, and dropping `place()` leaves an indicator unplaced for the life
|
|
78
|
+
* Both, and dropping `place()` leaves an indicator unplaced for the life
|
|
94
79
|
* of the page. The order of events is what does it: the host renders and
|
|
95
80
|
* measures before its tabs have upgraded, so there is no selected tab to
|
|
96
81
|
* measure and `place` refuses; the ResizeObserver's one initial callback
|
|
@@ -19,8 +19,9 @@ let HelixHeadlessTabs = class HelixHeadlessTabs extends MixinControllerActive(He
|
|
|
19
19
|
});
|
|
20
20
|
this.indicator = new IndicatorController(this, {
|
|
21
21
|
active: () => this.tabs.find((tab) => tab.selected),
|
|
22
|
-
indicator: () => this.
|
|
23
|
-
|
|
22
|
+
indicator: () => this.partNamed('indicator'),
|
|
23
|
+
observe: () => this.tabs,
|
|
24
|
+
surface: () => this.partNamed('tabs'),
|
|
24
25
|
});
|
|
25
26
|
this.label = 'Tabs';
|
|
26
27
|
this.manual = false;
|
|
@@ -29,7 +30,6 @@ let HelixHeadlessTabs = class HelixHeadlessTabs extends MixinControllerActive(He
|
|
|
29
30
|
};
|
|
30
31
|
this.handleSlotChange = () => {
|
|
31
32
|
this.sync();
|
|
32
|
-
this.watch();
|
|
33
33
|
this.indicator.place();
|
|
34
34
|
};
|
|
35
35
|
}
|
|
@@ -54,34 +54,16 @@ let HelixHeadlessTabs = class HelixHeadlessTabs extends MixinControllerActive(He
|
|
|
54
54
|
connectedCallback() {
|
|
55
55
|
super.connectedCallback();
|
|
56
56
|
this.addEventListener('helix-select', this.handleSelection);
|
|
57
|
-
if (this.hasUpdated) {
|
|
58
|
-
this.measure();
|
|
59
|
-
this.watch();
|
|
60
|
-
}
|
|
61
57
|
}
|
|
62
58
|
disconnectedCallback() {
|
|
63
59
|
super.disconnectedCallback();
|
|
64
60
|
this.removeEventListener('helix-select', this.handleSelection);
|
|
65
|
-
this.observer?.disconnect();
|
|
66
|
-
this.observer = undefined;
|
|
67
61
|
}
|
|
68
62
|
firstUpdated(changed) {
|
|
69
63
|
super.firstUpdated(changed);
|
|
70
64
|
this.sync();
|
|
71
65
|
this.indicator.place();
|
|
72
66
|
requestAnimationFrame(() => this.indicator.place());
|
|
73
|
-
this.measure();
|
|
74
|
-
this.watch();
|
|
75
|
-
}
|
|
76
|
-
measure() {
|
|
77
|
-
this.observer?.disconnect();
|
|
78
|
-
this.observer = new ResizeObserver(() => this.indicator.place());
|
|
79
|
-
this.observer.observe(this);
|
|
80
|
-
}
|
|
81
|
-
watch() {
|
|
82
|
-
for (const tab of this.tabs) {
|
|
83
|
-
this.observer?.observe(tab);
|
|
84
|
-
}
|
|
85
67
|
}
|
|
86
68
|
updated(changed) {
|
|
87
69
|
super.updated(changed);
|
package/dist/tabs/tab/tab.js
CHANGED
|
@@ -11,7 +11,7 @@ let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerV
|
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.aria = new AriaForwardController(this, {
|
|
14
|
-
target: () => this.
|
|
14
|
+
target: () => this.partNamed('control'),
|
|
15
15
|
});
|
|
16
16
|
this.announcesInput = true;
|
|
17
17
|
this.autocomplete = '';
|
|
@@ -29,7 +29,7 @@ let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerV
|
|
|
29
29
|
};
|
|
30
30
|
this.handleChange = (event) => {
|
|
31
31
|
event.stopPropagation();
|
|
32
|
-
this.
|
|
32
|
+
this.announceChange();
|
|
33
33
|
};
|
|
34
34
|
this.rows = 3;
|
|
35
35
|
this.wrap = 'soft';
|
|
@@ -39,7 +39,7 @@ let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerV
|
|
|
39
39
|
delegatesFocus: true,
|
|
40
40
|
}; }
|
|
41
41
|
get control() {
|
|
42
|
-
return this.
|
|
42
|
+
return this.partNamed('control');
|
|
43
43
|
}
|
|
44
44
|
grow() {
|
|
45
45
|
const control = this.control;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { AriaForwardController, HelixFormElement
|
|
1
|
+
import { AriaForwardController, HelixFormElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../icon/index.js';
|
|
4
4
|
import '../../tag/index.js';
|
|
5
5
|
import '../../time-picker/index.js';
|
|
6
|
-
declare const HelixHeadlessTimeInput_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinTokensInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
6
|
+
declare const HelixHeadlessTimeInput_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinPickerEditingInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinPickerFieldInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinTokensInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
7
7
|
/**
|
|
8
8
|
* @summary A time, typed or picked from a list.
|
|
9
9
|
*
|
|
@@ -122,20 +122,6 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
|
|
|
122
122
|
* What the field says before a time is in it.
|
|
123
123
|
*/
|
|
124
124
|
placeholder: string;
|
|
125
|
-
/**
|
|
126
|
-
* Whether the control refuses changes while still submitting its value.
|
|
127
|
-
*
|
|
128
|
-
* **Enforced by refusing every request in one place**, which is the seam this
|
|
129
|
-
* component already has: `requestValue` is what every path here comes through,
|
|
130
|
-
* and gating it once is what stops the next call site from being written
|
|
131
|
-
* without the check.
|
|
132
|
-
*
|
|
133
|
-
* Not `disabled`, which is the confusion worth naming: a disabled control
|
|
134
|
-
* submits nothing and leaves the tab order, and a read-only one submits its
|
|
135
|
-
* value and stays reachable, which is what a form showing a value somebody
|
|
136
|
-
* else set needs.
|
|
137
|
-
*/
|
|
138
|
-
readOnly: boolean;
|
|
139
125
|
/**
|
|
140
126
|
* How far apart the offered times are, in minutes.
|
|
141
127
|
*/
|
|
@@ -153,19 +139,12 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
|
|
|
153
139
|
* Accessible name for the control that opens the list.
|
|
154
140
|
*/
|
|
155
141
|
triggerLabel: string;
|
|
156
|
-
/**
|
|
157
|
-
* Whether the caret is in the field, which is when it holds the value.
|
|
158
|
-
*/
|
|
159
|
-
private editing;
|
|
160
|
-
/** The overlay, placed against the field for the reason Date Input gives. */
|
|
161
|
-
protected readonly panel: PopoverController;
|
|
162
|
-
private get control();
|
|
163
142
|
/** Every time in the value, which may hold more than one. */
|
|
164
143
|
private get held();
|
|
165
144
|
/** One time, written the way `time-style` asks for. */
|
|
166
145
|
private written;
|
|
167
146
|
/** What the field shows: the value while it is being edited, a reading when not. */
|
|
168
|
-
|
|
147
|
+
protected get display(): string;
|
|
169
148
|
/**
|
|
170
149
|
* What is being typed but not yet held, for `multiple` only.
|
|
171
150
|
*
|
|
@@ -192,41 +171,8 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
|
|
|
192
171
|
private get picked();
|
|
193
172
|
private readonly handleInput;
|
|
194
173
|
private readonly handlePicked;
|
|
195
|
-
/**
|
|
196
|
-
|
|
197
|
-
*
|
|
198
|
-
* Focus opens the list, so handing focus back after a pick would reopen the
|
|
199
|
-
* thing that was just answered, and a reader could not get out of it. Input
|
|
200
|
-
* Date guards the same case by asking where focus came from, which is enough
|
|
201
|
-
* there and is not enough here: the option that had focus is gone by the time
|
|
202
|
-
* this runs, so `relatedTarget` is whatever the document fell back to, which
|
|
203
|
-
* is outside this element and reads as a genuine arrival.
|
|
204
|
-
*
|
|
205
|
-
* A flag rather than a better guess, because this element is the one moving
|
|
206
|
-
* the focus and it is the only thing that can know so. Cleared synchronously,
|
|
207
|
-
* since `focus()` dispatches before it returns.
|
|
208
|
-
*
|
|
209
|
-
* The path cannot be exercised from a spec: `focus()` dispatches no event in
|
|
210
|
-
* an unfocused document, which is what both the test runtime and the browser
|
|
211
|
-
* pane here are.
|
|
212
|
-
*/
|
|
213
|
-
private returning;
|
|
214
|
-
private returnFocus;
|
|
215
|
-
private readonly handleBlur;
|
|
216
|
-
/**
|
|
217
|
-
* Focusing the field opens the list, and only from outside the element.
|
|
218
|
-
*
|
|
219
|
-
* The guard is the one Date Input needed: picking a time shuts the panel and
|
|
220
|
-
* puts the caret back in the field, and without it the list came straight
|
|
221
|
-
* back and a reader could not get out of it.
|
|
222
|
-
*/
|
|
223
|
-
private readonly handleFocus;
|
|
224
|
-
/** Puts the field back where the answer differs from what was typed. */
|
|
225
|
-
private restore;
|
|
226
|
-
/** Reports the value and the validity the host stands behind. */
|
|
227
|
-
private sync;
|
|
228
|
-
/** Escape shuts the list without moving the time. */
|
|
229
|
-
private readonly handleKeydown;
|
|
174
|
+
/** What is wrong with the times, which the text input cannot say. */
|
|
175
|
+
protected validate(): string;
|
|
230
176
|
/**
|
|
231
177
|
* Whether the panel is one list of times or a column each.
|
|
232
178
|
*
|
|
@@ -243,12 +189,7 @@ export declare class HelixHeadlessTimeInput extends HelixHeadlessTimeInput_base
|
|
|
243
189
|
* only the departure has to be named.
|
|
244
190
|
*/
|
|
245
191
|
variant?: 'list' | 'wheels';
|
|
246
|
-
/** Refuses every change while read-only. See `readOnly`. */
|
|
247
|
-
requestValue(next: string): boolean;
|
|
248
|
-
protected firstUpdated(changed: PropertyValues): void;
|
|
249
192
|
protected updated(changed: PropertyValues): void;
|
|
250
|
-
/** Puts the caret in the field, the way a label pointing at one would. */
|
|
251
|
-
focus(options?: FocusOptions): void;
|
|
252
193
|
/**
|
|
253
194
|
* The clock the field opens, behind a seam the styled tier can move.
|
|
254
195
|
*
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { AriaForwardController, valueAsTime as asTime, customElement, timeAsValue as fromTime, HelixFormElement, MixinControllerOpen, MixinControllerValue, MixinField,
|
|
7
|
+
import { AriaForwardController, valueAsTime as asTime, customElement, timeAsValue as fromTime, HelixFormElement, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerEditing, MixinPickerField, MixinTokens, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { clock } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -14,33 +14,20 @@ import '../../icon/index.js';
|
|
|
14
14
|
import '../../tag/index.js';
|
|
15
15
|
import '../../time-picker/index.js';
|
|
16
16
|
import { isTime, toMinutes, writeTime } from '../../time-picker/root/time-picker-root.js';
|
|
17
|
-
let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinControllerOpen(MixinTokens(MixinControllerValue(MixinField(HelixFormElement)))) {
|
|
17
|
+
let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinPickerEditing(MixinPickerField(MixinControllerOpen(MixinTokens(MixinControllerValue(MixinField(HelixFormElement)))))) {
|
|
18
18
|
constructor() {
|
|
19
19
|
super(...arguments);
|
|
20
20
|
this.aria = new AriaForwardController(this, {
|
|
21
|
-
target: () => this.
|
|
21
|
+
target: () => this.partNamed('control'),
|
|
22
22
|
});
|
|
23
23
|
this.autocomplete = '';
|
|
24
24
|
this.locale = '';
|
|
25
25
|
this.max = '23:59';
|
|
26
26
|
this.min = '00:00';
|
|
27
27
|
this.placeholder = 'HH:mm';
|
|
28
|
-
this.readOnly = false;
|
|
29
28
|
this.step = 15;
|
|
30
29
|
this.timeStyle = 'local';
|
|
31
30
|
this.triggerLabel = 'Choose a time';
|
|
32
|
-
this.editing = false;
|
|
33
|
-
this.panel = new PopoverController(this, {
|
|
34
|
-
anchor: () => this.renderRoot?.querySelector('[part="field"]'),
|
|
35
|
-
boundary: () => [
|
|
36
|
-
this.renderRoot?.querySelector('[part="surface"]'),
|
|
37
|
-
this.renderRoot?.querySelector('[part="trigger"]'),
|
|
38
|
-
],
|
|
39
|
-
offset: () => 8,
|
|
40
|
-
onDismiss: () => this.requestOpen(false),
|
|
41
|
-
placement: 'bottom-start',
|
|
42
|
-
surface: () => this.renderRoot?.querySelector('[part="surface"]'),
|
|
43
|
-
});
|
|
44
31
|
this.draft = '';
|
|
45
32
|
this.handleDraftKey = (event) => {
|
|
46
33
|
if (this.mode !== 'multiple') {
|
|
@@ -87,34 +74,6 @@ let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinControlle
|
|
|
87
74
|
this.updateComplete.then(() => this.returnFocus());
|
|
88
75
|
}
|
|
89
76
|
};
|
|
90
|
-
this.returning = false;
|
|
91
|
-
this.handleBlur = () => {
|
|
92
|
-
this.editing = false;
|
|
93
|
-
};
|
|
94
|
-
this.handleFocus = (event) => {
|
|
95
|
-
this.editing = !this.returning;
|
|
96
|
-
const from = event.relatedTarget;
|
|
97
|
-
if (this.open || this.isDisabled || this.returning) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (from instanceof Node && this.renderRoot?.contains?.(from)) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
this.requestOpen(true);
|
|
104
|
-
};
|
|
105
|
-
this.handleKeydown = (event) => {
|
|
106
|
-
if (event.key === 'Escape' && this.open) {
|
|
107
|
-
event.stopPropagation();
|
|
108
|
-
this.requestOpen(false);
|
|
109
|
-
this.returnFocus();
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
get control() {
|
|
114
|
-
if (typeof this.renderRoot?.querySelector !== 'function') {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
return this.renderRoot.querySelector('[part="control"]');
|
|
118
77
|
}
|
|
119
78
|
get held() {
|
|
120
79
|
return this.value
|
|
@@ -148,77 +107,32 @@ let HelixHeadlessTimeInput = class HelixHeadlessTimeInput extends MixinControlle
|
|
|
148
107
|
const held = this.held;
|
|
149
108
|
return held.length > 0 && held.every(isTime) ? held.join(',') : '';
|
|
150
109
|
}
|
|
151
|
-
|
|
152
|
-
this.returning = true;
|
|
153
|
-
this.control?.focus();
|
|
154
|
-
this.returning = false;
|
|
155
|
-
}
|
|
156
|
-
restore() {
|
|
157
|
-
const control = this.control;
|
|
158
|
-
if (control && control.value !== this.display) {
|
|
159
|
-
control.value = this.display;
|
|
160
|
-
}
|
|
161
|
-
this.sync();
|
|
162
|
-
}
|
|
163
|
-
sync() {
|
|
164
|
-
this.internals.setFormValue(this.value);
|
|
165
|
-
const control = this.control;
|
|
166
|
-
if (!control) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
110
|
+
validate() {
|
|
169
111
|
const held = this.held;
|
|
170
112
|
const floor = toMinutes(this.min) ?? 0;
|
|
171
113
|
const ceiling = toMinutes(this.max) ?? 1439;
|
|
172
|
-
let message = '';
|
|
173
114
|
if (held.length > 0 && !held.every(isTime)) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
: 'Enter times as HH:mm, separated by commas.';
|
|
178
|
-
}
|
|
179
|
-
else if (held.some((one) => (toMinutes(one) ?? 0) < floor)) {
|
|
180
|
-
message = `Choose a time at or after ${writeTime(this.min, this.locale)}.`;
|
|
115
|
+
return this.mode === undefined
|
|
116
|
+
? 'Enter a time as HH:mm.'
|
|
117
|
+
: 'Enter times as HH:mm, separated by commas.';
|
|
181
118
|
}
|
|
182
|
-
|
|
183
|
-
|
|
119
|
+
if (held.some((one) => (toMinutes(one) ?? 0) < floor)) {
|
|
120
|
+
return `Choose a time at or after ${writeTime(this.min, this.locale)}.`;
|
|
184
121
|
}
|
|
185
|
-
|
|
186
|
-
|
|
122
|
+
if (held.some((one) => (toMinutes(one) ?? 0) > ceiling)) {
|
|
123
|
+
return `Choose a time at or before ${writeTime(this.max, this.locale)}.`;
|
|
187
124
|
}
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
this.internals.setValidity({ badInput: true }, message, control);
|
|
193
|
-
}
|
|
194
|
-
this.refreshFeedback();
|
|
195
|
-
}
|
|
196
|
-
requestValue(next) {
|
|
197
|
-
if (this.readOnly) {
|
|
198
|
-
return false;
|
|
125
|
+
if (this.mode === 'range' && held.length > 2) {
|
|
126
|
+
return 'A range is two times.';
|
|
199
127
|
}
|
|
200
|
-
return
|
|
201
|
-
}
|
|
202
|
-
firstUpdated(changed) {
|
|
203
|
-
super.firstUpdated(changed);
|
|
204
|
-
this.sync();
|
|
128
|
+
return '';
|
|
205
129
|
}
|
|
206
130
|
updated(changed) {
|
|
207
131
|
super.updated(changed);
|
|
208
|
-
this.sync();
|
|
209
132
|
if (this.open) {
|
|
210
|
-
this.
|
|
211
|
-
this.renderRoot
|
|
212
|
-
?.querySelector('[part="picker"]')
|
|
213
|
-
?.reveal?.();
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
this.panel.hide();
|
|
133
|
+
this.partNamed('picker')?.reveal?.();
|
|
217
134
|
}
|
|
218
135
|
}
|
|
219
|
-
focus(options) {
|
|
220
|
-
this.control?.focus(options);
|
|
221
|
-
}
|
|
222
136
|
renderPicker() {
|
|
223
137
|
return html `<${this.tag('time-picker')}
|
|
224
138
|
part="picker"
|
|
@@ -341,9 +255,6 @@ __decorate([
|
|
|
341
255
|
__decorate([
|
|
342
256
|
property()
|
|
343
257
|
], HelixHeadlessTimeInput.prototype, "placeholder", void 0);
|
|
344
|
-
__decorate([
|
|
345
|
-
property({ attribute: 'readonly', reflect: true, type: Boolean })
|
|
346
|
-
], HelixHeadlessTimeInput.prototype, "readOnly", void 0);
|
|
347
258
|
__decorate([
|
|
348
259
|
property({ type: Number })
|
|
349
260
|
], HelixHeadlessTimeInput.prototype, "step", void 0);
|
|
@@ -353,9 +264,6 @@ __decorate([
|
|
|
353
264
|
__decorate([
|
|
354
265
|
property({ attribute: 'trigger-label' })
|
|
355
266
|
], HelixHeadlessTimeInput.prototype, "triggerLabel", void 0);
|
|
356
|
-
__decorate([
|
|
357
|
-
state()
|
|
358
|
-
], HelixHeadlessTimeInput.prototype, "editing", void 0);
|
|
359
267
|
__decorate([
|
|
360
268
|
state()
|
|
361
269
|
], HelixHeadlessTimeInput.prototype, "draft", void 0);
|
|
@@ -167,7 +167,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControl
|
|
|
167
167
|
return super.requestValue(next);
|
|
168
168
|
}
|
|
169
169
|
reportRequired() {
|
|
170
|
-
const anchor = this.
|
|
170
|
+
const anchor = this.partNamed('list') ?? undefined;
|
|
171
171
|
if (this.required && this.value === '') {
|
|
172
172
|
this.internals.setValidity({ valueMissing: true }, 'Choose a time.', anchor);
|
|
173
173
|
return;
|
|
@@ -212,7 +212,7 @@ let HelixHeadlessTimePicker = class HelixHeadlessTimePicker extends MixinControl
|
|
|
212
212
|
void this.revealWhenSettled();
|
|
213
213
|
}
|
|
214
214
|
focus(options) {
|
|
215
|
-
this.
|
|
215
|
+
this.partNamed('list')?.focus(options);
|
|
216
216
|
}
|
|
217
217
|
renderColumn(part, label, values, written, value, barred = () => false) {
|
|
218
218
|
return html `<${this.tag('listbox')}
|
|
@@ -39,26 +39,13 @@ export declare class HelixHeadlessToggleGroup extends HelixHeadlessToggleGroup_b
|
|
|
39
39
|
/** Marks the chosen item, separately from placing the indicator. */
|
|
40
40
|
private sync;
|
|
41
41
|
private readonly indicator;
|
|
42
|
-
private observer;
|
|
43
42
|
protected readonly keys: KeyboardNavigationController;
|
|
44
43
|
protected readonly cascade: DisabledCascadeController;
|
|
45
44
|
private get items();
|
|
46
|
-
/**
|
|
47
|
-
* Watches the group and every item it currently holds.
|
|
48
|
-
*
|
|
49
|
-
* Called again on `slotchange`, because the set was read once at first paint:
|
|
50
|
-
* an item added later was measured by nothing, so a group whose options
|
|
51
|
-
* arrive with the data had a thumb that stopped following the moment one of
|
|
52
|
-
* them changed width. Observing the same element twice is a no-op, so there
|
|
53
|
-
* is nothing to unwind first.
|
|
54
|
-
*/
|
|
55
|
-
private watch;
|
|
56
45
|
private readonly handleSelection;
|
|
57
46
|
connectedCallback(): void;
|
|
58
47
|
disconnectedCallback(): void;
|
|
59
48
|
protected firstUpdated(changed: PropertyValues): void;
|
|
60
|
-
/** The observer the items are registered on, rebuilt with them. */
|
|
61
|
-
private measure;
|
|
62
49
|
protected updated(changed: PropertyValues): void;
|
|
63
50
|
protected willUpdate(changed: PropertyValues): void;
|
|
64
51
|
/**
|
|
@@ -13,8 +13,9 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
13
13
|
super(...arguments);
|
|
14
14
|
this.indicator = new IndicatorController(this, {
|
|
15
15
|
active: () => this.items.find((item) => item.value === this.value),
|
|
16
|
-
indicator: () => this.
|
|
17
|
-
|
|
16
|
+
indicator: () => this.partNamed('indicator'),
|
|
17
|
+
observe: () => this.items,
|
|
18
|
+
surface: () => this.partNamed('track'),
|
|
18
19
|
});
|
|
19
20
|
this.keys = new KeyboardNavigationController(this, { items: () => this.items });
|
|
20
21
|
this.cascade = new DisabledCascadeController(this, {
|
|
@@ -35,42 +36,22 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
35
36
|
get items() {
|
|
36
37
|
return [...this.children].filter((child) => child instanceof HelixHeadlessToggle);
|
|
37
38
|
}
|
|
38
|
-
watch() {
|
|
39
|
-
this.observer?.observe(this);
|
|
40
|
-
for (const item of this.items) {
|
|
41
|
-
this.observer?.observe(item);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
39
|
connectedCallback() {
|
|
45
40
|
super.connectedCallback();
|
|
46
41
|
this.addEventListener('helix-select', this.handleSelection);
|
|
47
|
-
if (this.hasUpdated) {
|
|
48
|
-
this.measure();
|
|
49
|
-
this.watch();
|
|
50
|
-
}
|
|
51
42
|
}
|
|
52
43
|
disconnectedCallback() {
|
|
53
44
|
super.disconnectedCallback();
|
|
54
45
|
this.removeEventListener('helix-select', this.handleSelection);
|
|
55
|
-
this.observer?.disconnect();
|
|
56
46
|
}
|
|
57
47
|
firstUpdated(changed) {
|
|
58
48
|
super.firstUpdated(changed);
|
|
59
49
|
this.sync();
|
|
60
50
|
this.indicator.place();
|
|
61
|
-
this.measure();
|
|
62
|
-
this.watch();
|
|
63
|
-
}
|
|
64
|
-
measure() {
|
|
65
|
-
this.observer?.disconnect();
|
|
66
|
-
this.observer = new ResizeObserver(() => this.indicator.place());
|
|
67
51
|
}
|
|
68
52
|
updated(changed) {
|
|
69
53
|
super.updated(changed);
|
|
70
54
|
this.sync();
|
|
71
|
-
if (changed.has('value')) {
|
|
72
|
-
this.indicator.place();
|
|
73
|
-
}
|
|
74
55
|
this.validate();
|
|
75
56
|
this.linkHost();
|
|
76
57
|
}
|
|
@@ -93,7 +74,6 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
|
|
|
93
74
|
<div part="indicator" aria-hidden="true"></div>
|
|
94
75
|
<slot
|
|
95
76
|
@slotchange=${() => {
|
|
96
|
-
this.watch();
|
|
97
77
|
this.sync();
|
|
98
78
|
this.indicator.place();
|
|
99
79
|
}}
|
|
@@ -289,18 +289,6 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
|
289
289
|
* really is still over the trigger. See the property.
|
|
290
290
|
*/
|
|
291
291
|
private readonly handleActivate;
|
|
292
|
-
/**
|
|
293
|
-
* Escape closes the bubble from wherever the reader is.
|
|
294
|
-
*
|
|
295
|
-
* On the document, not on the host: a tooltip opened by hover has focus
|
|
296
|
-
* somewhere else entirely, so a press never reaches this element and Escape
|
|
297
|
-
* would work for everything except the case the pattern is named for, a
|
|
298
|
-
* reader escaping a tooltip obscuring what is under it.
|
|
299
|
-
*
|
|
300
|
-
* Not stopped from propagating: a tooltip is not what the reader was trying
|
|
301
|
-
* to escape if it sits inside something else that also closes.
|
|
302
|
-
*/
|
|
303
|
-
private readonly handleKeydown;
|
|
304
292
|
/**
|
|
305
293
|
* What the pointer and focus listeners are currently on.
|
|
306
294
|
*
|
|
@@ -345,7 +333,6 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
|
345
333
|
* this should not be the thing to settle it.
|
|
346
334
|
*/
|
|
347
335
|
private auditDescription;
|
|
348
|
-
connectedCallback(): void;
|
|
349
336
|
disconnectedCallback(): void;
|
|
350
337
|
protected firstUpdated(changed: PropertyValues): void;
|
|
351
338
|
protected updated(changed: PropertyValues): void;
|
|
@@ -23,15 +23,18 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
23
23
|
this.holds = new Set();
|
|
24
24
|
this.bubbleLayer = new PopoverController(this, {
|
|
25
25
|
anchor: () => this.trigger,
|
|
26
|
-
arrow: () => this.
|
|
26
|
+
arrow: () => this.partNamed('arrow'),
|
|
27
27
|
boundary: () => [this, this.named],
|
|
28
28
|
offset: () => {
|
|
29
|
-
const point = this.
|
|
29
|
+
const point = this.partNamed('arrow');
|
|
30
30
|
return this.offset + (point?.offsetWidth ?? 0) / Math.SQRT2;
|
|
31
31
|
},
|
|
32
|
-
onDismiss: () =>
|
|
32
|
+
onDismiss: () => {
|
|
33
|
+
this.holds.clear();
|
|
34
|
+
this.hide();
|
|
35
|
+
},
|
|
33
36
|
placement: () => this.placement,
|
|
34
|
-
surface: () => this.
|
|
37
|
+
surface: () => this.partNamed('tooltip'),
|
|
35
38
|
within: () => this.enclosure,
|
|
36
39
|
});
|
|
37
40
|
this.handleContentChange = () => {
|
|
@@ -66,12 +69,6 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
66
69
|
this.holds.clear();
|
|
67
70
|
this.hide();
|
|
68
71
|
};
|
|
69
|
-
this.handleKeydown = (event) => {
|
|
70
|
-
if (event.key === 'Escape' && this.open) {
|
|
71
|
-
this.holds.clear();
|
|
72
|
-
this.hide();
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
72
|
this.audited = false;
|
|
76
73
|
}
|
|
77
74
|
get trigger() {
|
|
@@ -101,7 +98,7 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
101
98
|
: null;
|
|
102
99
|
}
|
|
103
100
|
get bubble() {
|
|
104
|
-
return this.
|
|
101
|
+
return this.partNamed('tooltip');
|
|
105
102
|
}
|
|
106
103
|
get hasContent() {
|
|
107
104
|
if (this.content !== '') {
|
|
@@ -204,14 +201,9 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
204
201
|
'`aria-describedby="<that id>"` to the element it names. Written in your own markup ' +
|
|
205
202
|
'it survives server rendering, which is why this element will not write it for you.');
|
|
206
203
|
}
|
|
207
|
-
connectedCallback() {
|
|
208
|
-
super.connectedCallback();
|
|
209
|
-
document.addEventListener('keydown', this.handleKeydown);
|
|
210
|
-
}
|
|
211
204
|
disconnectedCallback() {
|
|
212
205
|
super.disconnectedCallback();
|
|
213
206
|
this.unbind();
|
|
214
|
-
document.removeEventListener('keydown', this.handleKeydown);
|
|
215
207
|
this.holds.clear();
|
|
216
208
|
clearTimeout(this.timer);
|
|
217
209
|
}
|
|
@@ -95,9 +95,9 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
95
95
|
connectedCallback() {
|
|
96
96
|
super.connectedCallback();
|
|
97
97
|
this.addEventListener('helix-tour-ask', this.handleAsk);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
document.addEventListener('keydown', this.handleKeydown);
|
|
99
|
+
window.addEventListener('resize', this.handleViewport, { passive: true });
|
|
100
|
+
window.addEventListener('scroll', this.handleViewport, { capture: true, passive: true });
|
|
101
101
|
if (this.hasUpdated) {
|
|
102
102
|
this.watch(this.lit);
|
|
103
103
|
}
|
|
@@ -105,9 +105,9 @@ let HelixHeadlessTour = class HelixHeadlessTour extends HelixElement {
|
|
|
105
105
|
disconnectedCallback() {
|
|
106
106
|
super.disconnectedCallback();
|
|
107
107
|
this.removeEventListener('helix-tour-ask', this.handleAsk);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
document.removeEventListener('keydown', this.handleKeydown);
|
|
109
|
+
window.removeEventListener('resize', this.handleViewport);
|
|
110
|
+
window.removeEventListener('scroll', this.handleViewport, { capture: true });
|
|
111
111
|
this.sizer?.disconnect();
|
|
112
112
|
this.sized = undefined;
|
|
113
113
|
}
|