@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
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,453 @@ and friends remain the complete record.
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## 5.2.0 — 2026-10-29
|
|
12
|
+
|
|
13
|
+
A record collection pattern with a five-way view switch and filter chips, two components to go
|
|
14
|
+
with it, and the sixteen defects a library-wide consistency audit found, fixed.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`WorkspaceSwitcher`** — the account or workspace switcher at the head of a module menu: the
|
|
19
|
+
open workspace's tile, name and secondary line with a chevron, opening a menu of the user's
|
|
20
|
+
workspaces as `menuitemradio` rows followed by workspace actions; `compact` shows the tile
|
|
21
|
+
alone. `select` is cancelable, `setActive()`, `setWorkspaces()`, `setCompact()`. The layout
|
|
22
|
+
kit's `suiteNav()` takes a `workspace` option that puts it in place of the brand.
|
|
23
|
+
- **`ViewSettings`** — the content of a "View settings" drawer: search the hidden fields and add
|
|
24
|
+
one with an explicit button, see every field's type glyph, arrange the shown fields by pointer
|
|
25
|
+
or keyboard (announced, auto-scrolling), hide them, choose the grouping, and set a board's
|
|
26
|
+
columns, swim lanes and empty-column rule. `bind(view)` keeps it in step with a record view; a
|
|
27
|
+
`locked` field is offered neither to hide nor to move; the panel's own `fields` act as the
|
|
28
|
+
allow-list when bound.
|
|
29
|
+
- `ListToolbar` view presets `table | list | cards | gallery | board`, with bundled glyphs
|
|
30
|
+
`table`, `image`, `columns`, and `type`, `hash`, `mail`, `link-2`, `circle-chevron-down` for
|
|
31
|
+
field types.
|
|
32
|
+
- `Filter`: fields take an `icon` shown in the searchable picker; choice icons are drawn; a
|
|
33
|
+
many-valued operator on fixed choices uses a `TagPicker`; compact rows show their group's
|
|
34
|
+
and/or as a pill that switches the logic; `withinLast` / `withinNext` take an amount and a unit.
|
|
35
|
+
- A default English message catalogue in core (`defaultMessages`): `msg(key)` resolves the
|
|
36
|
+
instance table, the host translator, the class defaults, then the catalogue, so no raw key
|
|
37
|
+
reaches the screen without a translator. A test keeps it complete against every key in `src/`.
|
|
38
|
+
- `src/core/overlay-stack.js` — one registry of open overlays with the z-order, Escape routing
|
|
39
|
+
to the topmost layer, and the outside-press test along the opener chain; `Modal`, `Sheet`,
|
|
40
|
+
`Dropdown`, `MenuButton`, `ContextMenu`, `Tooltip`, `Message`, `Launcher` and the rail flyouts
|
|
41
|
+
use it.
|
|
42
|
+
- `Table`: the APG grid and treegrid keyboard model — arrows, Home/End, Page keys, Enter to
|
|
43
|
+
activate, Space and Shift+Arrow to select, Ctrl/Cmd+A — on tables that are `selectable`,
|
|
44
|
+
editable, hierarchical, listen for `rowclick`, or set `interactive: true`; focus kept by row id
|
|
45
|
+
across data changes; `label` / `labelledBy` for the grid's name; row controls named by the row's
|
|
46
|
+
first text cell; 24px targets on checkboxes and sort buttons.
|
|
47
|
+
- `RecordView.getFieldControls()` and `mountFieldControls(target)`; `KanbanView` honours
|
|
48
|
+
`fieldControls.target`; `ListToolbar.bind()` mounts the chooser through them.
|
|
49
|
+
- `MenuButton.toggle()`; `Select.get()`; `Field` `readonly` and `setReadonly()`;
|
|
50
|
+
`FilterPanel` `timeZone`; `dataFilterStateToFilters(state, defs, { timeZone })`; the ZeyOS
|
|
51
|
+
bindings' `load({ replace, pageSize })` and `pageSize` getter; `rovingTabindex` `rtl: 'auto'`;
|
|
52
|
+
`--zx-surface-shadow`.
|
|
53
|
+
- `Pagination` and `Search`: the summary and page size sit at the start of the bar, the pager at
|
|
54
|
+
the end; the search input fills a stretched field so the submit glyph stays on its trailing
|
|
55
|
+
edge.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- Geometry tokens (control sizes, blur, filters) are declared on `:root` only; the theme blocks
|
|
60
|
+
carry colours. A nested light region no longer resets an application's `--zx-control-height`.
|
|
61
|
+
- Every `outline: 0` in the stylesheets became `outline-color: transparent`, and `base.css` draws a
|
|
62
|
+
solid `Highlight` outline on `:focus-visible` under forced colors.
|
|
63
|
+
- The token lint covers `icons.css`, flags tier-1 accent, module and shadow names in component and
|
|
64
|
+
layout CSS, modern colour functions, raw colours in `var()` fallbacks, and outline suppression.
|
|
65
|
+
- A host translator now takes precedence over a class's own `defaults.msg`, which makes `Field`,
|
|
66
|
+
`Form` and `Questionnaire` translatable; a translator that returns the key counts as no answer.
|
|
67
|
+
- `Calendar` message keys are namespaced (`calendar.next`, `calendar.today`, …); the bare keys are
|
|
68
|
+
still honoured for one version.
|
|
69
|
+
- Light dismiss stops at the first overlay that contains the press: a press in the upper of two
|
|
70
|
+
light-dismiss sheets no longer closes the lower one. Anchored popups and toast regions are hosted
|
|
71
|
+
inside the open dialog their anchor sits in.
|
|
72
|
+
- The ZeyOS `zeyosTable` / `zeyosView` bindings share one loader; an invalid page or page size
|
|
73
|
+
throws a `RangeError` and non-object filters a `TypeError` where they used to clamp, and a
|
|
74
|
+
rejected call changes nothing. `Pagination`'s documentation shows the real mapping
|
|
75
|
+
(`offset = (page - 1) * pageSize`, `load({ page: page - 1, replace: true })`).
|
|
76
|
+
- `Field`'s `code` type reports `change` on commit and `input` on every keystroke.
|
|
77
|
+
- `Fieldset.addField()` writes with the caller's options; a component's own `change` listeners
|
|
78
|
+
hear a non-silent `setValues()`.
|
|
79
|
+
|
|
80
|
+
### Fixed
|
|
81
|
+
|
|
82
|
+
- Menus, dropdowns, context menus, rail flyouts and toasts were inert while a modal `Dialog` or
|
|
83
|
+
`Sheet` was open; a non-modal `Sheet` closed itself when an item was chosen in a menu inside it,
|
|
84
|
+
and Escape closed the sheet while leaving its dropdown open; an Escape another control handled is
|
|
85
|
+
ignored; a `Dropdown` panel is reachable with Tab, and Tab out of a panel holding a `Select` or a
|
|
86
|
+
roving toolbar lands after the trigger.
|
|
87
|
+
- `AccountMenu.toggle()` threw.
|
|
88
|
+
- `Table`, `CardView` and `DataFilter` showed raw message keys without a translator.
|
|
89
|
+
- `Table` rows were not focusable, so `rowclick` and single selection were mouse-only; re-rendering
|
|
90
|
+
a table scrolled the page back to it.
|
|
91
|
+
- `Fieldset.addField()` could not read, write or disable `get()/set()` components.
|
|
92
|
+
- `Field` emitted `change` twice for `slider` and `code`.
|
|
93
|
+
- Focus dropped to `<body>` after moving a field in the record-view chooser and after every
|
|
94
|
+
`FileList.updateItem()`; `ActivityList` had the same fault. The move is announced and Escape
|
|
95
|
+
closes the chooser.
|
|
96
|
+
- `rovingTabindex` took ArrowLeft/Right/Home/End from text fields inside a `Toolbar`, and missed a
|
|
97
|
+
disabled `<fieldset>` around its items.
|
|
98
|
+
- `FilterPanel` and the ZeyOS query conversion used the browser's local midnight for dates; both
|
|
99
|
+
take the instance time zone.
|
|
100
|
+
- `--zx-shadow-1`, a tier-1 token, was used by three components; `MasterPanel` wrote a module
|
|
101
|
+
accent property nothing read.
|
|
102
|
+
- The layout icon pack no longer shadows bundled glyphs.
|
|
103
|
+
|
|
104
|
+
### Website
|
|
105
|
+
|
|
106
|
+
- **Record collection**, a new screen pattern: one toolbar over the same records as a table, a
|
|
107
|
+
list, cards, a gallery and a board; dynamic filters as editable chips with all/any matching and
|
|
108
|
+
a Filters drawer holding the expression editor, kept in step both ways; a View settings drawer
|
|
109
|
+
bound to the current presentation, with the board's axes resolved so columns and swim lanes
|
|
110
|
+
never share a field; grouping, saved views, a stage facet, bulk actions, a workspace switcher at
|
|
111
|
+
the head of the module strip, and the pager. Keys: 1–5 views, F and V for the drawers, / for
|
|
112
|
+
search, N for a new record, ? for the sheet.
|
|
113
|
+
- The contributor notes gain a library consistency review, repository-only, with the defects above
|
|
114
|
+
and a staged programme for the remaining redundancies and inconsistencies.
|
|
115
|
+
|
|
116
|
+
## 5.1.0 — 2026-10-22
|
|
117
|
+
|
|
118
|
+
### Added
|
|
119
|
+
|
|
120
|
+
- **`ModuleBar`** — the module level of an application: one colour-coded tile per module in a
|
|
121
|
+
vertical strip or a horizontal bar. Modules take a theme `tone` or any CSS `color`, and draw as
|
|
122
|
+
`tint` (default), `solid` (the classic identity tile), or `plain`; `labels: 'below'` prints names
|
|
123
|
+
under the tiles, `labels: 'beside'` beside them as a navigation column of its own, and
|
|
124
|
+
`setLabels()` switches between the two; a section of modules is a heading over them, or a rule
|
|
125
|
+
between groups on an icon strip. A module's children open as a flyout menu, or (`menus: 'none'`) are left to a
|
|
126
|
+
panel the application owns, with `setExpanded()`, `aria-expanded`, and `aria-controls`. Modules
|
|
127
|
+
that do not fit, or are not `pinned`, are under an "All modules" catalogue — grouped, filterable,
|
|
128
|
+
arrow-navigable — while the current module stays on the bar. One Tab stop, arrow keys, Home/End,
|
|
129
|
+
and type-ahead; `setBadge()` updates a count in place; `partitionModules()` and
|
|
130
|
+
`resolveModuleColor()` are exported.
|
|
131
|
+
- **`AppSidebar` sections** — `{ section: true, label, actions, children }` is a quiet heading over
|
|
132
|
+
rows at its own level, so one sidebar replaces several stacked ones: one landmark, one keyboard
|
|
133
|
+
sequence, and on a rail a separator.
|
|
134
|
+
- **`AppSidebar` `layout: 'modules'`** — the top level becomes a `ModuleBar` strip beside a panel
|
|
135
|
+
with one module's menu, plus that module's own `header` and `content`. Choosing a module fires a
|
|
136
|
+
cancelable `modulechange`; `setModule()`, `getModule()`, `setBadge()`, `setModuleLabels()`, and
|
|
137
|
+
`moduleBar` presentation options. Three presentations — both menus expanded, the module menu
|
|
138
|
+
collapsed to icons beside the side menu, or both collapsed with every menu as a flyout — and a
|
|
139
|
+
small three-way switch at the foot of the strip to choose between them (`presentations`,
|
|
140
|
+
`presentation`, `getPresentation()`, `setPresentation()`, `togglePresentation()`,
|
|
141
|
+
`presentationchange`).
|
|
142
|
+
- **ZeyOS module bar** — `zeyosModuleItems()`, `buildZeyosModuleBarConfig()`,
|
|
143
|
+
`buildZeyosAppSidebarConfig()`, and `zeyosModuleBar()` build both from the launcher's shell
|
|
144
|
+
state plus each module's menu and badges, in the ZeyOS identity colours.
|
|
145
|
+
- `AccountMenu.setCompact()` switches between the avatar alone and the avatar with name and role.
|
|
146
|
+
- **Menu choices** — a `{type: 'choice', label, value, options, onselect}` entry in `MenuButton`
|
|
147
|
+
and `AccountMenu` items: a setting chosen in place as a small segmented group of
|
|
148
|
+
`menuitemradio` options, the menu staying open. `AppSidebar`'s `presentationChoice()` returns
|
|
149
|
+
its layout switch as one, `presentationGlyph()` draws its pictograms, and
|
|
150
|
+
`presentationSwitch: false` takes the switch off the strip.
|
|
151
|
+
- `--zx-color-tone-{blue,…,slate}-solid`, solid identity fills the white icon glyph reads on in
|
|
152
|
+
both themes, and `AppIcon`'s `tone` option that uses them.
|
|
153
|
+
- A `grid` (`table-cells-large`) icon in the bundled set.
|
|
154
|
+
|
|
155
|
+
### Fixed
|
|
156
|
+
|
|
157
|
+
- `position()` adds its name to the anchor's `anchor-name` list and removes only its own, so a
|
|
158
|
+
tooltip and a menu on one trigger no longer overwrite each other — a keyboard-opened rail flyout
|
|
159
|
+
appeared at the page origin.
|
|
160
|
+
- `AppRail`: a tile's tooltip stays quiet while its flyout is open, so the first Escape closes the
|
|
161
|
+
flyout, and on a vertical rail ArrowLeft leaves a top-level flyout for its tile.
|
|
162
|
+
|
|
163
|
+
### Website
|
|
164
|
+
|
|
165
|
+
- Every layout with a navigation column now shares one suite navigation: the Zx mark, the ACME
|
|
166
|
+
modules under their headings, the signed-in user, and the layout's own menu. The account menu
|
|
167
|
+
opens above the account and holds the layout — both menus expanded, the module menu collapsed,
|
|
168
|
+
or both collapsed — and the theme — light, dark, or system — each a three-way choice; Mod+B
|
|
169
|
+
steps through the layouts, and the choice is remembered. Below 1440px the module menu keeps
|
|
170
|
+
its labels off, between 860 and 1180px both menus start collapsed, and below that the navigation
|
|
171
|
+
is a drawer; choosing another module's screen opens that layout, and each layout's menu ends with
|
|
172
|
+
a "More in <module>" section leading to its sibling layouts.
|
|
173
|
+
- The fictional company the layouts share is now called ACME.
|
|
174
|
+
|
|
175
|
+
## 5.0.0 — 2026-10-09
|
|
176
|
+
|
|
177
|
+
Xenon now has one geometry and a quieter finish. The cozy and compact view modes are gone; in their
|
|
178
|
+
place is a single, slightly tighter default whose spacing, corners, and control height are tokens a
|
|
179
|
+
product sets once. On top of it the visual language was refined against how well-made business
|
|
180
|
+
applications look today: "where you are" is a neutral fill rather than a block of accent colour,
|
|
181
|
+
status colours no longer borrow the brand green, chrome and canvas separate by tone instead of by
|
|
182
|
+
lines, labels are sentence case at medium weights, and icons are outlines.
|
|
183
|
+
|
|
184
|
+
The other half is what building twenty complete screens on the library asked of it. A layout
|
|
185
|
+
gallery of application templates and screen patterns — mail, an issue tracker, a knowledge base, AI
|
|
186
|
+
chat, an agent workspace, invoicing, inventory, workflows, infrastructure, CRM, and the screens
|
|
187
|
+
inside them — every one usable from a phone to a wide screen and clean under an accessibility
|
|
188
|
+
audit. Fixing what those screens found: some forty component defects, status colours that read as
|
|
189
|
+
text, nested dark themes, and focus that never falls to the page. And what they needed: motion as
|
|
190
|
+
a reader's setting, a command palette with pages, toasts that carry their action, busy buttons,
|
|
191
|
+
type-to-confirm, and public status and priority glyphs.
|
|
192
|
+
|
|
193
|
+
### Breaking
|
|
194
|
+
|
|
195
|
+
- **Form field keys are no longer element ids.** Control ids are generated per Form and Fieldset
|
|
196
|
+
instance (`<idPrefix>-<key>`; `idPrefix` makes them predictable), so a form mounted twice repeats
|
|
197
|
+
no id and a key such as `stage` never collides with `#stage` elsewhere. The key stays the field's
|
|
198
|
+
`name`, the native control's `name`, and its `data-field-id`; radio groups are named after the
|
|
199
|
+
control id. Code that looked a control up by `#<key>` reads `form.getField(key).controlId` (or
|
|
200
|
+
queries `[data-field-id="<key>"]`) instead. An explicit `id` that differs from the key is used as
|
|
201
|
+
given, and the legacy compatibility layer keeps key ids.
|
|
202
|
+
- **Density modes are removed.** `data-zx-density` (`cozy` | `compact`) no longer has any effect,
|
|
203
|
+
`styles/tokens/density.css` no longer ships, and no component carries density-specific rules.
|
|
204
|
+
Migration: drop the attribute. To tighten an application — or one region of it — set
|
|
205
|
+
`--zx-space-unit` and `--zx-control-height` instead, for example
|
|
206
|
+
`:root { --zx-space-unit: 3.5px; --zx-control-height: 28px; }`, which is close to what compact
|
|
207
|
+
used to do without shrinking the type.
|
|
208
|
+
- **`FileItem`'s `density` option is now `identitySize`** (`'sm'|'md'|'lg'`, the size of the
|
|
209
|
+
file's icon and name), and `FileList` items take the same name. The word now means one thing
|
|
210
|
+
nowhere in the library.
|
|
211
|
+
|
|
212
|
+
### Changed
|
|
213
|
+
|
|
214
|
+
- Every toast pauses while it holds focus as well as hover, resumes when neither applies, and
|
|
215
|
+
returns focus to where it came from if it closes while focused.
|
|
216
|
+
- Sheet slides on `--zx-ease-drawer`; KanbanView's drag preview and grabbed card take
|
|
217
|
+
`--zx-drag-shadow`. A solid primary button's pressed step is darker than its hover step.
|
|
218
|
+
- Launcher `select` and `error` details carry `page`; closing the launcher returns it to its root.
|
|
219
|
+
The status and priority glyph styles are `.zx-status-icon` and `.zx-priority-icon` (Select's
|
|
220
|
+
glyphs keep their old classes as well).
|
|
221
|
+
- **`Select.priority()` reads by height, not hue**: levels are four grey signal bars filled to the
|
|
222
|
+
level in muted ink, and only the highest is coloured — a danger square with "!". It offers "No
|
|
223
|
+
priority" (value null, message `priority.none`) at the head of the list; `clearable: false`
|
|
224
|
+
restores the old list, a required priority field leaves it out, and the legacy compatibility
|
|
225
|
+
select keeps its old list unless it allows empty values. Values and message keys are unchanged.
|
|
226
|
+
- **Quiet NumberField** start-aligns its value with the quiet values around it; both steppers sit
|
|
227
|
+
at the trailing end, shown on hover or focus.
|
|
228
|
+
- **Field `type: 'html'`** draws no input frame; display content keeps a control's height.
|
|
229
|
+
- **Toggle labels** start-align and wrap like text, the track level with the first line; a field
|
|
230
|
+
beside a taller one keeps its label and control at the top of its cell.
|
|
231
|
+
- **FileItem** shows a readable type ("PDF", "Image") instead of the MIME type and picks its icon
|
|
232
|
+
from the MIME type when the icon set has one.
|
|
233
|
+
- **AppSidebar** creates its own root as a `<div>` (the `<nav>` inside is the landmark), so it no
|
|
234
|
+
longer adds an unnamed complementary landmark; `getItems()` leaves out empty `children`.
|
|
235
|
+
- **Table** puts `data-column` on every header and body cell in every mode; **KanbanView**
|
|
236
|
+
assignee faces take Avatar's tint from the name (or a descriptor `tone`); the neutral soft
|
|
237
|
+
**Badge** is a wash of the text colour, visible on raised dark surfaces, and a small dotted
|
|
238
|
+
Badge has 12px text and a 4px gap.
|
|
239
|
+
- **ZeyOS enums read as labels** ("Invoiced", "Partly paid") in generated tables and forms; a
|
|
240
|
+
schema `{value, label}` is used as given. **ZeyOS date-only fields are calendar days** — indexed
|
|
241
|
+
`date`, `duedate`, `birthdate`, `datefrom`/`dateto` outside appointments and events, `datecancel`,
|
|
242
|
+
and `lastbilling` show no time and are stored as midnight in the instance's zone (`timeZone`,
|
|
243
|
+
default the browser's); `lastmodified` and the appointment, event, comment, record, and
|
|
244
|
+
document-version timestamps are date-times.
|
|
245
|
+
- **Spacing derives from one unit.** `--zx-space-1` … `--zx-space-8` are multiples of the new
|
|
246
|
+
`--zx-space-unit` (4px by default, so the steps are unchanged at 4–40px).
|
|
247
|
+
- **Corners are smaller and proportional.** `--zx-radius` is now `4px`, and `-sm`, `-md`, `-lg`,
|
|
248
|
+
and `-xl` are ×0.5, ×0.75, ×1, and ×1.5 of it — 2 / 3 / 4 / 6px, down from 3 / 5 / 7 / 11px — so a
|
|
249
|
+
theme that scales the base keeps every step in proportion. `--zx-control-radius` still follows
|
|
250
|
+
`-lg`. Panels that used `-xl` (Launcher, Sheet, the AppSidebar and AppRail items) use `-lg` or
|
|
251
|
+
`-md`; ValueList chips and record-card metadata chips are no longer pills, and the SortControl
|
|
252
|
+
direction button is a control rather than a circle.
|
|
253
|
+
- **Controls are 30px tall** (`--zx-control-height`, from 32px). `--zx-control-pad-x` stays 10px
|
|
254
|
+
and text sizes are unchanged.
|
|
255
|
+
- **Structured menus are tighter.** AppSidebar rows are one control tall (from control + 8px) with
|
|
256
|
+
2px between rows, 12px between groups, and a 3px corner. A text-only child starts under its
|
|
257
|
+
parent's label; a child with its own icon steps in 16px, just clear of the guide line, instead
|
|
258
|
+
of a whole icon column. The rail flyouts follow. TreeView indents 12px per level (from
|
|
259
|
+
18px) with a 4px block padding per row. MenuButton, ContextMenu, Select, TagPicker, Launcher,
|
|
260
|
+
Finder, Checklist, and the Table column menu share one row: 4px × 8px padding, the smallest
|
|
261
|
+
radius, panels at `--zx-radius-lg`, and section labels no taller than an item.
|
|
262
|
+
- **"Current" is neutral, and nothing is docked to an edge.** Where you are — the active
|
|
263
|
+
navigation item (AppSidebar, its rails and flyouts), the open TreeView node, the current Finder
|
|
264
|
+
column entry, the active tab in every Tabbox variant, the pressed ListToolbar view, the current
|
|
265
|
+
Calendar view, Launcher app and Pagination page — is a neutral `--zx-color-bg-current` fill with
|
|
266
|
+
the text colour at weight 600; the edge marker beside the active item is gone. What you have
|
|
267
|
+
*picked* (checked rows, chosen options, a multi-selection) keeps the accent tint. A rail item
|
|
268
|
+
whose flyout holds the active route takes the accent colour. Forced colours still use the
|
|
269
|
+
system's selected pair.
|
|
270
|
+
- **One solid accent per screen.** Solid accent is for the primary button; tab underlines, pressed
|
|
271
|
+
toggles, and decorative icons no longer use it. In dark, the primary button sits on the accent
|
|
272
|
+
600 step with white text (`--zx-color-accent-solid` / `--zx-color-on-accent-solid`) instead of
|
|
273
|
+
the bright 400 step.
|
|
274
|
+
- **Status green is its own colour.** `--zx-green-*` is a yellow-green status ramp that no longer
|
|
275
|
+
matches the default ZeyOS accent, so a "success" badge or chart segment never reads as branding.
|
|
276
|
+
The brand values moved to `--zx-emerald-*`, which the default accent points at.
|
|
277
|
+
- **Dark theme is layered.** Page, chrome, surface, raised, and overlay steps sit off near-black
|
|
278
|
+
(#1b1b1e → #313136), primary text is about 90% white, and borders are translucent white.
|
|
279
|
+
- **Quieter type.** Decorative upper-case and letter-spaced labels are gone from every component
|
|
280
|
+
(menu and Select groups, Launcher groups, StatTile labels, Calendar weekdays, Table headers, …);
|
|
281
|
+
row and label weights moved from 600 to 500, titles to 600–650, and UI text is set with
|
|
282
|
+
`--zx-tracking-tight` and Inter's `cv11`. Field labels and Fieldset legends are small, medium, and
|
|
283
|
+
muted, so values lead.
|
|
284
|
+
- **Tables** drop the header band (muted medium labels on the surface), divide rows with
|
|
285
|
+
`--zx-color-border-subtle`, and set numbers in tabular figures.
|
|
286
|
+
- **Avatars** fall back to a colour picked from the name (one of eight tones) with no ring, at
|
|
287
|
+
24 / 32 / 40px, and show one initial below 24px.
|
|
288
|
+
- **StatTile** labels are sentence case, values 24px tabular, the icon is a muted glyph without a
|
|
289
|
+
coloured chip, and tiles in a row line up whether or not they carry a sparkline.
|
|
290
|
+
- **EmptyState** draws its icon in `--zx-color-text-subtle` and its title semibold.
|
|
291
|
+
- **Danger is legible as text.** Light `--zx-color-danger` moves to the 600 step and the dark
|
|
292
|
+
danger tint is lighter, so danger ink keeps 4.5:1 on every surface and on its own tint, as the
|
|
293
|
+
other status colours do (now tested for all four in both themes and every preset).
|
|
294
|
+
- **The dark selected tint is lighter** (13% of the accent instead of 18%), so muted text on a
|
|
295
|
+
checked row or chosen option keeps 4.5:1 under every preset (now tested, light and dark).
|
|
296
|
+
- **Toasts lose their coloured leading-edge bar**; the kind shows in the icon and a tinted border,
|
|
297
|
+
as everywhere else nothing is docked to an edge.
|
|
298
|
+
- **Button key hints** are quieter by colour and weight instead of opacity, which left them below
|
|
299
|
+
4.5:1 on a solid primary button.
|
|
300
|
+
- **Select.entity** shows an entity without a colour as a neutral tile with a muted glyph; before,
|
|
301
|
+
the glyph was white on the pale accent tint and could not be seen.
|
|
302
|
+
- **Icons are Lucide outlines.** The bundled set renders as strokes in `currentColor` (ISC; a
|
|
303
|
+
1.75-unit stroke per 24 that never thins below 1px), with every existing name kept. Bundles keep
|
|
304
|
+
the licence notice. A chosen Rating star is drawn solid.
|
|
305
|
+
- **The theme studio's Density section is now Spacing**: a slider for `--zx-space-unit` (3–6px).
|
|
306
|
+
The radius slider sets `--zx-radius` in pixels (0–10px), the standard recipes carry a spacing
|
|
307
|
+
unit instead of a density, Copy CSS exports the unit, and a theme saved by an earlier studio
|
|
308
|
+
still loads.
|
|
309
|
+
|
|
310
|
+
### Added
|
|
311
|
+
|
|
312
|
+
- **Motion as a setting.** `data-zx-motion="reduced"` on any element stops motion inside it: the
|
|
313
|
+
duration tokens become `0ms` and a base rule stops CSS animations and transitions, while state
|
|
314
|
+
changes still apply; the system preference zeroes the tokens too. `prefersReducedMotion(element)`,
|
|
315
|
+
`watchMotion(element, fn, { signal, immediate })`, and `MOTION_ATTRIBUTE` let script follow it;
|
|
316
|
+
Chart passes `reducedMotion` to its adapter and `ChartJsAdapter` turns animation off under it.
|
|
317
|
+
- `--zx-ease-spring` (a small overshoot) and `--zx-ease-drawer` (a decisive ease-out) beside
|
|
318
|
+
`--zx-ease`, and `--zx-drag-shadow` for an item being dragged.
|
|
319
|
+
- **Launcher pages.** An item with `items` (an array, or a loader `(query, { signal })`) opens a
|
|
320
|
+
nested page: a scope chip in the input, Backspace, ArrowLeft, or × to go back, "⌫ Back" in the
|
|
321
|
+
footer, `open({ page })`, `back()`, `getPage()`, and a `page` event. Items take a `hint` (muted
|
|
322
|
+
text at the end of the row), `shortcut` key caps, and `keys` for `aria-keyshortcuts`.
|
|
323
|
+
- **Message `action`** (`{ label, onclick, kind }`, a small button that runs and closes the toast;
|
|
324
|
+
a toast with an action stays at least 8 seconds) and **`leading`** (a node such as an Avatar in
|
|
325
|
+
place of the kind icon).
|
|
326
|
+
- **`Dialog.confirm({ confirmText })`** — type-to-confirm: a labelled input that has focus, and a
|
|
327
|
+
confirm button and Enter that work only on an exact match.
|
|
328
|
+
- **Busy buttons.** `button({ busy })` and `setButtonBusy(button, busy)` show a spinner in place of
|
|
329
|
+
the icon, set `aria-busy`, and ignore activation while the action runs — but keep the button
|
|
330
|
+
focusable, so focus does not fall to the page as it does from a disabled button.
|
|
331
|
+
- **`statusIcon(status)` and `priorityIcon(level)`**, the glyphs `Select.status()` and
|
|
332
|
+
`Select.priority()` draw, for lists, boards, and filters; decorative unless given a `label`.
|
|
333
|
+
- `idPrefix` on Form and Fieldset; Field `name`, `field.name`, and `field.controlId`.
|
|
334
|
+
- Checklist `hideLabel`; TagPicker `toneKey` (default `'tone'`), colouring a tag the way a Badge
|
|
335
|
+
`tone` does; ActivityList `variant: 'compact'` for cards narrower than 30rem; Table column
|
|
336
|
+
`ariaLabel` for a blank or terse header; FileItem `typeLabel`; `Dialog.prompt` `okLabel` and
|
|
337
|
+
`cancelLabel`.
|
|
338
|
+
- `MenuButton.open({ returnFocus })` (also on `focusFirst()` and `focusLast()`) and
|
|
339
|
+
`Message.disposeRegion(scope)`.
|
|
340
|
+
- ZeyOS: `zeyosTable` passes Table options through (`variant`, `zebra`, `stickyHeader`,
|
|
341
|
+
`responsive`, `growing`, `emptyText`, `rowClass`, `rowKind(s)`, the column chooser, and the Table
|
|
342
|
+
listeners; editing, row reordering, and hierarchy stay out because the binding never persists
|
|
343
|
+
them); `timeZone` and per-field `formats` on `zeyosTable`, `zeyosForm`, `zeyosView`, and
|
|
344
|
+
`resolveFields`; `unixSecondsToCalendarDay()` and `calendarDayToUnixSeconds()`; `zeyosForm`
|
|
345
|
+
`scope` and `notify`.
|
|
346
|
+
- **Colour roles:** `--zx-color-bg-current`, `--zx-color-bg-chrome`, `--zx-color-border-subtle`,
|
|
347
|
+
`--zx-color-text-subtle`, the categorical tones `--zx-color-tone-{blue,teal,green,amber,orange,
|
|
348
|
+
red,pink,violet,slate}-{bg,fg}`, and the chart series `--zx-color-chart-1` … `-8`, whose first
|
|
349
|
+
series is deliberately not the accent. Contrast is tested in both themes and all six presets.
|
|
350
|
+
- **Type tokens:** `--zx-text-3xl` (30px), `--zx-weight-medium`, `--zx-weight-semibold`,
|
|
351
|
+
`--zx-tracking-tight`, `--zx-tracking-title`.
|
|
352
|
+
- **Quiet fields:** inside any `[data-zx-fields="quiet"]` container, native fields and Select,
|
|
353
|
+
TagPicker, Datebox, DateRangeBox, NumberField, and Timebox show their frame only on hover and
|
|
354
|
+
focus — property panels read as data, not as a wall of boxes.
|
|
355
|
+
- `Table` / `TableView` `variant: 'plain'` (no frame, no header band) for tables inside cards;
|
|
356
|
+
`badge({ tone })` with the categorical tones (and `BADGE_TONES`); `Avatar` `tone`, `avatarTone()`
|
|
357
|
+
and `AVATAR_TONES`; `StatTile` `caption`, read with the value.
|
|
358
|
+
- `registerIcons()` accepts outline glyphs as `[viewBox, path, 'stroke']`; `[viewBox, path]` pairs
|
|
359
|
+
still render filled.
|
|
360
|
+
- `Tabbox` `label`, the tab list's accessible name.
|
|
361
|
+
|
|
362
|
+
### Fixed
|
|
363
|
+
|
|
364
|
+
- A destructive `Dialog.confirm` started focus on the destructive button; it starts on Cancel, the
|
|
365
|
+
least destructive choice (type-to-confirm starts in its input).
|
|
366
|
+
- On a phone, toasts covered the header's controls; they rise from the foot of the screen there.
|
|
367
|
+
- A ghost Button showed no focus ring: its `box-shadow: none` outranked `:focus-visible`.
|
|
368
|
+
- Select's loading spinner never turned (it read an undefined duration token).
|
|
369
|
+
- The Launcher's search row could push its close button off a narrow screen.
|
|
370
|
+
- A `[data-zx-theme="dark"]` region on a light page inherited light glass, overlays, hover and
|
|
371
|
+
current fills, tone tints, and focus ring: colours derived from other theme colours were resolved
|
|
372
|
+
on `:root` only. They are restated on every theme element now; geometry overrides on `:root`
|
|
373
|
+
still reach nested regions.
|
|
374
|
+
- Overlays (Dropdown, Tooltip, MenuButton, ContextMenu, Modal, Dialog, Sheet, Launcher) created before their
|
|
375
|
+
anchor or scope was in the document parked their panel on `<body>`, outside the theme scope; they
|
|
376
|
+
find their host on first open.
|
|
377
|
+
- Choosing a MenuButton item dropped focus to `<body>`; it returns to the trigger. CodeEditor
|
|
378
|
+
trapped the keyboard; Escape then Tab leaves it, as documented.
|
|
379
|
+
- Floating Message regions kept sending toasts into an emptied host and were never removed.
|
|
380
|
+
- Table and Grid number and date editors select their content on entry (typing "6" over "1.00"
|
|
381
|
+
gives 6); sortable headers use the same font as the others; no scrollbar gutter is reserved on a
|
|
382
|
+
table that does not scroll; a blank header has an accessible name. TreeView type-ahead calls
|
|
383
|
+
`preventDefault` and leaves text controls in rows alone.
|
|
384
|
+
- Table's selection checkboxes and row-reorder handles sit in the middle of their cell. They rode a
|
|
385
|
+
few pixels high on the text baseline, and the cell padding pushed them off the centre of their
|
|
386
|
+
control-height column, in a fixed layout past its edge.
|
|
387
|
+
- NumberField, Datebox, and DateRangeBox fill a Field's control column; clear-button padding is
|
|
388
|
+
reserved only when `clearable`, and a disabled Datebox or DateRangeBox shows no clear button.
|
|
389
|
+
Slider end labels stay inside the component. A Checklist inside a Field no longer repeats its
|
|
390
|
+
heading.
|
|
391
|
+
- `colorKey` on `Select.entity()` and TagPicker accepts token references (`var(--zx-…)`). Clicking a
|
|
392
|
+
read-only Select no longer draws the keyboard focus ring; a disabled Select fades like a disabled
|
|
393
|
+
Field; a read-only TagPicker shows only its tags.
|
|
394
|
+
- `collapsible: false` still showed AppSidebar's minimise button. copyButton's status line and
|
|
395
|
+
CopyInput's hidden label were positioned outside their control.
|
|
396
|
+
- A Field whose adapter returns a wrapper (a `custom` field holding a component) named the
|
|
397
|
+
wrapper, which cannot carry a name; its label, description, and validity now reach the first
|
|
398
|
+
unnamed form control inside it, or the adapter's new `labelTarget`.
|
|
399
|
+
- Launcher ran an item's command before closing, so closing put focus back on an element the
|
|
400
|
+
command had just redrawn or moved focus away from; it closes first now.
|
|
401
|
+
- A MenuButton's menu had no accessible name; it is labelled by its trigger, as the APG pattern
|
|
402
|
+
has it. NumberField no longer swallows Mod+Enter (and other chords), so a form or dialog's submit
|
|
403
|
+
shortcut works from a number field. Datebox and DateRangeBox were 2px taller than the text input
|
|
404
|
+
beside them; every control is one control height.
|
|
405
|
+
- A Tooltip placed beside an anchor near the edge of the screen squeezed to a word per line
|
|
406
|
+
instead of moving: it now takes the other side, or goes above or below when neither side fits.
|
|
407
|
+
- A Chart in a narrow card overflowed it (its 220px minimum height became a 587px minimum width
|
|
408
|
+
through the aspect ratio); it grows taller instead. A StatTile delta keeps its figure on one line
|
|
409
|
+
in a narrow tile.
|
|
410
|
+
- `zeyosTable` showed a due date as a date-time whose hour moved with daylight saving, and
|
|
411
|
+
`zeyosForm` edited it as one; `zeyosForm.save()` raised its toast wherever focus was.
|
|
412
|
+
- The AccountMenu trigger rendered as a centred, boxed card because `menu-button.css` loaded after
|
|
413
|
+
`account-menu.css`; it is a flat row again.
|
|
414
|
+
- CodeEditor referenced `--zx-color-bg-subtle`, which never existed.
|
|
415
|
+
- The Marque Gold preset's accent text now reaches 4.5:1 on the light chrome tone.
|
|
416
|
+
- A sortable end-aligned Table column put its header label at the start, away from its figures;
|
|
417
|
+
the label now sits at the end with the sort arrow before it.
|
|
418
|
+
- ActivityItem's heading read the actor and title as one word ("Jonas Weberset…") to assistive
|
|
419
|
+
technology; a space now separates them.
|
|
420
|
+
- Table's Columns chooser, RecordView's Fields chooser, KanbanView's undo and redo, and Filter's
|
|
421
|
+
actions used a `zx-button` class no stylesheet defines, so they rendered as bare browser buttons;
|
|
422
|
+
they are small Zx buttons now (ghost in toolbars, primary for Apply).
|
|
423
|
+
|
|
424
|
+
### Website
|
|
425
|
+
|
|
426
|
+
- The application layouts moved from the documentation sidebar to a gallery of their own
|
|
427
|
+
(`layouts.html`), with a live thumbnail per layout, a near-full-screen view with its source, and a
|
|
428
|
+
standalone page (`layout.html#<id>`) for opening one in its own tab. Nine complete application
|
|
429
|
+
templates join the eight screen patterns, which are rebuilt on the same application shell.
|
|
430
|
+
- The documentation, gallery, and theme studio share the library's look: navigation on the chrome
|
|
431
|
+
tone, neutral current entries, sentence-case labels, hairline example cards, and code and API
|
|
432
|
+
tables drawn like the refined Table.
|
|
433
|
+
- New in the gallery: an **agent workspace** template — agents with live presence, editor tabs, a
|
|
434
|
+
plan and execution log with hand-offs, approvals as toasts that carry their action, a command
|
|
435
|
+
palette with pages, a bottom panel, and a status bar — and two screen patterns, **agent chat**
|
|
436
|
+
(tool calls, an approval that blocks the run, sources, and the run beside the thread) and
|
|
437
|
+
**system states** (every empty, loading, error, validation, and confirmation state, with a
|
|
438
|
+
switch to go offline). The AI chat template shows its work: tool steps, sources, artifacts with
|
|
439
|
+
versions, regenerate and branch, and `@agent` mentions.
|
|
440
|
+
- Every layout works from a phone to a wide screen: below 1180px the inspector and below 860px
|
|
441
|
+
the navigation become drawers, and on a phone a layout shows its list or its record with a way
|
|
442
|
+
back. All seventeen pass an accessibility audit — named controls and landmarks, text contrast,
|
|
443
|
+
visible focus, heading order — in both themes, wide and narrow.
|
|
444
|
+
- The theme studio has a Motion setting (System or Reduced), kept across the whole site as a
|
|
445
|
+
reader's preference, and a Button states card showing every kind in every state.
|
|
446
|
+
- The site self-hosts Inter as a variable font (SIL OFL), so every weight renders as designed and no
|
|
447
|
+
font request leaves the site.
|
|
448
|
+
- The theme studio offers more to build from. Eleven neutral tints — Neutral, Zinc, Stone, Cool,
|
|
449
|
+
Mist, Sage, Olive, Warm, Taupe, Mauve, and Accent — are picked from swatches of the ramp each
|
|
450
|
+
would produce, and a strength control scales any of them from grey to twice its colour; every
|
|
451
|
+
tint keeps the text roles legible at full strength. The typeface list grows from six system
|
|
452
|
+
stacks to eleven, drawn in their own type, plus a custom stack for a brand font, and the code
|
|
453
|
+
font (`--zx-font-mono`) is a choice of its own.
|
|
454
|
+
- Themes can be saved and loaded as JSON. Export writes a `zx-theme` file — the settings, plus the
|
|
455
|
+
custom properties they produce — to copy or download; Import takes one pasted, dropped, or chosen,
|
|
456
|
+
loads it even when a value is out of range or unknown, and says what it adjusted.
|
|
457
|
+
|
|
11
458
|
## 4.4.0 — 2026-09-22
|
|
12
459
|
|
|
13
460
|
A large release in two halves. The first adds capability: a dependency-free code editor, the
|
package/README.md
CHANGED
|
@@ -80,6 +80,10 @@ namespaced `storage()` view that degrades to memory when the browser refuses wri
|
|
|
80
80
|
`toCsv`/`downloadBlob`/`copyToClipboard` for exporting what a table is showing.
|
|
81
81
|
|
|
82
82
|
`icon()` renders the inline SVG glyphs Zx bundles — no webfont, stylesheet, or network request.
|
|
83
|
+
They are outline icons from [Lucide](https://lucide.dev) (ISC licence; the notice ships in
|
|
84
|
+
`src/core/icons.js`): `currentColor` strokes on a 24-unit grid, about 1.2px at the default 16px.
|
|
85
|
+
`registerIcons()` adds more, either filled (`[viewBox, path]`, e.g. Font Awesome paths) or outlined
|
|
86
|
+
(`[viewBox, path, 'stroke']`, e.g. further Lucide icons).
|
|
83
87
|
Applications that want Font Awesome call `loadFontAwesome({ kit })` once, and every icon in the
|
|
84
88
|
library follows, including names Zx maps to their Font Awesome counterparts. Names can also pick a
|
|
85
89
|
renderer themselves: `'fa:user'`, `'duotone:user'`, `'kit:zeyos-notes'`, `'builtin:check'`, or a
|
|
@@ -173,7 +177,8 @@ ZeyOS binding — see `src/zeyos/modules.js`.
|
|
|
173
177
|
| `MasterPanel` | Full-height application panel with fixed header actions and footer. |
|
|
174
178
|
| `Tabbox` | APG tabs in four appearances, with lazy content, closing, badges, and disabled states. |
|
|
175
179
|
| `NavigationBar` | Responsive application navigation with optional tab panels and overflow. |
|
|
176
|
-
| `AppSidebar` | Expanded or minimized vertical application navigation plus horizontal rails; descendants are inline only while expanded. |
|
|
180
|
+
| `AppSidebar` | Expanded or minimized vertical application navigation plus horizontal rails; descendants are inline only while expanded. Sections group a tree; `layout: 'modules'` puts a module strip beside one module's menu. |
|
|
181
|
+
| `ModuleBar` | Colour-coded module tiles in a strip or bar: flyout menus, live badges, one Tab stop, and an "All modules" catalogue for what does not fit. |
|
|
177
182
|
| `Toolbar` | APG toolbar: one tab stop, arrow-key movement, and overflow into a menu. |
|
|
178
183
|
| `SplitView` | Resizable two-pane split with a keyboard-operable separator. |
|
|
179
184
|
| `Stepper` | Linear multi-step progress with completed, active, and error states. |
|
|
@@ -233,13 +238,13 @@ moduleColor('invoices'); // '#535494'
|
|
|
233
238
|
name, identity colour, label, and a stock Font Awesome fallback. The `--zx-module-*` CSS custom
|
|
234
239
|
properties are generated from that file, so CSS and JavaScript cannot disagree about a colour.
|
|
235
240
|
|
|
236
|
-
## Themes
|
|
241
|
+
## Themes
|
|
237
242
|
|
|
238
243
|
Load `zx.css` once. Zx components consume semantic `--zx-*` tokens and inherit their values from
|
|
239
|
-
the document. Select a built-in theme
|
|
244
|
+
the document. Select a built-in theme on any ancestor (normally `<html>`):
|
|
240
245
|
|
|
241
246
|
```html
|
|
242
|
-
<html data-zx-theme="dark"
|
|
247
|
+
<html data-zx-theme="dark">
|
|
243
248
|
```
|
|
244
249
|
|
|
245
250
|
Top-layer menus, dialogs, tooltips, launchers, and toast regions stay under the nearest Zx theme
|
|
@@ -247,10 +252,22 @@ scope in the DOM, so a theme or product-token override on a nested application s
|
|
|
247
252
|
to its overlays. Pass the optional `scope` context to Modal, Dialog, Sheet, Launcher, or static
|
|
248
253
|
Message calls when the opener is not inside the intended scope.
|
|
249
254
|
|
|
250
|
-
Theme values are `light`, `dark`, and `auto
|
|
251
|
-
|
|
255
|
+
Theme values are `light`, `dark`, and `auto`. `auto` follows the operating-system color
|
|
256
|
+
preference.
|
|
252
257
|
|
|
253
|
-
|
|
258
|
+
There is one geometry. Spacing steps are multiples of `--zx-space-unit` (4px:
|
|
259
|
+
4, 8, 12, 16, 20, 24, 32, 40), radius steps are fractions of `--zx-radius` (4px: 2, 3, 4, 6), and
|
|
260
|
+
controls are `--zx-control-height` (30px) tall. To tighten or loosen an application — or one
|
|
261
|
+
region of it — override those tokens rather than switching a mode:
|
|
262
|
+
|
|
263
|
+
```css
|
|
264
|
+
:root {
|
|
265
|
+
--zx-space-unit: 3.5px;
|
|
266
|
+
--zx-control-height: 28px;
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
A second attribute picks the **accent**, orthogonally to the theme:
|
|
254
271
|
|
|
255
272
|
```html
|
|
256
273
|
<html data-zx-theme="dark" data-zx-preset="ocean">
|
|
@@ -272,6 +289,8 @@ through, so a preset rethemes light, dark, and auto at once:
|
|
|
272
289
|
|
|
273
290
|
Light surfaces take the 600 and 700 stops, dark ones take 300, 400, and 500 — so keep 600 legible
|
|
274
291
|
against white and 400 against near-black, and `--zx-color-on-accent` stays correct in both. The
|
|
292
|
+
primary button is the exception on purpose: `--zx-color-accent-solid` is the 600 stop with white
|
|
293
|
+
ink in both themes, so the one solid accent on a screen never turns into a bright slab in dark. The
|
|
275
294
|
[theme studio](https://zx.zeyos.com/theme.html) renders every component family under a live theme and
|
|
276
295
|
exports the result.
|
|
277
296
|
|
|
@@ -292,7 +311,20 @@ Anything beyond the accent is a semantic token override, without reaching into c
|
|
|
292
311
|
|
|
293
312
|
Prefer semantic tokens such as `--zx-color-*`, `--zx-control-*`, `--zx-space-*`,
|
|
294
313
|
`--zx-radius-*`, and `--zx-text-*`. Palette tokens are implementation details and should not be
|
|
295
|
-
used by application or component CSS.
|
|
314
|
+
used by application or component CSS. A few roles carry most of the visual language:
|
|
315
|
+
|
|
316
|
+
- `--zx-color-bg-chrome` for navigation and inspector columns beside the `--zx-color-bg-surface`
|
|
317
|
+
canvas, and `--zx-color-border-subtle` for dividers inside them — tone separates, lines only
|
|
318
|
+
where tone cannot.
|
|
319
|
+
- `--zx-color-bg-current` (neutral) for where you are, `--zx-color-bg-selected` (accent tint) for
|
|
320
|
+
what you picked.
|
|
321
|
+
- `--zx-color-text-muted` for secondary text and `--zx-color-text-subtle` for icons and meta.
|
|
322
|
+
- `--zx-color-tone-<hue>-bg` / `-fg` (blue, teal, green, amber, orange, red, pink, violet, slate)
|
|
323
|
+
for categorical colour — tags, avatars, icon tiles — and `--zx-color-chart-1` … `-8` for chart
|
|
324
|
+
series. Neither is the accent or a status colour; `success` is a yellow-green of its own.
|
|
325
|
+
|
|
326
|
+
Add `data-zx-fields="quiet"` to a property panel and its native fields show no border or fill until
|
|
327
|
+
hovered or focused.
|
|
296
328
|
|
|
297
329
|
## Browser support
|
|
298
330
|
|
|
@@ -311,9 +343,10 @@ npm install
|
|
|
311
343
|
npm run serve
|
|
312
344
|
```
|
|
313
345
|
|
|
314
|
-
Open <http://127.0.0.1:8321/website/docs.html> for the documentation — getting started, every
|
|
315
|
-
component with a live demo and its JavaScript source
|
|
316
|
-
|
|
346
|
+
Open <http://127.0.0.1:8321/website/docs.html> for the documentation — getting started, and every
|
|
347
|
+
component with a live demo and its JavaScript source — and
|
|
348
|
+
<http://127.0.0.1:8321/website/layouts.html> for the gallery of application layouts. Also
|
|
349
|
+
available: <http://127.0.0.1:8321/tests/smoke/smoke.html> for source-module smoke tests, or build first and open <http://127.0.0.1:8321/tests/smoke/smoke-dist.html> for
|
|
317
350
|
classic-script distribution tests.
|
|
318
351
|
|
|
319
352
|
```sh
|
|
@@ -126,6 +126,14 @@ export declare class AccountMenu extends Component<AccountMenuOptions> {
|
|
|
126
126
|
isOpen(): boolean;
|
|
127
127
|
/** Replaces account presentation without touching session state. @param {AccountIdentity} account @returns {this} */
|
|
128
128
|
setAccount(account: AccountIdentity): this;
|
|
129
|
+
/**
|
|
130
|
+
* Shows the avatar alone or the avatar with the name and secondary line — for a navigation
|
|
131
|
+
* column that narrows to icons and widens again. The trigger keeps its full accessible name
|
|
132
|
+
* either way.
|
|
133
|
+
* @param {boolean} compact
|
|
134
|
+
* @returns {this}
|
|
135
|
+
*/
|
|
136
|
+
setCompact(compact: boolean): this;
|
|
129
137
|
/** Replaces account actions. @param {MenuButtonItem[]} items @returns {this} */
|
|
130
138
|
setItems(items: MenuButtonItem[]): this;
|
|
131
139
|
/** Focuses the account trigger. @returns {this} */
|