@zeyos/zx 4.3.4 → 5.0.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 +438 -0
- package/README.md +49 -10
- package/dist/types/components/activity-item/activity-item.d.ts +351 -0
- package/dist/types/components/activity-list/activity-list.d.ts +217 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +33 -3
- 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 +23 -0
- package/dist/types/components/calendar/calendar.d.ts +19 -0
- package/dist/types/components/card/card.d.ts +7 -0
- package/dist/types/components/card-view/card-view.d.ts +11 -3
- package/dist/types/components/card-view/record-card.d.ts +7 -1
- 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 +149 -0
- package/dist/types/components/code-editor/field-adapter.d.ts +5 -0
- package/dist/types/components/context-menu/context-menu.d.ts +18 -2
- package/dist/types/components/date-picker/date-picker.d.ts +8 -0
- package/dist/types/components/date-picker/time-picker.d.ts +7 -0
- 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 +75 -6
- package/dist/types/components/dropdown/dropdown.d.ts +2 -2
- package/dist/types/components/entity-ref/entity-ref.d.ts +331 -0
- package/dist/types/components/field/field.d.ts +24 -2
- package/dist/types/components/fieldset/fieldset.d.ts +19 -1
- package/dist/types/components/file-item/file-item.d.ts +262 -0
- package/dist/types/components/file-list/file-list.d.ts +171 -0
- package/dist/types/components/filter/filter.d.ts +91 -36
- package/dist/types/components/filter-panel/filter-panel.d.ts +449 -0
- package/dist/types/components/form/form.d.ts +12 -1
- package/dist/types/components/kanban-view/kanban-card.d.ts +146 -0
- package/dist/types/components/kanban-view/kanban-view.d.ts +170 -4
- package/dist/types/components/launcher/launcher.d.ts +278 -26
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +599 -0
- package/dist/types/components/menu-button/menu-button.d.ts +37 -42
- package/dist/types/components/message/message.d.ts +126 -17
- package/dist/types/components/modal/modal.d.ts +61 -2
- package/dist/types/components/navigation-bar/navigation-bar.d.ts +105 -21
- package/dist/types/components/panel/panel.d.ts +7 -0
- package/dist/types/components/search/search.d.ts +7 -0
- 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 +15 -3
- package/dist/types/components/sort-control/sort-control.d.ts +105 -0
- package/dist/types/components/stat-tile/stat-tile.d.ts +288 -0
- package/dist/types/components/tabbox/tabbox.d.ts +16 -0
- package/dist/types/components/table/table.d.ts +190 -1
- package/dist/types/components/table-view/table-view.d.ts +11 -5
- package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
- package/dist/types/components/timebox/timebox.d.ts +7 -0
- package/dist/types/components/tree/tree.d.ts +13 -0
- package/dist/types/components/value-list/value-list.d.ts +8 -0
- package/dist/types/components/view/record-view.d.ts +96 -5
- package/dist/types/core/breakpoint.d.ts +1 -1
- package/dist/types/core/icons.d.ts +37 -22
- package/dist/types/core/motion.d.ts +59 -0
- package/dist/types/core/overlay-host.d.ts +15 -1
- package/dist/types/index.d.ts +16 -3
- package/dist/types/internal/app-rail.d.ts +10 -0
- package/dist/types/internal/menu-items.d.ts +134 -0
- 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 +1 -1
- package/dist/types/zeyos/query.d.ts +79 -0
- package/dist/types/zeyos/schema.d.ts +24 -1
- package/dist/types/zeyos/table.d.ts +100 -14
- package/dist/types/zeyos/view.d.ts +10 -0
- package/dist/zx-zeyos.esm.js +2206 -489
- package/dist/zx-zeyos.esm.min.js +56 -1
- package/dist/zx.css +3322 -724
- package/dist/zx.esm.js +12244 -5809
- package/dist/zx.esm.min.js +58 -3
- package/dist/zx.global.js +12246 -5811
- package/dist/zx.global.min.js +58 -3
- package/dist/zx.min.css +1 -1
- package/docs/api.json +1683 -146
- package/docs/llms.md +777 -110
- package/docs/llms.txt +14 -8
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- package/src/components/activity-item/activity-item.css +137 -0
- package/src/components/activity-item/activity-item.js +602 -0
- package/src/components/activity-list/activity-list.css +99 -0
- package/src/components/activity-list/activity-list.js +409 -0
- package/src/components/app-icon/app-icon.css +1 -1
- package/src/components/app-rail/app-rail.css +191 -22
- package/src/components/app-sidebar/app-sidebar.css +349 -24
- package/src/components/app-sidebar/app-sidebar.js +86 -11
- 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/button/button.css +74 -8
- package/src/components/button/button.js +44 -1
- package/src/components/calendar/calendar.css +46 -46
- package/src/components/calendar/calendar.js +33 -3
- package/src/components/card/card.css +2 -2
- package/src/components/card/card.js +12 -1
- package/src/components/card-view/card-view.css +10 -7
- package/src/components/card-view/card-view.js +25 -9
- package/src/components/card-view/record-card.js +7 -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 +68 -0
- package/src/components/code-editor/code-editor.js +306 -0
- package/src/components/code-editor/field-adapter.js +34 -0
- package/src/components/context-menu/context-menu.css +87 -5
- package/src/components/context-menu/context-menu.js +22 -30
- package/src/components/copy/copy-button.css +6 -0
- package/src/components/copy/copy-input.css +8 -3
- package/src/components/data-filter/data-filter.css +5 -4
- package/src/components/date-picker/date-picker.css +6 -6
- package/src/components/date-picker/date-picker.js +22 -8
- package/src/components/date-picker/date-range-picker.css +3 -3
- package/src/components/date-picker/month-picker.js +3 -3
- package/src/components/date-picker/time-picker.css +1 -1
- package/src/components/date-picker/time-picker.js +20 -8
- 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 +174 -70
- package/src/components/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +7 -5
- package/src/components/empty-state/empty-state.css +2 -2
- package/src/components/entity-ref/entity-ref.css +182 -0
- package/src/components/entity-ref/entity-ref.js +496 -0
- package/src/components/field/field.css +28 -9
- package/src/components/field/field.js +68 -26
- package/src/components/field-upload/field-upload.css +1 -1
- package/src/components/fieldset/fieldset.css +5 -3
- package/src/components/fieldset/fieldset.js +28 -5
- package/src/components/file-item/file-item.css +88 -0
- package/src/components/file-item/file-item.js +505 -0
- package/src/components/file-list/file-list.css +51 -0
- package/src/components/file-list/file-list.js +320 -0
- package/src/components/filter/filter.css +27 -1
- package/src/components/filter/filter.js +205 -47
- package/src/components/filter-panel/filter-panel.css +104 -0
- package/src/components/filter-panel/filter-panel.js +964 -0
- package/src/components/finder/finder.css +15 -13
- 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 +247 -0
- package/src/components/kanban-view/kanban-view.css +226 -8
- package/src/components/kanban-view/kanban-view.js +255 -12
- package/src/components/launcher/launcher.css +107 -25
- package/src/components/launcher/launcher.js +557 -63
- package/src/components/list-toolbar/list-toolbar.css +194 -0
- package/src/components/list-toolbar/list-toolbar.js +851 -0
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/menu-button/menu-button.css +87 -5
- package/src/components/menu-button/menu-button.js +86 -46
- package/src/components/message/message.css +38 -5
- package/src/components/message/message.js +230 -17
- package/src/components/modal/modal.css +15 -0
- package/src/components/modal/modal.js +159 -3
- package/src/components/navigation-bar/navigation-bar.css +95 -11
- package/src/components/navigation-bar/navigation-bar.js +171 -4
- package/src/components/number-field/field-adapter.js +1 -0
- 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 +8 -6
- package/src/components/panel/panel.css +1 -1
- package/src/components/panel/panel.js +13 -2
- package/src/components/rating/rating.css +7 -0
- package/src/components/search/search.js +17 -5
- package/src/components/select/color.js +22 -0
- package/src/components/select/field-adapter.js +6 -1
- package/src/components/select/glyphs.js +165 -0
- package/src/components/select/select.css +138 -45
- package/src/components/select/select.js +86 -47
- package/src/components/sheet/sheet.css +11 -8
- package/src/components/slider/slider.css +16 -2
- package/src/components/slider/slider.js +1 -1
- package/src/components/sort-control/sort-control.css +20 -0
- package/src/components/sort-control/sort-control.js +140 -0
- package/src/components/stat-tile/stat-tile.css +208 -0
- package/src/components/stat-tile/stat-tile.js +601 -0
- package/src/components/tabbox/tabbox.css +32 -27
- package/src/components/tabbox/tabbox.js +17 -2
- package/src/components/table/table.css +155 -31
- package/src/components/table/table.js +386 -33
- package/src/components/table-view/table-view.css +8 -2
- package/src/components/table-view/table-view.js +21 -6
- package/src/components/tag-picker/tag-picker.css +86 -6
- package/src/components/tag-picker/tag-picker.js +25 -8
- package/src/components/timebox/timebox.css +22 -2
- package/src/components/timebox/timebox.js +18 -5
- 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 +10 -3
- package/src/components/tree/tree.css +25 -16
- package/src/components/tree/tree.js +31 -0
- package/src/components/value-list/value-list.css +3 -3
- package/src/components/value-list/value-list.js +22 -6
- package/src/components/view/record-view.css +5 -0
- package/src/components/view/record-view.js +100 -7
- package/src/core/breakpoint.js +1 -1
- package/src/core/icons.js +259 -57
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +21 -2
- package/src/index.js +30 -3
- package/src/internal/app-rail.js +18 -1
- package/src/internal/menu-items.js +142 -0
- package/src/zeyos/connect.js +6 -2
- package/src/zeyos/form.js +67 -27
- package/src/zeyos/index.js +1 -1
- package/src/zeyos/query.js +153 -0
- package/src/zeyos/schema.js +144 -27
- package/src/zeyos/table.js +68 -5
- package/src/zeyos/view.js +6 -0
- package/styles/base.css +56 -0
- package/styles/icons.css +11 -1
- package/styles/print.css +192 -0
- package/styles/tokens/dark.css +113 -37
- package/styles/tokens/global.css +121 -27
- package/styles/tokens/semantic.css +100 -31
- package/styles/tokens/themes.css +7 -6
- package/styles/zx.css +11 -1
- package/styles/tokens/density.css +0 -9
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
max-inline-size: 100%;
|
|
30
30
|
padding-inline: var(--zx-space-2);
|
|
31
31
|
border: 1px solid var(--zx-color-border);
|
|
32
|
-
border-radius: var(--zx-radius-
|
|
33
|
-
background: var(--zx-color-bg-
|
|
32
|
+
border-radius: var(--zx-radius-md);
|
|
33
|
+
background: var(--zx-color-bg-muted);
|
|
34
34
|
color: var(--zx-color-text);
|
|
35
35
|
cursor: grab;
|
|
36
36
|
}
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
place-items: center;
|
|
51
51
|
min-inline-size: 1.25rem;
|
|
52
52
|
min-block-size: 1.25rem;
|
|
53
|
-
border-radius: var(--zx-radius-
|
|
53
|
+
border-radius: var(--zx-radius-sm);
|
|
54
54
|
color: var(--zx-color-text-muted);
|
|
55
55
|
cursor: pointer;
|
|
56
56
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component } from '../../core/component.js';
|
|
2
2
|
import { h } from '../../core/dom.js';
|
|
3
|
+
import { printf } from '../../core/i18n.js';
|
|
3
4
|
import { uid } from '../../core/util.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -49,14 +50,14 @@ export class ValueList extends Component {
|
|
|
49
50
|
this._list = h('ul', {
|
|
50
51
|
class: 'zx-value-list__list',
|
|
51
52
|
role: 'listbox',
|
|
52
|
-
ariaLabel: 'Values',
|
|
53
|
+
ariaLabel: this._message('valueList.values', 'Values'),
|
|
53
54
|
ariaOrientation: 'horizontal'
|
|
54
55
|
});
|
|
55
56
|
this._input = h('input', {
|
|
56
57
|
class: 'zx-value-list__input',
|
|
57
58
|
type: 'text',
|
|
58
59
|
placeholder: String(this.options.placeholder ?? ''),
|
|
59
|
-
ariaLabel: 'Add value',
|
|
60
|
+
ariaLabel: this._message('valueList.add', 'Add value'),
|
|
60
61
|
ariaDescribedby: instructionsId
|
|
61
62
|
});
|
|
62
63
|
this._status = h('div', {
|
|
@@ -67,7 +68,8 @@ export class ValueList extends Component {
|
|
|
67
68
|
this._instructions = h('span', {
|
|
68
69
|
class: 'zx-value-list__instructions',
|
|
69
70
|
id: instructionsId
|
|
70
|
-
}, '
|
|
71
|
+
}, this._message('valueList.instructions',
|
|
72
|
+
'Press Enter to add. Focus a value and press Ctrl plus Left or Right to reorder.'));
|
|
71
73
|
this._ownedNodes.push(this._list, this._input, this._status, this._instructions);
|
|
72
74
|
root.append(this._list, this._input, this._status, this._instructions);
|
|
73
75
|
|
|
@@ -120,13 +122,14 @@ export class ValueList extends Component {
|
|
|
120
122
|
const normalized = String(value ?? '').trim();
|
|
121
123
|
if (!normalized) return false;
|
|
122
124
|
if (this.options.unique && this._values.includes(normalized)) {
|
|
123
|
-
this._showError('This value already exists.');
|
|
125
|
+
this._showError(this._message('valueList.duplicate', 'This value already exists.'));
|
|
124
126
|
return false;
|
|
125
127
|
}
|
|
126
128
|
if (typeof this.options.validate === 'function') {
|
|
127
129
|
const result = this.options.validate(normalized);
|
|
128
130
|
if (result !== true) {
|
|
129
|
-
this._showError(typeof result === 'string' ? result
|
|
131
|
+
this._showError(typeof result === 'string' ? result
|
|
132
|
+
: this._message('valueList.invalid', 'This value is not valid.'));
|
|
130
133
|
return false;
|
|
131
134
|
}
|
|
132
135
|
}
|
|
@@ -196,7 +199,8 @@ export class ValueList extends Component {
|
|
|
196
199
|
draggable: Boolean(this.options.sortable) && !this._disabled,
|
|
197
200
|
ariaSelected: 'false',
|
|
198
201
|
ariaDisabled: String(this._disabled),
|
|
199
|
-
ariaLabel: this.options.deletable
|
|
202
|
+
ariaLabel: this.options.deletable
|
|
203
|
+
? this._message('valueList.removable', '%1. Press Delete to remove.', value) : value,
|
|
200
204
|
dataset: { index }
|
|
201
205
|
}, h('span', { class: 'zx-value-list__value' }, value), this.options.deletable ? h('span', {
|
|
202
206
|
class: 'zx-value-list__remove',
|
|
@@ -302,6 +306,18 @@ export class ValueList extends Component {
|
|
|
302
306
|
this._input.setAttribute('aria-invalid', 'true');
|
|
303
307
|
}
|
|
304
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Resolves a message through the host translator, falling back to the built-in English text.
|
|
311
|
+
* @param {string} key Message key.
|
|
312
|
+
* @param {string} fallback Built-in text, with `%1`-style placeholders.
|
|
313
|
+
* @param {...unknown} args Interpolation values.
|
|
314
|
+
* @returns {string}
|
|
315
|
+
*/
|
|
316
|
+
_message(key, fallback, ...args) {
|
|
317
|
+
const message = this.msg(key, ...args);
|
|
318
|
+
return message === key ? printf(fallback, args) : message;
|
|
319
|
+
}
|
|
320
|
+
|
|
305
321
|
/** @returns {void} */
|
|
306
322
|
destroy() {
|
|
307
323
|
for (const node of this._ownedNodes ?? []) node.remove();
|
|
@@ -17,6 +17,11 @@
|
|
|
17
17
|
margin-inline-start: auto;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/* Mounted into a host toolbar the view does not own: the host decides where it sits. */
|
|
21
|
+
.zx-record-view__field-controls[data-mounted="external"] {
|
|
22
|
+
margin-inline-start: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
20
25
|
.zx-record-view__field-controls > summary {
|
|
21
26
|
display: inline-flex;
|
|
22
27
|
align-items: center;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { Component } from '../../core/component.js';
|
|
3
|
-
import { h, restoreTarget, snapshotTarget } from '../../core/dom.js';
|
|
3
|
+
import { h, resolveElement, restoreTarget, snapshotTarget } from '../../core/dom.js';
|
|
4
4
|
import { icon } from '../../core/icons.js';
|
|
5
|
+
import { printf } from '../../core/i18n.js';
|
|
5
6
|
import { sortRows } from '../table/sort.js';
|
|
6
7
|
|
|
7
8
|
/** @typedef {Record<string, any>} ViewRecord */
|
|
@@ -31,6 +32,23 @@ import { sortRows } from '../table/sort.js';
|
|
|
31
32
|
* @property {ViewSortDirection} dir Sort direction.
|
|
32
33
|
*/
|
|
33
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Trigger customisation for the shared field chooser. Passing this object in place of `true` keeps
|
|
37
|
+
* the control and its state model exactly as they are; only its wording and mount point change.
|
|
38
|
+
* @typedef {Object} ViewFieldControlsConfig
|
|
39
|
+
* @property {string} [label] Trigger label. Omitted resolves `recordView.fields`, English `Fields`.
|
|
40
|
+
* @property {Element|string|null} [target=null] Element or selector the disclosure is mounted into
|
|
41
|
+
* instead of the view's own toolbar. An unresolvable target falls back to the view.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {Object} ViewFieldControlsSettings
|
|
46
|
+
* @property {boolean} enabled Whether a concrete view renders the chooser at all.
|
|
47
|
+
* @property {boolean} custom Whether the option was given as a `ViewFieldControlsConfig` object.
|
|
48
|
+
* @property {string|null} label Configured trigger label, or null to resolve the message.
|
|
49
|
+
* @property {Element|string|null} target Configured mount point, before resolution.
|
|
50
|
+
*/
|
|
51
|
+
|
|
34
52
|
/**
|
|
35
53
|
* @typedef {Object} RecordViewState
|
|
36
54
|
* @property {1} version State schema version.
|
|
@@ -50,7 +68,10 @@ import { sortRows } from '../table/sort.js';
|
|
|
50
68
|
* @property {unknown[]} [selection=[]] Initially selected record ids.
|
|
51
69
|
* @property {string[]} [fieldOrder=[]] Field ids in preferred order.
|
|
52
70
|
* @property {string[]} [hiddenFields=[]] Initially hidden field ids.
|
|
53
|
-
* @property {boolean} [fieldControls=true] Whether concrete views show the
|
|
71
|
+
* @property {boolean|ViewFieldControlsConfig} [fieldControls=true] Whether concrete views show the
|
|
72
|
+
* shared field chooser. `true` renders it in the view's own toolbar and `false` omits it; a
|
|
73
|
+
* `ViewFieldControlsConfig` object renders the same control with a translated `label` and, with
|
|
74
|
+
* `target`, mounts it into a host element such as a list toolbar.
|
|
54
75
|
* @property {string|Node|(() => string|Node)|null} [emptyText=null] Empty-result content.
|
|
55
76
|
* @property {(event: CustomEvent<Record<string, unknown>>) => void} [onrecordclick]
|
|
56
77
|
* @property {(event: CustomEvent<Record<string, unknown>>) => void} [onrecorddblclick]
|
|
@@ -117,6 +138,7 @@ export class RecordView extends Component {
|
|
|
117
138
|
this._recordViewDestroyed = true;
|
|
118
139
|
const root = this.el;
|
|
119
140
|
const snapshot = this._recordViewOriginal;
|
|
141
|
+
this._removeViewFieldControls();
|
|
120
142
|
super.destroy();
|
|
121
143
|
if (snapshot && root) restoreTarget(root, snapshot);
|
|
122
144
|
}
|
|
@@ -139,6 +161,9 @@ export class RecordView extends Component {
|
|
|
139
161
|
this._viewSelectionAnchor = null;
|
|
140
162
|
this._viewFieldControls = null;
|
|
141
163
|
this._viewFieldList = null;
|
|
164
|
+
this._viewFieldSettings = normalizeViewFieldControls(this.options.fieldControls);
|
|
165
|
+
// Resolved once, here, so the mount point cannot drift between render and destroy.
|
|
166
|
+
this._viewFieldControlsTarget = resolveElement(this._viewFieldSettings.target);
|
|
142
167
|
this._viewInitialized = true;
|
|
143
168
|
if (this._viewSort && this.options.sortMode === 'local') this._sortViewData();
|
|
144
169
|
this._setInitialSelection(this.options.selection);
|
|
@@ -467,13 +492,15 @@ export class RecordView extends Component {
|
|
|
467
492
|
/**
|
|
468
493
|
* Builds the shared show/hide and ordering disclosure for a concrete view toolbar.
|
|
469
494
|
* @protected
|
|
470
|
-
* @param {string} [label=
|
|
495
|
+
* @param {string|null} [label=null] Explicit trigger label. Omitted resolves the configured
|
|
496
|
+
* `fieldControls.label` and then the `recordView.fields` message.
|
|
471
497
|
* @returns {HTMLElement} Disclosure element.
|
|
472
498
|
*/
|
|
473
|
-
_createViewFieldControls(label =
|
|
499
|
+
_createViewFieldControls(label = null) {
|
|
500
|
+
const text = label ?? this._viewFieldControlsLabel();
|
|
474
501
|
const list = h('div', { class: 'zx-record-view__field-list' });
|
|
475
502
|
const details = h('details', { class: 'zx-record-view__field-controls' },
|
|
476
|
-
h('summary', { class: 'zx-
|
|
503
|
+
h('summary', { class: 'zx-btn', dataset: { size: 'sm', kind: 'ghost' } }, icon('fields'), text),
|
|
477
504
|
list);
|
|
478
505
|
this._viewFieldControls = details;
|
|
479
506
|
this._viewFieldList = list;
|
|
@@ -498,6 +525,58 @@ export class RecordView extends Component {
|
|
|
498
525
|
return details;
|
|
499
526
|
}
|
|
500
527
|
|
|
528
|
+
/**
|
|
529
|
+
* Builds the shared field disclosure and mounts it where `fieldControls` asks for it: the host
|
|
530
|
+
* element named by `target`, or the view's own toolbar when no target resolves.
|
|
531
|
+
* @protected
|
|
532
|
+
* @param {Element} toolbar The view's own toolbar.
|
|
533
|
+
* @param {string|null} [label=null] Explicit trigger label, for views that own their wording.
|
|
534
|
+
* @returns {HTMLElement} The mounted disclosure.
|
|
535
|
+
*/
|
|
536
|
+
_mountViewFieldControls(toolbar, label = null) {
|
|
537
|
+
const controls = this._createViewFieldControls(label);
|
|
538
|
+
const target = this._viewFieldControlsTarget;
|
|
539
|
+
if (target) controls.dataset.mounted = 'external';
|
|
540
|
+
(target ?? toolbar).append(controls);
|
|
541
|
+
return controls;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Removes the shared field disclosure from wherever it was mounted. An external `target` keeps
|
|
546
|
+
* every node it had before the view was created.
|
|
547
|
+
* @protected
|
|
548
|
+
* @returns {void}
|
|
549
|
+
*/
|
|
550
|
+
_removeViewFieldControls() {
|
|
551
|
+
this._viewFieldControls?.remove?.();
|
|
552
|
+
this._viewFieldControls = null;
|
|
553
|
+
this._viewFieldList = null;
|
|
554
|
+
this._viewFieldControlsTarget = null;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Resolves the field-chooser trigger label: the configured one, else the translated message.
|
|
559
|
+
* @protected
|
|
560
|
+
* @returns {string} Trigger label.
|
|
561
|
+
*/
|
|
562
|
+
_viewFieldControlsLabel() {
|
|
563
|
+
const settings = this._viewFieldSettings ?? normalizeViewFieldControls(this.options.fieldControls);
|
|
564
|
+
return settings.label ?? this._message('recordView.fields', 'Fields');
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Resolves a message through the host translator, falling back to the built-in English text.
|
|
569
|
+
* @protected
|
|
570
|
+
* @param {string} key Message key.
|
|
571
|
+
* @param {string} fallback Built-in text, with `%1`-style placeholders.
|
|
572
|
+
* @param {...unknown} args Interpolation values.
|
|
573
|
+
* @returns {string} Translated or built-in text.
|
|
574
|
+
*/
|
|
575
|
+
_message(key, fallback, ...args) {
|
|
576
|
+
const message = this.msg(key, ...args);
|
|
577
|
+
return message === key ? printf(fallback, args) : message;
|
|
578
|
+
}
|
|
579
|
+
|
|
501
580
|
/** Concrete renderers override this hook. @protected @param {string} _reason Refresh reason. @returns {void} */
|
|
502
581
|
_refreshView(_reason) {}
|
|
503
582
|
|
|
@@ -567,14 +646,14 @@ export class RecordView extends Component {
|
|
|
567
646
|
const up = h('button', {
|
|
568
647
|
class: 'zx-record-view__field-move',
|
|
569
648
|
type: 'button',
|
|
570
|
-
ariaLabel:
|
|
649
|
+
ariaLabel: this._message('recordView.moveFieldUp', 'Move %1 up', field.label),
|
|
571
650
|
disabled: index === 0,
|
|
572
651
|
dataset: { viewFieldAction: 'up', fieldId: field.id }
|
|
573
652
|
}, icon('chevron-up', { size: 11 }));
|
|
574
653
|
const down = h('button', {
|
|
575
654
|
class: 'zx-record-view__field-move',
|
|
576
655
|
type: 'button',
|
|
577
|
-
ariaLabel:
|
|
656
|
+
ariaLabel: this._message('recordView.moveFieldDown', 'Move %1 down', field.label),
|
|
578
657
|
disabled: index === fields.length - 1,
|
|
579
658
|
dataset: { viewFieldAction: 'down', fieldId: field.id }
|
|
580
659
|
}, icon('chevron-down', { size: 11 }));
|
|
@@ -593,6 +672,20 @@ export class RecordView extends Component {
|
|
|
593
672
|
}
|
|
594
673
|
}
|
|
595
674
|
|
|
675
|
+
/**
|
|
676
|
+
* Reads the `fieldControls` option in its three shapes. `true` and `false` keep their exact
|
|
677
|
+
* meaning; an object additionally carries the trigger label and the host element to mount into.
|
|
678
|
+
* @param {boolean|ViewFieldControlsConfig|null|undefined} value Raw option value.
|
|
679
|
+
* @returns {ViewFieldControlsSettings} Normalized settings.
|
|
680
|
+
*/
|
|
681
|
+
export function normalizeViewFieldControls(value) {
|
|
682
|
+
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
683
|
+
const label = value.label == null ? null : String(value.label);
|
|
684
|
+
return { enabled: true, custom: true, label, target: value.target ?? null };
|
|
685
|
+
}
|
|
686
|
+
return { enabled: Boolean(value), custom: false, label: null, target: null };
|
|
687
|
+
}
|
|
688
|
+
|
|
596
689
|
/**
|
|
597
690
|
* Validates and clones field descriptors.
|
|
598
691
|
* @param {ViewField[]} fields Fields.
|
package/src/core/breakpoint.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* used inside a media query, so a `--zx-bp-*` token would be a value no stylesheet could read.
|
|
7
7
|
* Zx's own layout utilities avoid the problem entirely — `.zx-grid` reflows on intrinsic track
|
|
8
8
|
* widths, not on breakpoints — which leaves this module for the cases only script can decide:
|
|
9
|
-
* rendering a Table as cards below a width, collapsing a MasterPanel, choosing a chart
|
|
9
|
+
* rendering a Table as cards below a width, collapsing a MasterPanel, choosing how many labels a chart shows.
|
|
10
10
|
* @module zx/core/breakpoint
|
|
11
11
|
*/
|
|
12
12
|
|