@fusion.dev/helix-headless 0.143.0 → 0.144.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 +8551 -375
- package/dist/area-chart/root/area-chart-root.d.ts +12 -4
- package/dist/area-chart/root/area-chart-root.js +24 -7
- package/dist/avatar/root/avatar-root.d.ts +14 -0
- package/dist/avatar/root/avatar-root.js +23 -9
- package/dist/badge/root/badge-root.d.ts +11 -7
- package/dist/badge/root/badge-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +12 -3
- package/dist/bar-chart/root/bar-chart-root.js +17 -10
- package/dist/button/root/button-root.d.ts +47 -1
- package/dist/button/root/button-root.js +38 -4
- package/dist/callout/root/callout-root.d.ts +18 -1
- package/dist/callout/root/callout-root.js +15 -4
- package/dist/card/root/card-root.d.ts +30 -1
- package/dist/card/root/card-root.js +38 -5
- package/dist/checkbox/root/checkbox-root.js +2 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +53 -3
- package/dist/checkbox-group/root/checkbox-group-root.js +71 -22
- package/dist/code-block/lines.d.ts +13 -0
- package/dist/code-block/lines.js +2 -0
- package/dist/code-block/root/code-block-root.d.ts +30 -0
- package/dist/code-block/root/code-block-root.js +23 -2
- package/dist/color-input/root/color-input-root.d.ts +34 -1
- package/dist/color-input/root/color-input-root.js +23 -4
- package/dist/color-picker/channels.d.ts +26 -0
- package/dist/color-picker/channels.js +84 -0
- package/dist/color-picker/root/color-picker-root.d.ts +81 -5
- package/dist/color-picker/root/color-picker-root.js +103 -10
- package/dist/combobox/root/combobox-root.d.ts +38 -3
- package/dist/combobox/root/combobox-root.js +64 -2
- package/dist/command/root/command-root.d.ts +30 -4
- package/dist/command/root/command-root.js +33 -3
- package/dist/copy-button/from.d.ts +22 -0
- package/dist/copy-button/from.js +28 -0
- package/dist/copy-button/root/copy-button-root.d.ts +27 -1
- package/dist/copy-button/root/copy-button-root.js +43 -7
- package/dist/date-input/root/date-input-root.d.ts +73 -4
- package/dist/date-input/root/date-input-root.js +93 -43
- package/dist/date-picker/root/date-picker-root.d.ts +145 -1
- package/dist/date-picker/root/date-picker-root.js +239 -48
- package/dist/dialog/description.d.ts +9 -0
- package/dist/dialog/description.js +14 -0
- package/dist/dialog/root/dialog-root.d.ts +64 -1
- package/dist/dialog/root/dialog-root.js +49 -23
- package/dist/donut-chart/root/donut-chart-root.d.ts +25 -4
- package/dist/donut-chart/root/donut-chart-root.js +21 -6
- package/dist/drawer/root/drawer-root.d.ts +63 -2
- package/dist/drawer/root/drawer-root.js +95 -19
- package/dist/drawer/swipe-start.d.ts +9 -0
- package/dist/drawer/swipe-start.js +12 -0
- package/dist/element-events.generated.js +8 -5
- package/dist/empty/root/empty-root.d.ts +1 -1
- package/dist/file-input/root/file-input-root.d.ts +47 -0
- package/dist/file-input/root/file-input-root.js +60 -22
- package/dist/file-input/screen.d.ts +35 -0
- package/dist/file-input/screen.js +49 -0
- package/dist/filter-input/root/filter-input-root.d.ts +38 -4
- package/dist/filter-input/root/filter-input-root.js +67 -3
- package/dist/filter-input/suggest.d.ts +17 -0
- package/dist/filter-input/suggest.js +23 -0
- package/dist/format-date/options.d.ts +33 -0
- package/dist/format-date/options.js +42 -0
- package/dist/format-date/root/format-date-root.d.ts +51 -0
- package/dist/format-date/root/format-date-root.js +58 -38
- package/dist/heatmap/root/heatmap-root.d.ts +23 -6
- package/dist/heatmap/root/heatmap-root.js +24 -13
- package/dist/icon/index.d.ts +2 -0
- package/dist/icon/index.js +2 -0
- package/dist/icon/registry.d.ts +37 -0
- package/dist/icon/registry.js +83 -0
- package/dist/icon/root/icon-root.d.ts +30 -4
- package/dist/icon/root/icon-root.js +41 -6
- package/dist/icon/root/index.d.ts +2 -0
- package/dist/icon/root/index.js +2 -0
- package/dist/icon/set.d.ts +1 -0
- package/dist/icon/set.js +3 -0
- package/dist/image/root/image-root.d.ts +14 -0
- package/dist/image/root/image-root.js +15 -2
- package/dist/input/root/input-root.d.ts +11 -0
- package/dist/input/root/input-root.js +15 -0
- package/dist/kbd/root/kbd-root.d.ts +20 -13
- package/dist/kbd/root/kbd-root.js +35 -37
- package/dist/kbd/shortcut.d.ts +18 -0
- package/dist/kbd/shortcut.js +35 -0
- package/dist/legend/hidden-series.d.ts +8 -0
- package/dist/legend/hidden-series.js +13 -0
- package/dist/legend/root/legend-root.d.ts +56 -0
- package/dist/legend/root/legend-root.js +54 -5
- package/dist/lightbox/item/lightbox-item.d.ts +15 -0
- package/dist/lightbox/item/lightbox-item.js +10 -1
- package/dist/lightbox/root/lightbox-root.d.ts +61 -1
- package/dist/lightbox/root/lightbox-root.js +94 -4
- package/dist/line-chart/root/line-chart-root.d.ts +11 -3
- package/dist/line-chart/root/line-chart-root.js +19 -5
- package/dist/listbox/range.d.ts +17 -0
- package/dist/listbox/range.js +5 -0
- package/dist/listbox/root/listbox-root.d.ts +74 -3
- package/dist/listbox/root/listbox-root.js +87 -9
- package/dist/loader/busy.d.ts +17 -0
- package/dist/loader/busy.js +24 -0
- package/dist/loader/root/loader-root.d.ts +37 -0
- package/dist/loader/root/loader-root.js +52 -3
- package/dist/meter/root/meter-root.d.ts +7 -0
- package/dist/meter/root/meter-root.js +6 -3
- package/dist/notifications/feed-keys.d.ts +10 -0
- package/dist/notifications/feed-keys.js +14 -0
- package/dist/notifications/notification/notification.d.ts +17 -0
- package/dist/notifications/notification/notification.js +21 -2
- package/dist/notifications/root/notifications-root.d.ts +42 -0
- package/dist/notifications/root/notifications-root.js +60 -1
- package/dist/number-input/root/number-input-root.d.ts +47 -0
- package/dist/number-input/root/number-input-root.js +58 -22
- package/dist/object-inspector/root/object-inspector-root.d.ts +1 -0
- package/dist/object-inspector/root/object-inspector-root.js +1 -1
- package/dist/option/root/option-root.d.ts +54 -5
- package/dist/option/root/option-root.js +34 -5
- package/dist/pin-input/format.d.ts +7 -0
- package/dist/pin-input/format.js +16 -0
- package/dist/pin-input/root/pin-input-root.d.ts +21 -0
- package/dist/pin-input/root/pin-input-root.js +29 -2
- package/dist/popover/root/popover-root.d.ts +62 -4
- package/dist/popover/root/popover-root.js +53 -5
- package/dist/progress/root/progress-root.d.ts +7 -0
- package/dist/progress/root/progress-root.js +9 -3
- package/dist/qr-code/export.d.ts +31 -0
- package/dist/qr-code/export.js +10 -0
- package/dist/qr-code/root/qr-code-root.d.ts +26 -0
- package/dist/qr-code/root/qr-code-root.js +49 -2
- package/dist/radio/group/radio-group.d.ts +23 -0
- package/dist/radio/group/radio-group.js +18 -0
- package/dist/rating/root/rating-root.d.ts +25 -0
- package/dist/rating/root/rating-root.js +45 -3
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
- package/dist/scatter-chart/root/scatter-chart-root.js +25 -7
- package/dist/select/root/select-root.d.ts +24 -0
- package/dist/select/root/select-root.js +20 -6
- package/dist/skeleton/root/skeleton-root.d.ts +25 -0
- package/dist/skeleton/root/skeleton-root.js +17 -2
- package/dist/slider/root/slider-root.d.ts +39 -0
- package/dist/slider/root/slider-root.js +45 -9
- package/dist/stat/root/stat-root.d.ts +2 -0
- package/dist/stat/root/stat-root.js +1 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/switch/root/switch-root.d.ts +12 -2
- package/dist/switch/root/switch-root.js +6 -1
- package/dist/tag/group/tag-group.d.ts +107 -0
- package/dist/tag/group/tag-group.js +157 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.d.ts +60 -0
- package/dist/tag/root/tag-root.js +74 -18
- package/dist/tag/selection.d.ts +10 -0
- package/dist/tag/selection.js +12 -0
- package/dist/textarea/grow.d.ts +22 -0
- package/dist/textarea/grow.js +20 -0
- package/dist/textarea/root/textarea-root.d.ts +9 -0
- package/dist/textarea/root/textarea-root.js +9 -1
- package/dist/time-input/root/time-input-root.d.ts +44 -5
- package/dist/time-input/root/time-input-root.js +69 -39
- package/dist/time-picker/root/time-picker-root.d.ts +54 -8
- package/dist/time-picker/root/time-picker-root.js +121 -91
- package/dist/toast/hotkey.d.ts +22 -0
- package/dist/toast/hotkey.js +23 -0
- package/dist/toast/item/toast-item.d.ts +16 -1
- package/dist/toast/item/toast-item.js +41 -13
- package/dist/toast/root/toast-root.d.ts +42 -8
- package/dist/toast/root/toast-root.js +64 -4
- package/dist/toggle/group/toggle-group.d.ts +57 -15
- package/dist/toggle/group/toggle-group.js +69 -9
- package/dist/toggle/root/toggle-root.d.ts +12 -1
- package/dist/toggle/root/toggle-root.js +11 -3
- package/dist/tooltip/focus-target.d.ts +6 -0
- package/dist/tooltip/focus-target.js +9 -0
- package/dist/tooltip/root/tooltip-root.d.ts +42 -17
- package/dist/tooltip/root/tooltip-root.js +50 -9
- package/dist/tour/naming.d.ts +30 -0
- package/dist/tour/naming.js +10 -0
- package/dist/tour/root/tour-root.d.ts +35 -0
- package/dist/tour/root/tour-root.js +56 -5
- package/dist/tour/stop/tour-stop.d.ts +53 -8
- package/dist/tour/stop/tour-stop.js +45 -15
- package/dist/tour/wait.d.ts +11 -0
- package/dist/tour/wait.js +19 -0
- package/dist/trend/root/trend-root.d.ts +13 -0
- package/dist/trend/root/trend-root.js +14 -9
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +4862 -254
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +1149 -67
|
@@ -5,10 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { customElement, HelixElement, hostAria, reportRuntime } from '@fusion.dev/helix-core';
|
|
8
|
-
import { icons } from '@fusion.dev/helix-icons';
|
|
9
8
|
import { html, nothing } from 'lit';
|
|
10
9
|
import { property } from 'lit/decorators.js';
|
|
11
10
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
11
|
+
import { resolveIcon, watchIcons } from '../registry.js';
|
|
12
12
|
let HelixHeadlessIcon = class HelixHeadlessIcon extends HelixElement {
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
@@ -16,6 +16,8 @@ let HelixHeadlessIcon = class HelixHeadlessIcon extends HelixElement {
|
|
|
16
16
|
this.mirror = false;
|
|
17
17
|
this.name = '';
|
|
18
18
|
this.missed = '';
|
|
19
|
+
this.waiting = false;
|
|
20
|
+
this.arrived = '';
|
|
19
21
|
}
|
|
20
22
|
static get observedAttributes() {
|
|
21
23
|
return [...super.observedAttributes, 'aria-label'];
|
|
@@ -26,21 +28,55 @@ let HelixHeadlessIcon = class HelixHeadlessIcon extends HelixElement {
|
|
|
26
28
|
this.requestUpdate();
|
|
27
29
|
}
|
|
28
30
|
}
|
|
31
|
+
connectedCallback() {
|
|
32
|
+
super.connectedCallback();
|
|
33
|
+
this.unwatch = watchIcons(() => {
|
|
34
|
+
if (this.icon === undefined && this.name !== '') {
|
|
35
|
+
this.requestUpdate();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
disconnectedCallback() {
|
|
40
|
+
super.disconnectedCallback();
|
|
41
|
+
this.unwatch?.();
|
|
42
|
+
this.unwatch = undefined;
|
|
43
|
+
}
|
|
44
|
+
lookup() {
|
|
45
|
+
const found = this.name === '' ? undefined : resolveIcon(this.name);
|
|
46
|
+
this.waiting = found instanceof Promise;
|
|
47
|
+
if (!(found instanceof Promise)) {
|
|
48
|
+
return found;
|
|
49
|
+
}
|
|
50
|
+
const name = this.name;
|
|
51
|
+
void found.then(() => {
|
|
52
|
+
if (this.name === name && this.isConnected) {
|
|
53
|
+
this.arrived = name;
|
|
54
|
+
this.requestUpdate();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
29
59
|
willUpdate(changed) {
|
|
30
60
|
super.willUpdate(changed);
|
|
31
61
|
const named = this.label === '' && (this.getAttribute?.('aria-label') ?? '') !== '';
|
|
32
62
|
hostAria(this.internals, { role: named ? 'img' : '' });
|
|
63
|
+
this.drawn = this.icon ?? this.lookup();
|
|
33
64
|
}
|
|
34
65
|
updated(changed) {
|
|
35
66
|
super.updated(changed);
|
|
36
|
-
if (this.
|
|
67
|
+
if (this.arrived === this.name && this.drawn !== undefined) {
|
|
68
|
+
this.dispatchEvent(new Event('load', { bubbles: false, cancelable: false, composed: false }));
|
|
69
|
+
}
|
|
70
|
+
this.arrived = '';
|
|
71
|
+
if (this.drawn === undefined && this.name !== '' && !this.waiting) {
|
|
37
72
|
if (this.missed !== this.name) {
|
|
38
73
|
this.missed = this.name;
|
|
39
74
|
this.dispatchEvent(new Event('error', { bubbles: false, cancelable: false, composed: false }));
|
|
40
75
|
reportRuntime({
|
|
41
76
|
kind: 'unknown-icon',
|
|
42
|
-
message: `<${this.localName} name="${this.name}"> names no icon
|
|
43
|
-
'nothing. Check the name,
|
|
77
|
+
message: `<${this.localName} name="${this.name}"> names no registered icon, so it draws ` +
|
|
78
|
+
'nothing. Check the name, register the glyph with `registerIcons`, or import it ' +
|
|
79
|
+
'and pass it as `icon`.',
|
|
44
80
|
tag: this.localName,
|
|
45
81
|
});
|
|
46
82
|
}
|
|
@@ -50,8 +86,7 @@ let HelixHeadlessIcon = class HelixHeadlessIcon extends HelixElement {
|
|
|
50
86
|
}
|
|
51
87
|
}
|
|
52
88
|
render() {
|
|
53
|
-
const
|
|
54
|
-
const icon = this.icon ?? named;
|
|
89
|
+
const icon = this.drawn;
|
|
55
90
|
if (!icon) {
|
|
56
91
|
return nothing;
|
|
57
92
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/icon/set.js
ADDED
|
@@ -27,6 +27,9 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
27
27
|
* @csspart fallback - The fallback, shown when the image fails to load.
|
|
28
28
|
* @csspart image - The image itself.
|
|
29
29
|
* @csspart placeholder - The placeholder, shown until the image loads.
|
|
30
|
+
*
|
|
31
|
+
* @cssstate error - The image failed to load, and the fallback shows.
|
|
32
|
+
* @cssstate loaded - The image loaded.
|
|
30
33
|
*/
|
|
31
34
|
export declare class HelixHeadlessImage extends HelixElement {
|
|
32
35
|
/**
|
|
@@ -71,6 +74,14 @@ export declare class HelixHeadlessImage extends HelixElement {
|
|
|
71
74
|
* that is not is the exception worth writing down.
|
|
72
75
|
*/
|
|
73
76
|
loading?: 'eager' | 'lazy';
|
|
77
|
+
/**
|
|
78
|
+
* How long, in milliseconds, the placeholder waits before it shows.
|
|
79
|
+
*
|
|
80
|
+
* Absent or `0` shows it at once. A picture that arrives inside
|
|
81
|
+
* the wait never shows a placeholder at all, so a cached or fast image does
|
|
82
|
+
* not flash one. Radix's `delayMs` on its avatar fallback is the same idea.
|
|
83
|
+
*/
|
|
84
|
+
placeholderDelay: number;
|
|
74
85
|
/**
|
|
75
86
|
* How much of the referring URL to send with the request.
|
|
76
87
|
*/
|
|
@@ -112,6 +123,8 @@ export declare class HelixHeadlessImage extends HelixElement {
|
|
|
112
123
|
* Which `src` the current status belongs to, so a new one starts over.
|
|
113
124
|
*/
|
|
114
125
|
private answered;
|
|
126
|
+
/** The placeholder's wait for this `src`, and whether it is over. */
|
|
127
|
+
private readonly wait;
|
|
115
128
|
/**
|
|
116
129
|
* Whether this picture's answer has been given, or is on its way.
|
|
117
130
|
*
|
|
@@ -177,6 +190,7 @@ export declare class HelixHeadlessImage extends HelixElement {
|
|
|
177
190
|
private settle;
|
|
178
191
|
protected willUpdate(changed: PropertyValues): void;
|
|
179
192
|
protected updated(changed: PropertyValues): void;
|
|
193
|
+
private startWait;
|
|
180
194
|
protected firstUpdated(changed: PropertyValues): void;
|
|
181
195
|
/**
|
|
182
196
|
* The picture's own state, under the platform's own names.
|
|
@@ -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 { customElement, HelixElement } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, DelayController, HelixElement } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessImage = class HelixHeadlessImage extends HelixElement {
|
|
@@ -13,12 +13,14 @@ let HelixHeadlessImage = class HelixHeadlessImage extends HelixElement {
|
|
|
13
13
|
this.crossOrigin = null;
|
|
14
14
|
this.decoding = 'async';
|
|
15
15
|
this.fetchPriority = 'auto';
|
|
16
|
+
this.placeholderDelay = 0;
|
|
16
17
|
this.referrerPolicy = '';
|
|
17
18
|
this.sizes = '';
|
|
18
19
|
this.src = '';
|
|
19
20
|
this.srcset = '';
|
|
20
21
|
this.status = 'loading';
|
|
21
22
|
this.answered = '';
|
|
23
|
+
this.wait = new DelayController(this);
|
|
22
24
|
this.reported = false;
|
|
23
25
|
this.synthesized = undefined;
|
|
24
26
|
this.handleLoad = (event) => {
|
|
@@ -78,6 +80,9 @@ let HelixHeadlessImage = class HelixHeadlessImage extends HelixElement {
|
|
|
78
80
|
if (changed.has('src')) {
|
|
79
81
|
this.settle();
|
|
80
82
|
}
|
|
83
|
+
if (changed.has('src') || changed.has('placeholderDelay')) {
|
|
84
|
+
this.startWait();
|
|
85
|
+
}
|
|
81
86
|
if (changed.has('status')) {
|
|
82
87
|
if (this.status === 'loading') {
|
|
83
88
|
this.removeAttribute('data-status');
|
|
@@ -85,8 +90,13 @@ let HelixHeadlessImage = class HelixHeadlessImage extends HelixElement {
|
|
|
85
90
|
else {
|
|
86
91
|
this.setAttribute('data-status', this.status);
|
|
87
92
|
}
|
|
93
|
+
this.toggleState('loaded', this.status === 'loaded');
|
|
94
|
+
this.toggleState('error', this.status === 'error');
|
|
88
95
|
}
|
|
89
96
|
}
|
|
97
|
+
startWait() {
|
|
98
|
+
this.wait.start(this.placeholderDelay > 0 ? this.placeholderDelay : undefined);
|
|
99
|
+
}
|
|
90
100
|
firstUpdated(changed) {
|
|
91
101
|
super.firstUpdated?.(changed);
|
|
92
102
|
this.settle();
|
|
@@ -124,7 +134,7 @@ let HelixHeadlessImage = class HelixHeadlessImage extends HelixElement {
|
|
|
124
134
|
<span
|
|
125
135
|
part="placeholder"
|
|
126
136
|
aria-hidden="true"
|
|
127
|
-
?hidden=${this.status !== 'loading'}
|
|
137
|
+
?hidden=${this.status !== 'loading' || (this.placeholderDelay > 0 && !this.wait.elapsed)}
|
|
128
138
|
><slot name="placeholder"></slot
|
|
129
139
|
></span>
|
|
130
140
|
<span
|
|
@@ -150,6 +160,9 @@ __decorate([
|
|
|
150
160
|
__decorate([
|
|
151
161
|
property({ reflect: true })
|
|
152
162
|
], HelixHeadlessImage.prototype, "loading", void 0);
|
|
163
|
+
__decorate([
|
|
164
|
+
property({ attribute: 'placeholder-delay', type: Number })
|
|
165
|
+
], HelixHeadlessImage.prototype, "placeholderDelay", void 0);
|
|
153
166
|
__decorate([
|
|
154
167
|
property({ attribute: 'referrerpolicy' })
|
|
155
168
|
], HelixHeadlessImage.prototype, "referrerPolicy", void 0);
|
|
@@ -36,6 +36,7 @@ declare const HelixHeadlessInput_base: (new (...args: any[]) => import("@fusion.
|
|
|
36
36
|
*
|
|
37
37
|
* @event {Event} change - Sent when the user finishes changing the value. Relayed from the native input.
|
|
38
38
|
* @event {HelixBeforeChangeEvent} helix-before-change - The text is about to change. Cancelable: cancel it to keep the current text.
|
|
39
|
+
* @event {Event} helix-clear - Fired after the clear button has emptied the field, after `input` and `change`.
|
|
39
40
|
* @event {Event} input - Fired as the value changes.
|
|
40
41
|
*
|
|
41
42
|
* @csspart clear - The button that empties the field.
|
|
@@ -235,6 +236,16 @@ export declare class HelixHeadlessInput extends HelixHeadlessInput_base {
|
|
|
235
236
|
focus(options?: FocusOptions): void;
|
|
236
237
|
/** Selects everything in the field. */
|
|
237
238
|
select(): void;
|
|
239
|
+
/**
|
|
240
|
+
* Moves a number, a date or a time up by `step`, `count` times, as the native
|
|
241
|
+
* method does. It sends no event, as the native method sends none, and it
|
|
242
|
+
* throws `InvalidStateError` on a type with no step, such as `text`.
|
|
243
|
+
*/
|
|
244
|
+
stepUp(count?: number): void;
|
|
245
|
+
/** Moves a number, a date or a time down by `step`, `count` times. See `stepUp`. */
|
|
246
|
+
stepDown(count?: number): void;
|
|
247
|
+
/** Takes the native control's answer, which knows `min`, `max` and `step`. */
|
|
248
|
+
private takeStep;
|
|
238
249
|
/**
|
|
239
250
|
* The caret, held across a value the consumer wrote rather than the reader.
|
|
240
251
|
*
|
|
@@ -38,6 +38,7 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
|
|
|
38
38
|
this.handleClear = () => {
|
|
39
39
|
if (this.value !== '' && this.requestValue('')) {
|
|
40
40
|
this.announceChange();
|
|
41
|
+
this.dispatchEvent(new Event('helix-clear', { bubbles: true, composed: true }));
|
|
41
42
|
}
|
|
42
43
|
const control = this.control;
|
|
43
44
|
if (control) {
|
|
@@ -119,6 +120,20 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
|
|
|
119
120
|
select() {
|
|
120
121
|
this.control?.select();
|
|
121
122
|
}
|
|
123
|
+
stepUp(count = 1) {
|
|
124
|
+
this.control?.stepUp(count);
|
|
125
|
+
this.takeStep();
|
|
126
|
+
}
|
|
127
|
+
stepDown(count = 1) {
|
|
128
|
+
this.control?.stepDown(count);
|
|
129
|
+
this.takeStep();
|
|
130
|
+
}
|
|
131
|
+
takeStep() {
|
|
132
|
+
const control = this.control;
|
|
133
|
+
if (control) {
|
|
134
|
+
this.value = control.value;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
122
137
|
willUpdate(changed) {
|
|
123
138
|
super.willUpdate(changed);
|
|
124
139
|
if (!this.hasUpdated) {
|
|
@@ -17,6 +17,12 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
17
17
|
* The element binds the shortcut only when `within` is set. By default it draws
|
|
18
18
|
* the key and listens for nothing.
|
|
19
19
|
*
|
|
20
|
+
* **`for` names the control the shortcut works**, and the key writes its chord
|
|
21
|
+
* onto that control's `aria-keyshortcuts`, in the platform's words (`Meta+K`
|
|
22
|
+
* on an Apple keyboard, `Control+K` elsewhere), so a screen reader announces
|
|
23
|
+
* the shortcut with the control. A chord the page wrote there itself is left
|
|
24
|
+
* alone, and the key takes back only what it added.
|
|
25
|
+
*
|
|
20
26
|
* @since 0.1.0
|
|
21
27
|
* @status stable
|
|
22
28
|
* @category typography
|
|
@@ -30,6 +36,15 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
30
36
|
* @csspart kbd - The key.
|
|
31
37
|
*/
|
|
32
38
|
export declare class HelixHeadlessKbd extends HelixElement {
|
|
39
|
+
/**
|
|
40
|
+
* The id of the control the shortcut works, which is given the chord as its
|
|
41
|
+
* `aria-keyshortcuts`.
|
|
42
|
+
*
|
|
43
|
+
* Names an element in the same tree, the way `Tooltip.for` does. Separate
|
|
44
|
+
* from `within`, which says where the key listens: a key can describe a
|
|
45
|
+
* shortcut the page binds itself.
|
|
46
|
+
*/
|
|
47
|
+
for: string;
|
|
33
48
|
/**
|
|
34
49
|
* The key or chord to show, such as `mod+k`, `?`, or `/`.
|
|
35
50
|
*
|
|
@@ -57,8 +72,13 @@ export declare class HelixHeadlessKbd extends HelixElement {
|
|
|
57
72
|
within?: 'control' | 'document';
|
|
58
73
|
/** The element the listener is on, kept so it can be taken off the same one. */
|
|
59
74
|
private listening;
|
|
75
|
+
/** The control and the chord written onto it, so the same pair is taken back. */
|
|
76
|
+
private described;
|
|
60
77
|
connectedCallback(): void;
|
|
61
78
|
disconnectedCallback(): void;
|
|
79
|
+
/** Writes the chord onto the control `for` names, taking back one written before. */
|
|
80
|
+
private describe;
|
|
81
|
+
private undescribe;
|
|
62
82
|
protected updated(changed: Map<string, unknown>): void;
|
|
63
83
|
/**
|
|
64
84
|
* The chord as this reader's keyboard labels it.
|
|
@@ -71,19 +91,6 @@ export declare class HelixHeadlessKbd extends HelixElement {
|
|
|
71
91
|
private listen;
|
|
72
92
|
private deafen;
|
|
73
93
|
private readonly handleKeydown;
|
|
74
|
-
/**
|
|
75
|
-
* Whether this chord types a character, and so is indistinguishable from
|
|
76
|
-
* typing.
|
|
77
|
-
*
|
|
78
|
-
* One code point means a character rather than a name: `/` and `?` are
|
|
79
|
-
* printable, `escape` and `enter` are not. **Shift is allowed beside it**,
|
|
80
|
-
* because Shift is how a character is typed: `shift+?` and `shift+a` are a
|
|
81
|
-
* question mark and a capital A in a field, and taking them ate every one
|
|
82
|
-
* a reader typed on the page.
|
|
83
|
-
*/
|
|
84
|
-
private get printable();
|
|
85
|
-
/** Whether a press is this chord, modifiers and all. */
|
|
86
|
-
private matches_;
|
|
87
94
|
protected firstUpdated(changed: PropertyValues): void;
|
|
88
95
|
protected render(): TemplateResult;
|
|
89
96
|
}
|
|
@@ -4,9 +4,10 @@ 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, HelixElement, HelixShortcutEvent } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ariaChord, chordParts, customElement, elementById, HelixElement, HelixShortcutEvent, matchesChord, onApple, printableChord, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
|
+
import { claimShortcut, releaseShortcut } from '../shortcut.js';
|
|
10
11
|
const typing = (node) => {
|
|
11
12
|
if (node instanceof HTMLTextAreaElement) {
|
|
12
13
|
return true;
|
|
@@ -66,20 +67,22 @@ const ELSEWHERE = {
|
|
|
66
67
|
tab: 'Tab',
|
|
67
68
|
up: '↑',
|
|
68
69
|
};
|
|
69
|
-
const onApple = () => typeof navigator !== 'undefined' && /mac|iphone|ipad|ipod/i.test(navigator.userAgent);
|
|
70
70
|
let HelixHeadlessKbd = class HelixHeadlessKbd extends HelixElement {
|
|
71
71
|
constructor() {
|
|
72
72
|
super(...arguments);
|
|
73
|
+
this.for = '';
|
|
73
74
|
this.keys = '';
|
|
74
75
|
this.handleKeydown = (event) => {
|
|
75
76
|
const press = event;
|
|
76
77
|
if (press.isComposing) {
|
|
77
78
|
return;
|
|
78
79
|
}
|
|
79
|
-
if (this.within === 'document' &&
|
|
80
|
+
if (this.within === 'document' &&
|
|
81
|
+
printableChord(this.keys) &&
|
|
82
|
+
typing(press.composedPath()[0])) {
|
|
80
83
|
return;
|
|
81
84
|
}
|
|
82
|
-
if (!this.
|
|
85
|
+
if (!matchesChord(press, this.keys, onApple())) {
|
|
83
86
|
return;
|
|
84
87
|
}
|
|
85
88
|
const shortcut = new HelixShortcutEvent({ keys: this.keys });
|
|
@@ -92,10 +95,30 @@ let HelixHeadlessKbd = class HelixHeadlessKbd extends HelixElement {
|
|
|
92
95
|
connectedCallback() {
|
|
93
96
|
super.connectedCallback();
|
|
94
97
|
this.listen();
|
|
98
|
+
requestAnimationFrame(() => this.describe());
|
|
95
99
|
}
|
|
96
100
|
disconnectedCallback() {
|
|
97
101
|
super.disconnectedCallback();
|
|
98
102
|
this.deafen();
|
|
103
|
+
this.undescribe();
|
|
104
|
+
}
|
|
105
|
+
describe() {
|
|
106
|
+
const control = this.isConnected && this.for !== '' ? elementById(this, this.for) : null;
|
|
107
|
+
const chord = ariaChord(this.keys, onApple());
|
|
108
|
+
if (control === this.described?.control && chord === this.described?.chord) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
this.undescribe();
|
|
112
|
+
if (control && chord !== '') {
|
|
113
|
+
claimShortcut(control, chord);
|
|
114
|
+
this.described = { chord, control };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
undescribe() {
|
|
118
|
+
if (this.described) {
|
|
119
|
+
releaseShortcut(this.described.control, this.described.chord);
|
|
120
|
+
this.described = undefined;
|
|
121
|
+
}
|
|
99
122
|
}
|
|
100
123
|
updated(changed) {
|
|
101
124
|
super.updated(changed);
|
|
@@ -103,15 +126,15 @@ let HelixHeadlessKbd = class HelixHeadlessKbd extends HelixElement {
|
|
|
103
126
|
this.deafen();
|
|
104
127
|
this.listen();
|
|
105
128
|
}
|
|
129
|
+
if ((changed.has('for') && changed.get('for') !== undefined) ||
|
|
130
|
+
(changed.has('keys') && changed.get('keys') !== undefined)) {
|
|
131
|
+
this.describe();
|
|
132
|
+
}
|
|
106
133
|
}
|
|
107
134
|
get label() {
|
|
108
135
|
const apple = !this.hydrating && onApple();
|
|
109
136
|
const names = apple ? APPLE : ELSEWHERE;
|
|
110
|
-
const parts = this.keys
|
|
111
|
-
.split('+')
|
|
112
|
-
.map((part) => part.trim())
|
|
113
|
-
.filter((part) => part !== '')
|
|
114
|
-
.map((part) => names[part.toLowerCase()] ?? (part.length === 1 ? part.toUpperCase() : part));
|
|
137
|
+
const parts = chordParts(this.keys).map((part) => names[part.toLowerCase()] ?? (part.length === 1 ? part.toUpperCase() : part));
|
|
115
138
|
return parts.join(apple ? '' : '+');
|
|
116
139
|
}
|
|
117
140
|
listen() {
|
|
@@ -129,34 +152,6 @@ let HelixHeadlessKbd = class HelixHeadlessKbd extends HelixElement {
|
|
|
129
152
|
this.listening?.removeEventListener('keydown', this.handleKeydown);
|
|
130
153
|
this.listening = undefined;
|
|
131
154
|
}
|
|
132
|
-
get printable() {
|
|
133
|
-
const parts = this.keys
|
|
134
|
-
.split('+')
|
|
135
|
-
.map((part) => part.trim().toLowerCase())
|
|
136
|
-
.filter((part) => part !== '');
|
|
137
|
-
const key = parts.at(-1) ?? '';
|
|
138
|
-
return [...key].length === 1 && parts.slice(0, -1).every((modifier) => modifier === 'shift');
|
|
139
|
-
}
|
|
140
|
-
matches_(press) {
|
|
141
|
-
const parts = this.keys
|
|
142
|
-
.split('+')
|
|
143
|
-
.map((part) => part.trim().toLowerCase())
|
|
144
|
-
.filter((part) => part !== '');
|
|
145
|
-
if (parts.length === 0) {
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
const wanted = parts[parts.length - 1] ?? '';
|
|
149
|
-
const modifiers = new Set(parts.slice(0, -1));
|
|
150
|
-
const apple = onApple();
|
|
151
|
-
const ctrl = modifiers.has('ctrl') || (modifiers.has('mod') && !apple);
|
|
152
|
-
const meta = modifiers.has('cmd') || modifiers.has('meta') || (modifiers.has('mod') && apple);
|
|
153
|
-
const symbol = wanted.toLowerCase() === wanted.toUpperCase() && [...wanted].length === 1;
|
|
154
|
-
return (press.key.toLowerCase() === wanted &&
|
|
155
|
-
(modifiers.has('shift') ? press.shiftKey : symbol || !press.shiftKey) &&
|
|
156
|
-
(modifiers.has('alt') || modifiers.has('opt') ? press.altKey : !press.altKey) &&
|
|
157
|
-
(ctrl ? press.ctrlKey : !press.ctrlKey) &&
|
|
158
|
-
(meta ? press.metaKey : !press.metaKey));
|
|
159
|
-
}
|
|
160
155
|
firstUpdated(changed) {
|
|
161
156
|
super.firstUpdated(changed);
|
|
162
157
|
this.finishHydration();
|
|
@@ -165,6 +160,9 @@ let HelixHeadlessKbd = class HelixHeadlessKbd extends HelixElement {
|
|
|
165
160
|
return html `<kbd part="kbd">${this.keys === '' ? html `<slot></slot>` : this.label}</kbd>`;
|
|
166
161
|
}
|
|
167
162
|
};
|
|
163
|
+
__decorate([
|
|
164
|
+
property()
|
|
165
|
+
], HelixHeadlessKbd.prototype, "for", void 0);
|
|
168
166
|
__decorate([
|
|
169
167
|
property()
|
|
170
168
|
], HelixHeadlessKbd.prototype, "keys", void 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bookkeeping that writes a chord onto the control a shortcut belongs to,
|
|
3
|
+
* in the words core's `ariaChord` spells it in.
|
|
4
|
+
*
|
|
5
|
+
* Beside the family's `index.ts`, because the attribute is a fact about
|
|
6
|
+
* another element, and not the key's template.
|
|
7
|
+
*/
|
|
8
|
+
/** The space-separated list with `chord` added once. */
|
|
9
|
+
export declare const withShortcut: (list: string | null, chord: string) => string;
|
|
10
|
+
/** The list with `chord` taken out, or `null` when nothing is left. */
|
|
11
|
+
export declare const withoutShortcut: (list: string | null, chord: string) => string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Adds a chord to the control's `aria-keyshortcuts`, leaving any the page
|
|
14
|
+
* wrote itself.
|
|
15
|
+
*/
|
|
16
|
+
export declare const claimShortcut: (control: Element, chord: string) => void;
|
|
17
|
+
/** Takes back a chord this file wrote, and the attribute with the last one. */
|
|
18
|
+
export declare const releaseShortcut: (control: Element, chord: string) => void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const withShortcut = (list, chord) => {
|
|
2
|
+
const chords = (list ?? '').split(/\s+/).filter(Boolean);
|
|
3
|
+
return chords.includes(chord) ? chords.join(' ') : [...chords, chord].join(' ');
|
|
4
|
+
};
|
|
5
|
+
export const withoutShortcut = (list, chord) => {
|
|
6
|
+
const chords = (list ?? '').split(/\s+/).filter((one) => one !== '' && one !== chord);
|
|
7
|
+
return chords.length > 0 ? chords.join(' ') : null;
|
|
8
|
+
};
|
|
9
|
+
const WRITTEN = new WeakMap();
|
|
10
|
+
export const claimShortcut = (control, chord) => {
|
|
11
|
+
if (chord === '') {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const before = control.getAttribute('aria-keyshortcuts');
|
|
15
|
+
if ((before ?? '').split(/\s+/).includes(chord) && !WRITTEN.get(control)?.has(chord)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const written = WRITTEN.get(control) ?? new Set();
|
|
19
|
+
written.add(chord);
|
|
20
|
+
WRITTEN.set(control, written);
|
|
21
|
+
control.setAttribute('aria-keyshortcuts', withShortcut(before, chord));
|
|
22
|
+
};
|
|
23
|
+
export const releaseShortcut = (control, chord) => {
|
|
24
|
+
const written = WRITTEN.get(control);
|
|
25
|
+
if (!written?.delete(chord)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const after = withoutShortcut(control.getAttribute('aria-keyshortcuts'), chord);
|
|
29
|
+
if (after === null) {
|
|
30
|
+
control.removeAttribute('aria-keyshortcuts');
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
control.setAttribute('aria-keyshortcuts', after);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Whether a name is in the list, matched without regard to case, as a heading is. */
|
|
2
|
+
export declare const isHidden: (list: string, name: string) => boolean;
|
|
3
|
+
/**
|
|
4
|
+
* The list a press on this name leaves: without it where it was hidden, and
|
|
5
|
+
* with it at the end where it was shown. Written back with a comma and a
|
|
6
|
+
* space, as a person writes a list.
|
|
7
|
+
*/
|
|
8
|
+
export declare const toggledNames: (list: string, name: string) => string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { commaList, seriesKey } from '@fusion.dev/helix-core';
|
|
2
|
+
export const isHidden = (list, name) => {
|
|
3
|
+
const key = seriesKey(name);
|
|
4
|
+
return commaList(list).some((one) => seriesKey(one) === key);
|
|
5
|
+
};
|
|
6
|
+
export const toggledNames = (list, name) => {
|
|
7
|
+
const key = seriesKey(name);
|
|
8
|
+
const now = commaList(list);
|
|
9
|
+
const next = isHidden(list, name)
|
|
10
|
+
? now.filter((one) => seriesKey(one) !== key)
|
|
11
|
+
: [...now, name.trim()];
|
|
12
|
+
return next.join(', ');
|
|
13
|
+
};
|
|
@@ -18,17 +18,28 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
18
18
|
*
|
|
19
19
|
* The table is resolved on the client. There is no server pass.
|
|
20
20
|
*
|
|
21
|
+
* **`toggles` makes each entry a button that hides its series.** Every chart
|
|
22
|
+
* reading the same table draws without a hidden series and fits its scale to
|
|
23
|
+
* the rest, and the series keeps its color. The button says whether its
|
|
24
|
+
* series is shown with `aria-pressed`. `hidden-series` holds the hidden names,
|
|
25
|
+
* so a page can start with some hidden or read which are.
|
|
26
|
+
*
|
|
21
27
|
* @since 0.1.0
|
|
22
28
|
* @status stable
|
|
23
29
|
* @category charts
|
|
24
30
|
* @aliases Key, Series Key
|
|
25
31
|
* @documentation https://fusion.dev/helix/components/legend
|
|
26
32
|
*
|
|
33
|
+
* @event {Event} change - Fired once a toggle has hidden or shown a series.
|
|
34
|
+
* @event {HelixBeforeChangeEvent} helix-before-change - Fired before a toggle hides or shows a series, with the `hidden-series` it would leave. Cancelable.
|
|
35
|
+
*
|
|
27
36
|
* @csspart entry - One name and its swatch. Draw the swatch with
|
|
28
37
|
* `::part(entry)::before` in your stylesheet. The entry holds its series color
|
|
29
38
|
* as `--chart-series`, and this tier ships no CSS.
|
|
39
|
+
* @csspart entry-hidden - An entry whose series is hidden. Set alongside `entry`.
|
|
30
40
|
* @csspart list - The list of entries.
|
|
31
41
|
* @csspart name - One series name.
|
|
42
|
+
* @csspart toggle - The button around a name under `toggles`, which hides or shows its series.
|
|
32
43
|
*/
|
|
33
44
|
export declare class HelixHeadlessLegend extends HelixElement {
|
|
34
45
|
/**
|
|
@@ -62,6 +73,15 @@ export declare class HelixHeadlessLegend extends HelixElement {
|
|
|
62
73
|
* `Tooltip.for` does, so it does not reflect and nothing styles on it.
|
|
63
74
|
*/
|
|
64
75
|
for: string;
|
|
76
|
+
/**
|
|
77
|
+
* The series hidden on the table, by name, separated by commas: what
|
|
78
|
+
* `toggles` hides and shows.
|
|
79
|
+
*
|
|
80
|
+
* Set it to start with series hidden. Every chart reading the same table
|
|
81
|
+
* draws without them. Commas only, because a column's heading may hold a
|
|
82
|
+
* space. For a ring the names are the rows.
|
|
83
|
+
*/
|
|
84
|
+
hiddenSeries: string;
|
|
65
85
|
/**
|
|
66
86
|
* The name of the list, which a screen reader announces before its entries.
|
|
67
87
|
*
|
|
@@ -69,8 +89,37 @@ export declare class HelixHeadlessLegend extends HelixElement {
|
|
|
69
89
|
* charts has a legend list for each that says which chart it keys.
|
|
70
90
|
*/
|
|
71
91
|
label: string;
|
|
92
|
+
/**
|
|
93
|
+
* Makes each entry a button that hides or shows its series in every chart
|
|
94
|
+
* reading the same table.
|
|
95
|
+
*
|
|
96
|
+
* Absent, the legend only displays, which is what it did before this
|
|
97
|
+
* existed. Reflected, because the styled tier draws a button differently
|
|
98
|
+
* from a plain entry.
|
|
99
|
+
*/
|
|
100
|
+
toggles: boolean;
|
|
72
101
|
protected readonly source: SourceController;
|
|
102
|
+
/** Whether this legend has written the table's hidden series, so leaving undoes it. */
|
|
103
|
+
private wrote;
|
|
73
104
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
105
|
+
/**
|
|
106
|
+
* Hands `hidden-series` to the table, where every chart reading it finds
|
|
107
|
+
* it.
|
|
108
|
+
*
|
|
109
|
+
* After the update rather than before, because a server has no table and a
|
|
110
|
+
* hydrating render must draw what the server drew: the charts follow a frame
|
|
111
|
+
* after the legend, which is when they draw at all.
|
|
112
|
+
*/
|
|
113
|
+
protected updated(changed: PropertyValues<this>): void;
|
|
114
|
+
disconnectedCallback(): void;
|
|
115
|
+
/**
|
|
116
|
+
* Hides the series of this name, or shows it again, asking first.
|
|
117
|
+
*
|
|
118
|
+
* `helix-before-change` carries the `hidden-series` the press would leave,
|
|
119
|
+
* and a listener that refuses it keeps the chart as it is. `change` follows
|
|
120
|
+
* once the series is hidden or shown.
|
|
121
|
+
*/
|
|
122
|
+
protected toggle(name: string): void;
|
|
74
123
|
/**
|
|
75
124
|
* The names, in the order the chart will draw them.
|
|
76
125
|
*
|
|
@@ -82,6 +131,13 @@ export declare class HelixHeadlessLegend extends HelixElement {
|
|
|
82
131
|
*/
|
|
83
132
|
protected names(): string[];
|
|
84
133
|
protected render(): TemplateResult;
|
|
134
|
+
/**
|
|
135
|
+
* The button around a name under `toggles`, behind a seam a tier can move.
|
|
136
|
+
*
|
|
137
|
+
* Pressed while its series is shown, which is the state a reader changes by
|
|
138
|
+
* pressing it: a toggle button says whether its thing is on.
|
|
139
|
+
*/
|
|
140
|
+
protected renderToggle(name: string, off: boolean): TemplateResult;
|
|
85
141
|
}
|
|
86
142
|
declare global {
|
|
87
143
|
interface HTMLElementTagNameMap {
|