@adia-ai/web-components 0.8.41 → 0.8.43
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/CHANGELOG.md +35 -0
- package/MIGRATION.md +240 -3
- package/USAGE.md +4 -4
- package/color/index.js +1 -1
- package/components/action-list/action-item.a2ui.json +7 -7
- package/components/action-list/action-item.yaml +21 -9
- package/components/action-list/action-list.class.js +13 -7
- package/components/action-list/action-list.d.ts +2 -2
- package/components/button/button.yaml +1 -1
- package/components/calendar-picker/calendar-picker.a2ui.json +1 -1
- package/components/calendar-picker/calendar-picker.class.js +2 -3
- package/components/calendar-picker/calendar-picker.css +16 -18
- package/components/calendar-picker/calendar-picker.yaml +2 -2
- package/components/card/card.css +3 -3
- package/components/chart/chart.a2ui.json +8 -8
- package/components/chart/chart.class.js +21 -19
- package/components/chart/chart.d.ts +6 -6
- package/components/chart/chart.yaml +16 -9
- package/components/chart-legend/chart-legend.a2ui.json +7 -11
- package/components/chart-legend/chart-legend.class.js +17 -8
- package/components/chart-legend/chart-legend.css +5 -2
- package/components/chart-legend/chart-legend.d.ts +2 -2
- package/components/chart-legend/chart-legend.yaml +12 -8
- package/components/check/check.css +9 -0
- package/components/{color-picker/color-picker.a2ui.json → color-area/color-area.a2ui.json} +15 -12
- package/components/{color-picker/color-picker.class.js → color-area/color-area.class.js} +10 -8
- package/components/color-area/color-area.css +185 -0
- package/components/color-area/color-area.d.ts +66 -0
- package/components/color-area/color-area.examples.md +19 -0
- package/components/color-area/color-area.js +17 -0
- package/components/{color-picker/color-picker.yaml → color-area/color-area.yaml} +17 -9
- package/components/color-input/color-input.a2ui.json +5 -5
- package/components/color-input/color-input.class.js +9 -6
- package/components/color-input/color-input.css +1 -1
- package/components/color-input/color-input.js +2 -2
- package/components/color-input/color-input.yaml +14 -12
- package/components/description-list/description-list.a2ui.json +1 -1
- package/components/description-list/description-list.css +1 -1
- package/components/description-list/description-list.d.ts +1 -1
- package/components/description-list/description-list.yaml +1 -1
- package/components/drilldown/drilldown.a2ui.json +3 -0
- package/components/drilldown/drilldown.css +8 -1
- package/components/drilldown/drilldown.yaml +2 -0
- package/components/field/field.a2ui.json +1 -1
- package/components/field/field.class.js +5 -2
- package/components/field/field.yaml +1 -1
- package/components/index.js +1 -4
- package/components/input/input.a2ui.json +4 -4
- package/components/input/input.class.js +8 -0
- package/components/input/input.css +6 -0
- package/components/input/input.yaml +11 -8
- package/components/integration-card/integration-card.examples.md +2 -1
- package/components/menu/menu-item.a2ui.json +7 -7
- package/components/menu/menu-item.yaml +20 -7
- package/components/menu/menu.class.js +13 -7
- package/components/menu/menu.d.ts +2 -2
- package/components/pane/pane.a2ui.json +11 -11
- package/components/pane/pane.class.js +8 -4
- package/components/pane/pane.css +15 -10
- package/components/pane/pane.d.ts +10 -9
- package/components/pane/pane.yaml +9 -7
- package/components/progress/progress.a2ui.json +1 -1
- package/components/progress/progress.class.js +2 -2
- package/components/progress/progress.d.ts +1 -1
- package/components/progress/progress.yaml +2 -2
- package/components/radio/radio.css +7 -0
- package/components/search/search.css +10 -1
- package/components/segment/segment.a2ui.json +1 -2
- package/components/segment/segment.css +10 -0
- package/components/segment/segment.yaml +1 -2
- package/components/segmented/segmented.a2ui.json +1 -3
- package/components/segmented/segmented.class.js +2 -2
- package/components/segmented/segmented.yaml +2 -4
- package/components/select/select.css +6 -0
- package/components/step-progress/step-progress.yaml +1 -1
- package/components/swatch/swatch.yaml +1 -1
- package/components/switch/switch.css +8 -0
- package/components/table-toolbar/table-toolbar.a2ui.json +42 -1
- package/components/table-toolbar/table-toolbar.class.js +166 -14
- package/components/table-toolbar/table-toolbar.css +46 -0
- package/components/table-toolbar/table-toolbar.d.ts +13 -1
- package/components/table-toolbar/table-toolbar.yaml +104 -14
- package/components/textarea/textarea.css +4 -0
- package/components/time-picker/time-picker.yaml +3 -2
- package/components/tree/tree.yaml +1 -1
- package/components/upload/upload.class.js +16 -0
- package/components/upload/upload.d.ts +7 -0
- package/components/upload/upload.yaml +7 -3
- package/core/icons.js +3 -1
- package/custom-elements.json +147 -468
- package/dist/host.min.css +1 -1
- package/dist/host.sheet.js +1 -1
- package/dist/theme-provider.min.js +1 -1
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +88 -85
- package/dist/web-components.sheet.js +1 -1
- package/index.d.ts +9 -13
- package/package.json +1 -1
- package/patterns/admin-shell/admin-shell.examples.html +2 -2
- package/patterns/chart-in-card/chart-in-card.examples.html +10 -10
- package/patterns/conversion-funnel/conversion-funnel.html +2 -2
- package/patterns/editor-shell/editor-shell.examples.html +3 -3
- package/patterns/form-system/form-system.examples.html +1 -1
- package/styles/colors/semantics/features.css +8 -1
- package/styles/components.css +1 -4
- package/traits/arrow-grid-nav/arrow-grid-nav.js +1 -1
- package/traits/resize-observer/resize-observer.js +1 -1
- package/components/color-picker/color-picker.css +0 -182
- package/components/color-picker/color-picker.d.ts +0 -99
- package/components/color-picker/color-picker.examples.md +0 -19
- package/components/color-picker/color-picker.js +0 -17
- package/components/datetime-picker/datetime-picker.a2ui.json +0 -256
- package/components/datetime-picker/datetime-picker.class.js +0 -58
- package/components/datetime-picker/datetime-picker.css +0 -11
- package/components/datetime-picker/datetime-picker.d.ts +0 -87
- package/components/datetime-picker/datetime-picker.examples.md +0 -25
- package/components/datetime-picker/datetime-picker.js +0 -17
- package/components/datetime-picker/datetime-picker.yaml +0 -254
- package/components/progress-row/progress-row.a2ui.json +0 -107
- package/components/progress-row/progress-row.class.js +0 -118
- package/components/progress-row/progress-row.css +0 -60
- package/components/progress-row/progress-row.d.ts +0 -24
- package/components/progress-row/progress-row.examples.md +0 -7
- package/components/progress-row/progress-row.js +0 -17
- package/components/progress-row/progress-row.yaml +0 -85
- package/components/toggle-group/toggle-group.a2ui.json +0 -148
- package/components/toggle-group/toggle-group.class.js +0 -195
- package/components/toggle-group/toggle-group.css +0 -127
- package/components/toggle-group/toggle-group.d.ts +0 -50
- package/components/toggle-group/toggle-group.examples.md +0 -33
- package/components/toggle-group/toggle-group.js +0 -18
- package/components/toggle-group/toggle-group.yaml +0 -135
- package/components/toggle-group/toggle-option.a2ui.json +0 -86
- package/components/toggle-group/toggle-option.yaml +0 -75
|
@@ -57,6 +57,18 @@ function popoverHead(text) {
|
|
|
57
57
|
return el;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
// `col.label` is sometimes set to an nbsp or a bare space — the idiom
|
|
61
|
+
// consumers use on render-only columns (e.g. `_cancel` / `_download` /
|
|
62
|
+
// `_replay`) to keep the TABLE header cell blank while still rendering a
|
|
63
|
+
// custom cell. That whitespace is truthy, so a plain `col.label || col.key`
|
|
64
|
+
// fallback never engages and popover rows (filter / sort / columns) render
|
|
65
|
+
// with no visible text. Trim before testing so the fallback only skips when
|
|
66
|
+
// a label is genuinely present, never when it's intentional whitespace.
|
|
67
|
+
function columnLabel(col) {
|
|
68
|
+
const label = col.label;
|
|
69
|
+
return typeof label === 'string' && label.trim() ? label : col.key;
|
|
70
|
+
}
|
|
71
|
+
|
|
60
72
|
const SELECT_THRESHOLD = 50;
|
|
61
73
|
const SAMPLE_LIMIT = 500;
|
|
62
74
|
|
|
@@ -116,6 +128,10 @@ export class UITableToolbar extends UIElement {
|
|
|
116
128
|
for: { type: String, default: '', reflect: true },
|
|
117
129
|
text: { type: String, default: '', reflect: false },
|
|
118
130
|
count: { type: String, default: '', reflect: false },
|
|
131
|
+
rangeStart: { type: Number, default: 0, reflect: true, attribute: 'range-start' },
|
|
132
|
+
rangeEnd: { type: Number, default: 0, reflect: true, attribute: 'range-end' },
|
|
133
|
+
rangeTotal: { type: Number, default: 0, reflect: true, attribute: 'range-total' },
|
|
134
|
+
pageSize: { type: Number, default: 0, reflect: true, attribute: 'page-size' },
|
|
119
135
|
noFilter: { type: Boolean, default: false, reflect: true, attribute: 'no-filter' },
|
|
120
136
|
noSort: { type: Boolean, default: false, reflect: true, attribute: 'no-sort' },
|
|
121
137
|
noColumns: { type: Boolean, default: false, reflect: true, attribute: 'no-columns' },
|
|
@@ -137,6 +153,19 @@ export class UITableToolbar extends UIElement {
|
|
|
137
153
|
#docListenersBound = false;
|
|
138
154
|
#docListenerRaf = null;
|
|
139
155
|
#sortIndicatorRafs = new Set();
|
|
156
|
+
#pageSizeOptions = [];
|
|
157
|
+
|
|
158
|
+
// ── Public API: pageSizeOptions ──────────────────────────────────────────
|
|
159
|
+
// Dynamic array prop (JS-set collection, custom setter) — same shape as
|
|
160
|
+
// table-ui's `columns`/`data`. Deliberately not in `static properties`
|
|
161
|
+
// (gh#970 — an array prop needs its own setter, not the scalar signal path).
|
|
162
|
+
|
|
163
|
+
set pageSizeOptions(arr) {
|
|
164
|
+
this.#pageSizeOptions = Array.isArray(arr) ? arr.map(Number).filter((n) => Number.isFinite(n)) : [];
|
|
165
|
+
this.#updatePageSizeSelect();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
get pageSizeOptions() { return this.#pageSizeOptions; }
|
|
140
169
|
|
|
141
170
|
// §381 (v0.6.10, slice F): one-shot dev-mode warning when consumers
|
|
142
171
|
// set common-but-unknown opt-out attributes (e.g. `searchable`,
|
|
@@ -153,11 +182,37 @@ export class UITableToolbar extends UIElement {
|
|
|
153
182
|
connected() {
|
|
154
183
|
this.setAttribute('role', 'toolbar');
|
|
155
184
|
this.#warnUnknownOptOutAttrs();
|
|
185
|
+
// gh#1615 — hydrate `page-size-options="[10,25,50]"` once at connect,
|
|
186
|
+
// same pattern as table-ui's `data`/`columns` JSON-array attributes
|
|
187
|
+
// (table.class.js connected()). A later programmatic `.pageSizeOptions
|
|
188
|
+
// = [...]` set still wins (guarded by the length check).
|
|
189
|
+
if (this.#pageSizeOptions.length === 0 && this.hasAttribute('page-size-options')) {
|
|
190
|
+
try {
|
|
191
|
+
const parsed = JSON.parse(this.getAttribute('page-size-options'));
|
|
192
|
+
if (Array.isArray(parsed)) this.pageSizeOptions = parsed;
|
|
193
|
+
} catch (_) { /* malformed JSON — leave empty, select renders hidden */ }
|
|
194
|
+
}
|
|
156
195
|
this.#stamp();
|
|
157
196
|
this.#resolveTarget();
|
|
158
197
|
this.#syncFromTarget();
|
|
159
198
|
}
|
|
160
199
|
|
|
200
|
+
// gh#1620 — this used to live in a declared `attributeChanged(name)` hook
|
|
201
|
+
// that the base class never calls (core/element.js only ever invokes
|
|
202
|
+
// `updated(changed)`, keyed by property name, not attribute name); the
|
|
203
|
+
// reactions below silently never fired. Migrated verbatim onto the live
|
|
204
|
+
// hook, keyed by the matching property names.
|
|
205
|
+
updated(changed) {
|
|
206
|
+
if (changed.has('noFilter') || changed.has('noSort')
|
|
207
|
+
|| changed.has('noColumns') || changed.has('noSearch')) {
|
|
208
|
+
this.#updateControlVisibility();
|
|
209
|
+
}
|
|
210
|
+
if (changed.has('placeholder')) {
|
|
211
|
+
const search = this.querySelector(':scope [data-search]');
|
|
212
|
+
search?.setAttribute('placeholder', this.placeholder);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
161
216
|
disconnected() {
|
|
162
217
|
if (this.#docListenerRaf != null) {
|
|
163
218
|
cancelAnimationFrame(this.#docListenerRaf);
|
|
@@ -174,6 +229,8 @@ export class UITableToolbar extends UIElement {
|
|
|
174
229
|
this.#resolveTarget();
|
|
175
230
|
this.#syncFromTarget();
|
|
176
231
|
this.#updateTitle();
|
|
232
|
+
this.#updateSummary();
|
|
233
|
+
this.#updatePageSizeSelect();
|
|
177
234
|
}
|
|
178
235
|
|
|
179
236
|
// ── Unknown opt-out attribute warning (§381, v0.6.10 slice F) ────────────
|
|
@@ -261,6 +318,20 @@ export class UITableToolbar extends UIElement {
|
|
|
261
318
|
const root = document.createElement('div');
|
|
262
319
|
root.setAttribute('data-toolbar', '');
|
|
263
320
|
|
|
321
|
+
// Scope slot passthrough (gh#1615) — leading region before the title
|
|
322
|
+
// cluster. Same real-insertion-point pattern as [slot="actions"] below:
|
|
323
|
+
// move any pre-existing [slot="scope"] children into a stamped wrapper
|
|
324
|
+
// rather than declaring a template-owned `parts:` entry (ADR-0067 — an
|
|
325
|
+
// author-fillable span is `slots:`, never `parts:`).
|
|
326
|
+
const scopeSlot = document.createElement('div');
|
|
327
|
+
scopeSlot.setAttribute('data-scope', '');
|
|
328
|
+
for (const node of [...this.children]) {
|
|
329
|
+
if (node === root) continue;
|
|
330
|
+
if (node.getAttribute?.('slot') === 'scope') {
|
|
331
|
+
scopeSlot.appendChild(node);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
264
335
|
// Title cluster
|
|
265
336
|
const title = document.createElement('div');
|
|
266
337
|
title.setAttribute('data-title', '');
|
|
@@ -276,6 +347,16 @@ export class UITableToolbar extends UIElement {
|
|
|
276
347
|
badge.hidden = true;
|
|
277
348
|
title.appendChild(badge);
|
|
278
349
|
|
|
350
|
+
// Range summary ("Showing X–Y of N", gh#1615) — its own cluster,
|
|
351
|
+
// independent of [data-title]: coexists with [text]/[count] rather than
|
|
352
|
+
// nesting inside their hide-with-children logic (ADIA2-8897).
|
|
353
|
+
const summary = document.createElement('div');
|
|
354
|
+
summary.setAttribute('data-summary', '');
|
|
355
|
+
summary.hidden = true;
|
|
356
|
+
const summaryText = document.createElement('span');
|
|
357
|
+
summaryText.setAttribute('data-summary-text', '');
|
|
358
|
+
summary.appendChild(summaryText);
|
|
359
|
+
|
|
279
360
|
// Controls cluster
|
|
280
361
|
const controls = document.createElement('div');
|
|
281
362
|
controls.setAttribute('data-controls', '');
|
|
@@ -295,6 +376,19 @@ export class UITableToolbar extends UIElement {
|
|
|
295
376
|
search.setAttribute('debounce', String(SEARCH_DEBOUNCE));
|
|
296
377
|
search.addEventListener('search', this.#onSearch);
|
|
297
378
|
|
|
379
|
+
// Page-size select (gh#1615) — hidden until pageSizeOptions is set
|
|
380
|
+
// (additive opt-in, zero footprint on existing consumers). Carries the
|
|
381
|
+
// same `margin-inline-start: auto` as [data-search] so the trailing
|
|
382
|
+
// group (controls/search/page-size/actions) still pushes to the far
|
|
383
|
+
// edge when [no-search] drops search — without touching search's own
|
|
384
|
+
// existing default behavior for consumers that never set pageSizeOptions.
|
|
385
|
+
const pageSize = document.createElement('select-ui');
|
|
386
|
+
pageSize.setAttribute('data-page-size', '');
|
|
387
|
+
pageSize.setAttribute('size', 'sm');
|
|
388
|
+
pageSize.setAttribute('aria-label', 'Rows per page');
|
|
389
|
+
pageSize.hidden = true;
|
|
390
|
+
pageSize.addEventListener('change', this.#onPageSizeChange);
|
|
391
|
+
|
|
298
392
|
// Actions slot passthrough — we move any pre-existing [slot="actions"] children here
|
|
299
393
|
const actionsSlot = document.createElement('div');
|
|
300
394
|
actionsSlot.setAttribute('data-actions', '');
|
|
@@ -305,14 +399,19 @@ export class UITableToolbar extends UIElement {
|
|
|
305
399
|
}
|
|
306
400
|
}
|
|
307
401
|
|
|
402
|
+
root.appendChild(scopeSlot);
|
|
308
403
|
root.appendChild(title);
|
|
404
|
+
root.appendChild(summary);
|
|
309
405
|
root.appendChild(controls);
|
|
310
406
|
root.appendChild(search);
|
|
407
|
+
root.appendChild(pageSize);
|
|
311
408
|
root.appendChild(actionsSlot);
|
|
312
409
|
|
|
313
410
|
this.appendChild(root);
|
|
314
411
|
this.#updateTitle();
|
|
412
|
+
this.#updateSummary();
|
|
315
413
|
this.#updateControlVisibility();
|
|
414
|
+
this.#updatePageSizeSelect();
|
|
316
415
|
}
|
|
317
416
|
|
|
318
417
|
#mkPopoverAction(label, onClick) {
|
|
@@ -385,6 +484,70 @@ export class UITableToolbar extends UIElement {
|
|
|
385
484
|
}
|
|
386
485
|
}
|
|
387
486
|
|
|
487
|
+
// ── Range summary ("Showing X–Y of N", gh#1615) ─────────────────────────
|
|
488
|
+
// Independent of #updateTitle's [data-title] cluster by design — coexists
|
|
489
|
+
// with [text]/[count] rather than sharing their hide-with-children logic.
|
|
490
|
+
|
|
491
|
+
#updateSummary() {
|
|
492
|
+
const summary = this.querySelector(':scope > [data-toolbar] > [data-summary]');
|
|
493
|
+
if (!summary) return;
|
|
494
|
+
const start = Number(this.rangeStart) || 0;
|
|
495
|
+
const end = Number(this.rangeEnd) || 0;
|
|
496
|
+
const total = Number(this.rangeTotal) || 0;
|
|
497
|
+
if (start > 0 && end > 0 && total > 0) {
|
|
498
|
+
const text = summary.querySelector(':scope [data-summary-text]');
|
|
499
|
+
if (text) text.textContent = `Showing ${start}–${end} of ${total}`;
|
|
500
|
+
summary.hidden = false;
|
|
501
|
+
} else {
|
|
502
|
+
summary.hidden = true;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// ── Page-size select (gh#1615) ───────────────────────────────────────────
|
|
507
|
+
// Hidden whenever pageSizeOptions is empty — additive opt-in, matching the
|
|
508
|
+
// [slot="actions"]:empty pattern's "no footprint unless a consumer opts in".
|
|
509
|
+
|
|
510
|
+
#updatePageSizeSelect() {
|
|
511
|
+
const select = this.querySelector(':scope > [data-toolbar] > [data-page-size]');
|
|
512
|
+
if (!select) return;
|
|
513
|
+
const options = this.#pageSizeOptions;
|
|
514
|
+
if (!options.length) {
|
|
515
|
+
select.hidden = true;
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
select.hidden = false;
|
|
519
|
+
|
|
520
|
+
// `.options = [...]` (select-ui's documented programmatic API) rather
|
|
521
|
+
// than appending light-DOM <option> children: select-ui's own
|
|
522
|
+
// #parseOptions() PARSES-THEN-REMOVES any <option>/<optgroup> children
|
|
523
|
+
// once connected, and only re-parses newly-appended ones via an async
|
|
524
|
+
// MutationObserver — appending after this element is already connected
|
|
525
|
+
// (which it is, by the time a later pageSizeOptions/pageSize change
|
|
526
|
+
// reaches this method) races that observer. `.options=` is synchronous
|
|
527
|
+
// and connection-state-agnostic, matching table-toolbar's own
|
|
528
|
+
// initial-mount-through-any-later-update determinism elsewhere.
|
|
529
|
+
const desired = options.map((n) => ({ value: String(n), label: `${n} / page` }));
|
|
530
|
+
select.options = desired;
|
|
531
|
+
|
|
532
|
+
const size = Number(this.pageSize) || 0;
|
|
533
|
+
const value = options.includes(size) ? size : options[0];
|
|
534
|
+
select.value = String(value);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
#onPageSizeChange = (e) => {
|
|
538
|
+
const pageSize = Number(e.detail?.value ?? this.querySelector(':scope [data-page-size]')?.value) || 0;
|
|
539
|
+
this.pageSize = pageSize;
|
|
540
|
+
// Applied directly to the bound table's own [paginate] (rows-per-page)
|
|
541
|
+
// prop — the same "mirror to URL/analytics via the event, but the
|
|
542
|
+
// toolbar already wires the change into the target" pattern
|
|
543
|
+
// columns-change/sort-change already use.
|
|
544
|
+
if (this.#target) this.#target.paginate = pageSize;
|
|
545
|
+
this.dispatchEvent(new CustomEvent('page-size-change', {
|
|
546
|
+
bubbles: true,
|
|
547
|
+
detail: { pageSize },
|
|
548
|
+
}));
|
|
549
|
+
};
|
|
550
|
+
|
|
388
551
|
#updateControlVisibility() {
|
|
389
552
|
const root = this.querySelector(':scope > [data-toolbar]');
|
|
390
553
|
if (!root) return;
|
|
@@ -400,17 +563,6 @@ export class UITableToolbar extends UIElement {
|
|
|
400
563
|
setHidden('[data-search]', this.noSearch);
|
|
401
564
|
}
|
|
402
565
|
|
|
403
|
-
// Re-run on attribute changes for boolean flags.
|
|
404
|
-
attributeChanged(name) {
|
|
405
|
-
if (['no-filter', 'no-sort', 'no-columns', 'no-search'].includes(name)) {
|
|
406
|
-
this.#updateControlVisibility();
|
|
407
|
-
}
|
|
408
|
-
if (name === 'placeholder') {
|
|
409
|
-
const search = this.querySelector(':scope [data-search]');
|
|
410
|
-
search?.setAttribute('placeholder', this.placeholder);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
566
|
// ── Search ───────────────────────────────────────────────────────────────
|
|
415
567
|
|
|
416
568
|
#onSearch = (e) => {
|
|
@@ -530,7 +682,7 @@ export class UITableToolbar extends UIElement {
|
|
|
530
682
|
const row = document.createElement('field-ui');
|
|
531
683
|
row.setAttribute('data-filter-row', '');
|
|
532
684
|
row.setAttribute('inline', '');
|
|
533
|
-
row.setAttribute('label', col
|
|
685
|
+
row.setAttribute('label', columnLabel(col));
|
|
534
686
|
|
|
535
687
|
const shape = detectFilterShape(col, data);
|
|
536
688
|
const current = filters[col.key];
|
|
@@ -637,7 +789,7 @@ export class UITableToolbar extends UIElement {
|
|
|
637
789
|
const dir = dirByKey.get(col.key);
|
|
638
790
|
const row = document.createElement('menu-item-ui');
|
|
639
791
|
row.setAttribute('data-sort-row', '');
|
|
640
|
-
row.setAttribute('text', col
|
|
792
|
+
row.setAttribute('text', columnLabel(col));
|
|
641
793
|
row.dataset.key = col.key;
|
|
642
794
|
if (dir) row.dataset.active = dir;
|
|
643
795
|
|
|
@@ -731,7 +883,7 @@ export class UITableToolbar extends UIElement {
|
|
|
731
883
|
const row = document.createElement('field-ui');
|
|
732
884
|
row.setAttribute('data-columns-row', '');
|
|
733
885
|
row.setAttribute('inline', '');
|
|
734
|
-
row.setAttribute('label', col
|
|
886
|
+
row.setAttribute('label', columnLabel(col));
|
|
735
887
|
|
|
736
888
|
const check = document.createElement('check-ui');
|
|
737
889
|
if (!col.hidden) check.setAttribute('checked', '');
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
--table-toolbar-title-weight: var(--a-weight-medium);
|
|
19
19
|
--table-toolbar-title-gap: var(--a-space-2);
|
|
20
20
|
|
|
21
|
+
/* ── Range summary ("Showing X–Y of N") ── */
|
|
22
|
+
--table-toolbar-summary-fg: var(--md-sys-color-neutral-on-surface-variant);
|
|
23
|
+
--table-toolbar-summary-size: var(--a-ui-size);
|
|
24
|
+
|
|
21
25
|
/* ── Search ── */
|
|
22
26
|
--table-toolbar-search-min: 14rem;
|
|
23
27
|
--table-toolbar-search-max: 22rem;
|
|
@@ -68,6 +72,17 @@
|
|
|
68
72
|
--table-toolbar-px: var(--a-space-4);
|
|
69
73
|
}
|
|
70
74
|
|
|
75
|
+
/* ═══════ Scope slot ═══════ (gh#1615 — leading region before the title cluster) */
|
|
76
|
+
|
|
77
|
+
[data-scope] {
|
|
78
|
+
display: inline-flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
gap: var(--table-toolbar-cluster-gap);
|
|
81
|
+
flex: 0 0 auto;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
[data-scope]:empty { display: none; }
|
|
85
|
+
|
|
71
86
|
/* ═══════ Title cluster ═══════ */
|
|
72
87
|
|
|
73
88
|
[data-title] {
|
|
@@ -87,6 +102,20 @@
|
|
|
87
102
|
|
|
88
103
|
[data-toolbar-count-badge][hidden] { display: none; }
|
|
89
104
|
|
|
105
|
+
/* ═══════ Range summary ═══════ (gh#1615 — "Showing X–Y of N", independent of [data-title]) */
|
|
106
|
+
|
|
107
|
+
[data-summary] {
|
|
108
|
+
flex: 0 0 auto;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
[data-summary][hidden] { display: none; }
|
|
112
|
+
|
|
113
|
+
[data-summary-text] {
|
|
114
|
+
font-size: var(--table-toolbar-summary-size);
|
|
115
|
+
color: var(--table-toolbar-summary-fg);
|
|
116
|
+
line-height: var(--a-font-leading-snug);
|
|
117
|
+
}
|
|
118
|
+
|
|
90
119
|
/* ═══════ Controls cluster ═══════ */
|
|
91
120
|
|
|
92
121
|
[data-controls] {
|
|
@@ -111,6 +140,23 @@
|
|
|
111
140
|
|
|
112
141
|
[data-search][hidden] { display: none; }
|
|
113
142
|
|
|
143
|
+
/* ═══════ Page-size select ═══════ (gh#1615)
|
|
144
|
+
Carries the SAME margin-inline-start:auto as [data-search] so the
|
|
145
|
+
trailing group (controls/search/page-size/actions) still pushes to the
|
|
146
|
+
far edge when [no-search] drops search — without changing search's own
|
|
147
|
+
existing default for consumers that never set [page-size-options]
|
|
148
|
+
(the element doesn't render at all until then; see [hidden] below and
|
|
149
|
+
#updatePageSizeSelect). Multiple auto-margin siblings in one flex row
|
|
150
|
+
is safe — only the first one with unclaimed free space to its left
|
|
151
|
+
actually receives it. */
|
|
152
|
+
|
|
153
|
+
[data-page-size] {
|
|
154
|
+
flex: 0 0 auto;
|
|
155
|
+
margin-inline-start: auto;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
[data-page-size][hidden] { display: none; }
|
|
159
|
+
|
|
114
160
|
/* ═══════ Actions slot ═══════ */
|
|
115
161
|
|
|
116
162
|
[data-actions] {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `<table-toolbar-ui>` — Header / companion bar for a sibling table-ui. Renders title + count badge, filter / sort / columns popovers,
|
|
2
|
+
* `<table-toolbar-ui>` — Header / companion bar for a sibling table-ui. Renders an optional leading [slot="scope"] region, title + count badge, an optional "Showing X–Y of N" range summary, filter / sort / columns popovers, a search input, an optional page-size select, and a trailing [slot="actions"] region — all wired to the target table via an [for] id-ref. Modeled on chart-legend-ui's [for] binding pattern. Drop next to (or above) any table-ui to add the standard data-grid toolbar without re-implementing search, filter, sort, column visibility, or pagination summary/page-size. Filter rows auto-pick a primitive per column: ≤ 50 distinct values → multi-select (searchable when ≥ 12 options), id-like keys → free-text contains. The column descriptor's `filter` field overrides the auto-detect: `'select'` forces multi-select even on high-cardinality columns; `'text'` forces a contains input even on small enums.
|
|
3
3
|
*
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/table-toolbar
|
|
5
5
|
*
|
|
@@ -14,6 +14,7 @@ import { UIElement } from '../../core/element.js';
|
|
|
14
14
|
|
|
15
15
|
export type TableToolbarColumnsChangeEvent = CustomEvent<unknown>;
|
|
16
16
|
export type TableToolbarFilterChangeEvent = CustomEvent<unknown>;
|
|
17
|
+
export type TableToolbarPageSizeChangeEvent = CustomEvent<unknown>;
|
|
17
18
|
export type TableToolbarSearchEvent = CustomEvent<unknown>;
|
|
18
19
|
export type TableToolbarSortChangeEvent = CustomEvent<unknown>;
|
|
19
20
|
|
|
@@ -30,8 +31,18 @@ export class UITableToolbar extends UIElement {
|
|
|
30
31
|
noSearch: boolean;
|
|
31
32
|
/** Hide the Sort popover button. Sort is shown by default; set to opt out. */
|
|
32
33
|
noSort: boolean;
|
|
34
|
+
/** Current rows-per-page value, shown as the selected option in the page-size select. Falls back to the first entry of pageSizeOptions when unset (0) or not present among the options. Applied directly to the bound table's own [paginate] prop (rows-per-page), the same way filter/sort/columns changes are applied to the target — mirror this prop only to reflect state to URL / persistence / analytics. */
|
|
35
|
+
pageSize: number;
|
|
36
|
+
/** Rows-per-page choices rendered as `<option>`s in the page-size select (e.g. `[10, 25, 50, 100]`). JS property (`.pageSizeOptions = [...]`), or a declarative JSON-array `page-size-options="[10,25,50]"` attribute hydrated once at connect — the same dynamic-array pattern table-ui's own `columns`/`data` props use. Empty (the default) hides the page-size select entirely — additive opt-in, no footprint on existing consumers. */
|
|
37
|
+
pageSizeOptions: string;
|
|
33
38
|
/** Placeholder text for the search input. */
|
|
34
39
|
placeholder: string;
|
|
40
|
+
/** 1-indexed last row number of the current page, for the range summary (e.g. `25` in "Showing 1–25 of 320"). See rangeStart. */
|
|
41
|
+
rangeEnd: number;
|
|
42
|
+
/** 1-indexed first row number of the current page, for the "Showing X–Y of N" range summary (e.g. `1` in "Showing 1–25 of 320"). Renders alongside — never in place of — [text]/[count]; the range summary is its own cluster, independent of the title cluster. All three of rangeStart/rangeEnd/rangeTotal must be set (> 0) for the summary to render; omit all three (the default) to opt out entirely. */
|
|
43
|
+
rangeStart: number;
|
|
44
|
+
/** Total row count across all pages, for the range summary (e.g. `320` in "Showing 1–25 of 320"). Distinct from pagination-ui's `total` (total PAGES) — this is total ROWS; deliberately not spelled `total` to avoid that cross-sibling name collision (ADR-0063 B5). See rangeStart. */
|
|
45
|
+
rangeTotal: number;
|
|
35
46
|
/** Title text shown on the left. */
|
|
36
47
|
text: string;
|
|
37
48
|
/** Toolbar visual variant. `default` renders bare on parent surface; `card` adds the same chrome as a card-ui header. */
|
|
@@ -39,6 +50,7 @@ export class UITableToolbar extends UIElement {
|
|
|
39
50
|
|
|
40
51
|
addEventListener(type: 'columns-change', listener: (ev: TableToolbarColumnsChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
41
52
|
addEventListener(type: 'filter-change', listener: (ev: TableToolbarFilterChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
53
|
+
addEventListener(type: 'page-size-change', listener: (ev: TableToolbarPageSizeChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
42
54
|
addEventListener(type: 'search', listener: (ev: TableToolbarSearchEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
43
55
|
addEventListener(type: 'sort-change', listener: (ev: TableToolbarSortChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
44
56
|
addEventListener<K extends keyof HTMLElementEventMap>(
|
|
@@ -6,16 +6,19 @@ component: TableToolbar
|
|
|
6
6
|
category: agent
|
|
7
7
|
version: 1
|
|
8
8
|
description: >-
|
|
9
|
-
Header / companion bar for a sibling table-ui. Renders
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
column
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
Header / companion bar for a sibling table-ui. Renders an optional leading
|
|
10
|
+
[slot="scope"] region, title + count badge, an optional "Showing X–Y of N"
|
|
11
|
+
range summary, filter / sort / columns popovers, a search input, an
|
|
12
|
+
optional page-size select, and a trailing [slot="actions"] region — all
|
|
13
|
+
wired to the target table via an [for] id-ref. Modeled on chart-legend-ui's
|
|
14
|
+
[for] binding pattern. Drop next to (or above) any table-ui to add the
|
|
15
|
+
standard data-grid toolbar without re-implementing search, filter, sort,
|
|
16
|
+
column visibility, or pagination summary/page-size. Filter rows auto-pick
|
|
17
|
+
a primitive per column: ≤ 50 distinct values → multi-select (searchable
|
|
18
|
+
when ≥ 12 options), id-like keys → free-text contains. The column
|
|
19
|
+
descriptor's `filter` field overrides the auto-detect: `'select'` forces
|
|
20
|
+
multi-select even on high-cardinality columns; `'text'` forces a contains
|
|
21
|
+
input even on small enums.
|
|
19
22
|
# Per ADR-0027 — primitives that programmatically create other primitives
|
|
20
23
|
# do NOT auto-import them. Consumer (or demo shell) must explicitly import.
|
|
21
24
|
composes:
|
|
@@ -43,6 +46,63 @@ props:
|
|
|
43
46
|
description: Optional count badge value shown next to the title. When unset, falls back to the row count of the bound table.
|
|
44
47
|
type: string
|
|
45
48
|
default: ""
|
|
49
|
+
rangeStart:
|
|
50
|
+
description: >-
|
|
51
|
+
1-indexed first row number of the current page, for the "Showing X–Y
|
|
52
|
+
of N" range summary (e.g. `1` in "Showing 1–25 of 320"). Renders
|
|
53
|
+
alongside — never in place of — [text]/[count]; the range summary is
|
|
54
|
+
its own cluster, independent of the title cluster. All three of
|
|
55
|
+
rangeStart/rangeEnd/rangeTotal must be set (> 0) for the summary to
|
|
56
|
+
render; omit all three (the default) to opt out entirely.
|
|
57
|
+
type: number
|
|
58
|
+
default: 0
|
|
59
|
+
reflect: true
|
|
60
|
+
attribute: range-start
|
|
61
|
+
rangeEnd:
|
|
62
|
+
description: >-
|
|
63
|
+
1-indexed last row number of the current page, for the range summary
|
|
64
|
+
(e.g. `25` in "Showing 1–25 of 320"). See rangeStart.
|
|
65
|
+
type: number
|
|
66
|
+
default: 0
|
|
67
|
+
reflect: true
|
|
68
|
+
attribute: range-end
|
|
69
|
+
rangeTotal:
|
|
70
|
+
description: >-
|
|
71
|
+
Total row count across all pages, for the range summary (e.g. `320`
|
|
72
|
+
in "Showing 1–25 of 320"). Distinct from pagination-ui's `total`
|
|
73
|
+
(total PAGES) — this is total ROWS; deliberately not spelled `total`
|
|
74
|
+
to avoid that cross-sibling name collision (ADR-0063 B5). See
|
|
75
|
+
rangeStart.
|
|
76
|
+
type: number
|
|
77
|
+
default: 0
|
|
78
|
+
reflect: true
|
|
79
|
+
attribute: range-total
|
|
80
|
+
pageSize:
|
|
81
|
+
description: >-
|
|
82
|
+
Current rows-per-page value, shown as the selected option in the
|
|
83
|
+
page-size select. Falls back to the first entry of pageSizeOptions
|
|
84
|
+
when unset (0) or not present among the options. Applied directly to
|
|
85
|
+
the bound table's own [paginate] prop (rows-per-page), the same way
|
|
86
|
+
filter/sort/columns changes are applied to the target — mirror this
|
|
87
|
+
prop only to reflect state to URL / persistence / analytics.
|
|
88
|
+
type: number
|
|
89
|
+
default: 0
|
|
90
|
+
reflect: true
|
|
91
|
+
attribute: page-size
|
|
92
|
+
pageSizeOptions:
|
|
93
|
+
description: >-
|
|
94
|
+
Rows-per-page choices rendered as `<option>`s in the page-size select
|
|
95
|
+
(e.g. `[10, 25, 50, 100]`). JS property (`.pageSizeOptions = [...]`),
|
|
96
|
+
or a declarative JSON-array `page-size-options="[10,25,50]"` attribute
|
|
97
|
+
hydrated once at connect — the same dynamic-array pattern table-ui's
|
|
98
|
+
own `columns`/`data` props use. Empty (the default) hides the
|
|
99
|
+
page-size select entirely — additive opt-in, no footprint on existing
|
|
100
|
+
consumers.
|
|
101
|
+
type: array
|
|
102
|
+
items:
|
|
103
|
+
type: number
|
|
104
|
+
default: []
|
|
105
|
+
dynamic: true # JS-set collection prop with a custom setter — deliberately not in static properties
|
|
46
106
|
noFilter:
|
|
47
107
|
description: Hide the Filter popover button. Filter is shown by default; set to opt out.
|
|
48
108
|
type: boolean
|
|
@@ -88,7 +148,11 @@ events:
|
|
|
88
148
|
description: "Sort state changed. Detail: { sortState }."
|
|
89
149
|
columns-change:
|
|
90
150
|
description: "Column visibility changed. Detail: { hiddenColumns }."
|
|
151
|
+
page-size-change:
|
|
152
|
+
description: "Page-size select changed. Detail: { pageSize }."
|
|
91
153
|
slots:
|
|
154
|
+
scope:
|
|
155
|
+
description: Leading region rendered BEFORE the [text]/[count] title cluster — e.g. a scope/view-switcher menu (an org's teams, a saved view). Positioning is CSS by DOM order, mirroring how [slot="actions"] is a real, author-fillable insertion point rather than template-stamped content.
|
|
92
156
|
actions:
|
|
93
157
|
description: Trailing action area — primary buttons (e.g. "New row") rendered after the search input.
|
|
94
158
|
states:
|
|
@@ -114,6 +178,10 @@ tokens:
|
|
|
114
178
|
description: Title font size
|
|
115
179
|
--table-toolbar-title-weight:
|
|
116
180
|
description: Title font weight
|
|
181
|
+
--table-toolbar-summary-fg:
|
|
182
|
+
description: Range-summary ("Showing X–Y of N") text color
|
|
183
|
+
--table-toolbar-summary-size:
|
|
184
|
+
description: Range-summary font size
|
|
117
185
|
requiredIcons:
|
|
118
186
|
- arrow-up
|
|
119
187
|
- arrow-down
|
|
@@ -142,10 +210,19 @@ a2ui:
|
|
|
142
210
|
when content is markup (a <span> + <badge-ui>, etc.).
|
|
143
211
|
- >-
|
|
144
212
|
Listen for toolbar events (`search`, `filter-change`,
|
|
145
|
-
`sort-change`, `columns-change`) only to mirror
|
|
146
|
-
persistence / analytics. The toolbar already wires
|
|
147
|
-
into the bound table — you don't need to manually
|
|
148
|
-
table.
|
|
213
|
+
`sort-change`, `columns-change`, `page-size-change`) only to mirror
|
|
214
|
+
state to URL / persistence / analytics. The toolbar already wires
|
|
215
|
+
its changes into the bound table — you don't need to manually
|
|
216
|
+
update the table.
|
|
217
|
+
- >-
|
|
218
|
+
Use [slot="scope"] for a leading scope/view switcher (an org's
|
|
219
|
+
teams, a saved view) rendered before [text]/[count]. Use
|
|
220
|
+
[range-start] / [range-end] / [range-total] together for a
|
|
221
|
+
"Showing X–Y of N" summary — it renders independently of, and
|
|
222
|
+
alongside, [text]/[count], never in place of them. Use [page-size]
|
|
223
|
+
+ [page-size-options] for a rows-per-page select; it applies
|
|
224
|
+
directly to the bound table's [paginate] prop the same way
|
|
225
|
+
filter/sort/columns changes apply directly to the target.
|
|
149
226
|
anti_patterns: []
|
|
150
227
|
examples:
|
|
151
228
|
- name: members-toolbar
|
|
@@ -158,6 +235,19 @@ examples:
|
|
|
158
235
|
{"id": "sec", "component": "Section", "bleed": true, "children": ["tbl"]},
|
|
159
236
|
{"id": "tbl", "component": "Table", "id": "members", "sortable": true, "raw": true}
|
|
160
237
|
]
|
|
238
|
+
- name: adiav2-list-page-toolbar-row
|
|
239
|
+
description: >-
|
|
240
|
+
The ratified adiav2 list-page toolbar row (ADIA2-9123): scope menu,
|
|
241
|
+
range summary, filter/columns triggers, page-size select, and a
|
|
242
|
+
primary CTA — search and sort dropped per that contract.
|
|
243
|
+
a2ui: >-
|
|
244
|
+
[
|
|
245
|
+
{"id": "root", "component": "Column", "gap": "3", "children": ["bar", "card"]},
|
|
246
|
+
{"id": "bar", "component": "TableToolbar", "for": "accounts", "no-sort": true, "no-search": true, "range-start": 1, "range-end": 25, "range-total": 320, "page-size": 25, "page-size-options": [10, 25, 50, 100]},
|
|
247
|
+
{"id": "card", "component": "Card", "children": ["sec"]},
|
|
248
|
+
{"id": "sec", "component": "Section", "bleed": true, "children": ["tbl"]},
|
|
249
|
+
{"id": "tbl", "component": "Table", "id": "accounts", "sortable": true, "raw": true}
|
|
250
|
+
]
|
|
161
251
|
keywords:
|
|
162
252
|
- table-toolbar
|
|
163
253
|
- data-grid
|
|
@@ -37,6 +37,9 @@ textarea-ui:not([disabled]) [slot="text"]:hover {
|
|
|
37
37
|
--textarea-label-fg-focus: var(--md-sys-color-neutral-on-surface-variant);
|
|
38
38
|
--textarea-bg-disabled: var(--a-ui-bg-disabled);
|
|
39
39
|
--textarea-fg-disabled: var(--a-ui-text-disabled);
|
|
40
|
+
/* Same gap as gh#1595 (input-ui) — rides along here since it's the
|
|
41
|
+
identical shared-field pattern, same root-cause class. */
|
|
42
|
+
--textarea-border-disabled: var(--a-ui-border-disabled);
|
|
40
43
|
text-align: start; /* §text-align-reset — blocks inheritance from centered ancestors */
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -124,6 +127,7 @@ textarea-ui:not([disabled]) [slot="text"]:hover {
|
|
|
124
127
|
:scope[disabled] [slot="text"] {
|
|
125
128
|
background: var(--textarea-bg-disabled);
|
|
126
129
|
color: var(--textarea-fg-disabled);
|
|
130
|
+
border-color: var(--textarea-border-disabled);
|
|
127
131
|
cursor: not-allowed;
|
|
128
132
|
}
|
|
129
133
|
}
|
|
@@ -175,8 +175,9 @@ a2ui:
|
|
|
175
175
|
(`h12` / `h23`) when the surface needs a specific cycle (cron
|
|
176
176
|
editors, log queries, system surfaces).
|
|
177
177
|
- >-
|
|
178
|
-
For datetime selection use `<
|
|
179
|
-
|
|
178
|
+
For datetime selection use `<calendar-picker-ui precision="minute">`
|
|
179
|
+
(SPEC-038; the former `<datetime-picker-ui>` thin alias was cut in
|
|
180
|
+
0.8.43, gh#1617) — it composes this primitive as its time pane.
|
|
180
181
|
anti_patterns:
|
|
181
182
|
- wrong: |
|
|
182
183
|
{"component": "TimePicker", "value": "9:30 AM"}
|
|
@@ -108,7 +108,7 @@ a2ui:
|
|
|
108
108
|
for one-level collapsible groups use <accordion-ui>.
|
|
109
109
|
- >-
|
|
110
110
|
Canonical mount: inside <editor-sidebar slot="leading"> →
|
|
111
|
-
<pane-ui
|
|
111
|
+
<pane-ui edge="leading" resizable> → <section> → <tree-ui id="…">
|
|
112
112
|
as the structure / navigator pane of the three-pane editor shell.
|
|
113
113
|
Pair with a <header> in the same pane (e.g. "Structure",
|
|
114
114
|
"Layers", "Files").
|
|
@@ -93,6 +93,22 @@ export class UIUpload extends UIFormElement {
|
|
|
93
93
|
return this.#files;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Empty the selected file list and return the dropzone to idle — the
|
|
98
|
+
* public counterpart to `open()` (gh#1605). A consumer's own Clear/Reset
|
|
99
|
+
* action can call this without reaching into `[data-dropzone]`'s internal
|
|
100
|
+
* anatomy, which the yaml spec forbids.
|
|
101
|
+
*/
|
|
102
|
+
clear() {
|
|
103
|
+
this.#setFiles([]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ── Form lifecycle ──
|
|
107
|
+
|
|
108
|
+
onFormReset() {
|
|
109
|
+
this.clear();
|
|
110
|
+
}
|
|
111
|
+
|
|
96
112
|
// ── File picking ──
|
|
97
113
|
|
|
98
114
|
/**
|
|
@@ -40,6 +40,13 @@ export class UIUpload extends UIFormElement {
|
|
|
40
40
|
*/
|
|
41
41
|
open(): Promise<void>;
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* gh#1605: empty the selected file list and return the dropzone to idle
|
|
45
|
+
* — the public counterpart to `open()`. Also runs automatically on
|
|
46
|
+
* native form reset (the element is form-associated).
|
|
47
|
+
*/
|
|
48
|
+
clear(): void;
|
|
49
|
+
|
|
43
50
|
addEventListener<K extends keyof HTMLElementEventMap>(
|
|
44
51
|
type: K,
|
|
45
52
|
listener: (this: UIUpload, ev: HTMLElementEventMap[K]) => unknown,
|