@fusion.dev/helix-headless 0.147.0 → 0.148.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 +4512 -790
- package/dist/accordion/item/accordion-item.d.ts +5 -2
- package/dist/accordion/item/accordion-item.js +11 -7
- package/dist/accordion/root/accordion-root.js +4 -6
- package/dist/announcement/root/announcement-root.d.ts +56 -5
- package/dist/announcement/root/announcement-root.js +124 -21
- package/dist/area-chart/root/area-chart-root.js +3 -4
- package/dist/badge/count.d.ts +14 -0
- package/dist/badge/count.js +20 -0
- package/dist/badge/root/badge-root.js +8 -22
- package/dist/blockquote/root/blockquote-root.d.ts +66 -8
- package/dist/blockquote/root/blockquote-root.js +85 -8
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +2 -2
- package/dist/button-group/arrows.d.ts +14 -0
- package/dist/button-group/arrows.js +10 -0
- package/dist/button-group/root/button-group-root.d.ts +141 -3
- package/dist/button-group/root/button-group-root.js +142 -2
- package/dist/canvas/edge-pan.d.ts +61 -0
- package/dist/canvas/edge-pan.js +63 -0
- package/dist/canvas/node/canvas-node.d.ts +12 -2
- package/dist/canvas/node/canvas-node.js +6 -2
- package/dist/canvas/root/canvas-document.d.ts +10 -0
- package/dist/canvas/root/canvas-document.js +1 -0
- package/dist/canvas/root/canvas-root.d.ts +107 -5
- package/dist/canvas/root/canvas-root.js +140 -36
- package/dist/canvas/snap.d.ts +42 -0
- package/dist/canvas/snap.js +32 -0
- package/dist/carousel/root/carousel-root.d.ts +4 -3
- package/dist/carousel/root/carousel-root.js +2 -6
- package/dist/chat/root/chat-root.d.ts +13 -3
- package/dist/chat/root/chat-root.js +2 -6
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +18 -10
- package/dist/checkbox-group/select-all.d.ts +11 -0
- package/dist/checkbox-group/select-all.js +5 -0
- package/dist/code-block/root/code-block-root.d.ts +8 -6
- package/dist/code-block/root/code-block-root.js +4 -3
- package/dist/color-picker/root/color-picker-root.js +6 -12
- package/dist/color-picker/wheel.d.ts +11 -0
- package/dist/color-picker/wheel.js +9 -0
- package/dist/combobox/root/combobox-root.d.ts +70 -11
- package/dist/combobox/root/combobox-root.js +68 -18
- package/dist/command/root/command-root.d.ts +4 -3
- package/dist/data-table/root/data-table-root.js +17 -44
- package/dist/description-list/item/description-list-item.d.ts +4 -0
- package/dist/description-list/item/description-list-item.js +7 -1
- package/dist/divider/root/divider-root.d.ts +45 -16
- package/dist/divider/root/divider-root.js +28 -4
- package/dist/drilldown/item/drilldown-item.js +3 -4
- package/dist/element-events.generated.js +1 -0
- package/dist/empty/root/empty-root.d.ts +17 -3
- package/dist/empty/root/empty-root.js +29 -5
- package/dist/file-input/root/file-input-root.js +3 -4
- package/dist/file-input/status.js +2 -1
- package/dist/filter-input/chip/filter-chip.js +2 -3
- package/dist/format-date/fields.d.ts +20 -0
- package/dist/format-date/fields.js +14 -0
- package/dist/format-date/options.d.ts +2 -1
- package/dist/format-date/options.js +9 -38
- package/dist/format-date/root/format-date-root.d.ts +35 -3
- package/dist/format-date/root/format-date-root.js +24 -32
- package/dist/graph/root/graph-root.d.ts +23 -5
- package/dist/graph/root/graph-root.js +17 -20
- package/dist/heatmap/root/heatmap-root.d.ts +12 -0
- package/dist/heatmap/root/heatmap-root.js +26 -11
- package/dist/image/root/image-root.d.ts +11 -0
- package/dist/kbd/root/kbd-root.js +1 -2
- package/dist/legend/root/legend-root.js +4 -17
- package/dist/list/root/list-root.js +8 -22
- package/dist/listbox/root/listbox-root.d.ts +119 -24
- package/dist/listbox/root/listbox-root.js +130 -132
- package/dist/map/marker/map-marker.d.ts +2 -1
- package/dist/map/root/map-root.d.ts +40 -2
- package/dist/map/root/map-root.js +64 -23
- package/dist/megamenu/root/megamenu-root.js +4 -11
- package/dist/menu/root/menu-root.d.ts +2 -2
- package/dist/navigation/root/navigation-root.js +5 -8
- package/dist/notifications/group/notification-group.d.ts +8 -1
- package/dist/notifications/group/notification-group.js +12 -6
- package/dist/notifications/notification/notification.d.ts +12 -1
- package/dist/notifications/notification/notification.js +3 -1
- package/dist/notifications/root/notifications-root.d.ts +41 -5
- package/dist/notifications/root/notifications-root.js +27 -7
- package/dist/object-inspector/root/object-inspector-root.d.ts +5 -1
- package/dist/object-inspector/root/object-inspector-root.js +21 -11
- package/dist/pagination/size/pagination-size.d.ts +1 -0
- package/dist/pagination/size/pagination-size.js +1 -1
- package/dist/pin-input/code.d.ts +23 -0
- package/dist/pin-input/code.js +25 -0
- package/dist/pin-input/root/pin-input-root.js +9 -23
- package/dist/qr-code/root/qr-code-root.d.ts +14 -3
- package/dist/qr-code/root/qr-code-root.js +19 -5
- package/dist/scatter-chart/measures.d.ts +22 -0
- package/dist/scatter-chart/measures.js +11 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +2 -6
- package/dist/scatter-chart/root/scatter-chart-root.js +6 -19
- package/dist/select/root/select-root.d.ts +56 -8
- package/dist/select/root/select-root.js +33 -9
- package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
- package/dist/speed-dial/group/speed-dial-group.js +43 -0
- package/dist/speed-dial/index.d.ts +1 -0
- package/dist/speed-dial/index.js +1 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +26 -1
- package/dist/speed-dial/item/speed-dial-item.js +41 -3
- package/dist/speed-dial/long-press.d.ts +50 -0
- package/dist/speed-dial/long-press.js +48 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +80 -1
- package/dist/speed-dial/root/speed-dial-root.js +114 -5
- package/dist/splitter/root/splitter-root.d.ts +7 -3
- package/dist/splitter/root/splitter-root.js +16 -3
- package/dist/table/cell/table-cell.d.ts +8 -1
- package/dist/table/cell/table-cell.js +6 -2
- package/dist/table/grid-controller.d.ts +117 -0
- package/dist/table/grid-controller.js +293 -0
- package/dist/table/root/table-root.d.ts +47 -3
- package/dist/table/root/table-root.js +81 -24
- package/dist/table/row/table-row.d.ts +13 -1
- package/dist/table/row/table-row.js +20 -6
- package/dist/tag/group/tag-group.js +6 -15
- package/dist/time-picker/root/time-picker-root.d.ts +1 -0
- package/dist/time-picker/root/time-picker-root.js +3 -0
- package/dist/toast/item/toast-item.d.ts +6 -3
- package/dist/toast/item/toast-item.js +1 -0
- package/dist/toast/root/toast-root.d.ts +13 -1
- package/dist/toast/root/toast-root.js +20 -14
- package/dist/toggle/group/toggle-group.js +3 -5
- package/dist/toolbar/root/toolbar-root.d.ts +31 -0
- package/dist/toolbar/root/toolbar-root.js +39 -8
- package/dist/tooltip/root/tooltip-root.js +1 -2
- package/dist/video/root/video-root.d.ts +11 -0
- package/dist/video/root/video-root.js +15 -1
- package/dist/virtual-list/root/virtual-list-root.js +6 -18
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +2005 -266
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +338 -62
- package/dist/kbd/keys.d.ts +0 -29
- package/dist/kbd/keys.js +0 -52
- package/dist/tooltip/focus-target.d.ts +0 -6
- package/dist/tooltip/focus-target.js +0 -9
|
@@ -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, afterLinkFollowed, customElement, DelayController, fillTemplate, HelixCreateEvent, HelixFilterEvent, HelixFormElement, MixinControllerOpen, MixinControllerValue, MixinField, MixinTokens, PopoverController, reportValues, submitImplicitly, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { AriaForwardController, afterLinkFollowed, countLabel, customElement, DelayController, drawAutofill, drawStatus, fillTemplate, HelixCreateEvent, HelixFilterEvent, HelixFormElement, MixinControllerOpen, MixinControllerValue, MixinField, MixinTokens, onApple, PopoverController, reportValues, StatusController, submitImplicitly, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretDown } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -21,6 +21,8 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
21
21
|
this.aria = new AriaForwardController(this, {
|
|
22
22
|
target: () => this.partNamed('control'),
|
|
23
23
|
});
|
|
24
|
+
this.status = new StatusController(this);
|
|
25
|
+
this.told = undefined;
|
|
24
26
|
this.allowsCustomValue = false;
|
|
25
27
|
this.autocomplete = 'off';
|
|
26
28
|
this.creatable = false;
|
|
@@ -38,6 +40,7 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
38
40
|
this.removeLabel = 'Remove {name}';
|
|
39
41
|
this.resultLabel = '{count} result';
|
|
40
42
|
this.resultsLabel = '{count} results';
|
|
43
|
+
this.selectedLabel = '{name}, selected';
|
|
41
44
|
this.suggest = false;
|
|
42
45
|
this.typed = '';
|
|
43
46
|
this.suggestion = '';
|
|
@@ -166,12 +169,17 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
166
169
|
submitImplicitly(this.form);
|
|
167
170
|
}
|
|
168
171
|
};
|
|
172
|
+
this.counted = '';
|
|
169
173
|
this.handleChange = (event) => {
|
|
170
174
|
event.stopPropagation();
|
|
171
175
|
const { value } = event.detail;
|
|
172
176
|
if (!this.requestValue(value)) {
|
|
173
177
|
return;
|
|
174
178
|
}
|
|
179
|
+
const chosen = this.listbox?.options.find((option) => option.value === value);
|
|
180
|
+
if (chosen && onApple()) {
|
|
181
|
+
this.status.say(fillTemplate(this.selectedLabel, { name: chosen.text }));
|
|
182
|
+
}
|
|
175
183
|
this.emptied = false;
|
|
176
184
|
this.typed = '';
|
|
177
185
|
this.suggestion = '';
|
|
@@ -247,7 +255,9 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
247
255
|
}
|
|
248
256
|
markStatus() {
|
|
249
257
|
const list = this.listbox;
|
|
250
|
-
this.toggleState('
|
|
258
|
+
this.toggleState('blank', this.value === '');
|
|
259
|
+
this.toggleState('loading', this.loading);
|
|
260
|
+
this.toggleState('error', Boolean(this.loadError));
|
|
251
261
|
this.toggleState('no-results', list !== null &&
|
|
252
262
|
!this.loading &&
|
|
253
263
|
list.filter !== '' &&
|
|
@@ -382,16 +392,47 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
382
392
|
}
|
|
383
393
|
linkActive() {
|
|
384
394
|
const control = this.partNamed('control');
|
|
385
|
-
if (!control || !('ariaActiveDescendantElement' in control)) {
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
395
|
const active = !this.open
|
|
389
396
|
? undefined
|
|
390
397
|
: this.onCreate
|
|
391
398
|
? this.partNamed('create')
|
|
392
399
|
: (this.listbox?.options ?? []).find((option) => option.active && !option.hidden);
|
|
400
|
+
this.tell(active);
|
|
401
|
+
if (!control || !('ariaActiveDescendantElement' in control)) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
;
|
|
393
405
|
control.ariaActiveDescendantElement = active ?? null;
|
|
394
406
|
}
|
|
407
|
+
tell(active) {
|
|
408
|
+
if (!this.open) {
|
|
409
|
+
this.told = undefined;
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
if ((active ?? null) === this.told ||
|
|
413
|
+
!onApple() ||
|
|
414
|
+
this.renderRoot.activeElement !== this.partNamed('control')) {
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
if (this.listbox?.isUpdatePending) {
|
|
418
|
+
void this.listbox.updateComplete.then(() => this.linkActive());
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
if (this.told === undefined) {
|
|
422
|
+
this.counted = countLabel(this.reachable.length, this.resultLabel, this.resultsLabel, this.lang);
|
|
423
|
+
}
|
|
424
|
+
this.told = active ?? null;
|
|
425
|
+
const option = active;
|
|
426
|
+
const words = option?.text === undefined
|
|
427
|
+
? (active?.textContent?.trim() ?? '')
|
|
428
|
+
: option.selected
|
|
429
|
+
? fillTemplate(this.selectedLabel, { name: option.text })
|
|
430
|
+
: option.text;
|
|
431
|
+
this.status.say([this.counted, words].filter(Boolean).join('. '));
|
|
432
|
+
if (active) {
|
|
433
|
+
this.counted = '';
|
|
434
|
+
}
|
|
435
|
+
}
|
|
395
436
|
removeLastToken() {
|
|
396
437
|
const last = this.values.at(-1);
|
|
397
438
|
if (last !== undefined) {
|
|
@@ -468,7 +509,11 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
468
509
|
this.opening = undefined;
|
|
469
510
|
void this.listbox?.updateComplete.then(() => this.linkActive());
|
|
470
511
|
}
|
|
471
|
-
if (control &&
|
|
512
|
+
if (control &&
|
|
513
|
+
!this.editing &&
|
|
514
|
+
!this.multiple &&
|
|
515
|
+
control.value !== '' &&
|
|
516
|
+
this.renderRoot.activeElement === control) {
|
|
472
517
|
control.select();
|
|
473
518
|
}
|
|
474
519
|
}
|
|
@@ -497,25 +542,16 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
497
542
|
?loading=${this.loading}
|
|
498
543
|
?multiple=${this.multiple}
|
|
499
544
|
.value=${this.value}
|
|
545
|
+
.chosenAgain=${() => this.close()}
|
|
500
546
|
@helix-before-change=${this.handleChange}
|
|
501
547
|
@change=${this.stopInner}
|
|
502
548
|
@helix-filter=${this.stopInner}
|
|
503
549
|
@input=${this.stopInner}
|
|
504
550
|
>
|
|
505
|
-
<!-- The field's words are read off the options, and on the first
|
|
506
|
-
render there are none: the slot has not been assigned yet, so a
|
|
507
|
-
combobox with a value comes up empty. Assignment changes no
|
|
508
|
-
property, so nothing else would schedule the update that fixes
|
|
509
|
-
it. -->
|
|
510
551
|
<slot @slotchange=${() => this.requestUpdate()}></slot>
|
|
511
|
-
<!-- Handed on to the list's own, with the text as this slot's fallback:
|
|
512
|
-
a slot passed into another is assigned there whether or not anything
|
|
513
|
-
fills it, so the list's fallback would never show. -->
|
|
514
552
|
<slot name="empty" slot="empty">${this.emptyText}</slot>
|
|
515
553
|
<slot name="loading" slot="loading">${this.loadingText}</slot>
|
|
516
554
|
<slot name="error" slot="error">${this.loadError}</slot>
|
|
517
|
-
<!-- Handed on only while something fills it: an assigned slot hides the
|
|
518
|
-
list's own fallback, which is no-results-text or empty-text. -->
|
|
519
555
|
<slot
|
|
520
556
|
name="no-results"
|
|
521
557
|
slot=${this.querySelector?.(':scope > [slot="no-results"]') ? 'no-results' : nothing}
|
|
@@ -565,7 +601,7 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
565
601
|
id=${this.controlId}
|
|
566
602
|
type="text"
|
|
567
603
|
role="combobox"
|
|
568
|
-
autocomplete=${this.autocomplete || nothing}
|
|
604
|
+
autocomplete=${(this.fills ? 'off' : this.autocomplete) || nothing}
|
|
569
605
|
spellcheck="false"
|
|
570
606
|
aria-controls="listbox"
|
|
571
607
|
aria-autocomplete=${this.suggest ? 'both' : 'list'}
|
|
@@ -588,7 +624,18 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
588
624
|
${this.renderListbox()}
|
|
589
625
|
${this.renderCreate()}
|
|
590
626
|
</div>
|
|
591
|
-
${this.renderHint()}${this.renderFeedback()}
|
|
627
|
+
${this.renderHint()}${this.renderFeedback()}${drawStatus(this.status)}
|
|
628
|
+
${drawAutofill({
|
|
629
|
+
autocomplete: this.fills ? this.autocomplete : '',
|
|
630
|
+
disabled: this.isDisabled || this.readOnly,
|
|
631
|
+
multiple: this.multiple,
|
|
632
|
+
onFill: (value) => this.requestValue(value),
|
|
633
|
+
options: optionsAmong(this.knownChildren),
|
|
634
|
+
value: this.value,
|
|
635
|
+
})}`;
|
|
636
|
+
}
|
|
637
|
+
get fills() {
|
|
638
|
+
return !this.allowsCustomValue && this.autocomplete !== 'off' && this.autocomplete !== '';
|
|
592
639
|
}
|
|
593
640
|
};
|
|
594
641
|
__decorate([
|
|
@@ -645,6 +692,9 @@ __decorate([
|
|
|
645
692
|
__decorate([
|
|
646
693
|
property({ attribute: 'results-label' })
|
|
647
694
|
], HelixHeadlessCombobox.prototype, "resultsLabel", void 0);
|
|
695
|
+
__decorate([
|
|
696
|
+
property({ attribute: 'selected-label' })
|
|
697
|
+
], HelixHeadlessCombobox.prototype, "selectedLabel", void 0);
|
|
648
698
|
__decorate([
|
|
649
699
|
property({ type: Boolean })
|
|
650
700
|
], HelixHeadlessCombobox.prototype, "suggest", void 0);
|
|
@@ -96,10 +96,11 @@ export declare class HelixHeadlessCommand extends HelixHeadlessCommand_base {
|
|
|
96
96
|
label: string;
|
|
97
97
|
/**
|
|
98
98
|
* What the list says when its commands could not be loaded, such as after a
|
|
99
|
-
* request to a server fails. Empty
|
|
100
|
-
*
|
|
99
|
+
* request to a server fails. Empty, null or no attribute is no error, so
|
|
100
|
+
* removing the attribute clears it. Passed to the list, which shows it
|
|
101
|
+
* under any commands there are and tells screen readers.
|
|
101
102
|
*/
|
|
102
|
-
loadError: string;
|
|
103
|
+
loadError: string | null;
|
|
103
104
|
/**
|
|
104
105
|
* Whether the commands are still loading, for a palette that asks a server
|
|
105
106
|
* for them as the user types.
|
|
@@ -5,7 +5,7 @@ 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
|
var HelixHeadlessDataTable_1;
|
|
8
|
-
import { anchorAt, arranged, commaList, countLabel, customElement, cycle, deepActiveElement, deepContains, everyState, fillTemplate, format, formatNumbers, HelixActivateEvent, HelixElement, HelixExpandEvent, HelixFilterEvent, HelixFilteredEvent, HelixLoadMoreEvent, HelixNavigateEvent, HelixReorderEvent, HelixReorderedEvent, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, hostAria, inlineStep, inRowOrder, isRtl, MixinCollection, markRegion, onAndroid, ordered, parse, rangeAdd, reportRuntime, requestChange, selectsAll, Typeahead, toggleEvery, treeArrow, typesCharacter, VirtualizeController, valueAt, window_, writtenList, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { anchorAt, arranged, commaList, countLabel, customElement, cycle, deepActiveElement, deepContains, everyState, fillTemplate, format, formatNumbers, gridMove, HelixActivateEvent, HelixElement, HelixExpandEvent, HelixFilterEvent, HelixFilteredEvent, HelixLoadMoreEvent, HelixNavigateEvent, HelixReorderEvent, HelixReorderedEvent, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, hostAria, inlineStep, inRowOrder, isRtl, MixinCollection, markRegion, onAndroid, ordered, pageRows, parse, rangeAdd, reportRuntime, requestChange, scrollRoom, selectsAll, Typeahead, toggleEvery, treeArrow, typesCharacter, VirtualizeController, valueAt, window_, writtenList, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { caretDown, caretRight } from '@fusion.dev/helix-icons';
|
|
10
10
|
import { nothing } from 'lit';
|
|
11
11
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -165,8 +165,6 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
165
165
|
return;
|
|
166
166
|
}
|
|
167
167
|
const last = this.drawnPage.length - 1 + (this.moreDrawn ? 1 : 0);
|
|
168
|
-
const edge = this.width - 1;
|
|
169
|
-
const control = event.ctrlKey || event.metaKey;
|
|
170
168
|
if (!event.shiftKey && selectsAll(event) && this.selectable) {
|
|
171
169
|
event.preventDefault();
|
|
172
170
|
this.requestSelected(new Set([...this.chosen, ...this.everyKey]));
|
|
@@ -180,43 +178,22 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
180
178
|
}
|
|
181
179
|
return;
|
|
182
180
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
row = Math.min(last, row + 1);
|
|
190
|
-
break;
|
|
191
|
-
case 'ArrowLeft':
|
|
192
|
-
case 'ArrowRight':
|
|
193
|
-
if (this.treeKey(event, place)) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
column = Math.max(0, Math.min(edge, column + inlineStep(this, event.key)));
|
|
197
|
-
break;
|
|
198
|
-
case 'Home':
|
|
199
|
-
row = control ? -1 : row;
|
|
200
|
-
column = 0;
|
|
201
|
-
break;
|
|
202
|
-
case 'End':
|
|
203
|
-
row = control ? Math.max(row, last) : row;
|
|
204
|
-
column = edge;
|
|
205
|
-
break;
|
|
206
|
-
case 'PageUp':
|
|
207
|
-
row = Math.max(-1, row - this.pageStep(place.cell));
|
|
208
|
-
break;
|
|
209
|
-
case 'PageDown':
|
|
210
|
-
row = Math.min(last, row + this.pageStep(place.cell));
|
|
211
|
-
break;
|
|
212
|
-
case 'Enter':
|
|
213
|
-
case ' ':
|
|
214
|
-
case 'F2':
|
|
215
|
-
this.activate(event, place);
|
|
216
|
-
return;
|
|
217
|
-
default:
|
|
218
|
-
return;
|
|
181
|
+
if (event.key === 'Enter' || event.key === ' ' || event.key === 'F2') {
|
|
182
|
+
this.activate(event, place);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight') && this.treeKey(event, place)) {
|
|
186
|
+
return;
|
|
219
187
|
}
|
|
188
|
+
const to = gridMove(event.key, place, { last, top: -1, width: this.width }, {
|
|
189
|
+
control: event.ctrlKey || event.metaKey,
|
|
190
|
+
page: event.key.startsWith('Page') ? this.pageStep(place.cell) : 1,
|
|
191
|
+
step: inlineStep(this, event.key),
|
|
192
|
+
});
|
|
193
|
+
if (!to) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const { column, row } = to;
|
|
220
197
|
event.preventDefault();
|
|
221
198
|
if (event.shiftKey &&
|
|
222
199
|
this.selectable &&
|
|
@@ -1204,11 +1181,7 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
1204
1181
|
this.focusWanted = true;
|
|
1205
1182
|
}
|
|
1206
1183
|
pageStep(cell) {
|
|
1207
|
-
|
|
1208
|
-
const tall = cell.getBoundingClientRect().height || this.estimate;
|
|
1209
|
-
const scrolls = box !== null && box.scrollHeight > box.clientHeight + 1;
|
|
1210
|
-
const room = scrolls ? box.clientHeight - this.headHeight() : window.innerHeight;
|
|
1211
|
-
return Math.max(1, Math.floor(room / tall) - 1);
|
|
1184
|
+
return pageRows(scrollRoom(this.partNamed('table'), { covered: this.headHeight() }), cell.getBoundingClientRect().height || this.estimate);
|
|
1212
1185
|
}
|
|
1213
1186
|
headHeight() {
|
|
1214
1187
|
return this.cellAt(-1, 0)?.getBoundingClientRect().height ?? 0;
|
|
@@ -33,8 +33,11 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
33
33
|
* @slot actions - Controls that act on the value, such as a copy button, after it inside its `<dd>`.
|
|
34
34
|
* @slot label - The label, when it is more than text. Falls back to `label`.
|
|
35
35
|
*
|
|
36
|
+
* @csspart actions - The box after the value inside its `<dd>`, holding the `actions` slot.
|
|
36
37
|
* @csspart label - The `<dt>`, holding the label.
|
|
37
38
|
* @csspart value - The `<dd>`, holding the value.
|
|
39
|
+
*
|
|
40
|
+
* @cssstate several - The values are several `<dd>` elements of your own, so the item draws no `value` part.
|
|
38
41
|
*/
|
|
39
42
|
export declare class HelixHeadlessDescriptionListItem extends HelixElement {
|
|
40
43
|
/**
|
|
@@ -58,6 +61,7 @@ export declare class HelixHeadlessDescriptionListItem extends HelixElement {
|
|
|
58
61
|
*/
|
|
59
62
|
private get ownValues();
|
|
60
63
|
protected firstUpdated(changed: PropertyValues): void;
|
|
64
|
+
protected updated(changed: PropertyValues): void;
|
|
61
65
|
protected render(): TemplateResult;
|
|
62
66
|
/** A value arriving or leaving can change whether the item wraps them. */
|
|
63
67
|
private readonly handleSlotChange;
|
|
@@ -23,12 +23,18 @@ let HelixHeadlessDescriptionListItem = class HelixHeadlessDescriptionListItem ex
|
|
|
23
23
|
super.firstUpdated(changed);
|
|
24
24
|
this.finishHydration();
|
|
25
25
|
}
|
|
26
|
+
updated(changed) {
|
|
27
|
+
super.updated(changed);
|
|
28
|
+
this.toggleState('several', this.ownValues);
|
|
29
|
+
}
|
|
26
30
|
render() {
|
|
27
31
|
const label = html `<dt part="label"><slot name="label">${this.label}</slot></dt>`;
|
|
28
32
|
return this.ownValues
|
|
29
33
|
? html `${label}<slot @slotchange=${this.handleSlotChange}></slot>`
|
|
30
34
|
: html `${label}
|
|
31
|
-
<dd part="value"><slot @slotchange=${this.handleSlotChange}></slot><
|
|
35
|
+
<dd part="value"><slot @slotchange=${this.handleSlotChange}></slot><span part="actions"
|
|
36
|
+
><slot name="actions"></slot></span
|
|
37
|
+
></dd>`;
|
|
32
38
|
}
|
|
33
39
|
};
|
|
34
40
|
__decorate([
|
|
@@ -9,12 +9,22 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
9
9
|
* rendered element. The semantics are then in the server-rendered markup, with
|
|
10
10
|
* no attribute written by script after the element connects.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* **The line is a separator**, as `<hr>` is, and as Radix Separator, React
|
|
13
|
+
* Aria Separator, and Web Awesome's divider are. It is named by any content
|
|
14
|
+
* set into it, so a screen reader says "Or, separator" where you wrote "Or" on
|
|
15
|
+
* the line. Set `decorative` on a rule that separates nothing, such as one
|
|
16
|
+
* under a heading or between the facts of a byline, and it leaves the
|
|
17
|
+
* accessibility tree.
|
|
14
18
|
*
|
|
15
|
-
* Use `orientation="vertical"` between items on one line
|
|
16
|
-
*
|
|
17
|
-
*
|
|
19
|
+
* Use `orientation="vertical"` between items on one line. A vertical divider
|
|
20
|
+
* stretches to fit its flex parent and sets no height of its own.
|
|
21
|
+
*
|
|
22
|
+
* **Inside a toolbar it runs across the toolbar** without being told: vertical
|
|
23
|
+
* in a horizontal toolbar and horizontal in a vertical one, with
|
|
24
|
+
* `aria-orientation` to match, as React Aria's separator does inside a
|
|
25
|
+
* toolbar. Inside means a child of Toolbar or of the page's own
|
|
26
|
+
* `role="toolbar"`. An `orientation` you write still wins. A server cannot see
|
|
27
|
+
* the toolbar, so the turn arrives with hydration, inside the shadow root.
|
|
18
28
|
*
|
|
19
29
|
* @since 0.1.0
|
|
20
30
|
* @status stable
|
|
@@ -26,27 +36,44 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
26
36
|
*
|
|
27
37
|
* @csspart content - The content set into the line.
|
|
28
38
|
* @csspart line - The line, or each half of it when content is set into it.
|
|
39
|
+
*
|
|
40
|
+
* @cssstate vertical - The line runs vertically: `orientation="vertical"`, or no `orientation` inside a horizontal toolbar.
|
|
29
41
|
*/
|
|
30
42
|
export declare class HelixHeadlessDivider extends HelixElement {
|
|
31
43
|
/**
|
|
32
|
-
* Whether screen readers announce the line as a separator
|
|
33
|
-
*
|
|
34
|
-
* Off by default, and out of the accessibility tree. Most rules on a page
|
|
35
|
-
* separate nothing: they underline a heading or close a section that space
|
|
36
|
-
* had already closed, and announcing every one as a separator is noise a
|
|
37
|
-
* screen-reader user has to walk past.
|
|
44
|
+
* Whether screen readers announce the line as a separator, which they now do
|
|
45
|
+
* by default.
|
|
38
46
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* property. An opt-in is absent by default, which every reflected property
|
|
43
|
-
* here has to be.
|
|
47
|
+
* It dates from when the line was decorative by default. It is still read,
|
|
48
|
+
* and it wins over `decorative`, so a divider written with it stays a
|
|
49
|
+
* separator.
|
|
44
50
|
*/
|
|
45
51
|
announced: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Takes the line out of the accessibility tree, for a rule that separates
|
|
54
|
+
* nothing: one under a heading, or between the facts of a byline.
|
|
55
|
+
*
|
|
56
|
+
* Absent, the line is a separator, as `<hr>` is. Radix Separator's opt-out
|
|
57
|
+
* has the same name. It turns the role off because a boolean attribute that
|
|
58
|
+
* is on by default cannot be turned off from HTML.
|
|
59
|
+
*/
|
|
60
|
+
decorative: boolean;
|
|
46
61
|
/**
|
|
47
62
|
* The direction the line runs: `horizontal` or `vertical`.
|
|
63
|
+
*
|
|
64
|
+
* Unset is horizontal, or across the toolbar the divider sits in.
|
|
48
65
|
*/
|
|
49
66
|
orientation?: 'horizontal' | 'vertical';
|
|
67
|
+
/**
|
|
68
|
+
* The direction the line is drawn and announced in: `orientation`, else
|
|
69
|
+
* across the toolbar around it, else horizontal.
|
|
70
|
+
*
|
|
71
|
+
* The toolbar is read only where the tree is known, never while hydrating
|
|
72
|
+
* what a server sent, whose render has to be the server's.
|
|
73
|
+
*/
|
|
74
|
+
private get drawn();
|
|
75
|
+
/** Reads the toolbar again when the divider moves into or out of one. */
|
|
76
|
+
connectedCallback(): void;
|
|
50
77
|
/**
|
|
51
78
|
* Marks the middle region when nothing has been set into it.
|
|
52
79
|
*
|
|
@@ -59,6 +86,8 @@ export declare class HelixHeadlessDivider extends HelixElement {
|
|
|
59
86
|
* attribute written onto the host is a change to markup the consumer rendered.
|
|
60
87
|
*/
|
|
61
88
|
private markEmpty;
|
|
89
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
90
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
62
91
|
protected updated(changed: PropertyValues): void;
|
|
63
92
|
protected render(): TemplateResult;
|
|
64
93
|
}
|
|
@@ -4,27 +4,48 @@ 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, markRegion } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixElement, markRegion, toolbarAround, toolbarAxis, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessDivider = class HelixHeadlessDivider extends HelixElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.announced = false;
|
|
14
|
+
this.decorative = false;
|
|
15
|
+
}
|
|
16
|
+
get drawn() {
|
|
17
|
+
const toolbar = this.orientation || this.hydrating ? null : toolbarAround(this);
|
|
18
|
+
if (toolbar) {
|
|
19
|
+
return toolbarAxis(toolbar) === 'vertical' ? 'horizontal' : 'vertical';
|
|
20
|
+
}
|
|
21
|
+
return this.orientation ?? 'horizontal';
|
|
22
|
+
}
|
|
23
|
+
connectedCallback() {
|
|
24
|
+
super.connectedCallback();
|
|
25
|
+
this.requestUpdate();
|
|
14
26
|
}
|
|
15
27
|
markEmpty() {
|
|
16
28
|
markRegion(this.renderRoot, 'content', ['']);
|
|
17
29
|
}
|
|
30
|
+
willUpdate(changed) {
|
|
31
|
+
super.willUpdate(changed);
|
|
32
|
+
this.toggleState('vertical', this.drawn === 'vertical');
|
|
33
|
+
}
|
|
34
|
+
firstUpdated(changed) {
|
|
35
|
+
super.firstUpdated(changed);
|
|
36
|
+
this.finishHydration();
|
|
37
|
+
}
|
|
18
38
|
updated(changed) {
|
|
19
39
|
super.updated(changed);
|
|
20
40
|
this.markEmpty();
|
|
21
41
|
}
|
|
22
42
|
render() {
|
|
43
|
+
const separator = this.announced || !this.decorative;
|
|
23
44
|
return html `<div
|
|
24
45
|
part="line"
|
|
25
|
-
role=${
|
|
26
|
-
aria-labelledby=${
|
|
27
|
-
aria-orientation=${
|
|
46
|
+
role=${separator ? 'separator' : 'presentation'}
|
|
47
|
+
aria-labelledby=${separator ? 'content' : nothing}
|
|
48
|
+
aria-orientation=${separator ? this.drawn : nothing}
|
|
28
49
|
></div>
|
|
29
50
|
<span id="content" part="content"><slot @slotchange=${() => this.markEmpty()}></slot></span>
|
|
30
51
|
<div part="line" role="presentation"></div>`;
|
|
@@ -33,6 +54,9 @@ let HelixHeadlessDivider = class HelixHeadlessDivider extends HelixElement {
|
|
|
33
54
|
__decorate([
|
|
34
55
|
property({ reflect: true, type: Boolean })
|
|
35
56
|
], HelixHeadlessDivider.prototype, "announced", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
property({ reflect: true, type: Boolean })
|
|
59
|
+
], HelixHeadlessDivider.prototype, "decorative", void 0);
|
|
36
60
|
__decorate([
|
|
37
61
|
property({ reflect: true })
|
|
38
62
|
], HelixHeadlessDivider.prototype, "orientation", void 0);
|
|
@@ -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, deepActiveElement, HelixElement, HelixSelectEvent, slotFilled, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, deepActiveElement, HelixElement, HelixSelectEvent, slotFilled, slotNamed, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { caretRight } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -27,9 +27,8 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
|
|
|
27
27
|
this.page = (slot?.assignedElements().length ?? 0) > 0;
|
|
28
28
|
};
|
|
29
29
|
this.readWords = () => {
|
|
30
|
-
|
|
31
|
-
this.
|
|
32
|
-
this.end = slotFilled(slot('end'));
|
|
30
|
+
this.description = slotFilled(slotNamed(this.renderRoot, 'description'));
|
|
31
|
+
this.end = slotFilled(slotNamed(this.renderRoot, 'end'));
|
|
33
32
|
};
|
|
34
33
|
}
|
|
35
34
|
willUpdate(changed) {
|
|
@@ -5,6 +5,7 @@ registerElementEvents({
|
|
|
5
5
|
'helix-headless-app-header': ['helix-scrolled'],
|
|
6
6
|
'helix-headless-avatar': ['error', 'load'],
|
|
7
7
|
'helix-headless-button': ['helix-press'],
|
|
8
|
+
'helix-headless-button-group': ['change', 'helix-before-change'],
|
|
8
9
|
'helix-headless-callout': ['helix-dismiss'],
|
|
9
10
|
'helix-headless-canvas': [
|
|
10
11
|
'helix-before-move',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArrivalController, HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
/**
|
|
4
4
|
* @summary A message that a region has nothing in it, and the next step to take.
|
|
5
5
|
*
|
|
@@ -24,6 +24,13 @@ import { type TemplateResult } from 'lit';
|
|
|
24
24
|
* rendering from data or on a server gets a heading a reader finds in the
|
|
25
25
|
* outline without writing the element. A heading slotted in replaces it.
|
|
26
26
|
*
|
|
27
|
+
* **Whatever is slotted into `heading` is read as a heading.** An element that
|
|
28
|
+
* is no heading, such as a `<span>` or a `<p>`, is set inside the `heading`
|
|
29
|
+
* part at `heading-level`, so a screen reader still finds it in the outline.
|
|
30
|
+
* A heading element, or an element holding one, keeps its own level. A server
|
|
31
|
+
* cannot see the slotted element, so a served `<span>` becomes a heading once
|
|
32
|
+
* the script runs.
|
|
33
|
+
*
|
|
27
34
|
* @since 0.1.0
|
|
28
35
|
* @status stable
|
|
29
36
|
* @category feedback
|
|
@@ -32,10 +39,10 @@ import { type TemplateResult } from 'lit';
|
|
|
32
39
|
*
|
|
33
40
|
* @slot - The message: why the region is empty, and what to do about it.
|
|
34
41
|
* @slot actions - The action that would put something in the region.
|
|
35
|
-
* @slot heading - The heading, which names what is missing.
|
|
42
|
+
* @slot heading - The heading, which names what is missing. A heading element, such as an `<h3>`, keeps its level; any other element is read as a heading at `heading-level`. Replaces the one `heading` draws.
|
|
36
43
|
* @slot icon - An icon above the heading.
|
|
37
44
|
*
|
|
38
|
-
* @csspart heading - The heading
|
|
45
|
+
* @csspart heading - The heading at `heading-level`: the one `heading` draws while nothing is slotted into `heading`, or the one around a slotted element that is no heading.
|
|
39
46
|
* @csspart live - A copy of the heading and the message, in a live region that screen readers announce when the view appears. Visually hidden in the styled tier.
|
|
40
47
|
*/
|
|
41
48
|
export declare class HelixHeadlessEmpty extends HelixElement {
|
|
@@ -61,6 +68,13 @@ export declare class HelixHeadlessEmpty extends HelixElement {
|
|
|
61
68
|
* has nothing to announce because nothing changed.
|
|
62
69
|
*/
|
|
63
70
|
noAnnounce: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the `heading` slot holds elements and none of them is or holds a
|
|
73
|
+
* heading, read from the children before each render.
|
|
74
|
+
*/
|
|
75
|
+
private looseHeading;
|
|
76
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
77
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
64
78
|
protected readonly arrival: ArrivalController;
|
|
65
79
|
/**
|
|
66
80
|
* The `heading` slot, with the heading `heading` draws as its fallback, so
|
|
@@ -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 { ArrivalController, customElement, HelixElement, headingLevel, slottedWords, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { ArrivalController, customElement, HelixElement, headingIn, headingLevel, slottedWords, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
|
|
@@ -12,6 +12,7 @@ let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
|
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.heading = '';
|
|
14
14
|
this.noAnnounce = false;
|
|
15
|
+
this.looseHeading = false;
|
|
15
16
|
this.arrival = new ArrivalController(this, {
|
|
16
17
|
arriving: () => !this.serverRendered && document.readyState === 'complete',
|
|
17
18
|
text: () => [slottedWords(this, ['heading']) || this.heading.trim(), slottedWords(this, [''])]
|
|
@@ -19,17 +20,40 @@ let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
|
|
|
19
20
|
.join(' '),
|
|
20
21
|
});
|
|
21
22
|
}
|
|
23
|
+
willUpdate(changed) {
|
|
24
|
+
super.willUpdate(changed);
|
|
25
|
+
if (this.childrenKnown) {
|
|
26
|
+
const slotted = this.knownChildren.filter((child) => child.slot === 'heading');
|
|
27
|
+
this.looseHeading = slotted.length > 0 && headingIn(slotted) === null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
firstUpdated(changed) {
|
|
31
|
+
super.firstUpdated(changed);
|
|
32
|
+
this.finishHydration();
|
|
33
|
+
}
|
|
22
34
|
renderHeading(hidden) {
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
const level = headingLevel(this.headingLevel);
|
|
36
|
+
const slot = html `<slot
|
|
37
|
+
aria-hidden=${hidden && !this.looseHeading ? 'true' : nothing}
|
|
25
38
|
name="heading"
|
|
26
|
-
@slotchange=${() =>
|
|
39
|
+
@slotchange=${() => {
|
|
40
|
+
this.arrival.say();
|
|
41
|
+
this.requestUpdate();
|
|
42
|
+
}}
|
|
27
43
|
>${this.heading.trim()
|
|
28
|
-
? html `<div aria-level=${
|
|
44
|
+
? html `<div aria-level=${level} part="heading" role="heading">
|
|
29
45
|
${this.heading}
|
|
30
46
|
</div>`
|
|
31
47
|
: nothing}</slot
|
|
32
48
|
>`;
|
|
49
|
+
return this.looseHeading
|
|
50
|
+
? html `<div
|
|
51
|
+
aria-hidden=${hidden ? 'true' : nothing}
|
|
52
|
+
aria-level=${level}
|
|
53
|
+
part="heading"
|
|
54
|
+
role="heading"
|
|
55
|
+
>${slot}</div>`
|
|
56
|
+
: slot;
|
|
33
57
|
}
|
|
34
58
|
render() {
|
|
35
59
|
const say = () => this.arrival.say();
|