@fusion.dev/helix-headless 0.182.2 → 0.184.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 +625 -90
- package/dist/bar-chart/root/bar-chart-root.d.ts +1 -0
- package/dist/bar-chart/root/bar-chart-root.js +3 -2
- package/dist/code-block/root/code-block-root.d.ts +42 -1
- package/dist/code-block/root/code-block-root.js +25 -4
- package/dist/heatmap/root/heatmap-root.d.ts +11 -1
- package/dist/heatmap/root/heatmap-root.js +17 -9
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/menu/filter/index.d.ts +1 -0
- package/dist/menu/filter/index.js +4 -0
- package/dist/menu/filter/menu-filter.d.ts +114 -0
- package/dist/menu/filter/menu-filter.js +172 -0
- package/dist/menu/root/menu-root.d.ts +28 -29
- package/dist/menu/root/menu-root.js +32 -107
- package/dist/time-input/root/time-input-root.d.ts +11 -0
- package/dist/time-input/root/time-input-root.js +11 -0
- package/dist/virtual-list/reorder/virtual-list-reorder.js +5 -1
- package/dist/virtual-list/root/virtual-list-root.d.ts +95 -17
- package/dist/virtual-list/root/virtual-list-root.js +123 -28
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +232 -30
- package/types/vue.d.ts +38 -7
- package/types/words.d.ts +7 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { AriaForwardController, anchorAt, commaList, customElement, elementById, HelixElement, HelixLoadMoreEvent, HelixRangeChangeEvent, inRowOrder, isRtl, pressedOwnControl, rangeAdd, requestValue, SCROLLER_RULE, searchableById, selectsAll, Typeahead, toggleValue, typesCharacter, VIRTUAL_RULE, VirtualizeController, words, } from '@fusion.dev/helix-core';
|
|
2
|
+
import { AriaForwardController, anchorAt, commaList, customElement, elementById, HelixElement, HelixLoadMoreEvent, HelixRangeChangeEvent, inRowOrder, isRtl, pressedOwnControl, rangeAdd, requestValue, SCROLLER_RULE, searchableById, selectsAll, Typeahead, toggleValue, typesCharacter, VIRTUAL_RULE, VirtualizeController, Waterfall, words, } from '@fusion.dev/helix-core';
|
|
3
3
|
import { html, nothing, render } from 'lit';
|
|
4
4
|
import { property, state } from 'lit/decorators.js';
|
|
5
5
|
import { holdControls, releaseControls } from '../controls.js';
|
|
@@ -13,6 +13,7 @@ const nextSectionId = () => {
|
|
|
13
13
|
return `virtual-list-${sectionCount}`;
|
|
14
14
|
};
|
|
15
15
|
const ROWS = ':scope > [data-index], :scope > [data-section] > [data-index]';
|
|
16
|
+
const LINE = 'helix-line-';
|
|
16
17
|
let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixElement {
|
|
17
18
|
constructor() {
|
|
18
19
|
super(...arguments);
|
|
@@ -24,6 +25,7 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
24
25
|
this.gap = 0;
|
|
25
26
|
this.keyField = '';
|
|
26
27
|
this.label = '';
|
|
28
|
+
this.layout = 'grid';
|
|
27
29
|
this.loading = false;
|
|
28
30
|
this.loadingLabel = 'Loading more';
|
|
29
31
|
this.measured = false;
|
|
@@ -54,7 +56,12 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
54
56
|
horizontal: () => this.horizontal,
|
|
55
57
|
measured: () => this.measured,
|
|
56
58
|
rows: () => this.lines(),
|
|
59
|
+
waterfall: () => {
|
|
60
|
+
this.lanes.lanes = this.columnCount;
|
|
61
|
+
return this.waterfall ? this.lanes : undefined;
|
|
62
|
+
},
|
|
57
63
|
});
|
|
64
|
+
this.lanes = new Waterfall();
|
|
58
65
|
this.boxWidth = 0;
|
|
59
66
|
this.measuredAcross = 1;
|
|
60
67
|
this.handleKeydown = (event) => {
|
|
@@ -97,7 +104,9 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
97
104
|
}
|
|
98
105
|
}
|
|
99
106
|
const extend = event.shiftKey && this.selectionMode === 'multiple';
|
|
100
|
-
|
|
107
|
+
const ends = event.key === 'Home' || event.key === 'End';
|
|
108
|
+
const lined = this.lined;
|
|
109
|
+
if (event.altKey || (toggle && !replacing && !(lined && ends)) || (event.shiftKey && !extend)) {
|
|
101
110
|
return;
|
|
102
111
|
}
|
|
103
112
|
const count = this.data.length;
|
|
@@ -112,13 +121,19 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
112
121
|
: event.key === 'ArrowDown' || event.key === 'ArrowUp'
|
|
113
122
|
? ''
|
|
114
123
|
: event.key;
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
const disabled = (one) => this.isDisabled(one);
|
|
125
|
+
const across = this.across;
|
|
126
|
+
const start = at - (at % across);
|
|
127
|
+
const stepped = lined && ends && !toggle
|
|
128
|
+
? key === 'Home'
|
|
129
|
+
? start
|
|
130
|
+
: Math.min(start + across, count) - 1
|
|
131
|
+
: this.waterfall && !ends
|
|
132
|
+
? this.inWaterfall(key, at, count, forward)
|
|
133
|
+
: stepIndex(key, at, count, last - first - 1, { across, forward });
|
|
119
134
|
const next = stepped === undefined
|
|
120
135
|
? undefined
|
|
121
|
-
: skipDisabled(key, at, stepped, count,
|
|
136
|
+
: skipDisabled(key, at, stepped, count, disabled, this.waterfall ? 1 : across);
|
|
122
137
|
if (next === undefined) {
|
|
123
138
|
if (stepped !== undefined) {
|
|
124
139
|
event.preventDefault();
|
|
@@ -172,6 +187,8 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
172
187
|
this.requestUpdate();
|
|
173
188
|
};
|
|
174
189
|
this.visited = false;
|
|
190
|
+
this.placedWaterfall = false;
|
|
191
|
+
this.drawnLines = [];
|
|
175
192
|
this.sectionId = nextSectionId();
|
|
176
193
|
}
|
|
177
194
|
static { this.markRules = [SCROLLER_RULE, VIRTUAL_RULE]; }
|
|
@@ -182,7 +199,20 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
182
199
|
get space() {
|
|
183
200
|
return Number.isFinite(this.gap) && this.gap > 0 ? this.gap : 0;
|
|
184
201
|
}
|
|
202
|
+
get waterfall() {
|
|
203
|
+
return this.layout === 'waterfall';
|
|
204
|
+
}
|
|
205
|
+
get lined() {
|
|
206
|
+
return (!this.selectionMode &&
|
|
207
|
+
!this.waterfall &&
|
|
208
|
+
!this.horizontal &&
|
|
209
|
+
this.sections === undefined &&
|
|
210
|
+
(this.across > 1 || this.minColumnWidth > 0));
|
|
211
|
+
}
|
|
185
212
|
get across() {
|
|
213
|
+
return this.waterfall ? 1 : this.columnCount;
|
|
214
|
+
}
|
|
215
|
+
get columnCount() {
|
|
186
216
|
if (this.minColumnWidth > 0 && this.boxWidth > 0) {
|
|
187
217
|
const space = this.space;
|
|
188
218
|
return Math.max(1, Math.floor((this.boxWidth + space) / (this.minColumnWidth + space)));
|
|
@@ -191,7 +221,9 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
191
221
|
}
|
|
192
222
|
watchWidth() {
|
|
193
223
|
const viewport = this.partNamed('viewport');
|
|
194
|
-
if (this.minColumnWidth <= 0
|
|
224
|
+
if ((this.minColumnWidth <= 0 && !this.waterfall) ||
|
|
225
|
+
!viewport ||
|
|
226
|
+
typeof ResizeObserver === 'undefined') {
|
|
195
227
|
this.widthWatch?.disconnect();
|
|
196
228
|
this.widthWatch = undefined;
|
|
197
229
|
return;
|
|
@@ -218,11 +250,11 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
218
250
|
return sections ? entryOf(sections, at) : Math.floor(at / this.across);
|
|
219
251
|
}
|
|
220
252
|
get horizontal() {
|
|
221
|
-
return this.orientation === 'horizontal' && this.across === 1;
|
|
253
|
+
return this.orientation === 'horizontal' && this.across === 1 && !this.waterfall;
|
|
222
254
|
}
|
|
223
255
|
get sections() {
|
|
224
256
|
const data = this.data;
|
|
225
|
-
if (this.sectionField === '' || data.length === 0 || this.
|
|
257
|
+
if (this.sectionField === '' || data.length === 0 || this.columnCount !== 1 || this.waterfall) {
|
|
226
258
|
return undefined;
|
|
227
259
|
}
|
|
228
260
|
const read = this.sectionsRead;
|
|
@@ -275,7 +307,7 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
275
307
|
this.readFor = this.for;
|
|
276
308
|
this.read();
|
|
277
309
|
}
|
|
278
|
-
const across = this.across;
|
|
310
|
+
const across = this.waterfall ? `${this.columnCount} ${this.boxWidth}` : this.across;
|
|
279
311
|
if (across !== this.measuredAcross) {
|
|
280
312
|
this.measuredAcross = across;
|
|
281
313
|
this.virtualize.forget();
|
|
@@ -450,6 +482,16 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
450
482
|
rowFor(index) {
|
|
451
483
|
return ([...this.querySelectorAll(ROWS)].find((row) => row.dataset.index === String(index)) ?? null);
|
|
452
484
|
}
|
|
485
|
+
inWaterfall(key, at, count, forward) {
|
|
486
|
+
const way = key === forward ? 'next' : key === 'ArrowLeft' || key === 'ArrowRight' ? 'previous' : key;
|
|
487
|
+
const box = this.partNamed('viewport');
|
|
488
|
+
let to = this.lanes.step(way, at, count, box?.clientHeight ?? 0);
|
|
489
|
+
const again = way === 'PageDown' ? 'ArrowDown' : way === 'PageUp' ? 'ArrowUp' : way;
|
|
490
|
+
while (to !== undefined && this.isDisabled(to)) {
|
|
491
|
+
to = this.lanes.step(again, to, count, 0);
|
|
492
|
+
}
|
|
493
|
+
return to;
|
|
494
|
+
}
|
|
453
495
|
keyAt(at) {
|
|
454
496
|
return keyOf(this.data[at], at, this.keyField);
|
|
455
497
|
}
|
|
@@ -530,7 +572,22 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
530
572
|
: undefined;
|
|
531
573
|
}
|
|
532
574
|
mark(element, at, chosen, off) {
|
|
533
|
-
|
|
575
|
+
const lined = this.lined;
|
|
576
|
+
element.setAttribute('role', this.selectionMode ? 'option' : lined ? 'gridcell' : 'listitem');
|
|
577
|
+
const across = this.across;
|
|
578
|
+
for (const [name, value] of [
|
|
579
|
+
['aria-colindex', lined ? (at % across) + 1 : undefined],
|
|
580
|
+
['aria-posinset', lined ? undefined : at + 1],
|
|
581
|
+
['aria-setsize', lined ? undefined : this.data.length],
|
|
582
|
+
['slot', lined ? `${LINE}${Math.floor(at / across)}` : undefined],
|
|
583
|
+
]) {
|
|
584
|
+
if (value === undefined) {
|
|
585
|
+
element.removeAttribute(name);
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
element.setAttribute(name, String(value));
|
|
589
|
+
}
|
|
590
|
+
}
|
|
534
591
|
const selected = Boolean(this.selectionMode) && chosen.has(this.keyAt(at));
|
|
535
592
|
if (this.selectionMode) {
|
|
536
593
|
element.setAttribute('aria-selected', String(selected));
|
|
@@ -549,8 +606,6 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
549
606
|
element.toggleAttribute('data-disabled', disabled);
|
|
550
607
|
}
|
|
551
608
|
stamp(element, at) {
|
|
552
|
-
element.setAttribute('aria-posinset', String(at + 1));
|
|
553
|
-
element.setAttribute('aria-setsize', String(this.data.length));
|
|
554
609
|
element.setAttribute('data-index', String(at));
|
|
555
610
|
}
|
|
556
611
|
fill(elements, at) {
|
|
@@ -595,12 +650,13 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
595
650
|
this.partNamed('after')?.style.setProperty(size, `${spacers.after}px`);
|
|
596
651
|
}
|
|
597
652
|
const sections = this.sections;
|
|
598
|
-
const regroup = sections !== this.placedSections;
|
|
653
|
+
const regroup = sections !== this.placedSections || this.waterfall !== this.placedWaterfall;
|
|
599
654
|
this.placedSections = sections;
|
|
655
|
+
this.placedWaterfall = this.waterfall;
|
|
600
656
|
const children = [
|
|
601
657
|
...[...this.children].filter((child) => child !== template &&
|
|
602
658
|
child instanceof HTMLElement &&
|
|
603
|
-
!child.hasAttribute('slot') &&
|
|
659
|
+
(child.dataset.index !== undefined || !child.hasAttribute('slot')) &&
|
|
604
660
|
!child.hasAttribute('data-section')),
|
|
605
661
|
...this.querySelectorAll(':scope > [data-section] > [data-index]'),
|
|
606
662
|
];
|
|
@@ -660,9 +716,23 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
660
716
|
});
|
|
661
717
|
const chosen = this.chosen;
|
|
662
718
|
const off = this.disabled;
|
|
719
|
+
const lines = this.lined ? [...new Set(plan.wanted.map((at) => this.lineOf(at)))] : [];
|
|
720
|
+
if (lines.join() !== this.drawnLines.join()) {
|
|
721
|
+
this.drawnLines = lines;
|
|
722
|
+
this.requestUpdate();
|
|
723
|
+
}
|
|
724
|
+
const gap = this.space;
|
|
725
|
+
const columns = this.columnCount;
|
|
663
726
|
for (const [at, group] of drawn) {
|
|
664
727
|
for (const element of group) {
|
|
665
728
|
this.mark(element, at, chosen, off);
|
|
729
|
+
if (this.waterfall) {
|
|
730
|
+
const style = element.style;
|
|
731
|
+
style.setProperty('position', 'absolute');
|
|
732
|
+
style.setProperty('inset-block-start', `${this.virtualize.offsetOf(at)}px`);
|
|
733
|
+
style.setProperty('inset-inline-start', `calc((100% + ${gap}px) * ${this.lanes.lane(at)} / ${columns})`);
|
|
734
|
+
style.setProperty('inline-size', `calc((100% - ${gap * (columns - 1)}px) / ${columns})`);
|
|
735
|
+
}
|
|
666
736
|
}
|
|
667
737
|
const stop = at === this.active;
|
|
668
738
|
group[0]?.setAttribute('tabindex', stop ? '0' : '-1');
|
|
@@ -745,6 +815,9 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
745
815
|
return groups;
|
|
746
816
|
}
|
|
747
817
|
spacerSizes() {
|
|
818
|
+
if (this.waterfall) {
|
|
819
|
+
return { after: 0, before: 0 };
|
|
820
|
+
}
|
|
748
821
|
const kept = this.hasUpdated ? this.keptIndex() : undefined;
|
|
749
822
|
const room = this.virtualize.spacers(kept === undefined ? undefined : this.lineOf(kept));
|
|
750
823
|
const sections = this.sections;
|
|
@@ -779,14 +852,20 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
779
852
|
const size = horizontal ? 'inline-size' : 'block-size';
|
|
780
853
|
const flex = horizontal ? '; flex: none' : '';
|
|
781
854
|
const gap = this.space;
|
|
855
|
+
const grid = gap === 0 ? '' : `; gap: ${gap}px; padding-block-end: ${gap}px`;
|
|
782
856
|
const empty = this.readFor !== undefined &&
|
|
783
857
|
!this.loading &&
|
|
784
858
|
this.data.length === 0 &&
|
|
785
859
|
(this.emptyLabel !== '' || this.querySelector(':scope > [slot="empty"]') !== null);
|
|
860
|
+
const lined = this.lined;
|
|
861
|
+
const own = (content) => lined ? html `<div role="gridcell">${content}</div>` : content;
|
|
862
|
+
const role = this.selectionMode ? 'option' : lined ? 'row' : 'listitem';
|
|
786
863
|
return html `<div
|
|
787
864
|
data-scroller
|
|
788
865
|
part="viewport"
|
|
789
|
-
role=${this.selectionMode ? 'listbox' : 'list'}
|
|
866
|
+
role=${this.selectionMode ? 'listbox' : lined ? 'grid' : 'list'}
|
|
867
|
+
aria-colcount=${lined ? across : nothing}
|
|
868
|
+
aria-rowcount=${lined ? Math.ceil(this.data.length / across) : nothing}
|
|
790
869
|
aria-multiselectable=${this.selectionMode === 'multiple' ? 'true' : nothing}
|
|
791
870
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
792
871
|
aria-label=${this.label}
|
|
@@ -798,24 +877,37 @@ let HelixHeadlessVirtualList = class HelixHeadlessVirtualList extends HelixEleme
|
|
|
798
877
|
}}
|
|
799
878
|
>
|
|
800
879
|
<div part="before" style="${size}: ${before}px${flex}"></div>
|
|
880
|
+
${lined
|
|
881
|
+
? html `<div style=${`display: grid; grid-template-columns: repeat(${across}, minmax(0, 1fr))${grid}`}>
|
|
882
|
+
${this.drawnLines.map((line) => html `<div
|
|
883
|
+
aria-rowindex=${line + 1}
|
|
884
|
+
role="row"
|
|
885
|
+
style="display: grid; grid-column: 1 / -1; grid-template-columns: subgrid"
|
|
886
|
+
>
|
|
887
|
+
<slot name=${`${LINE}${line}`}></slot>
|
|
888
|
+
</div>`)}
|
|
889
|
+
</div>`
|
|
890
|
+
: nothing}
|
|
801
891
|
<slot
|
|
802
|
-
style=${
|
|
803
|
-
? `display:
|
|
804
|
-
:
|
|
805
|
-
? gap === 0
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
892
|
+
style=${this.waterfall
|
|
893
|
+
? `display: block; position: relative; block-size: ${this.virtualize.offsetOf(this.data.length)}px`
|
|
894
|
+
: horizontal
|
|
895
|
+
? `display: flex; flex: none${gap === 0 ? '' : `; column-gap: ${gap}px; padding-inline-end: ${gap}px`}`
|
|
896
|
+
: across === 1 || lined
|
|
897
|
+
? gap === 0
|
|
898
|
+
? nothing
|
|
899
|
+
: `display: flex; flex-direction: column; row-gap: ${gap}px; padding-block-end: ${gap}px`
|
|
900
|
+
: `display: grid; grid-template-columns: repeat(${across}, minmax(0, 1fr))${grid}`}
|
|
809
901
|
></slot>
|
|
810
902
|
<div part="after" style="${size}: ${after}px${flex}"></div>
|
|
811
903
|
${this.loading
|
|
812
|
-
? html `<div part="loading" role=${
|
|
813
|
-
|
|
904
|
+
? html `<div part="loading" role=${role}>
|
|
905
|
+
${own(html `<slot name="loading">${this.loadingLabel}</slot>`)}
|
|
814
906
|
</div>`
|
|
815
907
|
: nothing}
|
|
816
908
|
${empty
|
|
817
|
-
? html `<div part="empty" role=${
|
|
818
|
-
|
|
909
|
+
? html `<div part="empty" role=${role}>
|
|
910
|
+
${own(html `<slot name="empty">${this.emptyLabel}</slot>`)}
|
|
819
911
|
</div>`
|
|
820
912
|
: nothing}
|
|
821
913
|
</div>`;
|
|
@@ -848,6 +940,9 @@ __decorate([
|
|
|
848
940
|
__decorate([
|
|
849
941
|
property()
|
|
850
942
|
], HelixHeadlessVirtualList.prototype, "label", void 0);
|
|
943
|
+
__decorate([
|
|
944
|
+
property()
|
|
945
|
+
], HelixHeadlessVirtualList.prototype, "layout", void 0);
|
|
851
946
|
__decorate([
|
|
852
947
|
property({ type: Boolean })
|
|
853
948
|
], HelixHeadlessVirtualList.prototype, "loading", void 0);
|