@fusion.dev/helix-headless 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +236 -29
- package/dist/data-table/root/data-table-root.d.ts +138 -28
- package/dist/data-table/root/data-table-root.js +110 -21
- package/dist/data-table/root/order.d.ts +25 -0
- package/dist/data-table/root/order.js +6 -3
- package/package.json +5 -5
- package/types/jsx.d.ts +154 -50
- package/types/vue.d.ts +40 -14
|
@@ -5,13 +5,13 @@ 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 { customElement, HelixElement, HelixFilterEvent, HelixNavigateEvent, HelixSortEvent, hostAria, MixinCollection, requestChange, slotFilled, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { customElement, HelixElement, HelixFilterEvent, HelixNavigateEvent, HelixSortEvent, hostAria, MixinCollection, requestChange, slotFilled, VirtualizeController, } from '@fusion.dev/helix-core';
|
|
9
9
|
import { nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { repeat } from 'lit/directives/repeat.js';
|
|
12
12
|
import { html } from 'lit/static-html.js';
|
|
13
13
|
import '../../pagination/index.js';
|
|
14
|
-
import { cycle, format, ordered, parse } from './order.js';
|
|
14
|
+
import { arranged, cycle, format, ordered, parse, window_, } from './order.js';
|
|
15
15
|
let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollection(HelixElement) {
|
|
16
16
|
constructor() {
|
|
17
17
|
super(...arguments);
|
|
@@ -19,20 +19,35 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
19
19
|
this.defaultPage = 1;
|
|
20
20
|
this.defaultPageSize = 0;
|
|
21
21
|
this.defaultSort = '';
|
|
22
|
+
this.estimate = 32;
|
|
22
23
|
this.key = '';
|
|
23
24
|
this.label = '';
|
|
24
25
|
this.mode = 'client';
|
|
25
26
|
this.rows = [];
|
|
26
27
|
this.total = 0;
|
|
28
|
+
this.windowed = false;
|
|
27
29
|
this.sortState = undefined;
|
|
28
30
|
this.filterState = undefined;
|
|
29
31
|
this.pageState = undefined;
|
|
30
32
|
this.pageSizeState = undefined;
|
|
31
33
|
this.paginatedState = undefined;
|
|
34
|
+
this.virtualize = new VirtualizeController(this, {
|
|
35
|
+
container: () => this.windowed ? this.renderRoot.querySelector('[part="table"]') : null,
|
|
36
|
+
count: () => this.available,
|
|
37
|
+
estimate: () => this.estimate,
|
|
38
|
+
measured: () => this.windowed,
|
|
39
|
+
rows: () => (this.windowed ? this.drawn() : []),
|
|
40
|
+
});
|
|
32
41
|
this.warnedAboutSize = false;
|
|
33
42
|
this.handleSlotChange = () => {
|
|
34
43
|
this.requestUpdate();
|
|
35
44
|
};
|
|
45
|
+
this.measuredAgainst = '';
|
|
46
|
+
this.handleScroll = () => {
|
|
47
|
+
if (this.windowed) {
|
|
48
|
+
this.virtualize.measure();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
36
51
|
this.handleHeadClick = (event) => {
|
|
37
52
|
const column = this.columnFrom(event);
|
|
38
53
|
if (column?.canSort) {
|
|
@@ -103,6 +118,37 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
103
118
|
this.paginatedState = next;
|
|
104
119
|
this.requestUpdate('paginated', previous);
|
|
105
120
|
}
|
|
121
|
+
drawn() {
|
|
122
|
+
return [...this.renderRoot.querySelectorAll('[part="row"][data-index]')].map((element) => ({ element, index: Number(element.dataset.index) }));
|
|
123
|
+
}
|
|
124
|
+
get available() {
|
|
125
|
+
if (this.mode === 'server') {
|
|
126
|
+
return this.rows.length;
|
|
127
|
+
}
|
|
128
|
+
const matched = this.windowed ? this.arrange().rows.length : this.matched;
|
|
129
|
+
const size = this.pageSize;
|
|
130
|
+
if (size <= 0) {
|
|
131
|
+
return matched;
|
|
132
|
+
}
|
|
133
|
+
return Math.max(0, Math.min(size, matched - (this.page - 1) * size));
|
|
134
|
+
}
|
|
135
|
+
arrange() {
|
|
136
|
+
const axes = this.axes;
|
|
137
|
+
const key = `${this.filter}\u0000${this.sort}\u0000${axes.map((axis) => axis.field).join('\u0001')}`;
|
|
138
|
+
if (this.held?.key === key && this.held.source === this.rows) {
|
|
139
|
+
return this.held.value;
|
|
140
|
+
}
|
|
141
|
+
const value = arranged(this.rows, axes, { query: this.filter, spec: this.sort });
|
|
142
|
+
this.held = { key, source: this.rows, value };
|
|
143
|
+
return value;
|
|
144
|
+
}
|
|
145
|
+
windowOf(rows) {
|
|
146
|
+
if (!this.windowed) {
|
|
147
|
+
return rows;
|
|
148
|
+
}
|
|
149
|
+
const { first, last } = this.virtualize.window;
|
|
150
|
+
return rows.slice(first, last);
|
|
151
|
+
}
|
|
106
152
|
get tableColumns() {
|
|
107
153
|
return [...(this.children ?? [])].filter((child) => 'isTableColumn' in child && child.isTableColumn === true);
|
|
108
154
|
}
|
|
@@ -131,16 +177,26 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
131
177
|
get view() {
|
|
132
178
|
if (this.mode === 'server') {
|
|
133
179
|
const total = Math.max(this.total, this.rows.length);
|
|
134
|
-
return {
|
|
180
|
+
return {
|
|
181
|
+
available: this.rows.length,
|
|
182
|
+
matched: total,
|
|
183
|
+
rows: this.windowOf([...this.rows]),
|
|
184
|
+
total,
|
|
185
|
+
};
|
|
135
186
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
187
|
+
if (!this.windowed) {
|
|
188
|
+
const view = ordered(this.rows, this.axes, {
|
|
189
|
+
page: this.page,
|
|
190
|
+
query: this.filter,
|
|
191
|
+
size: this.pageSize,
|
|
192
|
+
spec: this.sort,
|
|
193
|
+
});
|
|
194
|
+
this.warnIfCrowded(view.rows.length);
|
|
195
|
+
return { ...view, available: view.rows.length };
|
|
196
|
+
}
|
|
197
|
+
const { rows: inOrder, total } = this.arrange();
|
|
198
|
+
const page = window_(inOrder, this.page, this.pageSize);
|
|
199
|
+
return { available: page.length, matched: inOrder.length, rows: this.windowOf(page), total };
|
|
144
200
|
}
|
|
145
201
|
get pages() {
|
|
146
202
|
const size = this.pageSize;
|
|
@@ -237,6 +293,11 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
237
293
|
willUpdate(changed) {
|
|
238
294
|
super.willUpdate(changed);
|
|
239
295
|
hostAria(this.internals, { label: this.label || 'Table', role: 'grid' });
|
|
296
|
+
const placement = this.placement;
|
|
297
|
+
if (changed.has('rows') || placement !== this.measuredAgainst) {
|
|
298
|
+
this.measuredAgainst = placement;
|
|
299
|
+
this.virtualize.forget();
|
|
300
|
+
}
|
|
240
301
|
}
|
|
241
302
|
markEmpty() {
|
|
242
303
|
this.markRegion('toolbar', ['toolbar']);
|
|
@@ -253,6 +314,9 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
253
314
|
this.markEmpty();
|
|
254
315
|
this.assign();
|
|
255
316
|
this.announceSort();
|
|
317
|
+
if (this.windowed) {
|
|
318
|
+
this.virtualize.measure();
|
|
319
|
+
}
|
|
256
320
|
}
|
|
257
321
|
announceSort() {
|
|
258
322
|
const current = parse(this.sort);
|
|
@@ -276,21 +340,38 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
276
340
|
renderRows(rows) {
|
|
277
341
|
const columns = this.tableColumns;
|
|
278
342
|
const field = this.key;
|
|
279
|
-
|
|
343
|
+
const start = this.windowStart;
|
|
344
|
+
return html `${repeat(rows, (row, index) => (field ? String(row[field] ?? start + index) : start + index), (row, index) => html `<div
|
|
280
345
|
part="row"
|
|
281
346
|
role="row"
|
|
282
347
|
aria-rowindex=${this.rowIndex(index)}
|
|
348
|
+
data-index=${this.windowed ? start + index : nothing}
|
|
283
349
|
>
|
|
284
350
|
${columns.map((column) => this.renderCell(column, row))}
|
|
285
351
|
</div>`)}`;
|
|
286
352
|
}
|
|
287
353
|
rowIndex(within) {
|
|
288
354
|
const size = this.pageSize;
|
|
289
|
-
const
|
|
290
|
-
return
|
|
355
|
+
const page = size > 0 ? (this.page - 1) * size : 0;
|
|
356
|
+
return page + this.windowStart + within + 2;
|
|
357
|
+
}
|
|
358
|
+
get placement() {
|
|
359
|
+
return [this.mode, this.filter, this.sort, this.page, this.pageSize].join('\u0000');
|
|
360
|
+
}
|
|
361
|
+
get windowStart() {
|
|
362
|
+
return this.windowed ? this.virtualize.window.first : 0;
|
|
363
|
+
}
|
|
364
|
+
renderSpacer(end) {
|
|
365
|
+
if (!this.windowed) {
|
|
366
|
+
return nothing;
|
|
367
|
+
}
|
|
368
|
+
const { after, before } = this.virtualize.window;
|
|
369
|
+
return end === 'before'
|
|
370
|
+
? html `<div part="before" role="presentation" style="block-size: ${before}px"></div>`
|
|
371
|
+
: html `<div part="after" role="presentation" style="block-size: ${after}px"></div>`;
|
|
291
372
|
}
|
|
292
373
|
render() {
|
|
293
|
-
const { matched, rows } = this.view;
|
|
374
|
+
const { available, matched, rows } = this.view;
|
|
294
375
|
const template = this.template;
|
|
295
376
|
const columns = this.tableColumns;
|
|
296
377
|
const pagination = this.tag('pagination');
|
|
@@ -299,14 +380,16 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
|
|
|
299
380
|
part="table"
|
|
300
381
|
role="rowgroup"
|
|
301
382
|
aria-busy=${this.loading ? 'true' : nothing}
|
|
302
|
-
aria-rowcount=${this.mode === 'server' ? Math.max(this.total,
|
|
383
|
+
aria-rowcount=${this.mode === 'server' ? Math.max(this.total, available) + 1 : matched + 1}
|
|
303
384
|
aria-colcount=${columns.length || nothing}
|
|
304
385
|
style=${template ? `--data-table-template: ${template}` : nothing}
|
|
386
|
+
@scroll=${this.handleScroll}
|
|
305
387
|
>
|
|
306
388
|
<div part="head" role="row">
|
|
307
389
|
<slot name="columns" @slotchange=${this.handleSlotChange}></slot>
|
|
308
390
|
</div>
|
|
309
|
-
${this.renderRows(rows)}
|
|
391
|
+
${this.renderSpacer('before')}${this.renderRows(rows)}${this.renderSpacer('after')}
|
|
392
|
+
${this.renderStatus(available > 0)}
|
|
310
393
|
</div>
|
|
311
394
|
<div part="footer">
|
|
312
395
|
<slot name="footer"></slot>
|
|
@@ -354,23 +437,26 @@ __decorate([
|
|
|
354
437
|
property({ attribute: 'default-sort' })
|
|
355
438
|
], HelixHeadlessDataTable.prototype, "defaultSort", void 0);
|
|
356
439
|
__decorate([
|
|
357
|
-
property()
|
|
358
|
-
], HelixHeadlessDataTable.prototype, "
|
|
440
|
+
property({ type: Number })
|
|
441
|
+
], HelixHeadlessDataTable.prototype, "estimate", void 0);
|
|
359
442
|
__decorate([
|
|
360
443
|
property()
|
|
361
444
|
], HelixHeadlessDataTable.prototype, "sort", null);
|
|
362
445
|
__decorate([
|
|
363
446
|
property()
|
|
364
|
-
], HelixHeadlessDataTable.prototype, "
|
|
447
|
+
], HelixHeadlessDataTable.prototype, "key", void 0);
|
|
365
448
|
__decorate([
|
|
366
449
|
property()
|
|
367
450
|
], HelixHeadlessDataTable.prototype, "filter", null);
|
|
368
451
|
__decorate([
|
|
369
452
|
property()
|
|
370
|
-
], HelixHeadlessDataTable.prototype, "
|
|
453
|
+
], HelixHeadlessDataTable.prototype, "label", void 0);
|
|
371
454
|
__decorate([
|
|
372
455
|
property({ type: Number })
|
|
373
456
|
], HelixHeadlessDataTable.prototype, "page", null);
|
|
457
|
+
__decorate([
|
|
458
|
+
property()
|
|
459
|
+
], HelixHeadlessDataTable.prototype, "mode", void 0);
|
|
374
460
|
__decorate([
|
|
375
461
|
property({ attribute: false })
|
|
376
462
|
], HelixHeadlessDataTable.prototype, "rows", void 0);
|
|
@@ -380,6 +466,9 @@ __decorate([
|
|
|
380
466
|
__decorate([
|
|
381
467
|
property({ type: Number })
|
|
382
468
|
], HelixHeadlessDataTable.prototype, "total", void 0);
|
|
469
|
+
__decorate([
|
|
470
|
+
property({ reflect: true, type: Boolean })
|
|
471
|
+
], HelixHeadlessDataTable.prototype, "windowed", void 0);
|
|
383
472
|
__decorate([
|
|
384
473
|
property({ type: Boolean })
|
|
385
474
|
], HelixHeadlessDataTable.prototype, "paginated", null);
|
|
@@ -92,6 +92,31 @@ export declare const sort: (rows: readonly DataRow[], spec: Sort | undefined, ax
|
|
|
92
92
|
* same clamp `helix-pagination` already applies to what it reports.
|
|
93
93
|
*/
|
|
94
94
|
export declare const window_: (rows: readonly DataRow[], page: number, size: number) => DataRow[];
|
|
95
|
+
/** What arranging produces: the rows in order, with no page or window taken. */
|
|
96
|
+
export interface Arranged {
|
|
97
|
+
/** Rows after filtering and sorting, in the order they are to be drawn. */
|
|
98
|
+
rows: DataRow[];
|
|
99
|
+
/** Rows before filtering, which is what tells a reader a filter is on. */
|
|
100
|
+
total: number;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Filtering and sorting, with nothing taken off the end.
|
|
104
|
+
*
|
|
105
|
+
* **Split out of `ordered` because a window moves and this does not.** A table
|
|
106
|
+
* drawing a window on a result re-renders every time a scroll reveals a row,
|
|
107
|
+
* and deriving that render from the whole result means filtering and sorting it
|
|
108
|
+
* again each time: 23.7ms at five thousand rows, a frame budget spent three
|
|
109
|
+
* times over before a cell is drawn. A caller that keeps this between renders
|
|
110
|
+
* pays it once per change to the data rather than once per frame.
|
|
111
|
+
*
|
|
112
|
+
* The two steps stay together for the reason `ordered` gives below: sorting a
|
|
113
|
+
* page is the classic bug, and one function doing both is what makes calling
|
|
114
|
+
* them in the wrong order impossible.
|
|
115
|
+
*/
|
|
116
|
+
export declare const arranged: (rows: readonly DataRow[], axes: readonly Axis[], { query, spec }: {
|
|
117
|
+
query: string;
|
|
118
|
+
spec: string;
|
|
119
|
+
}) => Arranged;
|
|
95
120
|
/** What one pass over the data produces: the window, and the counts around it. */
|
|
96
121
|
export interface Ordered {
|
|
97
122
|
/** Rows after filtering, before paging. The number a pagination must page. */
|
|
@@ -66,8 +66,11 @@ const compare = (left, right, sign) => {
|
|
|
66
66
|
}
|
|
67
67
|
return (sign * text(left).localeCompare(text(right), undefined, { numeric: true, sensitivity: 'base' }));
|
|
68
68
|
};
|
|
69
|
+
export const arranged = (rows, axes, { query, spec }) => ({
|
|
70
|
+
rows: sort(filter(rows, query, axes), parse(spec), axes),
|
|
71
|
+
total: rows.length,
|
|
72
|
+
});
|
|
69
73
|
export const ordered = (rows, axes, { page, query, size, spec }) => {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
return { matched: matched.length, rows: window_(arranged, page, size), total: rows.length };
|
|
74
|
+
const { rows: inOrder, total } = arranged(rows, axes, { query, spec });
|
|
75
|
+
return { matched: inOrder.length, rows: window_(inOrder, page, size), total };
|
|
73
76
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-headless",
|
|
3
3
|
"description": "Headless component tier. Structure, accessibility, state, and form participation. No styling.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
},
|
|
46
46
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@fusion.dev/helix-core": "0.
|
|
49
|
-
"@fusion.dev/helix-icons": "0.
|
|
48
|
+
"@fusion.dev/helix-core": "0.7.1",
|
|
49
|
+
"@fusion.dev/helix-icons": "0.7.1",
|
|
50
50
|
"uqr": "^0.1.3"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@custom-elements-manifest/analyzer": "^0.11.0",
|
|
54
|
-
"@fusion.dev/helix-cem": "0.
|
|
55
|
-
"@fusion.dev/helix-testing": "0.
|
|
54
|
+
"@fusion.dev/helix-cem": "0.7.1",
|
|
55
|
+
"@fusion.dev/helix-testing": "0.7.1",
|
|
56
56
|
"@fusion.dev/scripts": "0.0.0-dev",
|
|
57
57
|
"@happy-dom/global-registrator": "^20.0.0",
|
|
58
58
|
"@lit-labs/ssr": "^3.3.0",
|
package/types/jsx.d.ts
CHANGED
|
@@ -3838,6 +3838,20 @@ export type HelixHeadlessDataTableProps = {
|
|
|
3838
3838
|
"default-sort"?: (HelixHeadlessDataTable["defaultSort"]) | undefined;
|
|
3839
3839
|
/** Order to open on, where nothing declared one. */
|
|
3840
3840
|
defaultSort?: (HelixHeadlessDataTable["defaultSort"]) | undefined;
|
|
3841
|
+
/** How tall a row is taken to be before it has been drawn, in pixels.
|
|
3842
|
+
|
|
3843
|
+
Only read while `windowed`, and a starting guess rather than a claim: a
|
|
3844
|
+
cell that wraps makes its row taller than its neighbors, and the window
|
|
3845
|
+
replaces this with what each row came to as it draws. It still has to be
|
|
3846
|
+
close, because it is what the scrollbar is built from before anything has
|
|
3847
|
+
been measured. */
|
|
3848
|
+
estimate?: (HelixHeadlessDataTable["estimate"]) | undefined;
|
|
3849
|
+
/** The order, as `field:direction`.
|
|
3850
|
+
|
|
3851
|
+
Set it and this element defers: a reader's click fires `helix-sort` and
|
|
3852
|
+
changes nothing until a new value arrives. `default-sort` seeds an order this
|
|
3853
|
+
element then owns. */
|
|
3854
|
+
sort?: (HelixHeadlessDataTable["sort"]) | undefined;
|
|
3841
3855
|
/** The field naming a row's stable identity.
|
|
3842
3856
|
|
|
3843
3857
|
**Needed before selection exists, not after.** Lit keys the rendered rows by
|
|
@@ -3847,20 +3861,20 @@ attached to the row it belongs to. Left unset the index is the key, which is
|
|
|
3847
3861
|
correct only while nothing reorders: it is why this defaults to something
|
|
3848
3862
|
that works and is worth setting anyway. */
|
|
3849
3863
|
key?: (HelixHeadlessDataTable["key"]) | undefined;
|
|
3850
|
-
/** The order, as `field:direction`.
|
|
3851
|
-
|
|
3852
|
-
Set it and this element defers: a reader's click fires `helix-sort` and
|
|
3853
|
-
changes nothing until a new value arrives. `default-sort` seeds an order this
|
|
3854
|
-
element then owns. */
|
|
3855
|
-
sort?: (HelixHeadlessDataTable["sort"]) | undefined;
|
|
3856
|
-
/** Accessible name for the grid. */
|
|
3857
|
-
label?: (HelixHeadlessDataTable["label"]) | undefined;
|
|
3858
3864
|
/** What the rows are narrowed to, as one query across every column.
|
|
3859
3865
|
|
|
3860
3866
|
One query rather than a predicate per column, which is what a reader means
|
|
3861
3867
|
by a search box above a table. It matches on each column's ordering value,
|
|
3862
3868
|
so search and sort cannot disagree about what a column holds. */
|
|
3863
3869
|
filter?: (HelixHeadlessDataTable["filter"]) | undefined;
|
|
3870
|
+
/** Accessible name for the grid. */
|
|
3871
|
+
label?: (HelixHeadlessDataTable["label"]) | undefined;
|
|
3872
|
+
/** The page on show, from 1.
|
|
3873
|
+
|
|
3874
|
+
Clamped on the way out, so what this reports is the page it drew: a
|
|
3875
|
+
bookmarked link to page 99 of a result that has since shrunk reads back as
|
|
3876
|
+
the last page rather than as 99. */
|
|
3877
|
+
page?: (HelixHeadlessDataTable["page"]) | undefined;
|
|
3864
3878
|
/** Whether this element does the work or asks the consumer to.
|
|
3865
3879
|
|
|
3866
3880
|
`client` filters, sorts and pages `rows` itself. `server` applies none of
|
|
@@ -3870,12 +3884,6 @@ the client cannot hold the data, so this is not an optimization, it is the
|
|
|
3870
3884
|
only mode that works, and it is here from the start because adding it later
|
|
3871
3885
|
inverts the data flow. */
|
|
3872
3886
|
mode?: (HelixHeadlessDataTable["mode"]) | undefined;
|
|
3873
|
-
/** The page on show, from 1.
|
|
3874
|
-
|
|
3875
|
-
Clamped on the way out, so what this reports is the page it drew: a
|
|
3876
|
-
bookmarked link to page 99 of a result that has since shrunk reads back as
|
|
3877
|
-
the last page rather than as 99. */
|
|
3878
|
-
page?: (HelixHeadlessDataTable["page"]) | undefined;
|
|
3879
3887
|
/** How many rows a page holds. Zero is every row, which is what "no paging" means.
|
|
3880
3888
|
|
|
3881
3889
|
**It announces nothing, and that is not an omission.** Nothing in this
|
|
@@ -3899,6 +3907,24 @@ nothing about the result. Ignored in `client` mode rather than trusted,
|
|
|
3899
3907
|
because two sources for one count is the mistake, and here the array is the
|
|
3900
3908
|
one that cannot be stale. */
|
|
3901
3909
|
total?: (HelixHeadlessDataTable["total"]) | undefined;
|
|
3910
|
+
/** Draws the rows in view and stands empty space in for the rest.
|
|
3911
|
+
|
|
3912
|
+
**Not a `mode`.** `mode` says where the rows come from and who filtered
|
|
3913
|
+
them; this says how many of the ones we hold get drawn. They are
|
|
3914
|
+
independent: a consumer fetching five thousand rows a chunk at a time wants
|
|
3915
|
+
`mode="server"` and this at once, and folding this into `mode` would be an
|
|
3916
|
+
API that forbids that combination for no reason.
|
|
3917
|
+
|
|
3918
|
+
**Composes with `paginated` rather than excluding it.** A window over a
|
|
3919
|
+
page is coherent -- the page is the slice of the result, the window is the
|
|
3920
|
+
part of that slice on screen -- and the arithmetic is the same either way,
|
|
3921
|
+
so there is nothing to forbid. Together they suit a table paging at a
|
|
3922
|
+
thousand rows, where the page is a reasonable fetch and a poor render.
|
|
3923
|
+
|
|
3924
|
+
Off by default. Windowing costs a scroll listener, a measurement per row
|
|
3925
|
+
drawn, and a `block-size` on the scrolling box, and a table of twenty rows
|
|
3926
|
+
should pay none of them. */
|
|
3927
|
+
windowed?: (HelixHeadlessDataTable["windowed"]) | undefined;
|
|
3902
3928
|
/** Whether to draw a pagination under the grid.
|
|
3903
3929
|
|
|
3904
3930
|
On by default once a page size is set, because a paged table with no way to
|
|
@@ -3958,6 +3984,20 @@ export type HelixHeadlessDataTableSolidJsProps = {
|
|
|
3958
3984
|
"attr:default-sort"?: (HelixHeadlessDataTable["defaultSort"]) | undefined;
|
|
3959
3985
|
/** Order to open on, where nothing declared one. */
|
|
3960
3986
|
"prop:defaultSort"?: (HelixHeadlessDataTable["defaultSort"]) | undefined;
|
|
3987
|
+
/** How tall a row is taken to be before it has been drawn, in pixels.
|
|
3988
|
+
|
|
3989
|
+
Only read while `windowed`, and a starting guess rather than a claim: a
|
|
3990
|
+
cell that wraps makes its row taller than its neighbors, and the window
|
|
3991
|
+
replaces this with what each row came to as it draws. It still has to be
|
|
3992
|
+
close, because it is what the scrollbar is built from before anything has
|
|
3993
|
+
been measured. */
|
|
3994
|
+
"prop:estimate"?: (HelixHeadlessDataTable["estimate"]) | undefined;
|
|
3995
|
+
/** The order, as `field:direction`.
|
|
3996
|
+
|
|
3997
|
+
Set it and this element defers: a reader's click fires `helix-sort` and
|
|
3998
|
+
changes nothing until a new value arrives. `default-sort` seeds an order this
|
|
3999
|
+
element then owns. */
|
|
4000
|
+
"prop:sort"?: (HelixHeadlessDataTable["sort"]) | undefined;
|
|
3961
4001
|
/** The field naming a row's stable identity.
|
|
3962
4002
|
|
|
3963
4003
|
**Needed before selection exists, not after.** Lit keys the rendered rows by
|
|
@@ -3967,20 +4007,20 @@ attached to the row it belongs to. Left unset the index is the key, which is
|
|
|
3967
4007
|
correct only while nothing reorders: it is why this defaults to something
|
|
3968
4008
|
that works and is worth setting anyway. */
|
|
3969
4009
|
"prop:key"?: (HelixHeadlessDataTable["key"]) | undefined;
|
|
3970
|
-
/** The order, as `field:direction`.
|
|
3971
|
-
|
|
3972
|
-
Set it and this element defers: a reader's click fires `helix-sort` and
|
|
3973
|
-
changes nothing until a new value arrives. `default-sort` seeds an order this
|
|
3974
|
-
element then owns. */
|
|
3975
|
-
"prop:sort"?: (HelixHeadlessDataTable["sort"]) | undefined;
|
|
3976
|
-
/** Accessible name for the grid. */
|
|
3977
|
-
"prop:label"?: (HelixHeadlessDataTable["label"]) | undefined;
|
|
3978
4010
|
/** What the rows are narrowed to, as one query across every column.
|
|
3979
4011
|
|
|
3980
4012
|
One query rather than a predicate per column, which is what a reader means
|
|
3981
4013
|
by a search box above a table. It matches on each column's ordering value,
|
|
3982
4014
|
so search and sort cannot disagree about what a column holds. */
|
|
3983
4015
|
"prop:filter"?: (HelixHeadlessDataTable["filter"]) | undefined;
|
|
4016
|
+
/** Accessible name for the grid. */
|
|
4017
|
+
"prop:label"?: (HelixHeadlessDataTable["label"]) | undefined;
|
|
4018
|
+
/** The page on show, from 1.
|
|
4019
|
+
|
|
4020
|
+
Clamped on the way out, so what this reports is the page it drew: a
|
|
4021
|
+
bookmarked link to page 99 of a result that has since shrunk reads back as
|
|
4022
|
+
the last page rather than as 99. */
|
|
4023
|
+
"prop:page"?: (HelixHeadlessDataTable["page"]) | undefined;
|
|
3984
4024
|
/** Whether this element does the work or asks the consumer to.
|
|
3985
4025
|
|
|
3986
4026
|
`client` filters, sorts and pages `rows` itself. `server` applies none of
|
|
@@ -3990,12 +4030,6 @@ the client cannot hold the data, so this is not an optimization, it is the
|
|
|
3990
4030
|
only mode that works, and it is here from the start because adding it later
|
|
3991
4031
|
inverts the data flow. */
|
|
3992
4032
|
"prop:mode"?: (HelixHeadlessDataTable["mode"]) | undefined;
|
|
3993
|
-
/** The page on show, from 1.
|
|
3994
|
-
|
|
3995
|
-
Clamped on the way out, so what this reports is the page it drew: a
|
|
3996
|
-
bookmarked link to page 99 of a result that has since shrunk reads back as
|
|
3997
|
-
the last page rather than as 99. */
|
|
3998
|
-
"prop:page"?: (HelixHeadlessDataTable["page"]) | undefined;
|
|
3999
4033
|
/** How many rows a page holds. Zero is every row, which is what "no paging" means.
|
|
4000
4034
|
|
|
4001
4035
|
**It announces nothing, and that is not an omission.** Nothing in this
|
|
@@ -4019,6 +4053,24 @@ nothing about the result. Ignored in `client` mode rather than trusted,
|
|
|
4019
4053
|
because two sources for one count is the mistake, and here the array is the
|
|
4020
4054
|
one that cannot be stale. */
|
|
4021
4055
|
"prop:total"?: (HelixHeadlessDataTable["total"]) | undefined;
|
|
4056
|
+
/** Draws the rows in view and stands empty space in for the rest.
|
|
4057
|
+
|
|
4058
|
+
**Not a `mode`.** `mode` says where the rows come from and who filtered
|
|
4059
|
+
them; this says how many of the ones we hold get drawn. They are
|
|
4060
|
+
independent: a consumer fetching five thousand rows a chunk at a time wants
|
|
4061
|
+
`mode="server"` and this at once, and folding this into `mode` would be an
|
|
4062
|
+
API that forbids that combination for no reason.
|
|
4063
|
+
|
|
4064
|
+
**Composes with `paginated` rather than excluding it.** A window over a
|
|
4065
|
+
page is coherent -- the page is the slice of the result, the window is the
|
|
4066
|
+
part of that slice on screen -- and the arithmetic is the same either way,
|
|
4067
|
+
so there is nothing to forbid. Together they suit a table paging at a
|
|
4068
|
+
thousand rows, where the page is a reasonable fetch and a poor render.
|
|
4069
|
+
|
|
4070
|
+
Off by default. Windowing costs a scroll listener, a measurement per row
|
|
4071
|
+
drawn, and a `block-size` on the scrolling box, and a table of twenty rows
|
|
4072
|
+
should pay none of them. */
|
|
4073
|
+
"prop:windowed"?: (HelixHeadlessDataTable["windowed"]) | undefined;
|
|
4022
4074
|
/** Whether to draw a pagination under the grid.
|
|
4023
4075
|
|
|
4024
4076
|
On by default once a page size is set, because a paged table with no way to
|
|
@@ -18758,6 +18810,18 @@ export type CustomElements = {
|
|
|
18758
18810
|
* - `default-page`/`defaultPage`: Page to open on, where nothing declared one.
|
|
18759
18811
|
* - `default-page-size`/`defaultPageSize`: Page size to open with, where nothing declared one.
|
|
18760
18812
|
* - `default-sort`/`defaultSort`: Order to open on, where nothing declared one.
|
|
18813
|
+
* - `estimate`: How tall a row is taken to be before it has been drawn, in pixels.
|
|
18814
|
+
*
|
|
18815
|
+
* Only read while `windowed`, and a starting guess rather than a claim: a
|
|
18816
|
+
* cell that wraps makes its row taller than its neighbors, and the window
|
|
18817
|
+
* replaces this with what each row came to as it draws. It still has to be
|
|
18818
|
+
* close, because it is what the scrollbar is built from before anything has
|
|
18819
|
+
* been measured.
|
|
18820
|
+
* - `sort`: The order, as `field:direction`.
|
|
18821
|
+
*
|
|
18822
|
+
* Set it and this element defers: a reader's click fires `helix-sort` and
|
|
18823
|
+
* changes nothing until a new value arrives. `default-sort` seeds an order this
|
|
18824
|
+
* element then owns.
|
|
18761
18825
|
* - `key`: The field naming a row's stable identity.
|
|
18762
18826
|
*
|
|
18763
18827
|
* **Needed before selection exists, not after.** Lit keys the rendered rows by
|
|
@@ -18766,17 +18830,17 @@ export type CustomElements = {
|
|
|
18766
18830
|
* attached to the row it belongs to. Left unset the index is the key, which is
|
|
18767
18831
|
* correct only while nothing reorders: it is why this defaults to something
|
|
18768
18832
|
* that works and is worth setting anyway.
|
|
18769
|
-
* - `sort`: The order, as `field:direction`.
|
|
18770
|
-
*
|
|
18771
|
-
* Set it and this element defers: a reader's click fires `helix-sort` and
|
|
18772
|
-
* changes nothing until a new value arrives. `default-sort` seeds an order this
|
|
18773
|
-
* element then owns.
|
|
18774
|
-
* - `label`: Accessible name for the grid.
|
|
18775
18833
|
* - `filter`: What the rows are narrowed to, as one query across every column.
|
|
18776
18834
|
*
|
|
18777
18835
|
* One query rather than a predicate per column, which is what a reader means
|
|
18778
18836
|
* by a search box above a table. It matches on each column's ordering value,
|
|
18779
18837
|
* so search and sort cannot disagree about what a column holds.
|
|
18838
|
+
* - `label`: Accessible name for the grid.
|
|
18839
|
+
* - `page`: The page on show, from 1.
|
|
18840
|
+
*
|
|
18841
|
+
* Clamped on the way out, so what this reports is the page it drew: a
|
|
18842
|
+
* bookmarked link to page 99 of a result that has since shrunk reads back as
|
|
18843
|
+
* the last page rather than as 99.
|
|
18780
18844
|
* - `mode`: Whether this element does the work or asks the consumer to.
|
|
18781
18845
|
*
|
|
18782
18846
|
* `client` filters, sorts and pages `rows` itself. `server` applies none of
|
|
@@ -18785,11 +18849,6 @@ export type CustomElements = {
|
|
|
18785
18849
|
* the client cannot hold the data, so this is not an optimization, it is the
|
|
18786
18850
|
* only mode that works, and it is here from the start because adding it later
|
|
18787
18851
|
* inverts the data flow.
|
|
18788
|
-
* - `page`: The page on show, from 1.
|
|
18789
|
-
*
|
|
18790
|
-
* Clamped on the way out, so what this reports is the page it drew: a
|
|
18791
|
-
* bookmarked link to page 99 of a result that has since shrunk reads back as
|
|
18792
|
-
* the last page rather than as 99.
|
|
18793
18852
|
* - `page-size`/`pageSize`: How many rows a page holds. Zero is every row, which is what "no paging" means.
|
|
18794
18853
|
*
|
|
18795
18854
|
* **It announces nothing, and that is not an omission.** Nothing in this
|
|
@@ -18803,6 +18862,23 @@ export type CustomElements = {
|
|
|
18803
18862
|
* nothing about the result. Ignored in `client` mode rather than trusted,
|
|
18804
18863
|
* because two sources for one count is the mistake, and here the array is the
|
|
18805
18864
|
* one that cannot be stale.
|
|
18865
|
+
* - `windowed`: Draws the rows in view and stands empty space in for the rest.
|
|
18866
|
+
*
|
|
18867
|
+
* **Not a `mode`.** `mode` says where the rows come from and who filtered
|
|
18868
|
+
* them; this says how many of the ones we hold get drawn. They are
|
|
18869
|
+
* independent: a consumer fetching five thousand rows a chunk at a time wants
|
|
18870
|
+
* `mode="server"` and this at once, and folding this into `mode` would be an
|
|
18871
|
+
* API that forbids that combination for no reason.
|
|
18872
|
+
*
|
|
18873
|
+
* **Composes with `paginated` rather than excluding it.** A window over a
|
|
18874
|
+
* page is coherent -- the page is the slice of the result, the window is the
|
|
18875
|
+
* part of that slice on screen -- and the arithmetic is the same either way,
|
|
18876
|
+
* so there is nothing to forbid. Together they suit a table paging at a
|
|
18877
|
+
* thousand rows, where the page is a reasonable fetch and a poor render.
|
|
18878
|
+
*
|
|
18879
|
+
* Off by default. Windowing costs a scroll listener, a measurement per row
|
|
18880
|
+
* drawn, and a `block-size` on the scrolling box, and a table of twenty rows
|
|
18881
|
+
* should pay none of them.
|
|
18806
18882
|
* - `paginated`: Whether to draw a pagination under the grid.
|
|
18807
18883
|
*
|
|
18808
18884
|
* On by default once a page size is set, because a paged table with no way to
|
|
@@ -18885,6 +18961,8 @@ export type CustomElements = {
|
|
|
18885
18961
|
*
|
|
18886
18962
|
* Custom selectors for styling elements within the component.
|
|
18887
18963
|
*
|
|
18964
|
+
* - `after`: The room the rows below the window would have taken. Windowed only.
|
|
18965
|
+
* - `before`: The room the rows above the window would have taken. Windowed only.
|
|
18888
18966
|
* - `cell`: One cell.
|
|
18889
18967
|
* - `empty`: Shown when no rows match.
|
|
18890
18968
|
* - `footer`: The region below the grid.
|
|
@@ -32967,6 +33045,18 @@ export type CustomElementsSolidJs = {
|
|
|
32967
33045
|
* - `default-page`/`defaultPage`: Page to open on, where nothing declared one.
|
|
32968
33046
|
* - `default-page-size`/`defaultPageSize`: Page size to open with, where nothing declared one.
|
|
32969
33047
|
* - `default-sort`/`defaultSort`: Order to open on, where nothing declared one.
|
|
33048
|
+
* - `estimate`: How tall a row is taken to be before it has been drawn, in pixels.
|
|
33049
|
+
*
|
|
33050
|
+
* Only read while `windowed`, and a starting guess rather than a claim: a
|
|
33051
|
+
* cell that wraps makes its row taller than its neighbors, and the window
|
|
33052
|
+
* replaces this with what each row came to as it draws. It still has to be
|
|
33053
|
+
* close, because it is what the scrollbar is built from before anything has
|
|
33054
|
+
* been measured.
|
|
33055
|
+
* - `sort`: The order, as `field:direction`.
|
|
33056
|
+
*
|
|
33057
|
+
* Set it and this element defers: a reader's click fires `helix-sort` and
|
|
33058
|
+
* changes nothing until a new value arrives. `default-sort` seeds an order this
|
|
33059
|
+
* element then owns.
|
|
32970
33060
|
* - `key`: The field naming a row's stable identity.
|
|
32971
33061
|
*
|
|
32972
33062
|
* **Needed before selection exists, not after.** Lit keys the rendered rows by
|
|
@@ -32975,17 +33065,17 @@ export type CustomElementsSolidJs = {
|
|
|
32975
33065
|
* attached to the row it belongs to. Left unset the index is the key, which is
|
|
32976
33066
|
* correct only while nothing reorders: it is why this defaults to something
|
|
32977
33067
|
* that works and is worth setting anyway.
|
|
32978
|
-
* - `sort`: The order, as `field:direction`.
|
|
32979
|
-
*
|
|
32980
|
-
* Set it and this element defers: a reader's click fires `helix-sort` and
|
|
32981
|
-
* changes nothing until a new value arrives. `default-sort` seeds an order this
|
|
32982
|
-
* element then owns.
|
|
32983
|
-
* - `label`: Accessible name for the grid.
|
|
32984
33068
|
* - `filter`: What the rows are narrowed to, as one query across every column.
|
|
32985
33069
|
*
|
|
32986
33070
|
* One query rather than a predicate per column, which is what a reader means
|
|
32987
33071
|
* by a search box above a table. It matches on each column's ordering value,
|
|
32988
33072
|
* so search and sort cannot disagree about what a column holds.
|
|
33073
|
+
* - `label`: Accessible name for the grid.
|
|
33074
|
+
* - `page`: The page on show, from 1.
|
|
33075
|
+
*
|
|
33076
|
+
* Clamped on the way out, so what this reports is the page it drew: a
|
|
33077
|
+
* bookmarked link to page 99 of a result that has since shrunk reads back as
|
|
33078
|
+
* the last page rather than as 99.
|
|
32989
33079
|
* - `mode`: Whether this element does the work or asks the consumer to.
|
|
32990
33080
|
*
|
|
32991
33081
|
* `client` filters, sorts and pages `rows` itself. `server` applies none of
|
|
@@ -32994,11 +33084,6 @@ export type CustomElementsSolidJs = {
|
|
|
32994
33084
|
* the client cannot hold the data, so this is not an optimization, it is the
|
|
32995
33085
|
* only mode that works, and it is here from the start because adding it later
|
|
32996
33086
|
* inverts the data flow.
|
|
32997
|
-
* - `page`: The page on show, from 1.
|
|
32998
|
-
*
|
|
32999
|
-
* Clamped on the way out, so what this reports is the page it drew: a
|
|
33000
|
-
* bookmarked link to page 99 of a result that has since shrunk reads back as
|
|
33001
|
-
* the last page rather than as 99.
|
|
33002
33087
|
* - `page-size`/`pageSize`: How many rows a page holds. Zero is every row, which is what "no paging" means.
|
|
33003
33088
|
*
|
|
33004
33089
|
* **It announces nothing, and that is not an omission.** Nothing in this
|
|
@@ -33012,6 +33097,23 @@ export type CustomElementsSolidJs = {
|
|
|
33012
33097
|
* nothing about the result. Ignored in `client` mode rather than trusted,
|
|
33013
33098
|
* because two sources for one count is the mistake, and here the array is the
|
|
33014
33099
|
* one that cannot be stale.
|
|
33100
|
+
* - `windowed`: Draws the rows in view and stands empty space in for the rest.
|
|
33101
|
+
*
|
|
33102
|
+
* **Not a `mode`.** `mode` says where the rows come from and who filtered
|
|
33103
|
+
* them; this says how many of the ones we hold get drawn. They are
|
|
33104
|
+
* independent: a consumer fetching five thousand rows a chunk at a time wants
|
|
33105
|
+
* `mode="server"` and this at once, and folding this into `mode` would be an
|
|
33106
|
+
* API that forbids that combination for no reason.
|
|
33107
|
+
*
|
|
33108
|
+
* **Composes with `paginated` rather than excluding it.** A window over a
|
|
33109
|
+
* page is coherent -- the page is the slice of the result, the window is the
|
|
33110
|
+
* part of that slice on screen -- and the arithmetic is the same either way,
|
|
33111
|
+
* so there is nothing to forbid. Together they suit a table paging at a
|
|
33112
|
+
* thousand rows, where the page is a reasonable fetch and a poor render.
|
|
33113
|
+
*
|
|
33114
|
+
* Off by default. Windowing costs a scroll listener, a measurement per row
|
|
33115
|
+
* drawn, and a `block-size` on the scrolling box, and a table of twenty rows
|
|
33116
|
+
* should pay none of them.
|
|
33015
33117
|
* - `paginated`: Whether to draw a pagination under the grid.
|
|
33016
33118
|
*
|
|
33017
33119
|
* On by default once a page size is set, because a paged table with no way to
|
|
@@ -33094,6 +33196,8 @@ export type CustomElementsSolidJs = {
|
|
|
33094
33196
|
*
|
|
33095
33197
|
* Custom selectors for styling elements within the component.
|
|
33096
33198
|
*
|
|
33199
|
+
* - `after`: The room the rows below the window would have taken. Windowed only.
|
|
33200
|
+
* - `before`: The room the rows above the window would have taken. Windowed only.
|
|
33097
33201
|
* - `cell`: One cell.
|
|
33098
33202
|
* - `empty`: Shown when no rows match.
|
|
33099
33203
|
* - `footer`: The region below the grid.
|