@fusion.dev/helix-headless 0.103.2 → 0.104.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/custom-elements.json +9259 -712
- package/dist/announcement/root/announcement-root.d.ts +9 -2
- package/dist/announcement/root/announcement-root.js +9 -6
- package/dist/badge/root/badge-root.js +2 -3
- package/dist/canvas/edge/canvas-edge.d.ts +112 -0
- package/dist/canvas/edge/canvas-edge.js +66 -0
- package/dist/canvas/index.d.ts +4 -0
- package/dist/canvas/index.js +3 -0
- package/dist/canvas/node/canvas-node.d.ts +211 -0
- package/dist/canvas/node/canvas-node.js +148 -0
- package/dist/canvas/root/canvas-document.d.ts +215 -0
- package/dist/canvas/root/canvas-document.js +284 -0
- package/dist/canvas/root/canvas-root.d.ts +912 -0
- package/dist/canvas/root/canvas-root.js +1814 -0
- package/dist/carousel/root/carousel-root.d.ts +53 -16
- package/dist/carousel/root/carousel-root.js +46 -11
- package/dist/chat/root/chat-root.d.ts +4 -0
- package/dist/chat/root/chat-root.js +11 -7
- package/dist/checkbox/root/checkbox-root.js +1 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +10 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +5 -0
- package/dist/color-input/root/color-input-root.js +21 -5
- package/dist/color-picker/root/color-picker-root.d.ts +55 -0
- package/dist/color-picker/root/color-picker-root.js +61 -12
- package/dist/combobox/root/combobox-root.d.ts +21 -2
- package/dist/combobox/root/combobox-root.js +23 -9
- package/dist/command/root/command-root.d.ts +1 -0
- package/dist/command/root/command-root.js +1 -1
- package/dist/data-table/root/data-table-root.d.ts +43 -42
- package/dist/data-table/root/data-table-root.js +35 -34
- package/dist/date-input/root/date-input-root.d.ts +27 -0
- package/dist/date-input/root/date-input-root.js +38 -9
- package/dist/date-picker/root/date-picker-root.d.ts +28 -16
- package/dist/date-picker/root/date-picker-root.js +17 -15
- package/dist/drilldown/root/drilldown-root.d.ts +1 -0
- package/dist/drilldown/root/drilldown-root.js +5 -2
- package/dist/element-events.generated.js +15 -0
- package/dist/empty/root/empty-root.d.ts +12 -7
- package/dist/empty/root/empty-root.js +13 -10
- package/dist/file-input/root/file-input-root.d.ts +5 -1
- package/dist/file-input/root/file-input-root.js +6 -4
- package/dist/filter-input/menu/filter-menu.d.ts +1 -0
- package/dist/filter-input/menu/filter-menu.js +1 -1
- package/dist/filter-input/root/filter-input-root.js +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/input/root/input-root.js +1 -1
- package/dist/lightbox/root/lightbox-root.d.ts +9 -1
- package/dist/lightbox/root/lightbox-root.js +17 -7
- package/dist/listbox/root/listbox-root.d.ts +16 -14
- package/dist/listbox/root/listbox-root.js +24 -15
- package/dist/map/root/map-root.d.ts +19 -127
- package/dist/map/root/map-root.js +10 -138
- package/dist/menu/root/menu-root.d.ts +1 -0
- package/dist/menu/root/menu-root.js +1 -1
- package/dist/notifications/group/notification-group.js +5 -4
- package/dist/notifications/notification/notification.d.ts +10 -10
- package/dist/notifications/notification/notification.js +3 -3
- package/dist/notifications/root/notifications-root.d.ts +1 -0
- package/dist/notifications/root/notifications-root.js +1 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -0
- package/dist/number-input/root/number-input-root.js +22 -6
- package/dist/object-inspector/root/object-inspector-root.d.ts +10 -0
- package/dist/object-inspector/root/object-inspector-root.js +10 -2
- package/dist/outline/root/outline-root.d.ts +15 -0
- package/dist/outline/root/outline-root.js +12 -7
- package/dist/pagination/root/pagination-root.d.ts +18 -18
- package/dist/pagination/root/pagination-root.js +5 -5
- package/dist/pagination/size/pagination-size.d.ts +10 -9
- package/dist/pagination/size/pagination-size.js +4 -4
- package/dist/pagination/summary/pagination-summary.js +6 -5
- package/dist/pin-input/root/pin-input-root.d.ts +5 -0
- package/dist/pin-input/root/pin-input-root.js +10 -6
- package/dist/rating/root/rating-root.js +3 -2
- package/dist/select/root/select-root.d.ts +1 -0
- package/dist/select/root/select-root.js +8 -3
- package/dist/slider/root/slider-root.d.ts +12 -0
- package/dist/slider/root/slider-root.js +13 -1
- package/dist/splitter/root/splitter-root.d.ts +44 -35
- package/dist/splitter/root/splitter-root.js +27 -22
- package/dist/switch/root/switch-root.js +1 -0
- package/dist/table/column/table-column.d.ts +17 -0
- package/dist/table/column/table-column.js +16 -4
- package/dist/table/root/table-root.d.ts +1 -0
- package/dist/table/root/table-root.js +1 -1
- package/dist/textarea/root/textarea-root.js +1 -1
- package/dist/time-input/root/time-input-root.d.ts +29 -0
- package/dist/time-input/root/time-input-root.js +31 -10
- package/dist/time-picker/root/time-picker-root.d.ts +14 -0
- package/dist/time-picker/root/time-picker-root.js +16 -14
- package/dist/toast/item/toast-item.d.ts +12 -11
- package/dist/toast/item/toast-item.js +11 -5
- package/dist/toolbar/root/toolbar-root.js +2 -16
- package/dist/tooltip/root/tooltip-root.d.ts +1 -0
- package/dist/tooltip/root/tooltip-root.js +6 -0
- package/dist/tour/root/tour-root.d.ts +10 -10
- package/dist/tour/root/tour-root.js +5 -5
- package/dist/tree/root/tree-root.d.ts +1 -0
- package/dist/tree/root/tree-root.js +1 -1
- package/dist/video/root/video-root.d.ts +84 -0
- package/dist/video/root/video-root.js +116 -41
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +1 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +4 -3
- package/package.json +5 -5
- package/types/jsx.d.ts +5753 -1076
- package/types/svelte.d.ts +3 -0
- package/types/vue.d.ts +1668 -282
|
@@ -12,8 +12,9 @@ declare const HelixHeadlessListbox_base: (new (...args: any[]) => import("@fusio
|
|
|
12
12
|
* what filters it, not in what the list is.
|
|
13
13
|
*
|
|
14
14
|
* **`value` is comma separated when `multiple` is set**, the way
|
|
15
|
-
* `Checkbox.Group`'s is
|
|
16
|
-
*
|
|
15
|
+
* `Checkbox.Group`'s is, and a string because that is what `MixinControllerValue`
|
|
16
|
+
* holds. The form is sent one entry per answer, as a native `<select multiple>`
|
|
17
|
+
* sends it, so a server never has to know to split on a comma.
|
|
17
18
|
*
|
|
18
19
|
* **Chosen and active are two different things.** Chosen is the answer; active
|
|
19
20
|
* is where the keyboard is. Only the second moves with the arrows, and
|
|
@@ -42,6 +43,7 @@ declare const HelixHeadlessListbox_base: (new (...args: any[]) => import("@fusio
|
|
|
42
43
|
* @csspart hint - Help under the list.
|
|
43
44
|
* @csspart items - The list itself.
|
|
44
45
|
* @csspart label - The question, over the list.
|
|
46
|
+
* @csspart live - The empty and loading lines again, in a region a screen reader hears when they change. Visually hidden in the styled tier.
|
|
45
47
|
* @csspart loading - Shown while the options are still on their way.
|
|
46
48
|
* @csspart search - The region holding the field that narrows the list.
|
|
47
49
|
* @csspart search-field - The field itself.
|
|
@@ -59,22 +61,10 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
|
59
61
|
* keystrokes as the listbox. A consumer who wants autofill can still ask.
|
|
60
62
|
*/
|
|
61
63
|
autocomplete: string;
|
|
62
|
-
/**
|
|
63
|
-
* What the list is narrowed to, if anything.
|
|
64
|
-
*
|
|
65
|
-
* Filtering hides rather than removes, so nothing about the value changes and
|
|
66
|
-
* the list is still the consumer's own elements in their own order. Reading
|
|
67
|
-
* gives what is being filtered on; writing declares it theirs, and
|
|
68
|
-
* `default-filter` seeds one the list owns.
|
|
69
|
-
*/
|
|
70
|
-
get filter(): string;
|
|
71
|
-
set filter(next: string);
|
|
72
64
|
/**
|
|
73
65
|
* What to start narrowed to, where nothing declared it.
|
|
74
66
|
*/
|
|
75
67
|
defaultFilter: string;
|
|
76
|
-
/** What the list is narrowed to, whoever set it. */
|
|
77
|
-
private filterState;
|
|
78
68
|
/**
|
|
79
69
|
* What is shown when a filter has hidden every option.
|
|
80
70
|
*
|
|
@@ -84,6 +74,18 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
|
|
|
84
74
|
* never given anything.
|
|
85
75
|
*/
|
|
86
76
|
emptyText: string;
|
|
77
|
+
/** What the list is narrowed to, whoever set it. */
|
|
78
|
+
private filterState;
|
|
79
|
+
/**
|
|
80
|
+
* What the list is narrowed to, if anything.
|
|
81
|
+
*
|
|
82
|
+
* Filtering hides rather than removes, so nothing about the value changes and
|
|
83
|
+
* the list is still the consumer's own elements in their own order. Reading
|
|
84
|
+
* gives what is being filtered on; writing declares it theirs, and
|
|
85
|
+
* `default-filter` seeds one the list owns.
|
|
86
|
+
*/
|
|
87
|
+
get filter(): string;
|
|
88
|
+
set filter(next: string);
|
|
87
89
|
/**
|
|
88
90
|
* Whether the list renders a field for narrowing itself.
|
|
89
91
|
*
|
|
@@ -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, customElement, DisabledCascadeController, HelixFilterEvent, HelixFormElement, hostAria, MixinCollection, MixinControllerValue, MixinField, requestChange, scrollItemIntoView, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, customElement, DisabledCascadeController, HelixFilterEvent, HelixFormElement, hostAria, MixinCollection, MixinControllerValue, MixinField, reportValues, requestChange, scrollItemIntoView, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { magnifyingGlass } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -63,8 +63,8 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
63
63
|
});
|
|
64
64
|
this.autocomplete = 'off';
|
|
65
65
|
this.defaultFilter = '';
|
|
66
|
-
this.filterState = undefined;
|
|
67
66
|
this.emptyText = 'No matches';
|
|
67
|
+
this.filterState = undefined;
|
|
68
68
|
this.filterable = false;
|
|
69
69
|
this.filterLabel = 'Filter';
|
|
70
70
|
this.multiple = false;
|
|
@@ -286,7 +286,12 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
sync() {
|
|
289
|
-
|
|
289
|
+
if (this.multiple) {
|
|
290
|
+
reportValues(this.internals, this.name, this.value === '' ? [] : this.value.split(','));
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
this.internals.setFormValue(this.value === '' ? null : this.value);
|
|
294
|
+
}
|
|
290
295
|
this.reportRequired(this.value === '', 'Choose one to continue.', 'items');
|
|
291
296
|
}
|
|
292
297
|
connectedCallback() {
|
|
@@ -303,8 +308,7 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
303
308
|
}
|
|
304
309
|
willUpdate(changed) {
|
|
305
310
|
super.willUpdate(changed);
|
|
306
|
-
hostAria(this.internals, {
|
|
307
|
-
this.internals.ariaMultiSelectable = this.multiple ? 'true' : null;
|
|
311
|
+
hostAria(this.internals, { role: '' });
|
|
308
312
|
if (this.childrenKnown) {
|
|
309
313
|
this.place();
|
|
310
314
|
}
|
|
@@ -324,7 +328,6 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
324
328
|
super.updated(changed);
|
|
325
329
|
this.followActive();
|
|
326
330
|
this.sync();
|
|
327
|
-
this.linkHost();
|
|
328
331
|
this.linkActive();
|
|
329
332
|
}
|
|
330
333
|
requestFilter(next) {
|
|
@@ -354,6 +357,11 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
354
357
|
</slot>`;
|
|
355
358
|
}
|
|
356
359
|
render() {
|
|
360
|
+
const shown = this.counted && !this.loading
|
|
361
|
+
? this.filter === ''
|
|
362
|
+
? this.options.length > 0
|
|
363
|
+
: this.hasMatches
|
|
364
|
+
: true;
|
|
357
365
|
return html `${this.renderGroupLabel()}
|
|
358
366
|
${this.filterable
|
|
359
367
|
? html `<div part="search">
|
|
@@ -378,32 +386,33 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
|
|
|
378
386
|
<div
|
|
379
387
|
part="items"
|
|
380
388
|
id="items"
|
|
389
|
+
role="listbox"
|
|
381
390
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
391
|
+
aria-describedby=${this.describedBy ?? nothing}
|
|
392
|
+
aria-labelledby=${this.labeled ? this.labelId : nothing}
|
|
393
|
+
aria-multiselectable=${this.multiple ? 'true' : nothing}
|
|
394
|
+
aria-required=${this.required ? 'true' : nothing}
|
|
382
395
|
${''}
|
|
383
396
|
tabindex=${this.isDisabled ? -1 : 0}
|
|
384
397
|
>
|
|
385
398
|
<slot @slotchange=${() => this.place()}></slot>
|
|
386
|
-
${this.renderStatus(
|
|
387
|
-
? this.filter === ''
|
|
388
|
-
? this.options.length > 0
|
|
389
|
-
: this.hasMatches
|
|
390
|
-
: true)}
|
|
399
|
+
${this.renderStatus(shown)}
|
|
391
400
|
</div>
|
|
392
|
-
${this.renderHint()}${this.renderFeedback()}`;
|
|
401
|
+
${this.renderLive(shown)}${this.renderHint()}${this.renderFeedback()}`;
|
|
393
402
|
}
|
|
394
403
|
};
|
|
395
404
|
__decorate([
|
|
396
405
|
property()
|
|
397
406
|
], HelixHeadlessListbox.prototype, "autocomplete", void 0);
|
|
398
|
-
__decorate([
|
|
399
|
-
property()
|
|
400
|
-
], HelixHeadlessListbox.prototype, "filter", null);
|
|
401
407
|
__decorate([
|
|
402
408
|
property({ attribute: 'default-filter' })
|
|
403
409
|
], HelixHeadlessListbox.prototype, "defaultFilter", void 0);
|
|
404
410
|
__decorate([
|
|
405
411
|
property({ attribute: 'empty-text' })
|
|
406
412
|
], HelixHeadlessListbox.prototype, "emptyText", void 0);
|
|
413
|
+
__decorate([
|
|
414
|
+
property()
|
|
415
|
+
], HelixHeadlessListbox.prototype, "filter", null);
|
|
407
416
|
__decorate([
|
|
408
417
|
property({ attribute: 'filterable', reflect: true, type: Boolean })
|
|
409
418
|
], HelixHeadlessListbox.prototype, "filterable", void 0);
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { HelixElement, type ViewportControlsPlacement, type ViewportPanDetail, type ViewportZoomDetail } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/**
|
|
4
|
+
* What `ViewportControlsPlacement` is called for a map.
|
|
5
|
+
*
|
|
6
|
+
* The corners are the surface's and the name is the family's, so a consumer who
|
|
7
|
+
* imported this before the surface was shared still has it.
|
|
8
|
+
*/
|
|
9
|
+
export type MapControlsPlacement = ViewportControlsPlacement;
|
|
10
|
+
declare const HelixHeadlessMap_base: (new (...args: any[]) => import("@fusion.dev/helix-core").ViewportElement) & typeof HelixElement;
|
|
7
11
|
/**
|
|
8
12
|
* @summary A frame around somebody else's map.
|
|
9
13
|
*
|
|
@@ -33,7 +37,7 @@ export type MapControlsPlacement = 'top-start' | 'top-end' | 'bottom-start' | 'b
|
|
|
33
37
|
* A frame that moved the map would have to know whose map it was.
|
|
34
38
|
*
|
|
35
39
|
* @since 0.100.0
|
|
36
|
-
* @status
|
|
40
|
+
* @status experimental
|
|
37
41
|
* @category media
|
|
38
42
|
* @aliases Map frame, Map container, Geo
|
|
39
43
|
* @documentation https://fusion.dev/helix/components/map
|
|
@@ -63,57 +67,7 @@ export type MapControlsPlacement = 'top-start' | 'top-end' | 'bottom-start' | 'b
|
|
|
63
67
|
* @cssstate fullscreen - While the frame fills the screen.
|
|
64
68
|
* @cssstate idle - While the reader has been still long enough to hide the chrome.
|
|
65
69
|
*/
|
|
66
|
-
export declare class HelixHeadlessMap extends
|
|
67
|
-
/**
|
|
68
|
-
* Which of the controls this frame draws, as a list of what to keep.
|
|
69
|
-
*
|
|
70
|
-
* **A list rather than a switch, because the overlap is not symmetric.**
|
|
71
|
-
* Every map library draws zoom controls and none of them draws pan buttons:
|
|
72
|
-
* MapLibre's navigation control is zoom and a compass, Leaflet's is zoom,
|
|
73
|
-
* Google's is zoom. So a consumer slotting one of those has our zoom twice
|
|
74
|
-
* over and our pan pad not at all, and a single switch would make them choose
|
|
75
|
-
* between a duplicate and nothing.
|
|
76
|
-
*
|
|
77
|
-
* `none` draws none of them, which is the right answer where the slotted map
|
|
78
|
-
* already has controls a reader can find: what this family argues for is that
|
|
79
|
-
* *a* findable control exists, never that it is ours. The methods stay public
|
|
80
|
-
* either way, so a consumer drawing their own chrome can still drive the
|
|
81
|
-
* frame.
|
|
82
|
-
*
|
|
83
|
-
* Absent is all three, which is this library's rule that a resting value is an
|
|
84
|
-
* attribute's absence, and it is what the stylesheet asks about: the layout
|
|
85
|
-
* rules are written against `[controls]:not([controls~="zoom"])` rather than
|
|
86
|
-
* the bare negation, or a frame that named no list at all would be laid out as
|
|
87
|
-
* though it had dropped everything.
|
|
88
|
-
*/
|
|
89
|
-
controls?: string;
|
|
90
|
-
/**
|
|
91
|
-
* Which corner the controls sit in.
|
|
92
|
-
*
|
|
93
|
-
* **Configurable because there is no safe default**, and this is a collision
|
|
94
|
-
* rather than a taste: MapLibre puts its own controls at the top end, Leaflet
|
|
95
|
-
* and OpenLayers at the top start, Google's zoom at the bottom end. Whichever
|
|
96
|
-
* corner this took would land on somebody's, which is why every one of those
|
|
97
|
-
* libraries made it a setting too.
|
|
98
|
-
*
|
|
99
|
-
* Logical corners rather than left and right, so a right-to-left page moves
|
|
100
|
-
* them without a consumer writing a second rule.
|
|
101
|
-
*
|
|
102
|
-
* Absent is the top end, which is this library's rule that a resting value is
|
|
103
|
-
* an attribute's absence: a default that reflected would write an attribute
|
|
104
|
-
* onto every host that no server sent and nobody asked for.
|
|
105
|
-
*/
|
|
106
|
-
controlsPlacement?: MapControlsPlacement;
|
|
107
|
-
/** What the control that fills the screen is called. */
|
|
108
|
-
fullscreenLabel: string;
|
|
109
|
-
/**
|
|
110
|
-
* How long the reader may be still before the chrome hides, in milliseconds.
|
|
111
|
-
*
|
|
112
|
-
* Zero keeps it up, which is the default: a map's controls are how a keyboard
|
|
113
|
-
* reader operates it, and chrome that hides itself by default would be this
|
|
114
|
-
* component undoing its own argument. Set it for a display map nobody drives.
|
|
115
|
-
*/
|
|
116
|
-
idleDelay: number;
|
|
70
|
+
export declare class HelixHeadlessMap extends HelixHeadlessMap_base {
|
|
117
71
|
/**
|
|
118
72
|
* Accessible name for the map, which is the one thing a consumer must write.
|
|
119
73
|
*
|
|
@@ -129,80 +83,18 @@ export declare class HelixHeadlessMap extends HelixElement {
|
|
|
129
83
|
* at every encounter.
|
|
130
84
|
*/
|
|
131
85
|
label: string;
|
|
86
|
+
/** The events this family names, the surface naming none of its own. */
|
|
87
|
+
protected panEvent(detail: ViewportPanDetail): Event;
|
|
88
|
+
protected zoomEvent(detail: ViewportZoomDetail): Event;
|
|
132
89
|
/**
|
|
133
|
-
* What the controls
|
|
134
|
-
*/
|
|
135
|
-
panLabel: string;
|
|
136
|
-
/**
|
|
137
|
-
* How far one press moves the map, as a fraction of what is on screen.
|
|
138
|
-
*
|
|
139
|
-
* A fraction rather than a distance, because this frame does not know the
|
|
140
|
-
* scale of what is inside it: a quarter of the viewport is the same gesture at
|
|
141
|
-
* street level and at country level, and a consumer who wants metres can
|
|
142
|
-
* multiply by their own.
|
|
143
|
-
*/
|
|
144
|
-
panStep: number;
|
|
145
|
-
/** What the zoom controls are called. */
|
|
146
|
-
zoomInLabel: string;
|
|
147
|
-
/** What the zoom control that goes the other way is called. */
|
|
148
|
-
zoomOutLabel: string;
|
|
149
|
-
/** Whether the reader has been still long enough to hide the chrome. */
|
|
150
|
-
private resting;
|
|
151
|
-
/** Whether the frame is filling the screen. */
|
|
152
|
-
private filled;
|
|
153
|
-
private readonly fullscreen;
|
|
154
|
-
private readonly idle;
|
|
155
|
-
/** Whether a named group of controls is one this frame draws. */
|
|
156
|
-
private draws;
|
|
157
|
-
/** Fills the screen with the frame, or comes back. */
|
|
158
|
-
toggleFullscreen(): void;
|
|
159
|
-
/** Asks for the map to move, which the consumer answers. */
|
|
160
|
-
pan(to: Way): void;
|
|
161
|
-
/** Asks for the map to zoom, `1` in and `-1` out. */
|
|
162
|
-
zoom(by: number): void;
|
|
163
|
-
/**
|
|
164
|
-
* The arrow keys, which are the second way rather than the only one.
|
|
165
|
-
*
|
|
166
|
-
* `inlineStep` rather than a test against `ArrowLeft`, so the reader on a
|
|
167
|
-
* right-to-left page gets `end` from the key that points the way their text
|
|
168
|
-
* runs, which is what the pan buttons say too.
|
|
90
|
+
* What the group of controls is called.
|
|
169
91
|
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* the event this would have sent: every press moving twice, and the consumer
|
|
174
|
-
* with no way to tell which half to turn off. A press that started in the
|
|
175
|
-
* shadow root is this frame's to relay; anything from the map belongs to the
|
|
176
|
-
* map.
|
|
92
|
+
* The surface is shared and this is the half that is a map: a reader meeting
|
|
93
|
+
* the group hears what it drives rather than "view controls", which names the
|
|
94
|
+
* mechanism.
|
|
177
95
|
*/
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Starts the wait, so a map nobody has touched counts as still.
|
|
181
|
-
*
|
|
182
|
-
* Without this the timer only ever starts on a pointer or a focus, and a frame
|
|
183
|
-
* rendered on a page the reader never reaches stays awake for as long as the
|
|
184
|
-
* page is open: the chrome a consumer asked to hide would hide only after
|
|
185
|
-
* being used once, which is the opposite of what an idle delay is for.
|
|
186
|
-
*/
|
|
187
|
-
protected firstUpdated(changed: PropertyValues): void;
|
|
96
|
+
protected get restingControlsLabel(): string;
|
|
188
97
|
protected willUpdate(changed: PropertyValues): void;
|
|
189
|
-
/**
|
|
190
|
-
* What one pan button is called, with the way it goes filled in.
|
|
191
|
-
*
|
|
192
|
-
* Left and right rather than start and end, because the label is read aloud
|
|
193
|
-
* and a reader knows which way left is. The event keeps the reading-order
|
|
194
|
-
* name, which is the one a right-to-left page needs.
|
|
195
|
-
*/
|
|
196
|
-
private named;
|
|
197
|
-
/**
|
|
198
|
-
* The controls, or nothing where a consumer kept none of them.
|
|
199
|
-
*
|
|
200
|
-
* **Written out rather than generated**, because a part name behind an
|
|
201
|
-
* interpolation is a part the manifest cannot see: it would publish `pan-`
|
|
202
|
-
* and a consumer's `::part(pan-up)` would match nothing. The same cost
|
|
203
|
-
* `drawIcon` names for `Trend`.
|
|
204
|
-
*/
|
|
205
|
-
private renderControls;
|
|
206
98
|
/**
|
|
207
99
|
* The frame, with each region in a box of its own.
|
|
208
100
|
*
|
|
@@ -4,73 +4,22 @@ 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 { customElement,
|
|
8
|
-
import { html
|
|
9
|
-
import { property
|
|
10
|
-
let HelixHeadlessMap = class HelixHeadlessMap extends HelixElement {
|
|
7
|
+
import { customElement, HelixElement, HelixMapPanEvent, HelixMapZoomEvent, hostAria, MixinViewport, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
let HelixHeadlessMap = class HelixHeadlessMap extends MixinViewport(HelixElement) {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
|
-
this.fullscreenLabel = 'Fill the screen';
|
|
14
|
-
this.idleDelay = 0;
|
|
15
13
|
this.label = '';
|
|
16
|
-
this.panLabel = 'Pan {way}';
|
|
17
|
-
this.panStep = 0.25;
|
|
18
|
-
this.zoomInLabel = 'Zoom in';
|
|
19
|
-
this.zoomOutLabel = 'Zoom out';
|
|
20
|
-
this.resting = false;
|
|
21
|
-
this.filled = false;
|
|
22
|
-
this.fullscreen = new FullscreenController(this, (full) => {
|
|
23
|
-
this.filled = full;
|
|
24
|
-
});
|
|
25
|
-
this.idle = new IdleController(this, () => this.idleDelay, (resting) => {
|
|
26
|
-
this.resting = resting;
|
|
27
|
-
});
|
|
28
|
-
this.handleKeydown = (event) => {
|
|
29
|
-
if (!this.renderRoot.contains(event.target)) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const along = inlineStep(this, event.key);
|
|
33
|
-
if (along === 1) {
|
|
34
|
-
event.preventDefault();
|
|
35
|
-
this.pan('end');
|
|
36
|
-
}
|
|
37
|
-
else if (along === -1) {
|
|
38
|
-
event.preventDefault();
|
|
39
|
-
this.pan('start');
|
|
40
|
-
}
|
|
41
|
-
else if (event.key === 'ArrowUp') {
|
|
42
|
-
event.preventDefault();
|
|
43
|
-
this.pan('up');
|
|
44
|
-
}
|
|
45
|
-
else if (event.key === 'ArrowDown') {
|
|
46
|
-
event.preventDefault();
|
|
47
|
-
this.pan('down');
|
|
48
|
-
}
|
|
49
|
-
else if (event.key === '+' || event.key === '=') {
|
|
50
|
-
event.preventDefault();
|
|
51
|
-
this.zoom(1);
|
|
52
|
-
}
|
|
53
|
-
else if (event.key === '-' || event.key === '_') {
|
|
54
|
-
event.preventDefault();
|
|
55
|
-
this.zoom(-1);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
14
|
}
|
|
59
|
-
|
|
60
|
-
return
|
|
15
|
+
panEvent(detail) {
|
|
16
|
+
return new HelixMapPanEvent(detail);
|
|
61
17
|
}
|
|
62
|
-
|
|
63
|
-
|
|
18
|
+
zoomEvent(detail) {
|
|
19
|
+
return new HelixMapZoomEvent(detail);
|
|
64
20
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
zoom(by) {
|
|
69
|
-
this.dispatchEvent(new HelixMapZoomEvent({ by }));
|
|
70
|
-
}
|
|
71
|
-
firstUpdated(changed) {
|
|
72
|
-
super.firstUpdated(changed);
|
|
73
|
-
this.idle.stir();
|
|
21
|
+
get restingControlsLabel() {
|
|
22
|
+
return 'Map controls';
|
|
74
23
|
}
|
|
75
24
|
willUpdate(changed) {
|
|
76
25
|
super.willUpdate(changed);
|
|
@@ -78,53 +27,6 @@ let HelixHeadlessMap = class HelixHeadlessMap extends HelixElement {
|
|
|
78
27
|
this.toggleState('fullscreen', this.filled);
|
|
79
28
|
this.toggleState('idle', this.resting);
|
|
80
29
|
}
|
|
81
|
-
named(way) {
|
|
82
|
-
const spoken = way === 'start' ? 'left' : way === 'end' ? 'right' : way;
|
|
83
|
-
return this.panLabel.replace('{way}', spoken);
|
|
84
|
-
}
|
|
85
|
-
renderControls() {
|
|
86
|
-
const pan = this.draws('pan');
|
|
87
|
-
const zoom = this.draws('zoom');
|
|
88
|
-
const fullscreen = this.draws('fullscreen');
|
|
89
|
-
if (!pan && !zoom && !fullscreen) {
|
|
90
|
-
return nothing;
|
|
91
|
-
}
|
|
92
|
-
return html `<div part="controls" role="group" aria-label="Map controls">
|
|
93
|
-
${pan
|
|
94
|
-
? html `<button part="pan-up" aria-label=${this.named('up')} type="button" @click=${() => this.pan('up')}>
|
|
95
|
-
↑
|
|
96
|
-
</button>
|
|
97
|
-
<button part="pan-start" aria-label=${this.named('start')} type="button" @click=${() => this.pan('start')}>
|
|
98
|
-
←
|
|
99
|
-
</button>
|
|
100
|
-
<button part="pan-end" aria-label=${this.named('end')} type="button" @click=${() => this.pan('end')}>
|
|
101
|
-
→
|
|
102
|
-
</button>
|
|
103
|
-
<button part="pan-down" aria-label=${this.named('down')} type="button" @click=${() => this.pan('down')}>
|
|
104
|
-
↓
|
|
105
|
-
</button>`
|
|
106
|
-
: nothing}
|
|
107
|
-
${zoom
|
|
108
|
-
? html `<button part="zoom-in" aria-label=${this.zoomInLabel} type="button" @click=${() => this.zoom(1)}>
|
|
109
|
-
+
|
|
110
|
-
</button>
|
|
111
|
-
<button part="zoom-out" aria-label=${this.zoomOutLabel} type="button" @click=${() => this.zoom(-1)}>
|
|
112
|
-
−
|
|
113
|
-
</button>`
|
|
114
|
-
: nothing}
|
|
115
|
-
${fullscreen
|
|
116
|
-
? html `<button
|
|
117
|
-
part="fullscreen"
|
|
118
|
-
aria-label=${this.fullscreenLabel}
|
|
119
|
-
aria-pressed=${this.filled ? 'true' : 'false'}
|
|
120
|
-
type="button"
|
|
121
|
-
@click=${this.toggleFullscreen}
|
|
122
|
-
>
|
|
123
|
-
⤢
|
|
124
|
-
</button>`
|
|
125
|
-
: nothing}
|
|
126
|
-
</div>`;
|
|
127
|
-
}
|
|
128
30
|
render() {
|
|
129
31
|
return html `<div
|
|
130
32
|
part="region"
|
|
@@ -153,39 +55,9 @@ let HelixHeadlessMap = class HelixHeadlessMap extends HelixElement {
|
|
|
153
55
|
</div>`;
|
|
154
56
|
}
|
|
155
57
|
};
|
|
156
|
-
__decorate([
|
|
157
|
-
property({ reflect: true })
|
|
158
|
-
], HelixHeadlessMap.prototype, "controls", void 0);
|
|
159
|
-
__decorate([
|
|
160
|
-
property({ attribute: 'controls-placement', reflect: true })
|
|
161
|
-
], HelixHeadlessMap.prototype, "controlsPlacement", void 0);
|
|
162
|
-
__decorate([
|
|
163
|
-
property({ attribute: 'fullscreen-label' })
|
|
164
|
-
], HelixHeadlessMap.prototype, "fullscreenLabel", void 0);
|
|
165
|
-
__decorate([
|
|
166
|
-
property({ attribute: 'idle-delay', type: Number })
|
|
167
|
-
], HelixHeadlessMap.prototype, "idleDelay", void 0);
|
|
168
58
|
__decorate([
|
|
169
59
|
property()
|
|
170
60
|
], HelixHeadlessMap.prototype, "label", void 0);
|
|
171
|
-
__decorate([
|
|
172
|
-
property({ attribute: 'pan-label' })
|
|
173
|
-
], HelixHeadlessMap.prototype, "panLabel", void 0);
|
|
174
|
-
__decorate([
|
|
175
|
-
property({ attribute: 'pan-step', type: Number })
|
|
176
|
-
], HelixHeadlessMap.prototype, "panStep", void 0);
|
|
177
|
-
__decorate([
|
|
178
|
-
property({ attribute: 'zoom-in-label' })
|
|
179
|
-
], HelixHeadlessMap.prototype, "zoomInLabel", void 0);
|
|
180
|
-
__decorate([
|
|
181
|
-
property({ attribute: 'zoom-out-label' })
|
|
182
|
-
], HelixHeadlessMap.prototype, "zoomOutLabel", void 0);
|
|
183
|
-
__decorate([
|
|
184
|
-
state()
|
|
185
|
-
], HelixHeadlessMap.prototype, "resting", void 0);
|
|
186
|
-
__decorate([
|
|
187
|
-
state()
|
|
188
|
-
], HelixHeadlessMap.prototype, "filled", void 0);
|
|
189
61
|
HelixHeadlessMap = __decorate([
|
|
190
62
|
customElement('helix-headless-map')
|
|
191
63
|
], HelixHeadlessMap);
|
|
@@ -40,6 +40,7 @@ declare const HelixHeadlessMenu_base: (new (...args: any[]) => import("@fusion.d
|
|
|
40
40
|
* @csspart back-mark - The glyph on the back control of a submenu.
|
|
41
41
|
* @csspart empty - Shown when there are no items to show.
|
|
42
42
|
* @csspart header - The bar above a submenu, holding the way back and its name.
|
|
43
|
+
* @csspart live - The empty and loading lines again, in a region a screen reader hears when they change. Visually hidden in the styled tier.
|
|
43
44
|
* @csspart loading - Shown while the items are still on their way.
|
|
44
45
|
* @csspart surface - The floating panel the menu is drawn on.
|
|
45
46
|
* @csspart title - The name of the submenu that is showing.
|
|
@@ -204,7 +204,7 @@ let HelixHeadlessMenu = class HelixHeadlessMenu extends MixinCollection(MixinCon
|
|
|
204
204
|
</div>`}
|
|
205
205
|
<slot @slotchange=${(event) => this.countRows(event)}></slot>
|
|
206
206
|
${this.renderStatus(this.hasRows)}
|
|
207
|
-
</div
|
|
207
|
+
</div>${this.renderLive(this.hasRows)}`;
|
|
208
208
|
}
|
|
209
209
|
};
|
|
210
210
|
__decorate([
|
|
@@ -9,6 +9,7 @@ import { html, nothing } from 'lit';
|
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
const TRIGGER_ID = 'trigger';
|
|
11
11
|
const ITEMS_ID = 'items';
|
|
12
|
+
const LABEL_ID = 'label';
|
|
12
13
|
let HelixHeadlessNotificationGroup = class HelixHeadlessNotificationGroup extends MixinControllerOpen(HelixElement) {
|
|
13
14
|
constructor() {
|
|
14
15
|
super(...arguments);
|
|
@@ -34,7 +35,7 @@ let HelixHeadlessNotificationGroup = class HelixHeadlessNotificationGroup extend
|
|
|
34
35
|
}
|
|
35
36
|
willUpdate(changed) {
|
|
36
37
|
super.willUpdate(changed);
|
|
37
|
-
hostAria(this.internals,
|
|
38
|
+
hostAria(this.internals, { role: 'listitem' });
|
|
38
39
|
}
|
|
39
40
|
firstUpdated(changed) {
|
|
40
41
|
super.firstUpdated(changed);
|
|
@@ -76,14 +77,14 @@ let HelixHeadlessNotificationGroup = class HelixHeadlessNotificationGroup extend
|
|
|
76
77
|
type="button"
|
|
77
78
|
@click=${this.handleToggle}
|
|
78
79
|
>
|
|
79
|
-
<span part="label"><slot name="label">${this.label}</slot></span>
|
|
80
|
+
<span part="label" id=${LABEL_ID}><slot name="label">${this.label}</slot></span>
|
|
80
81
|
${count}
|
|
81
82
|
</button>`
|
|
82
|
-
: html `<span part="label"><slot name="label">${this.label}</slot></span>
|
|
83
|
+
: html `<span part="label" id=${LABEL_ID}><slot name="label">${this.label}</slot></span>
|
|
83
84
|
${count}`}
|
|
84
85
|
<span part="actions"><slot name="actions"></slot></span>
|
|
85
86
|
</div>
|
|
86
|
-
<div id=${ITEMS_ID} part="items">
|
|
87
|
+
<div id=${ITEMS_ID} part="items" role="list" aria-labelledby=${LABEL_ID}>
|
|
87
88
|
<slot></slot>
|
|
88
89
|
</div>`;
|
|
89
90
|
}
|
|
@@ -77,6 +77,16 @@ export declare class HelixHeadlessNotification extends HelixHeadlessNotification
|
|
|
77
77
|
* empty string would give.
|
|
78
78
|
*/
|
|
79
79
|
at: string;
|
|
80
|
+
/**
|
|
81
|
+
* State to open with, where nothing declared one.
|
|
82
|
+
*/
|
|
83
|
+
defaultRead: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Locale for the timestamp.
|
|
86
|
+
*
|
|
87
|
+
* Empty is the runtime's own.
|
|
88
|
+
*/
|
|
89
|
+
locale: string;
|
|
80
90
|
/**
|
|
81
91
|
* Whether the reader has seen it.
|
|
82
92
|
*
|
|
@@ -94,16 +104,6 @@ export declare class HelixHeadlessNotification extends HelixHeadlessNotification
|
|
|
94
104
|
*/
|
|
95
105
|
get read(): boolean;
|
|
96
106
|
set read(next: boolean);
|
|
97
|
-
/**
|
|
98
|
-
* State to open with, where nothing declared one.
|
|
99
|
-
*/
|
|
100
|
-
defaultRead: boolean;
|
|
101
|
-
/**
|
|
102
|
-
* Locale for the timestamp.
|
|
103
|
-
*
|
|
104
|
-
* Empty is the runtime's own.
|
|
105
|
-
*/
|
|
106
|
-
locale: string;
|
|
107
107
|
/**
|
|
108
108
|
* @internal Read by the list to identify its children across the light DOM,
|
|
109
109
|
* which is cheaper than `instanceof` and is why this is public rather than
|
|
@@ -120,15 +120,15 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
|
|
|
120
120
|
__decorate([
|
|
121
121
|
property()
|
|
122
122
|
], HelixHeadlessNotification.prototype, "at", void 0);
|
|
123
|
-
__decorate([
|
|
124
|
-
property({ type: Boolean })
|
|
125
|
-
], HelixHeadlessNotification.prototype, "read", null);
|
|
126
123
|
__decorate([
|
|
127
124
|
property({ attribute: 'default-read', type: Boolean })
|
|
128
125
|
], HelixHeadlessNotification.prototype, "defaultRead", void 0);
|
|
129
126
|
__decorate([
|
|
130
127
|
property()
|
|
131
128
|
], HelixHeadlessNotification.prototype, "locale", void 0);
|
|
129
|
+
__decorate([
|
|
130
|
+
property({ type: Boolean })
|
|
131
|
+
], HelixHeadlessNotification.prototype, "read", null);
|
|
132
132
|
HelixHeadlessNotification = __decorate([
|
|
133
133
|
customElement('helix-headless-notification')
|
|
134
134
|
], HelixHeadlessNotification);
|
|
@@ -41,6 +41,7 @@ declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("
|
|
|
41
41
|
* @csspart footer - The region below the list.
|
|
42
42
|
* @csspart header - The region above the list.
|
|
43
43
|
* @csspart list - The list itself.
|
|
44
|
+
* @csspart live - The empty and loading lines again, in a region a screen reader hears when they change. Visually hidden in the styled tier.
|
|
44
45
|
* @csspart loading - Shown while the feed is still on its way.
|
|
45
46
|
* @csspart mark-all - The control that marks everything read.
|
|
46
47
|
*
|
|
@@ -139,6 +139,7 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
|
|
|
139
139
|
<slot name="items" @slotchange=${this.handleSlotChange}></slot>
|
|
140
140
|
${this.renderStatus(hasItems)}
|
|
141
141
|
</div>
|
|
142
|
+
${this.renderLive(hasItems)}
|
|
142
143
|
<div part="footer"><slot name="footer"></slot></div>`;
|
|
143
144
|
}
|
|
144
145
|
};
|