@zeyos/zx 4.4.0 → 5.2.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/CHANGELOG.md +447 -0
- package/README.md +44 -11
- package/dist/types/components/account-menu/account-menu.d.ts +8 -0
- package/dist/types/components/activity-list/activity-list.d.ts +31 -1
- package/dist/types/components/app-icon/app-icon.d.ts +14 -2
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +293 -17
- package/dist/types/components/avatar/avatar.d.ts +46 -7
- package/dist/types/components/badge/badge.d.ts +21 -1
- package/dist/types/components/button/button.d.ts +15 -0
- package/dist/types/components/calendar/calendar.d.ts +67 -5
- package/dist/types/components/card-view/card-view.d.ts +7 -4
- package/dist/types/components/card-view/record-card.d.ts +11 -0
- package/dist/types/components/chart/chart.d.ts +10 -0
- package/dist/types/components/checklist/checklist.d.ts +9 -0
- package/dist/types/components/code-editor/code-editor.d.ts +6 -17
- package/dist/types/components/context-menu/context-menu.d.ts +6 -2
- package/dist/types/components/data-filter/data-filter.d.ts +4 -4
- package/dist/types/components/datebox/date-range-box.d.ts +5 -1
- package/dist/types/components/datebox/datebox.d.ts +7 -2
- package/dist/types/components/dialog/dialog.d.ts +46 -6
- package/dist/types/components/dropdown/dropdown.d.ts +24 -9
- package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
- package/dist/types/components/field/field.d.ts +54 -2
- package/dist/types/components/fieldset/external-adapter.d.ts +83 -0
- package/dist/types/components/fieldset/fieldset.d.ts +26 -1
- package/dist/types/components/file-item/file-item.d.ts +34 -6
- package/dist/types/components/file-list/file-list.d.ts +35 -3
- package/dist/types/components/filter/filter.d.ts +127 -3
- package/dist/types/components/filter-panel/filter-panel.d.ts +36 -7
- package/dist/types/components/form/form.d.ts +12 -1
- package/dist/types/components/kanban-view/kanban-card.d.ts +8 -0
- package/dist/types/components/launcher/launcher.d.ts +268 -15
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +16 -7
- package/dist/types/components/menu-button/menu-button.d.ts +39 -5
- package/dist/types/components/message/message.d.ts +132 -17
- package/dist/types/components/modal/modal.d.ts +43 -2
- package/dist/types/components/module-bar/module-bar.d.ts +395 -0
- package/dist/types/components/pagination/pagination.d.ts +17 -3
- package/dist/types/components/select/color.d.ts +12 -0
- package/dist/types/components/select/glyphs.d.ts +124 -0
- package/dist/types/components/select/select.d.ts +17 -3
- package/dist/types/components/sheet/sheet.d.ts +15 -0
- package/dist/types/components/stat-tile/stat-tile.d.ts +16 -5
- package/dist/types/components/tabbox/tabbox.d.ts +9 -0
- package/dist/types/components/table/table.d.ts +311 -18
- package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
- package/dist/types/components/tree/tree.d.ts +13 -0
- package/dist/types/components/view/record-view.d.ts +59 -2
- package/dist/types/components/view-settings/view-settings.d.ts +879 -0
- package/dist/types/components/workspace-switcher/workspace-switcher.d.ts +327 -0
- package/dist/types/core/breakpoint.d.ts +1 -1
- package/dist/types/core/component.d.ts +12 -2
- package/dist/types/core/i18n.d.ts +27 -3
- package/dist/types/core/icons.d.ts +23 -25
- package/dist/types/core/keyboard.d.ts +98 -1
- package/dist/types/core/messages.d.ts +382 -0
- package/dist/types/core/motion.d.ts +59 -0
- package/dist/types/core/overlay-host.d.ts +42 -1
- package/dist/types/core/overlay-stack.d.ts +260 -0
- package/dist/types/index.d.ts +10 -5
- package/dist/types/internal/app-rail.d.ts +38 -0
- package/dist/types/internal/menu-items.d.ts +71 -3
- package/dist/types/zeyos/connect.d.ts +6 -0
- package/dist/types/zeyos/form.d.ts +50 -9
- package/dist/types/zeyos/index.d.ts +2 -1
- package/dist/types/zeyos/launcher.d.ts +9 -0
- package/dist/types/zeyos/module-bar.d.ts +176 -0
- package/dist/types/zeyos/query.d.ts +110 -5
- package/dist/types/zeyos/schema.d.ts +24 -1
- package/dist/types/zeyos/table.d.ts +345 -22
- package/dist/types/zeyos/view.d.ts +26 -2
- package/dist/zx-zeyos.esm.js +6178 -1008
- package/dist/zx-zeyos.esm.min.js +53 -5
- package/dist/zx.css +2861 -827
- package/dist/zx.esm.js +8909 -1480
- package/dist/zx.esm.min.js +55 -7
- package/dist/zx.global.js +8911 -1482
- package/dist/zx.global.min.js +55 -7
- package/dist/zx.min.css +1 -1
- package/docs/api.json +1079 -117
- package/docs/llms.md +956 -154
- package/docs/llms.txt +9 -5
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- package/src/components/account-menu/account-menu.js +12 -0
- package/src/components/activity-item/activity-item.css +1 -1
- package/src/components/activity-item/activity-item.js +3 -0
- package/src/components/activity-list/activity-list.css +38 -3
- package/src/components/activity-list/activity-list.js +61 -1
- package/src/components/app-icon/app-icon.css +14 -3
- package/src/components/app-icon/app-icon.js +11 -1
- package/src/components/app-rail/app-rail.css +59 -79
- package/src/components/app-sidebar/app-sidebar.css +304 -168
- package/src/components/app-sidebar/app-sidebar.js +667 -46
- package/src/components/aurora/aurora.css +5 -3
- package/src/components/avatar/avatar.css +32 -7
- package/src/components/avatar/avatar.js +72 -8
- package/src/components/badge/badge.css +54 -2
- package/src/components/badge/badge.js +29 -2
- package/src/components/breadcrumb/breadcrumb.css +1 -1
- package/src/components/button/button.css +67 -9
- package/src/components/button/button.js +38 -0
- package/src/components/calendar/calendar.css +47 -47
- package/src/components/calendar/calendar.js +26 -52
- package/src/components/card/card.css +4 -4
- package/src/components/card-view/card-view.css +14 -12
- package/src/components/card-view/card-view.js +13 -9
- package/src/components/card-view/record-card.js +14 -3
- package/src/components/chart/chart.css +4 -1
- package/src/components/chart/chart.js +12 -0
- package/src/components/check-button/check-button.css +10 -2
- package/src/components/checklist/checklist.css +9 -2
- package/src/components/checklist/checklist.js +11 -5
- package/src/components/checklist/field-adapter.js +3 -1
- package/src/components/code-editor/code-editor.css +7 -6
- package/src/components/code-editor/code-editor.js +19 -1
- package/src/components/code-editor/field-adapter.js +9 -2
- package/src/components/context-menu/context-menu.css +9 -4
- package/src/components/context-menu/context-menu.js +8 -2
- package/src/components/copy/copy-button.css +6 -0
- package/src/components/copy/copy-input.css +9 -4
- package/src/components/data-filter/data-filter.css +5 -4
- package/src/components/data-filter/data-filter.js +2 -2
- package/src/components/date-picker/date-picker.css +6 -6
- package/src/components/date-picker/date-range-picker.css +3 -3
- package/src/components/date-picker/time-picker.css +3 -3
- package/src/components/datebox/date-range-box.css +79 -2
- package/src/components/datebox/date-range-box.js +13 -2
- package/src/components/datebox/datebox.css +79 -2
- package/src/components/datebox/datebox.js +13 -2
- package/src/components/dialog/dialog.css +26 -0
- package/src/components/dialog/dialog.js +99 -17
- package/src/components/dock/dock.css +5 -4
- package/src/components/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +159 -72
- package/src/components/empty-state/empty-state.css +2 -2
- package/src/components/entity-ref/entity-ref.css +1 -1
- package/src/components/entity-ref/entity-ref.js +1 -1
- package/src/components/field/field.css +28 -9
- package/src/components/field/field.js +101 -29
- package/src/components/field-upload/field-upload.css +1 -1
- package/src/components/fieldset/external-adapter.js +363 -0
- package/src/components/fieldset/fieldset.css +5 -3
- package/src/components/fieldset/fieldset.js +38 -64
- package/src/components/file-item/file-item.js +144 -10
- package/src/components/file-list/file-list.js +144 -21
- package/src/components/filter/filter.css +86 -2
- package/src/components/filter/filter.js +307 -11
- package/src/components/filter-panel/filter-panel.css +1 -1
- package/src/components/filter-panel/filter-panel.js +149 -32
- package/src/components/finder/finder.css +16 -14
- package/src/components/form/form.css +5 -4
- package/src/components/form/form.js +11 -2
- package/src/components/grid/grid.css +1 -1
- package/src/components/groupbox/groupbox.css +1 -1
- package/src/components/kanban-view/kanban-card.js +11 -3
- package/src/components/kanban-view/kanban-view.css +42 -18
- package/src/components/kanban-view/kanban-view.js +9 -6
- package/src/components/launcher/launcher.css +108 -26
- package/src/components/launcher/launcher.js +530 -42
- package/src/components/list-toolbar/list-toolbar.css +13 -8
- package/src/components/list-toolbar/list-toolbar.js +40 -14
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/master-panel/master-panel.js +0 -1
- package/src/components/menu-button/menu-button.css +72 -4
- package/src/components/menu-button/menu-button.js +160 -18
- package/src/components/message/message.css +33 -3
- package/src/components/message/message.js +264 -22
- package/src/components/modal/modal.css +1 -1
- package/src/components/modal/modal.js +83 -15
- package/src/components/module-bar/module-bar.css +486 -0
- package/src/components/module-bar/module-bar.js +1074 -0
- package/src/components/multi-value-editor/multi-value-editor.css +1 -1
- package/src/components/navigation-bar/navigation-bar.css +18 -9
- package/src/components/number-field/field-adapter.js +3 -1
- package/src/components/number-field/number-field.css +70 -0
- package/src/components/number-field/number-field.js +2 -0
- package/src/components/pagination/pagination.css +13 -11
- package/src/components/pagination/pagination.js +20 -4
- package/src/components/panel/panel.css +4 -3
- package/src/components/questionnaire/questionnaire.css +4 -4
- package/src/components/rating/field-adapter.js +2 -1
- package/src/components/rating/rating.css +8 -1
- package/src/components/search/search.css +4 -1
- package/src/components/select/color.js +22 -0
- package/src/components/select/field-adapter.js +2 -0
- package/src/components/select/glyphs.js +165 -0
- package/src/components/select/select.css +138 -45
- package/src/components/select/select.js +92 -47
- package/src/components/sheet/sheet.css +12 -9
- package/src/components/sheet/sheet.js +74 -32
- package/src/components/slider/field-adapter.js +6 -1
- package/src/components/slider/slider.css +18 -4
- package/src/components/slider/slider.js +1 -1
- package/src/components/sort-control/sort-control.css +4 -1
- package/src/components/split-view/split-view.css +1 -1
- package/src/components/stat-tile/stat-tile.css +42 -47
- package/src/components/stat-tile/stat-tile.js +17 -6
- package/src/components/stepper/stepper.css +1 -1
- package/src/components/tabbox/tabbox.css +41 -32
- package/src/components/tabbox/tabbox.js +5 -1
- package/src/components/table/table.css +187 -37
- package/src/components/table/table.js +718 -73
- package/src/components/tag-picker/field-adapter.js +2 -1
- package/src/components/tag-picker/tag-picker.css +83 -5
- package/src/components/tag-picker/tag-picker.js +25 -8
- package/src/components/timebox/timebox.css +22 -2
- package/src/components/toggle/toggle.css +12 -1
- package/src/components/toolbar/toolbar.js +2 -2
- package/src/components/tooltip/tooltip.css +4 -0
- package/src/components/tooltip/tooltip.js +44 -19
- package/src/components/tree/tree.css +26 -17
- package/src/components/tree/tree.js +31 -0
- package/src/components/value-list/value-list.css +3 -3
- package/src/components/view/record-view.css +1 -1
- package/src/components/view/record-view.js +178 -18
- package/src/components/view-settings/view-settings.css +285 -0
- package/src/components/view-settings/view-settings.js +1830 -0
- package/src/components/workspace-switcher/workspace-switcher.css +188 -0
- package/src/components/workspace-switcher/workspace-switcher.js +463 -0
- package/src/core/breakpoint.js +1 -1
- package/src/core/component.js +88 -17
- package/src/core/fontawesome.js +5 -1
- package/src/core/i18n.js +47 -4
- package/src/core/icons.js +204 -61
- package/src/core/keyboard.js +206 -11
- package/src/core/messages.js +427 -0
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +77 -3
- package/src/core/overlay-stack.js +487 -0
- package/src/core/position.js +22 -3
- package/src/index.js +10 -5
- package/src/internal/app-rail.js +135 -55
- package/src/internal/menu-items.js +61 -3
- package/src/zeyos/connect.js +6 -2
- package/src/zeyos/form.js +69 -27
- package/src/zeyos/index.js +4 -1
- package/src/zeyos/launcher.js +8 -3
- package/src/zeyos/module-bar.js +181 -0
- package/src/zeyos/query.js +197 -13
- package/src/zeyos/schema.js +144 -27
- package/src/zeyos/table.js +287 -84
- package/src/zeyos/view.js +49 -93
- package/styles/base.css +72 -1
- package/styles/icons.css +11 -1
- package/styles/print.css +1 -1
- package/styles/tokens/dark.css +117 -37
- package/styles/tokens/global.css +121 -27
- package/styles/tokens/semantic.css +140 -43
- package/styles/tokens/themes.css +7 -6
- package/styles/zx.css +3 -1
- package/styles/tokens/density.css +0 -9
|
@@ -47,7 +47,8 @@ import {
|
|
|
47
47
|
* @property {'outlined'|'raised'|'filled'} [variant='outlined'] Card surface treatment.
|
|
48
48
|
* @property {number} [loadingCount=6] Skeleton cards shown while loading.
|
|
49
49
|
* @property {1|2|3|4|5|6} [headingLevel=3] Per-card title heading level.
|
|
50
|
-
* @property {string} [label=
|
|
50
|
+
* @property {string|null} [label=null] Accessible collection label; null resolves message
|
|
51
|
+
* `cardView.label`, "Card view".
|
|
51
52
|
* @property {(event:CustomEvent<Record<string,unknown>>)=>void} [onrecordaction]
|
|
52
53
|
*/
|
|
53
54
|
|
|
@@ -96,7 +97,7 @@ export class CardView extends RecordView {
|
|
|
96
97
|
variant: 'outlined',
|
|
97
98
|
loadingCount: 6,
|
|
98
99
|
headingLevel: 3,
|
|
99
|
-
label:
|
|
100
|
+
label: null
|
|
100
101
|
};
|
|
101
102
|
|
|
102
103
|
/**
|
|
@@ -126,7 +127,7 @@ export class CardView extends RecordView {
|
|
|
126
127
|
this._cardHeadingLevel = normalizeHeadingLevel(options.headingLevel);
|
|
127
128
|
try {
|
|
128
129
|
this._initRecordView(root);
|
|
129
|
-
root.setAttribute('aria-label', String(options.label || '
|
|
130
|
+
root.setAttribute('aria-label', String(options.label || this.msg('cardView.label')));
|
|
130
131
|
const sort = h('label', { ref: 'sortWrap', class: 'zx-card-view__sort' },
|
|
131
132
|
h('span', { class: 'zx-card-view__sort-label' }, this._message('cardView.sort', 'Sort')),
|
|
132
133
|
h('select', { ref: 'sort', ariaLabel: this._message('cardView.sortCards', 'Sort cards') }));
|
|
@@ -258,7 +259,7 @@ export class CardView extends RecordView {
|
|
|
258
259
|
return;
|
|
259
260
|
}
|
|
260
261
|
const groups = groupCardRecords(this._viewData, this._cardOptions().groupBy,
|
|
261
|
-
this._cardGroupOrder, this._viewFields);
|
|
262
|
+
this._cardGroupOrder, this._viewFields, this.msg('cardView.ungrouped'));
|
|
262
263
|
if (this._viewData.length === 0 && groups.length === 0) {
|
|
263
264
|
content.replaceChildren(this._createCardEmpty());
|
|
264
265
|
return;
|
|
@@ -298,13 +299,14 @@ export class CardView extends RecordView {
|
|
|
298
299
|
selectionTrigger: options.selectionTrigger,
|
|
299
300
|
selected: this._isViewSelected(id),
|
|
300
301
|
variant: this._cardVariant,
|
|
301
|
-
headingLevel: this._cardHeadingLevel
|
|
302
|
+
headingLevel: this._cardHeadingLevel,
|
|
303
|
+
message: (key, ...args) => this.msg(key, ...args)
|
|
302
304
|
});
|
|
303
305
|
this._cardNodesById.set(id, card);
|
|
304
306
|
list.append(card);
|
|
305
307
|
}
|
|
306
308
|
if (group.records.length === 0) {
|
|
307
|
-
list.append(h('li', { class: 'zx-card-view__group-empty' },
|
|
309
|
+
list.append(h('li', { class: 'zx-card-view__group-empty' }, this.msg('cardView.groupEmpty')));
|
|
308
310
|
}
|
|
309
311
|
if (group.id === null) return list;
|
|
310
312
|
return h('section', { class: 'zx-card-view__group', ariaLabelledby: headingId },
|
|
@@ -339,7 +341,8 @@ export class CardView extends RecordView {
|
|
|
339
341
|
for (const [id, card] of this._cardNodesById) {
|
|
340
342
|
const selected = this._isViewSelected(id);
|
|
341
343
|
card.dataset.selected = String(selected);
|
|
342
|
-
if (this.options.selectable) card.setAttribute('aria-description',
|
|
344
|
+
if (this.options.selectable) card.setAttribute('aria-description',
|
|
345
|
+
this.msg(selected ? 'recordCard.selected' : 'recordCard.notSelected'));
|
|
343
346
|
const checkbox = /** @type {HTMLInputElement|null} */ (card.querySelector('[data-record-selection]'));
|
|
344
347
|
if (checkbox) checkbox.checked = selected;
|
|
345
348
|
}
|
|
@@ -444,9 +447,10 @@ export class CardView extends RecordView {
|
|
|
444
447
|
* @param {CardViewOptions['groupBy']} groupBy Group field or resolver.
|
|
445
448
|
* @param {unknown[]} [groupOrder=[]] Preferred group ids.
|
|
446
449
|
* @param {ViewField[]} [fields=[]] Complete fields for accessor-aware grouping.
|
|
450
|
+
* @param {string} [ungroupedLabel='Ungrouped'] Label of the group collecting records without a value.
|
|
447
451
|
* @returns {CardRecordGroup[]} Deterministic groups.
|
|
448
452
|
*/
|
|
449
|
-
export function groupCardRecords(records, groupBy, groupOrder = [], fields = []) {
|
|
453
|
+
export function groupCardRecords(records, groupBy, groupOrder = [], fields = [], ungroupedLabel = 'Ungrouped') {
|
|
450
454
|
if (!Array.isArray(records)) throw new TypeError('Card view records must be an array');
|
|
451
455
|
if (groupBy == null) return records.length ? [{ id: null, label: '', records: [...records] }] : [];
|
|
452
456
|
const preferred = normalizeGroupOrder(groupOrder);
|
|
@@ -461,7 +465,7 @@ export function groupCardRecords(records, groupBy, groupOrder = [], fields = [])
|
|
|
461
465
|
}
|
|
462
466
|
return [...groups].map(([id, grouped]) => ({
|
|
463
467
|
id,
|
|
464
|
-
label: id ||
|
|
468
|
+
label: id || ungroupedLabel,
|
|
465
469
|
records: grouped
|
|
466
470
|
}));
|
|
467
471
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { h, safeHref } from '../../core/dom.js';
|
|
3
3
|
import { icon } from '../../core/icons.js';
|
|
4
|
+
import { translate } from '../../core/i18n.js';
|
|
4
5
|
import { uid } from '../../core/util.js';
|
|
5
6
|
import { readViewField, renderViewField } from '../view/record-view.js';
|
|
6
7
|
|
|
@@ -67,6 +68,10 @@ import { readViewField, renderViewField } from '../view/record-view.js';
|
|
|
67
68
|
* @property {'outlined'|'raised'|'filled'} [variant='outlined'] Surface treatment.
|
|
68
69
|
* @property {1|2|3|4|5|6} [headingLevel=3] Card title heading level.
|
|
69
70
|
* @property {Node[]} [controls=[]] Listener-free, owner-created controls such as a move handle.
|
|
71
|
+
* @property {(key: string, ...args: unknown[]) => string} [message] Resolves the card's built-in strings
|
|
72
|
+
* (`recordCard.select`, `recordCard.actions`, `recordCard.untitled`, `recordCard.selected`,
|
|
73
|
+
* `recordCard.notSelected`). An owning component passes its own `msg()`; omitted, the host
|
|
74
|
+
* translator and then the default English catalogue answer.
|
|
70
75
|
*/
|
|
71
76
|
|
|
72
77
|
/**
|
|
@@ -111,6 +116,11 @@ export function createRecordCard(record, index, options = {}) {
|
|
|
111
116
|
const selected = Boolean(options.selected);
|
|
112
117
|
const headingId = uid('zx-record-card-title');
|
|
113
118
|
const headingLevel = normalizeHeadingLevel(options.headingLevel);
|
|
119
|
+
/** @type {(key: string, ...args: unknown[]) => string} */
|
|
120
|
+
const message = typeof options.message === 'function'
|
|
121
|
+
? options.message
|
|
122
|
+
: (key, ...args) => translate(key, args);
|
|
123
|
+
const name = textAlternative(title) || message('recordCard.untitled');
|
|
114
124
|
|
|
115
125
|
const headingContent = link
|
|
116
126
|
? h('a', {
|
|
@@ -137,13 +147,13 @@ export function createRecordCard(record, index, options = {}) {
|
|
|
137
147
|
type: 'checkbox',
|
|
138
148
|
checked: selected,
|
|
139
149
|
dataset: { recordSelection: '' },
|
|
140
|
-
ariaLabel:
|
|
150
|
+
ariaLabel: message('recordCard.select', name)
|
|
141
151
|
})) : null;
|
|
142
152
|
const actionNodes = actions.map(createAction);
|
|
143
153
|
const actionArea = actionNodes.length || controls.length ? h('div', {
|
|
144
154
|
class: 'zx-record-card__actions',
|
|
145
155
|
role: 'group',
|
|
146
|
-
ariaLabel:
|
|
156
|
+
ariaLabel: message('recordCard.actions', name)
|
|
147
157
|
}, controls, actionNodes) : null;
|
|
148
158
|
const header = h('header', { class: 'zx-record-card__header' }, selection,
|
|
149
159
|
h('div', { class: 'zx-record-card__titles' }, titleRow,
|
|
@@ -154,7 +164,8 @@ export function createRecordCard(record, index, options = {}) {
|
|
|
154
164
|
const card = /** @type {HTMLLIElement} */ (h('li', {
|
|
155
165
|
class: 'zx-record-card',
|
|
156
166
|
tabindex: 0,
|
|
157
|
-
ariaDescription: selectable
|
|
167
|
+
ariaDescription: selectable
|
|
168
|
+
? message(selected ? 'recordCard.selected' : 'recordCard.notSelected') : undefined,
|
|
158
169
|
ariaLabelledby: headingId,
|
|
159
170
|
ariaKeyshortcuts: selectable && options.selectionTrigger === 'card' ? 'Space Enter' : undefined,
|
|
160
171
|
dataset: {
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
.zx-chart__viewport {
|
|
9
9
|
position: relative;
|
|
10
10
|
inline-size: 100%;
|
|
11
|
+
/* The automatic minimum width would carry the 220px floor through the aspect ratio (587px at
|
|
12
|
+
16 / 6) and push the canvas out of a narrow card; narrow, the chart grows taller instead. */
|
|
13
|
+
min-inline-size: 0;
|
|
11
14
|
min-block-size: 220px;
|
|
12
15
|
aspect-ratio: var(--zx-chart-aspect-ratio, 16 / 9);
|
|
13
16
|
}
|
|
@@ -54,7 +57,7 @@
|
|
|
54
57
|
border-collapse: collapse;
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
.zx-chart__table caption { margin-block-end: var(--zx-space-2); font-weight:
|
|
60
|
+
.zx-chart__table caption { margin-block-end: var(--zx-space-2); font-weight: var(--zx-weight-semibold); text-align: start; }
|
|
58
61
|
.zx-chart__table th,
|
|
59
62
|
.zx-chart__table td { border-block-end: 1px solid var(--zx-color-border); padding: var(--zx-space-2); text-align: end; }
|
|
60
63
|
.zx-chart__table th:first-child,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component } from '../../core/component.js';
|
|
2
2
|
import { h } from '../../core/dom.js';
|
|
3
|
+
import { prefersReducedMotion, watchMotion } from '../../core/motion.js';
|
|
3
4
|
import { uid } from '../../core/util.js';
|
|
4
5
|
|
|
5
6
|
/** @typedef {{label?: string, data?: unknown[], [key: string]: unknown}} ChartDataset */
|
|
@@ -9,6 +10,9 @@ import { uid } from '../../core/util.js';
|
|
|
9
10
|
* @property {string} type Chart type.
|
|
10
11
|
* @property {ChartData} data Chart data.
|
|
11
12
|
* @property {Record<string, unknown>} options Engine-specific options.
|
|
13
|
+
* @property {boolean} reducedMotion Whether the chart must not animate: the operating system asks
|
|
14
|
+
* for reduced motion, or the host sits inside a `data-zx-motion="reduced"` region. An adapter turns
|
|
15
|
+
* its engine's own animation off when this is true; `ChartJsAdapter` sets `animation: false`.
|
|
12
16
|
* @property {(detail: ChartSelectDetail) => void} onSelect Point-selection callback.
|
|
13
17
|
*/
|
|
14
18
|
/**
|
|
@@ -145,6 +149,9 @@ export class Chart extends Component {
|
|
|
145
149
|
|
|
146
150
|
this._observer = typeof ResizeObserver === 'function' ? new ResizeObserver(() => this.resize()) : null;
|
|
147
151
|
this._observer?.observe(viewport);
|
|
152
|
+
// The engine tweens in script, where no stylesheet can reach it: when motion is reduced, or
|
|
153
|
+
// stops being reduced, the mounted chart is updated with the new answer in its spec.
|
|
154
|
+
this._stopWatchingMotion = watchMotion(root, () => this._mountOrUpdate(false));
|
|
148
155
|
return root;
|
|
149
156
|
}
|
|
150
157
|
|
|
@@ -232,6 +239,7 @@ export class Chart extends Component {
|
|
|
232
239
|
this._destroyed = true;
|
|
233
240
|
const original = this._original;
|
|
234
241
|
this._observer?.disconnect();
|
|
242
|
+
this._stopWatchingMotion?.();
|
|
235
243
|
this._destroyHandle();
|
|
236
244
|
super.destroy();
|
|
237
245
|
if (!this._createdRoot && original) {
|
|
@@ -277,6 +285,7 @@ export class Chart extends Component {
|
|
|
277
285
|
...themeChartOptions(/** @type {HTMLElement} */ (this.el)),
|
|
278
286
|
...cloneChartValue(this._chartOptions)
|
|
279
287
|
},
|
|
288
|
+
reducedMotion: prefersReducedMotion(this.el),
|
|
280
289
|
onSelect: (detail) => this.emit('select', detail)
|
|
281
290
|
};
|
|
282
291
|
}
|
|
@@ -386,6 +395,9 @@ function chartJsConfig(spec, defaults, getInstance) {
|
|
|
386
395
|
...cloneChartValue(defaults),
|
|
387
396
|
...supplied
|
|
388
397
|
};
|
|
398
|
+
// Reduced motion wins over any animation the application configured: a person who asked for
|
|
399
|
+
// less motion gets it from every chart, not only from the ones that remembered to ask.
|
|
400
|
+
if (spec.reducedMotion) options.animation = false;
|
|
389
401
|
const originalClick = options.onClick;
|
|
390
402
|
options.onClick = (event, elements, chart) => {
|
|
391
403
|
if (typeof originalClick === 'function') originalClick(event, elements, chart);
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
padding-inline: var(--zx-control-pad-x);
|
|
12
12
|
font: inherit;
|
|
13
13
|
font-size: var(--zx-control-font-size);
|
|
14
|
+
font-weight: var(--zx-control-font-weight);
|
|
14
15
|
cursor: pointer;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -18,9 +19,16 @@
|
|
|
18
19
|
background: var(--zx-color-bg-hover);
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
/* Pressed is a state the button is in, so the button itself goes neutral — the current fill, a
|
|
23
|
+
stronger border, the full text colour — and only the check glyph, which is the mark, keeps the
|
|
24
|
+
accent, as a checkbox would. */
|
|
21
25
|
.zx-check-button[aria-pressed="true"] {
|
|
22
|
-
border-color: var(--zx-color-
|
|
23
|
-
background: var(--zx-color-bg-
|
|
26
|
+
border-color: var(--zx-color-border-strong);
|
|
27
|
+
background: var(--zx-color-bg-current);
|
|
28
|
+
color: var(--zx-color-text);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.zx-check-button__on {
|
|
24
32
|
color: var(--zx-color-accent);
|
|
25
33
|
}
|
|
26
34
|
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
.zx-checklist__label {
|
|
10
|
-
|
|
10
|
+
color: var(--zx-color-text-muted);
|
|
11
|
+
font-size: var(--zx-text-sm);
|
|
12
|
+
font-weight: var(--zx-weight-medium);
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
.zx-checklist__search {
|
|
@@ -31,10 +33,12 @@
|
|
|
31
33
|
display: flex;
|
|
32
34
|
align-items: center;
|
|
33
35
|
gap: var(--zx-space-2);
|
|
34
|
-
|
|
36
|
+
/* The same row as a listbox option. */
|
|
37
|
+
min-block-size: calc(var(--zx-control-height) - 2px);
|
|
35
38
|
border-radius: var(--zx-radius-sm);
|
|
36
39
|
cursor: pointer;
|
|
37
40
|
padding: var(--zx-space-1) var(--zx-space-2);
|
|
41
|
+
line-height: 1.35;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
.zx-checklist__item:hover {
|
|
@@ -45,8 +49,11 @@
|
|
|
45
49
|
background: var(--zx-color-bg-selected);
|
|
46
50
|
}
|
|
47
51
|
|
|
52
|
+
/* The base control height is for text fields; a checkbox that inherited it would make every row
|
|
53
|
+
a field tall. */
|
|
48
54
|
.zx-checklist__item input {
|
|
49
55
|
flex: none;
|
|
56
|
+
min-block-size: 0;
|
|
50
57
|
accent-color: var(--zx-color-accent);
|
|
51
58
|
}
|
|
52
59
|
|
|
@@ -13,6 +13,9 @@ import { matchItems } from '../select/filter.js';
|
|
|
13
13
|
* @property {boolean} [search=true] Whether the search field is shown.
|
|
14
14
|
* @property {number} [height=280] Maximum list height in pixels.
|
|
15
15
|
* @property {boolean} [defaultChecked=false] Fallback initial checked state.
|
|
16
|
+
* @property {boolean} [hideLabel=false] Whether the heading is left out. The group keeps the
|
|
17
|
+
* heading text as its accessible name (`aria-label`); a Field labelling the checklist names it
|
|
18
|
+
* instead, which is why the `checklist` field type sets this.
|
|
16
19
|
* @property {(() => Promise<ChecklistItem[]>|ChecklistItem[])|null} [load=null] Async item loader.
|
|
17
20
|
* @property {Record<string, string>|Record<string, Record<string, string>>} [msg] Localized messages.
|
|
18
21
|
* @property {(event: CustomEvent<ChecklistChangeDetail>) => void} [onchange] Change listener.
|
|
@@ -40,6 +43,7 @@ export class Checklist extends Component {
|
|
|
40
43
|
search: true,
|
|
41
44
|
height: 280,
|
|
42
45
|
defaultChecked: false,
|
|
46
|
+
hideLabel: false,
|
|
43
47
|
load: null
|
|
44
48
|
};
|
|
45
49
|
|
|
@@ -53,15 +57,16 @@ export class Checklist extends Component {
|
|
|
53
57
|
const root = /** @type {HTMLElement} */ (this.el ?? h('div'));
|
|
54
58
|
this.el = root;
|
|
55
59
|
if (!this._createdRoot) this._originalChildren = Array.from(root.childNodes);
|
|
56
|
-
for (const name of ['role', 'aria-labelledby', 'data-state']) {
|
|
60
|
+
for (const name of ['role', 'aria-label', 'aria-labelledby', 'data-state']) {
|
|
57
61
|
this._originalAttributes.set(name, root.getAttribute(name));
|
|
58
62
|
}
|
|
59
63
|
|
|
64
|
+
const labelText = this._message('checklist.label', 'Checklist');
|
|
60
65
|
const labelId = uid('zx-checklist-label');
|
|
61
|
-
const title = h('div', {
|
|
66
|
+
const title = this.options.hideLabel ? null : h('div', {
|
|
62
67
|
class: 'zx-checklist__label',
|
|
63
68
|
id: labelId
|
|
64
|
-
},
|
|
69
|
+
}, labelText);
|
|
65
70
|
const search = h('input', {
|
|
66
71
|
ref: 'search',
|
|
67
72
|
class: 'zx-checklist__search',
|
|
@@ -76,9 +81,10 @@ export class Checklist extends Component {
|
|
|
76
81
|
class: 'zx-checklist__list'
|
|
77
82
|
});
|
|
78
83
|
list.style.maxBlockSize = `${Math.max(0, Number(this.options.height) || 0)}px`;
|
|
79
|
-
root.replaceChildren(title, search, list);
|
|
84
|
+
root.replaceChildren(...[title, search, list].filter(Boolean));
|
|
80
85
|
root.setAttribute('role', 'group');
|
|
81
|
-
root.setAttribute('aria-labelledby', labelId);
|
|
86
|
+
if (title) root.setAttribute('aria-labelledby', labelId);
|
|
87
|
+
else root.setAttribute('aria-label', labelText);
|
|
82
88
|
|
|
83
89
|
this.listen(search, 'input', () => this.search(/** @type {HTMLInputElement} */ (search).value));
|
|
84
90
|
this.listen(list, 'change', (event) => {
|
|
@@ -7,7 +7,9 @@ import { Checklist } from './checklist.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export function registerChecklistFieldAdapter() {
|
|
9
9
|
Field.register('checklist', (field, options) => {
|
|
10
|
-
|
|
10
|
+
// The Field's label names the list (`aria-labelledby`), so the checklist draws no heading of
|
|
11
|
+
// its own under it.
|
|
12
|
+
const checklist = field.own(new Checklist(null, { hideLabel: true, ...(options.props ?? {}) }));
|
|
11
13
|
let disabled = false;
|
|
12
14
|
let setting = false;
|
|
13
15
|
const syncDisabled = () => {
|
|
@@ -17,17 +17,18 @@
|
|
|
17
17
|
min-block-size: var(--zx-control-height);
|
|
18
18
|
padding-inline: var(--zx-space-3);
|
|
19
19
|
border-block-end: 1px solid var(--zx-color-border);
|
|
20
|
-
background: var(--zx-color-bg-
|
|
20
|
+
background: var(--zx-color-bg-muted);
|
|
21
21
|
color: var(--zx-color-text-muted);
|
|
22
22
|
font-size: var(--zx-text-xs);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/* The language is an identifier (`json`, `sql`), so it is shown as one — in the mono face, as
|
|
26
|
+
written — rather than shouted in letter-spaced capitals. */
|
|
25
27
|
.zx-code-editor__language {
|
|
26
28
|
overflow: hidden;
|
|
27
|
-
font-
|
|
28
|
-
|
|
29
|
+
font-family: var(--zx-font-mono);
|
|
30
|
+
font-weight: var(--zx-weight-medium);
|
|
29
31
|
text-overflow: ellipsis;
|
|
30
|
-
text-transform: uppercase;
|
|
31
32
|
text-wrap: nowrap;
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
padding: var(--zx-space-3);
|
|
45
46
|
border: 0;
|
|
46
47
|
border-radius: 0;
|
|
47
|
-
outline:
|
|
48
|
+
outline-color: transparent;
|
|
48
49
|
background: transparent;
|
|
49
50
|
box-shadow: none;
|
|
50
51
|
color: var(--zx-color-text);
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
.zx-code-editor[data-readonly="true"] {
|
|
62
|
-
background: var(--zx-color-bg-
|
|
63
|
+
background: var(--zx-color-bg-muted);
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
.zx-code-editor[data-disabled="true"] {
|
|
@@ -19,10 +19,17 @@ import { h } from '../../core/dom.js';
|
|
|
19
19
|
* @property {(event: CustomEvent<{value:string}>) => void} [onchange] Change listener.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
/** Keys that only modify the next one: pressing them is not the keystroke that ends a Tab release. */
|
|
23
|
+
const MODIFIER_KEYS = new Set(['Shift', 'Control', 'Alt', 'Meta', 'AltGraph', 'CapsLock', 'Fn', 'OS']);
|
|
24
|
+
|
|
22
25
|
/**
|
|
23
26
|
* Dependency-free source editor for structured text, Markdown, JSON and code. It deliberately uses
|
|
24
27
|
* a native textarea: values remain text-safe, browser undo and IME behavior stay intact, and Tab /
|
|
25
28
|
* Shift+Tab provide predictable indentation without a third-party editor runtime.
|
|
29
|
+
*
|
|
30
|
+
* Capturing Tab is what a code surface has to do, and it would be a keyboard trap if nothing undid
|
|
31
|
+
* it: Escape releases the capture until the next keystroke in the editor, so Escape then Tab (or
|
|
32
|
+
* Shift+Tab) moves focus out of the editor as it would leave any other field.
|
|
26
33
|
* @fires CodeEditor#input
|
|
27
34
|
* @fires CodeEditor#change
|
|
28
35
|
* @extends {Component<CodeEditorOptions>}
|
|
@@ -81,8 +88,11 @@ export class CodeEditor extends Component {
|
|
|
81
88
|
root.dataset.readonly = String(Boolean(this.options.readOnly));
|
|
82
89
|
root.dataset.disabled = String(Boolean(this.options.disabled));
|
|
83
90
|
root.replaceChildren(this._header, this._input);
|
|
91
|
+
/** Set by Escape: the next Tab moves focus instead of indenting. */
|
|
92
|
+
this._tabReleased = false;
|
|
84
93
|
|
|
85
94
|
this.listen(this._input, 'keydown', (event) => this._handleKeydown(event));
|
|
95
|
+
this.listen(this._input, 'blur', () => { this._tabReleased = false; });
|
|
86
96
|
this.listen(this._input, 'input', () => {
|
|
87
97
|
this._updatePosition();
|
|
88
98
|
this.emit('input', { value: this.getValue() });
|
|
@@ -139,7 +149,15 @@ export class CodeEditor extends Component {
|
|
|
139
149
|
|
|
140
150
|
/** @param {KeyboardEvent} event @returns {void} */
|
|
141
151
|
_handleKeydown(event) {
|
|
142
|
-
if (event.
|
|
152
|
+
if (event.isComposing || MODIFIER_KEYS.has(event.key)) return;
|
|
153
|
+
if (event.key === 'Escape') {
|
|
154
|
+
this._tabReleased = true;
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// Any other keystroke ends the release, the Tab it was for included.
|
|
158
|
+
const released = this._tabReleased;
|
|
159
|
+
this._tabReleased = false;
|
|
160
|
+
if (released || event.key !== 'Tab' || event.altKey || event.ctrlKey || event.metaKey ||
|
|
143
161
|
this._input.readOnly || this._input.disabled) return;
|
|
144
162
|
const indent = String(this.options.indent ?? '\t');
|
|
145
163
|
if (!indent) return;
|
|
@@ -16,9 +16,15 @@ export function registerCodeEditorFieldAdapter() {
|
|
|
16
16
|
value: options.value
|
|
17
17
|
}));
|
|
18
18
|
let setting = false;
|
|
19
|
-
|
|
19
|
+
// The textarea's native `change` bubbles out of the editor after the editor has reported the
|
|
20
|
+
// same commit; without this the Field would emit `change` twice per edit.
|
|
21
|
+
field.listen(editor.el, 'change', (event) => event.stopImmediatePropagation());
|
|
22
|
+
// `change` on commit (the editor's own, when the textarea loses focus after an edit); every
|
|
23
|
+
// keystroke as `input`.
|
|
24
|
+
editor.on('change', (event) => {
|
|
20
25
|
if (!setting) field.emit('change', { value: event.detail.value });
|
|
21
26
|
});
|
|
27
|
+
editor.on('input', (event) => field.emit('input', { value: event.detail.value }));
|
|
22
28
|
return {
|
|
23
29
|
el: editor.el,
|
|
24
30
|
get: () => editor.getValue(),
|
|
@@ -28,7 +34,8 @@ export function registerCodeEditorFieldAdapter() {
|
|
|
28
34
|
finally { setting = false; }
|
|
29
35
|
},
|
|
30
36
|
focus: () => editor.focus(),
|
|
31
|
-
setDisabled: (value) => (value ? editor.disable() : editor.enable())
|
|
37
|
+
setDisabled: (value) => (value ? editor.disable() : editor.enable()),
|
|
38
|
+
setReadonly: (value) => { editor.setReadOnly(value); }
|
|
32
39
|
};
|
|
33
40
|
});
|
|
34
41
|
}
|
|
@@ -21,12 +21,16 @@
|
|
|
21
21
|
align-items: center;
|
|
22
22
|
gap: var(--zx-space-2);
|
|
23
23
|
inline-size: 100%;
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/* A menu row sits a little under a control so a list of them reads lighter than a column of
|
|
25
|
+
fields; the radius is the smallest step, inset inside the panel's own. */
|
|
26
|
+
min-block-size: calc(var(--zx-control-height) - 2px);
|
|
27
|
+
border: 0;
|
|
28
|
+
border-radius: var(--zx-radius-sm);
|
|
26
29
|
background: transparent;
|
|
27
|
-
padding
|
|
30
|
+
padding: var(--zx-space-1) var(--zx-space-2);
|
|
28
31
|
color: inherit;
|
|
29
32
|
font: inherit;
|
|
33
|
+
line-height: 1.35;
|
|
30
34
|
text-align: start;
|
|
31
35
|
text-decoration: none;
|
|
32
36
|
}
|
|
@@ -117,8 +121,9 @@
|
|
|
117
121
|
box-shadow: inset 0 0 0 2px var(--zx-color-bg-raised);
|
|
118
122
|
}
|
|
119
123
|
|
|
124
|
+
/* A section label is a caption, never taller than the rows it introduces. */
|
|
120
125
|
.zx-context-menu__heading {
|
|
121
|
-
padding: var(--zx-space-
|
|
126
|
+
padding: var(--zx-space-1) var(--zx-space-2);
|
|
122
127
|
color: var(--zx-color-text-muted);
|
|
123
128
|
font-size: var(--zx-text-xs);
|
|
124
129
|
font-weight: 600;
|
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
import { Dropdown } from '../dropdown/dropdown.js';
|
|
10
10
|
|
|
11
11
|
/** @typedef {import('../../internal/menu-items.js').MenuItem} MenuItem */
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* A context menu's entries: the shared menu model without `choice` rows, which a menu that closes
|
|
14
|
+
* on every activation cannot hold.
|
|
15
|
+
* @typedef {import('../../internal/menu-items.js').MenuItem|import('../../internal/menu-items.js').MenuHeading|import('../../internal/menu-items.js').MenuSeparator|'-'} ContextMenuEntry
|
|
16
|
+
*/
|
|
13
17
|
|
|
14
18
|
/**
|
|
15
19
|
* @typedef {Object} ContextMenuOptions
|
|
@@ -90,6 +94,8 @@ export class ContextMenu extends Component {
|
|
|
90
94
|
scope: resolved
|
|
91
95
|
});
|
|
92
96
|
this.#panel = this.#dropdown.getPanel();
|
|
97
|
+
// Escape arrives through the overlay stack; closing returns focus where the menu came from.
|
|
98
|
+
this.#dropdown._configure({ onEscape: () => this.close(), tabReach: false });
|
|
93
99
|
this.#panel.classList.add('zx-context-menu');
|
|
94
100
|
this.#panel.setAttribute('role', 'menu');
|
|
95
101
|
|
|
@@ -268,7 +274,7 @@ export class ContextMenu extends Component {
|
|
|
268
274
|
/** @param {Event} event @returns {void} */
|
|
269
275
|
#onMenuKeydown(event) {
|
|
270
276
|
const key = /** @type {KeyboardEvent} */ (event);
|
|
271
|
-
if (key.key === '
|
|
277
|
+
if (key.key === 'Tab') {
|
|
272
278
|
event.preventDefault();
|
|
273
279
|
this.close();
|
|
274
280
|
return;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
/* Positioned so the hidden status line below is placed inside the button. Without a positioned
|
|
2
|
+
ancestor it would hang off the page instead, adding scrollable overflow that focus() can scroll
|
|
3
|
+
into view. */
|
|
1
4
|
.zx-copy-button {
|
|
5
|
+
position: relative;
|
|
2
6
|
display: inline-flex;
|
|
3
7
|
align-items: center;
|
|
4
8
|
gap: var(--zx-space-2);
|
|
@@ -19,6 +23,8 @@
|
|
|
19
23
|
*/
|
|
20
24
|
.zx-copy-button__status {
|
|
21
25
|
position: absolute;
|
|
26
|
+
inset-block-start: 0;
|
|
27
|
+
inset-inline-start: 0;
|
|
22
28
|
clip-path: inset(50%);
|
|
23
29
|
inline-size: 1px;
|
|
24
30
|
block-size: 1px;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
.zx-copy-input {
|
|
2
|
+
/* Holds the visually hidden label below, which would otherwise hang off the page. */
|
|
3
|
+
position: relative;
|
|
2
4
|
display: flex;
|
|
3
5
|
flex-direction: column;
|
|
4
6
|
gap: var(--zx-space-1);
|
|
5
7
|
inline-size: 100%;
|
|
6
8
|
}
|
|
7
9
|
|
|
10
|
+
/* The same quiet label a Field draws, so a copy field sits in a form without standing out. */
|
|
8
11
|
.zx-copy-input__label {
|
|
9
|
-
color: var(--zx-color-text);
|
|
10
|
-
font-size: var(--zx-
|
|
11
|
-
font-weight:
|
|
12
|
+
color: var(--zx-color-text-muted);
|
|
13
|
+
font-size: var(--zx-text-sm);
|
|
14
|
+
font-weight: var(--zx-weight-medium);
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
.zx-copy-input[data-hide-label] .zx-copy-input__label {
|
|
15
18
|
position: absolute;
|
|
19
|
+
inset-block-start: 0;
|
|
20
|
+
inset-inline-start: 0;
|
|
16
21
|
clip-path: inset(50%);
|
|
17
22
|
inline-size: 1px;
|
|
18
23
|
block-size: 1px;
|
|
@@ -49,7 +54,7 @@
|
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
.zx-copy-input__field:focus-visible {
|
|
52
|
-
outline:
|
|
57
|
+
outline-color: transparent;
|
|
53
58
|
box-shadow: none;
|
|
54
59
|
}
|
|
55
60
|
|
|
@@ -28,18 +28,19 @@
|
|
|
28
28
|
.zx-data-filter__label {
|
|
29
29
|
color: var(--zx-color-text-muted);
|
|
30
30
|
font-size: var(--zx-text-sm);
|
|
31
|
-
font-weight:
|
|
31
|
+
font-weight: var(--zx-weight-medium);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
.zx-data-filter__badge {
|
|
35
35
|
align-self: center;
|
|
36
36
|
min-inline-size: var(--zx-control-height);
|
|
37
37
|
border-radius: var(--zx-radius-full);
|
|
38
|
-
background: var(--zx-color-bg-
|
|
39
|
-
color: var(--zx-color-
|
|
38
|
+
background: var(--zx-color-bg-current);
|
|
39
|
+
color: var(--zx-color-text);
|
|
40
40
|
padding: var(--zx-space-1) var(--zx-space-2);
|
|
41
41
|
font-size: var(--zx-text-sm);
|
|
42
|
-
font-
|
|
42
|
+
font-variant-numeric: tabular-nums;
|
|
43
|
+
font-weight: var(--zx-weight-medium);
|
|
43
44
|
text-align: center;
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
* @property {Array<string|((row: DataFilterRow) => unknown)>} [fields] Row fields combined with OR.
|
|
21
21
|
* @property {(row: DataFilterRow) => unknown} [get] Custom value accessor.
|
|
22
22
|
* @property {Array<unknown|DataFilterOption>} [options] Explicit options; omitted derives distinct values.
|
|
23
|
-
* @property {string} [emptyLabel] Empty option label.
|
|
23
|
+
* @property {string} [emptyLabel] Empty option label; omitted resolves message `dataFilter.all`, "All".
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
* @property {FilterDefinition[]} [filters=[]] Declarative filters.
|
|
49
49
|
* @property {DataFilterRow[]} [data=[]] Rows to filter.
|
|
50
50
|
* @property {boolean} [autoApply=true] Apply and emit whenever a control changes.
|
|
51
|
-
* @property {string|null} [clearLabel=null] Clear button label; null resolves `dataFilter.clear
|
|
51
|
+
* @property {string|null} [clearLabel=null] Clear button label; null resolves message `dataFilter.clear`, "Clear".
|
|
52
52
|
* @property {(event: CustomEvent<DataFilterEventDetail>) => void} [onfilter]
|
|
53
53
|
*/
|
|
54
54
|
|