@zeyos/zx 4.4.0 → 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 +283 -0
- package/README.md +42 -10
- package/dist/types/components/activity-list/activity-list.d.ts +22 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +5 -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 +15 -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/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 +2 -2
- package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
- 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 +34 -6
- 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 +260 -15
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +1 -1
- package/dist/types/components/menu-button/menu-button.d.ts +33 -5
- package/dist/types/components/message/message.d.ts +119 -17
- package/dist/types/components/modal/modal.d.ts +13 -2
- 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 +11 -3
- 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 +46 -1
- 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/core/breakpoint.d.ts +1 -1
- package/dist/types/core/icons.d.ts +23 -25
- 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 +5 -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 +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 +1621 -443
- package/dist/zx-zeyos.esm.min.js +53 -5
- package/dist/zx.css +1411 -660
- package/dist/zx.esm.js +1976 -703
- package/dist/zx.esm.min.js +56 -8
- package/dist/zx.global.js +1978 -705
- package/dist/zx.global.min.js +56 -8
- package/dist/zx.min.css +1 -1
- package/docs/api.json +219 -34
- package/docs/llms.md +472 -110
- package/docs/llms.txt +3 -3
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- 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 +34 -0
- package/src/components/app-icon/app-icon.css +1 -1
- package/src/components/app-rail/app-rail.css +40 -79
- package/src/components/app-sidebar/app-sidebar.css +109 -174
- package/src/components/app-sidebar/app-sidebar.js +21 -6
- 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 +67 -9
- package/src/components/button/button.js +38 -0
- package/src/components/calendar/calendar.css +46 -46
- package/src/components/card/card.css +2 -2
- package/src/components/card-view/card-view.css +9 -7
- 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 +6 -5
- package/src/components/code-editor/code-editor.js +19 -1
- package/src/components/context-menu/context-menu.css +9 -4
- 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-range-picker.css +3 -3
- package/src/components/date-picker/time-picker.css +1 -1
- 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/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +5 -3
- 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 +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.js +144 -10
- package/src/components/filter/filter.js +7 -3
- package/src/components/filter-panel/filter-panel.css +1 -1
- 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 +11 -3
- package/src/components/kanban-view/kanban-view.css +39 -15
- package/src/components/kanban-view/kanban-view.js +4 -4
- package/src/components/launcher/launcher.css +107 -25
- package/src/components/launcher/launcher.js +503 -41
- package/src/components/list-toolbar/list-toolbar.css +13 -8
- package/src/components/list-toolbar/list-toolbar.js +1 -1
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/menu-button/menu-button.css +9 -4
- package/src/components/menu-button/menu-button.js +65 -9
- package/src/components/message/message.css +33 -3
- package/src/components/message/message.js +217 -15
- package/src/components/modal/modal.js +18 -3
- package/src/components/navigation-bar/navigation-bar.css +18 -9
- 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/rating/rating.css +7 -0
- 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 +83 -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 +4 -1
- package/src/components/stat-tile/stat-tile.css +41 -46
- package/src/components/stat-tile/stat-tile.js +17 -6
- package/src/components/tabbox/tabbox.css +32 -27
- package/src/components/tabbox/tabbox.js +5 -1
- package/src/components/table/table.css +104 -29
- package/src/components/table/table.js +90 -16
- 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 +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/view/record-view.js +1 -1
- package/src/core/breakpoint.js +1 -1
- package/src/core/icons.js +193 -60
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +21 -2
- package/src/index.js +5 -3
- package/src/internal/app-rail.js +1 -2
- 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/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 +0 -1
- package/styles/tokens/density.css +0 -9
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,289 @@ and friends remain the complete record.
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## 5.0.0 — 2026-10-09
|
|
12
|
+
|
|
13
|
+
Xenon now has one geometry and a quieter finish. The cozy and compact view modes are gone; in their
|
|
14
|
+
place is a single, slightly tighter default whose spacing, corners, and control height are tokens a
|
|
15
|
+
product sets once. On top of it the visual language was refined against how well-made business
|
|
16
|
+
applications look today: "where you are" is a neutral fill rather than a block of accent colour,
|
|
17
|
+
status colours no longer borrow the brand green, chrome and canvas separate by tone instead of by
|
|
18
|
+
lines, labels are sentence case at medium weights, and icons are outlines.
|
|
19
|
+
|
|
20
|
+
The other half is what building twenty complete screens on the library asked of it. A layout
|
|
21
|
+
gallery of application templates and screen patterns — mail, an issue tracker, a knowledge base, AI
|
|
22
|
+
chat, an agent workspace, invoicing, inventory, workflows, infrastructure, CRM, and the screens
|
|
23
|
+
inside them — every one usable from a phone to a wide screen and clean under an accessibility
|
|
24
|
+
audit. Fixing what those screens found: some forty component defects, status colours that read as
|
|
25
|
+
text, nested dark themes, and focus that never falls to the page. And what they needed: motion as
|
|
26
|
+
a reader's setting, a command palette with pages, toasts that carry their action, busy buttons,
|
|
27
|
+
type-to-confirm, and public status and priority glyphs.
|
|
28
|
+
|
|
29
|
+
### Breaking
|
|
30
|
+
|
|
31
|
+
- **Form field keys are no longer element ids.** Control ids are generated per Form and Fieldset
|
|
32
|
+
instance (`<idPrefix>-<key>`; `idPrefix` makes them predictable), so a form mounted twice repeats
|
|
33
|
+
no id and a key such as `stage` never collides with `#stage` elsewhere. The key stays the field's
|
|
34
|
+
`name`, the native control's `name`, and its `data-field-id`; radio groups are named after the
|
|
35
|
+
control id. Code that looked a control up by `#<key>` reads `form.getField(key).controlId` (or
|
|
36
|
+
queries `[data-field-id="<key>"]`) instead. An explicit `id` that differs from the key is used as
|
|
37
|
+
given, and the legacy compatibility layer keeps key ids.
|
|
38
|
+
- **Density modes are removed.** `data-zx-density` (`cozy` | `compact`) no longer has any effect,
|
|
39
|
+
`styles/tokens/density.css` no longer ships, and no component carries density-specific rules.
|
|
40
|
+
Migration: drop the attribute. To tighten an application — or one region of it — set
|
|
41
|
+
`--zx-space-unit` and `--zx-control-height` instead, for example
|
|
42
|
+
`:root { --zx-space-unit: 3.5px; --zx-control-height: 28px; }`, which is close to what compact
|
|
43
|
+
used to do without shrinking the type.
|
|
44
|
+
- **`FileItem`'s `density` option is now `identitySize`** (`'sm'|'md'|'lg'`, the size of the
|
|
45
|
+
file's icon and name), and `FileList` items take the same name. The word now means one thing
|
|
46
|
+
nowhere in the library.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- Every toast pauses while it holds focus as well as hover, resumes when neither applies, and
|
|
51
|
+
returns focus to where it came from if it closes while focused.
|
|
52
|
+
- Sheet slides on `--zx-ease-drawer`; KanbanView's drag preview and grabbed card take
|
|
53
|
+
`--zx-drag-shadow`. A solid primary button's pressed step is darker than its hover step.
|
|
54
|
+
- Launcher `select` and `error` details carry `page`; closing the launcher returns it to its root.
|
|
55
|
+
The status and priority glyph styles are `.zx-status-icon` and `.zx-priority-icon` (Select's
|
|
56
|
+
glyphs keep their old classes as well).
|
|
57
|
+
- **`Select.priority()` reads by height, not hue**: levels are four grey signal bars filled to the
|
|
58
|
+
level in muted ink, and only the highest is coloured — a danger square with "!". It offers "No
|
|
59
|
+
priority" (value null, message `priority.none`) at the head of the list; `clearable: false`
|
|
60
|
+
restores the old list, a required priority field leaves it out, and the legacy compatibility
|
|
61
|
+
select keeps its old list unless it allows empty values. Values and message keys are unchanged.
|
|
62
|
+
- **Quiet NumberField** start-aligns its value with the quiet values around it; both steppers sit
|
|
63
|
+
at the trailing end, shown on hover or focus.
|
|
64
|
+
- **Field `type: 'html'`** draws no input frame; display content keeps a control's height.
|
|
65
|
+
- **Toggle labels** start-align and wrap like text, the track level with the first line; a field
|
|
66
|
+
beside a taller one keeps its label and control at the top of its cell.
|
|
67
|
+
- **FileItem** shows a readable type ("PDF", "Image") instead of the MIME type and picks its icon
|
|
68
|
+
from the MIME type when the icon set has one.
|
|
69
|
+
- **AppSidebar** creates its own root as a `<div>` (the `<nav>` inside is the landmark), so it no
|
|
70
|
+
longer adds an unnamed complementary landmark; `getItems()` leaves out empty `children`.
|
|
71
|
+
- **Table** puts `data-column` on every header and body cell in every mode; **KanbanView**
|
|
72
|
+
assignee faces take Avatar's tint from the name (or a descriptor `tone`); the neutral soft
|
|
73
|
+
**Badge** is a wash of the text colour, visible on raised dark surfaces, and a small dotted
|
|
74
|
+
Badge has 12px text and a 4px gap.
|
|
75
|
+
- **ZeyOS enums read as labels** ("Invoiced", "Partly paid") in generated tables and forms; a
|
|
76
|
+
schema `{value, label}` is used as given. **ZeyOS date-only fields are calendar days** — indexed
|
|
77
|
+
`date`, `duedate`, `birthdate`, `datefrom`/`dateto` outside appointments and events, `datecancel`,
|
|
78
|
+
and `lastbilling` show no time and are stored as midnight in the instance's zone (`timeZone`,
|
|
79
|
+
default the browser's); `lastmodified` and the appointment, event, comment, record, and
|
|
80
|
+
document-version timestamps are date-times.
|
|
81
|
+
- **Spacing derives from one unit.** `--zx-space-1` … `--zx-space-8` are multiples of the new
|
|
82
|
+
`--zx-space-unit` (4px by default, so the steps are unchanged at 4–40px).
|
|
83
|
+
- **Corners are smaller and proportional.** `--zx-radius` is now `4px`, and `-sm`, `-md`, `-lg`,
|
|
84
|
+
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
|
|
85
|
+
theme that scales the base keeps every step in proportion. `--zx-control-radius` still follows
|
|
86
|
+
`-lg`. Panels that used `-xl` (Launcher, Sheet, the AppSidebar and AppRail items) use `-lg` or
|
|
87
|
+
`-md`; ValueList chips and record-card metadata chips are no longer pills, and the SortControl
|
|
88
|
+
direction button is a control rather than a circle.
|
|
89
|
+
- **Controls are 30px tall** (`--zx-control-height`, from 32px). `--zx-control-pad-x` stays 10px
|
|
90
|
+
and text sizes are unchanged.
|
|
91
|
+
- **Structured menus are tighter.** AppSidebar rows are one control tall (from control + 8px) with
|
|
92
|
+
2px between rows, 12px between groups, and a 3px corner. A text-only child starts under its
|
|
93
|
+
parent's label; a child with its own icon steps in 16px, just clear of the guide line, instead
|
|
94
|
+
of a whole icon column. The rail flyouts follow. TreeView indents 12px per level (from
|
|
95
|
+
18px) with a 4px block padding per row. MenuButton, ContextMenu, Select, TagPicker, Launcher,
|
|
96
|
+
Finder, Checklist, and the Table column menu share one row: 4px × 8px padding, the smallest
|
|
97
|
+
radius, panels at `--zx-radius-lg`, and section labels no taller than an item.
|
|
98
|
+
- **"Current" is neutral, and nothing is docked to an edge.** Where you are — the active
|
|
99
|
+
navigation item (AppSidebar, its rails and flyouts), the open TreeView node, the current Finder
|
|
100
|
+
column entry, the active tab in every Tabbox variant, the pressed ListToolbar view, the current
|
|
101
|
+
Calendar view, Launcher app and Pagination page — is a neutral `--zx-color-bg-current` fill with
|
|
102
|
+
the text colour at weight 600; the edge marker beside the active item is gone. What you have
|
|
103
|
+
*picked* (checked rows, chosen options, a multi-selection) keeps the accent tint. A rail item
|
|
104
|
+
whose flyout holds the active route takes the accent colour. Forced colours still use the
|
|
105
|
+
system's selected pair.
|
|
106
|
+
- **One solid accent per screen.** Solid accent is for the primary button; tab underlines, pressed
|
|
107
|
+
toggles, and decorative icons no longer use it. In dark, the primary button sits on the accent
|
|
108
|
+
600 step with white text (`--zx-color-accent-solid` / `--zx-color-on-accent-solid`) instead of
|
|
109
|
+
the bright 400 step.
|
|
110
|
+
- **Status green is its own colour.** `--zx-green-*` is a yellow-green status ramp that no longer
|
|
111
|
+
matches the default ZeyOS accent, so a "success" badge or chart segment never reads as branding.
|
|
112
|
+
The brand values moved to `--zx-emerald-*`, which the default accent points at.
|
|
113
|
+
- **Dark theme is layered.** Page, chrome, surface, raised, and overlay steps sit off near-black
|
|
114
|
+
(#1b1b1e → #313136), primary text is about 90% white, and borders are translucent white.
|
|
115
|
+
- **Quieter type.** Decorative upper-case and letter-spaced labels are gone from every component
|
|
116
|
+
(menu and Select groups, Launcher groups, StatTile labels, Calendar weekdays, Table headers, …);
|
|
117
|
+
row and label weights moved from 600 to 500, titles to 600–650, and UI text is set with
|
|
118
|
+
`--zx-tracking-tight` and Inter's `cv11`. Field labels and Fieldset legends are small, medium, and
|
|
119
|
+
muted, so values lead.
|
|
120
|
+
- **Tables** drop the header band (muted medium labels on the surface), divide rows with
|
|
121
|
+
`--zx-color-border-subtle`, and set numbers in tabular figures.
|
|
122
|
+
- **Avatars** fall back to a colour picked from the name (one of eight tones) with no ring, at
|
|
123
|
+
24 / 32 / 40px, and show one initial below 24px.
|
|
124
|
+
- **StatTile** labels are sentence case, values 24px tabular, the icon is a muted glyph without a
|
|
125
|
+
coloured chip, and tiles in a row line up whether or not they carry a sparkline.
|
|
126
|
+
- **EmptyState** draws its icon in `--zx-color-text-subtle` and its title semibold.
|
|
127
|
+
- **Danger is legible as text.** Light `--zx-color-danger` moves to the 600 step and the dark
|
|
128
|
+
danger tint is lighter, so danger ink keeps 4.5:1 on every surface and on its own tint, as the
|
|
129
|
+
other status colours do (now tested for all four in both themes and every preset).
|
|
130
|
+
- **The dark selected tint is lighter** (13% of the accent instead of 18%), so muted text on a
|
|
131
|
+
checked row or chosen option keeps 4.5:1 under every preset (now tested, light and dark).
|
|
132
|
+
- **Toasts lose their coloured leading-edge bar**; the kind shows in the icon and a tinted border,
|
|
133
|
+
as everywhere else nothing is docked to an edge.
|
|
134
|
+
- **Button key hints** are quieter by colour and weight instead of opacity, which left them below
|
|
135
|
+
4.5:1 on a solid primary button.
|
|
136
|
+
- **Select.entity** shows an entity without a colour as a neutral tile with a muted glyph; before,
|
|
137
|
+
the glyph was white on the pale accent tint and could not be seen.
|
|
138
|
+
- **Icons are Lucide outlines.** The bundled set renders as strokes in `currentColor` (ISC; a
|
|
139
|
+
1.75-unit stroke per 24 that never thins below 1px), with every existing name kept. Bundles keep
|
|
140
|
+
the licence notice. A chosen Rating star is drawn solid.
|
|
141
|
+
- **The theme studio's Density section is now Spacing**: a slider for `--zx-space-unit` (3–6px).
|
|
142
|
+
The radius slider sets `--zx-radius` in pixels (0–10px), the standard recipes carry a spacing
|
|
143
|
+
unit instead of a density, Copy CSS exports the unit, and a theme saved by an earlier studio
|
|
144
|
+
still loads.
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
|
|
148
|
+
- **Motion as a setting.** `data-zx-motion="reduced"` on any element stops motion inside it: the
|
|
149
|
+
duration tokens become `0ms` and a base rule stops CSS animations and transitions, while state
|
|
150
|
+
changes still apply; the system preference zeroes the tokens too. `prefersReducedMotion(element)`,
|
|
151
|
+
`watchMotion(element, fn, { signal, immediate })`, and `MOTION_ATTRIBUTE` let script follow it;
|
|
152
|
+
Chart passes `reducedMotion` to its adapter and `ChartJsAdapter` turns animation off under it.
|
|
153
|
+
- `--zx-ease-spring` (a small overshoot) and `--zx-ease-drawer` (a decisive ease-out) beside
|
|
154
|
+
`--zx-ease`, and `--zx-drag-shadow` for an item being dragged.
|
|
155
|
+
- **Launcher pages.** An item with `items` (an array, or a loader `(query, { signal })`) opens a
|
|
156
|
+
nested page: a scope chip in the input, Backspace, ArrowLeft, or × to go back, "⌫ Back" in the
|
|
157
|
+
footer, `open({ page })`, `back()`, `getPage()`, and a `page` event. Items take a `hint` (muted
|
|
158
|
+
text at the end of the row), `shortcut` key caps, and `keys` for `aria-keyshortcuts`.
|
|
159
|
+
- **Message `action`** (`{ label, onclick, kind }`, a small button that runs and closes the toast;
|
|
160
|
+
a toast with an action stays at least 8 seconds) and **`leading`** (a node such as an Avatar in
|
|
161
|
+
place of the kind icon).
|
|
162
|
+
- **`Dialog.confirm({ confirmText })`** — type-to-confirm: a labelled input that has focus, and a
|
|
163
|
+
confirm button and Enter that work only on an exact match.
|
|
164
|
+
- **Busy buttons.** `button({ busy })` and `setButtonBusy(button, busy)` show a spinner in place of
|
|
165
|
+
the icon, set `aria-busy`, and ignore activation while the action runs — but keep the button
|
|
166
|
+
focusable, so focus does not fall to the page as it does from a disabled button.
|
|
167
|
+
- **`statusIcon(status)` and `priorityIcon(level)`**, the glyphs `Select.status()` and
|
|
168
|
+
`Select.priority()` draw, for lists, boards, and filters; decorative unless given a `label`.
|
|
169
|
+
- `idPrefix` on Form and Fieldset; Field `name`, `field.name`, and `field.controlId`.
|
|
170
|
+
- Checklist `hideLabel`; TagPicker `toneKey` (default `'tone'`), colouring a tag the way a Badge
|
|
171
|
+
`tone` does; ActivityList `variant: 'compact'` for cards narrower than 30rem; Table column
|
|
172
|
+
`ariaLabel` for a blank or terse header; FileItem `typeLabel`; `Dialog.prompt` `okLabel` and
|
|
173
|
+
`cancelLabel`.
|
|
174
|
+
- `MenuButton.open({ returnFocus })` (also on `focusFirst()` and `focusLast()`) and
|
|
175
|
+
`Message.disposeRegion(scope)`.
|
|
176
|
+
- ZeyOS: `zeyosTable` passes Table options through (`variant`, `zebra`, `stickyHeader`,
|
|
177
|
+
`responsive`, `growing`, `emptyText`, `rowClass`, `rowKind(s)`, the column chooser, and the Table
|
|
178
|
+
listeners; editing, row reordering, and hierarchy stay out because the binding never persists
|
|
179
|
+
them); `timeZone` and per-field `formats` on `zeyosTable`, `zeyosForm`, `zeyosView`, and
|
|
180
|
+
`resolveFields`; `unixSecondsToCalendarDay()` and `calendarDayToUnixSeconds()`; `zeyosForm`
|
|
181
|
+
`scope` and `notify`.
|
|
182
|
+
- **Colour roles:** `--zx-color-bg-current`, `--zx-color-bg-chrome`, `--zx-color-border-subtle`,
|
|
183
|
+
`--zx-color-text-subtle`, the categorical tones `--zx-color-tone-{blue,teal,green,amber,orange,
|
|
184
|
+
red,pink,violet,slate}-{bg,fg}`, and the chart series `--zx-color-chart-1` … `-8`, whose first
|
|
185
|
+
series is deliberately not the accent. Contrast is tested in both themes and all six presets.
|
|
186
|
+
- **Type tokens:** `--zx-text-3xl` (30px), `--zx-weight-medium`, `--zx-weight-semibold`,
|
|
187
|
+
`--zx-tracking-tight`, `--zx-tracking-title`.
|
|
188
|
+
- **Quiet fields:** inside any `[data-zx-fields="quiet"]` container, native fields and Select,
|
|
189
|
+
TagPicker, Datebox, DateRangeBox, NumberField, and Timebox show their frame only on hover and
|
|
190
|
+
focus — property panels read as data, not as a wall of boxes.
|
|
191
|
+
- `Table` / `TableView` `variant: 'plain'` (no frame, no header band) for tables inside cards;
|
|
192
|
+
`badge({ tone })` with the categorical tones (and `BADGE_TONES`); `Avatar` `tone`, `avatarTone()`
|
|
193
|
+
and `AVATAR_TONES`; `StatTile` `caption`, read with the value.
|
|
194
|
+
- `registerIcons()` accepts outline glyphs as `[viewBox, path, 'stroke']`; `[viewBox, path]` pairs
|
|
195
|
+
still render filled.
|
|
196
|
+
- `Tabbox` `label`, the tab list's accessible name.
|
|
197
|
+
|
|
198
|
+
### Fixed
|
|
199
|
+
|
|
200
|
+
- A destructive `Dialog.confirm` started focus on the destructive button; it starts on Cancel, the
|
|
201
|
+
least destructive choice (type-to-confirm starts in its input).
|
|
202
|
+
- On a phone, toasts covered the header's controls; they rise from the foot of the screen there.
|
|
203
|
+
- A ghost Button showed no focus ring: its `box-shadow: none` outranked `:focus-visible`.
|
|
204
|
+
- Select's loading spinner never turned (it read an undefined duration token).
|
|
205
|
+
- The Launcher's search row could push its close button off a narrow screen.
|
|
206
|
+
- A `[data-zx-theme="dark"]` region on a light page inherited light glass, overlays, hover and
|
|
207
|
+
current fills, tone tints, and focus ring: colours derived from other theme colours were resolved
|
|
208
|
+
on `:root` only. They are restated on every theme element now; geometry overrides on `:root`
|
|
209
|
+
still reach nested regions.
|
|
210
|
+
- Overlays (Dropdown, Tooltip, MenuButton, ContextMenu, Modal, Dialog, Sheet, Launcher) created before their
|
|
211
|
+
anchor or scope was in the document parked their panel on `<body>`, outside the theme scope; they
|
|
212
|
+
find their host on first open.
|
|
213
|
+
- Choosing a MenuButton item dropped focus to `<body>`; it returns to the trigger. CodeEditor
|
|
214
|
+
trapped the keyboard; Escape then Tab leaves it, as documented.
|
|
215
|
+
- Floating Message regions kept sending toasts into an emptied host and were never removed.
|
|
216
|
+
- Table and Grid number and date editors select their content on entry (typing "6" over "1.00"
|
|
217
|
+
gives 6); sortable headers use the same font as the others; no scrollbar gutter is reserved on a
|
|
218
|
+
table that does not scroll; a blank header has an accessible name. TreeView type-ahead calls
|
|
219
|
+
`preventDefault` and leaves text controls in rows alone.
|
|
220
|
+
- Table's selection checkboxes and row-reorder handles sit in the middle of their cell. They rode a
|
|
221
|
+
few pixels high on the text baseline, and the cell padding pushed them off the centre of their
|
|
222
|
+
control-height column, in a fixed layout past its edge.
|
|
223
|
+
- NumberField, Datebox, and DateRangeBox fill a Field's control column; clear-button padding is
|
|
224
|
+
reserved only when `clearable`, and a disabled Datebox or DateRangeBox shows no clear button.
|
|
225
|
+
Slider end labels stay inside the component. A Checklist inside a Field no longer repeats its
|
|
226
|
+
heading.
|
|
227
|
+
- `colorKey` on `Select.entity()` and TagPicker accepts token references (`var(--zx-…)`). Clicking a
|
|
228
|
+
read-only Select no longer draws the keyboard focus ring; a disabled Select fades like a disabled
|
|
229
|
+
Field; a read-only TagPicker shows only its tags.
|
|
230
|
+
- `collapsible: false` still showed AppSidebar's minimise button. copyButton's status line and
|
|
231
|
+
CopyInput's hidden label were positioned outside their control.
|
|
232
|
+
- A Field whose adapter returns a wrapper (a `custom` field holding a component) named the
|
|
233
|
+
wrapper, which cannot carry a name; its label, description, and validity now reach the first
|
|
234
|
+
unnamed form control inside it, or the adapter's new `labelTarget`.
|
|
235
|
+
- Launcher ran an item's command before closing, so closing put focus back on an element the
|
|
236
|
+
command had just redrawn or moved focus away from; it closes first now.
|
|
237
|
+
- A MenuButton's menu had no accessible name; it is labelled by its trigger, as the APG pattern
|
|
238
|
+
has it. NumberField no longer swallows Mod+Enter (and other chords), so a form or dialog's submit
|
|
239
|
+
shortcut works from a number field. Datebox and DateRangeBox were 2px taller than the text input
|
|
240
|
+
beside them; every control is one control height.
|
|
241
|
+
- A Tooltip placed beside an anchor near the edge of the screen squeezed to a word per line
|
|
242
|
+
instead of moving: it now takes the other side, or goes above or below when neither side fits.
|
|
243
|
+
- A Chart in a narrow card overflowed it (its 220px minimum height became a 587px minimum width
|
|
244
|
+
through the aspect ratio); it grows taller instead. A StatTile delta keeps its figure on one line
|
|
245
|
+
in a narrow tile.
|
|
246
|
+
- `zeyosTable` showed a due date as a date-time whose hour moved with daylight saving, and
|
|
247
|
+
`zeyosForm` edited it as one; `zeyosForm.save()` raised its toast wherever focus was.
|
|
248
|
+
- The AccountMenu trigger rendered as a centred, boxed card because `menu-button.css` loaded after
|
|
249
|
+
`account-menu.css`; it is a flat row again.
|
|
250
|
+
- CodeEditor referenced `--zx-color-bg-subtle`, which never existed.
|
|
251
|
+
- The Marque Gold preset's accent text now reaches 4.5:1 on the light chrome tone.
|
|
252
|
+
- A sortable end-aligned Table column put its header label at the start, away from its figures;
|
|
253
|
+
the label now sits at the end with the sort arrow before it.
|
|
254
|
+
- ActivityItem's heading read the actor and title as one word ("Jonas Weberset…") to assistive
|
|
255
|
+
technology; a space now separates them.
|
|
256
|
+
- Table's Columns chooser, RecordView's Fields chooser, KanbanView's undo and redo, and Filter's
|
|
257
|
+
actions used a `zx-button` class no stylesheet defines, so they rendered as bare browser buttons;
|
|
258
|
+
they are small Zx buttons now (ghost in toolbars, primary for Apply).
|
|
259
|
+
|
|
260
|
+
### Website
|
|
261
|
+
|
|
262
|
+
- The application layouts moved from the documentation sidebar to a gallery of their own
|
|
263
|
+
(`layouts.html`), with a live thumbnail per layout, a near-full-screen view with its source, and a
|
|
264
|
+
standalone page (`layout.html#<id>`) for opening one in its own tab. Nine complete application
|
|
265
|
+
templates join the eight screen patterns, which are rebuilt on the same application shell.
|
|
266
|
+
- The documentation, gallery, and theme studio share the library's look: navigation on the chrome
|
|
267
|
+
tone, neutral current entries, sentence-case labels, hairline example cards, and code and API
|
|
268
|
+
tables drawn like the refined Table.
|
|
269
|
+
- New in the gallery: an **agent workspace** template — agents with live presence, editor tabs, a
|
|
270
|
+
plan and execution log with hand-offs, approvals as toasts that carry their action, a command
|
|
271
|
+
palette with pages, a bottom panel, and a status bar — and two screen patterns, **agent chat**
|
|
272
|
+
(tool calls, an approval that blocks the run, sources, and the run beside the thread) and
|
|
273
|
+
**system states** (every empty, loading, error, validation, and confirmation state, with a
|
|
274
|
+
switch to go offline). The AI chat template shows its work: tool steps, sources, artifacts with
|
|
275
|
+
versions, regenerate and branch, and `@agent` mentions.
|
|
276
|
+
- Every layout works from a phone to a wide screen: below 1180px the inspector and below 860px
|
|
277
|
+
the navigation become drawers, and on a phone a layout shows its list or its record with a way
|
|
278
|
+
back. All seventeen pass an accessibility audit — named controls and landmarks, text contrast,
|
|
279
|
+
visible focus, heading order — in both themes, wide and narrow.
|
|
280
|
+
- The theme studio has a Motion setting (System or Reduced), kept across the whole site as a
|
|
281
|
+
reader's preference, and a Button states card showing every kind in every state.
|
|
282
|
+
- The site self-hosts Inter as a variable font (SIL OFL), so every weight renders as designed and no
|
|
283
|
+
font request leaves the site.
|
|
284
|
+
- The theme studio offers more to build from. Eleven neutral tints — Neutral, Zinc, Stone, Cool,
|
|
285
|
+
Mist, Sage, Olive, Warm, Taupe, Mauve, and Accent — are picked from swatches of the ramp each
|
|
286
|
+
would produce, and a strength control scales any of them from grey to twice its colour; every
|
|
287
|
+
tint keeps the text roles legible at full strength. The typeface list grows from six system
|
|
288
|
+
stacks to eleven, drawn in their own type, plus a custom stack for a brand font, and the code
|
|
289
|
+
font (`--zx-font-mono`) is a choice of its own.
|
|
290
|
+
- Themes can be saved and loaded as JSON. Export writes a `zx-theme` file — the settings, plus the
|
|
291
|
+
custom properties they produce — to copy or download; Import takes one pasted, dropped, or chosen,
|
|
292
|
+
loads it even when a value is out of range or unknown, and says what it adjusted.
|
|
293
|
+
|
|
11
294
|
## 4.4.0 — 2026-09-22
|
|
12
295
|
|
|
13
296
|
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
|
|
@@ -233,13 +237,13 @@ moduleColor('invoices'); // '#535494'
|
|
|
233
237
|
name, identity colour, label, and a stock Font Awesome fallback. The `--zx-module-*` CSS custom
|
|
234
238
|
properties are generated from that file, so CSS and JavaScript cannot disagree about a colour.
|
|
235
239
|
|
|
236
|
-
## Themes
|
|
240
|
+
## Themes
|
|
237
241
|
|
|
238
242
|
Load `zx.css` once. Zx components consume semantic `--zx-*` tokens and inherit their values from
|
|
239
|
-
the document. Select a built-in theme
|
|
243
|
+
the document. Select a built-in theme on any ancestor (normally `<html>`):
|
|
240
244
|
|
|
241
245
|
```html
|
|
242
|
-
<html data-zx-theme="dark"
|
|
246
|
+
<html data-zx-theme="dark">
|
|
243
247
|
```
|
|
244
248
|
|
|
245
249
|
Top-layer menus, dialogs, tooltips, launchers, and toast regions stay under the nearest Zx theme
|
|
@@ -247,10 +251,22 @@ scope in the DOM, so a theme or product-token override on a nested application s
|
|
|
247
251
|
to its overlays. Pass the optional `scope` context to Modal, Dialog, Sheet, Launcher, or static
|
|
248
252
|
Message calls when the opener is not inside the intended scope.
|
|
249
253
|
|
|
250
|
-
Theme values are `light`, `dark`, and `auto
|
|
251
|
-
|
|
254
|
+
Theme values are `light`, `dark`, and `auto`. `auto` follows the operating-system color
|
|
255
|
+
preference.
|
|
252
256
|
|
|
253
|
-
|
|
257
|
+
There is one geometry. Spacing steps are multiples of `--zx-space-unit` (4px:
|
|
258
|
+
4, 8, 12, 16, 20, 24, 32, 40), radius steps are fractions of `--zx-radius` (4px: 2, 3, 4, 6), and
|
|
259
|
+
controls are `--zx-control-height` (30px) tall. To tighten or loosen an application — or one
|
|
260
|
+
region of it — override those tokens rather than switching a mode:
|
|
261
|
+
|
|
262
|
+
```css
|
|
263
|
+
:root {
|
|
264
|
+
--zx-space-unit: 3.5px;
|
|
265
|
+
--zx-control-height: 28px;
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
A second attribute picks the **accent**, orthogonally to the theme:
|
|
254
270
|
|
|
255
271
|
```html
|
|
256
272
|
<html data-zx-theme="dark" data-zx-preset="ocean">
|
|
@@ -272,6 +288,8 @@ through, so a preset rethemes light, dark, and auto at once:
|
|
|
272
288
|
|
|
273
289
|
Light surfaces take the 600 and 700 stops, dark ones take 300, 400, and 500 — so keep 600 legible
|
|
274
290
|
against white and 400 against near-black, and `--zx-color-on-accent` stays correct in both. The
|
|
291
|
+
primary button is the exception on purpose: `--zx-color-accent-solid` is the 600 stop with white
|
|
292
|
+
ink in both themes, so the one solid accent on a screen never turns into a bright slab in dark. The
|
|
275
293
|
[theme studio](https://zx.zeyos.com/theme.html) renders every component family under a live theme and
|
|
276
294
|
exports the result.
|
|
277
295
|
|
|
@@ -292,7 +310,20 @@ Anything beyond the accent is a semantic token override, without reaching into c
|
|
|
292
310
|
|
|
293
311
|
Prefer semantic tokens such as `--zx-color-*`, `--zx-control-*`, `--zx-space-*`,
|
|
294
312
|
`--zx-radius-*`, and `--zx-text-*`. Palette tokens are implementation details and should not be
|
|
295
|
-
used by application or component CSS.
|
|
313
|
+
used by application or component CSS. A few roles carry most of the visual language:
|
|
314
|
+
|
|
315
|
+
- `--zx-color-bg-chrome` for navigation and inspector columns beside the `--zx-color-bg-surface`
|
|
316
|
+
canvas, and `--zx-color-border-subtle` for dividers inside them — tone separates, lines only
|
|
317
|
+
where tone cannot.
|
|
318
|
+
- `--zx-color-bg-current` (neutral) for where you are, `--zx-color-bg-selected` (accent tint) for
|
|
319
|
+
what you picked.
|
|
320
|
+
- `--zx-color-text-muted` for secondary text and `--zx-color-text-subtle` for icons and meta.
|
|
321
|
+
- `--zx-color-tone-<hue>-bg` / `-fg` (blue, teal, green, amber, orange, red, pink, violet, slate)
|
|
322
|
+
for categorical colour — tags, avatars, icon tiles — and `--zx-color-chart-1` … `-8` for chart
|
|
323
|
+
series. Neither is the accent or a status colour; `success` is a yellow-green of its own.
|
|
324
|
+
|
|
325
|
+
Add `data-zx-fields="quiet"` to a property panel and its native fields show no border or fill until
|
|
326
|
+
hovered or focused.
|
|
296
327
|
|
|
297
328
|
## Browser support
|
|
298
329
|
|
|
@@ -311,9 +342,10 @@ npm install
|
|
|
311
342
|
npm run serve
|
|
312
343
|
```
|
|
313
344
|
|
|
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
|
-
|
|
345
|
+
Open <http://127.0.0.1:8321/website/docs.html> for the documentation — getting started, and every
|
|
346
|
+
component with a live demo and its JavaScript source — and
|
|
347
|
+
<http://127.0.0.1:8321/website/layouts.html> for the gallery of application layouts. Also
|
|
348
|
+
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
349
|
classic-script distribution tests.
|
|
318
350
|
|
|
319
351
|
```sh
|
|
@@ -3,6 +3,7 @@ export type ActivityItemOptions = import('../activity-item/activity-item.js').Ac
|
|
|
3
3
|
export type ActivityListContent = string | number | Node | Component | null;
|
|
4
4
|
export type ActivityGroupReader = string | ((item: ActivityItemOptions, index: number) => unknown) | null;
|
|
5
5
|
export type ActivityGroupLabel = (group: unknown, items: ActivityItemOptions[]) => ActivityListContent;
|
|
6
|
+
export type ActivityListVariant = 'default' | 'compact';
|
|
6
7
|
export type ActivityGroup = {
|
|
7
8
|
/**
|
|
8
9
|
* Group identity returned by the configured reader.
|
|
@@ -30,6 +31,11 @@ export type ActivityListOptions = {
|
|
|
30
31
|
* Accessible collection name.
|
|
31
32
|
*/
|
|
32
33
|
label?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Entry layout, reflected as `data-variant` on
|
|
36
|
+
* the root. `'compact'` also makes an avatar descriptor without a `size` small.
|
|
37
|
+
*/
|
|
38
|
+
variant?: ActivityListVariant;
|
|
33
39
|
/**
|
|
34
40
|
* Whether initial or incremental activity is loading.
|
|
35
41
|
*/
|
|
@@ -62,6 +68,13 @@ export type ActivityListOptions = {
|
|
|
62
68
|
/** @typedef {string|number|Node|Component|null} ActivityListContent */
|
|
63
69
|
/** @typedef {string|((item:ActivityItemOptions,index:number)=>unknown)|null} ActivityGroupReader */
|
|
64
70
|
/** @typedef {(group:unknown,items:ActivityItemOptions[])=>ActivityListContent} ActivityGroupLabel */
|
|
71
|
+
/**
|
|
72
|
+
* Entry layout. `'default'` gives each entry its avatar, a heading row, and room for content;
|
|
73
|
+
* below 30rem the time moves under the heading. `'compact'` is one line per entry at any width —
|
|
74
|
+
* actor and summary reading as one sentence, the time at the trailing end, a small avatar, and
|
|
75
|
+
* metadata as a muted second line — for a summary card narrower than 30rem.
|
|
76
|
+
* @typedef {'default'|'compact'} ActivityListVariant
|
|
77
|
+
*/
|
|
65
78
|
/**
|
|
66
79
|
* @typedef {Object} ActivityGroup
|
|
67
80
|
* @property {unknown} id Group identity returned by the configured reader.
|
|
@@ -73,6 +86,8 @@ export type ActivityListOptions = {
|
|
|
73
86
|
* @property {ActivityGroupReader} [groupBy=null] Property or resolver used for stable grouping.
|
|
74
87
|
* @property {ActivityGroupLabel|null} [groupLabel=null] Group-heading renderer.
|
|
75
88
|
* @property {string} [label='Activity'] Accessible collection name.
|
|
89
|
+
* @property {ActivityListVariant} [variant='default'] Entry layout, reflected as `data-variant` on
|
|
90
|
+
* the root. `'compact'` also makes an avatar descriptor without a `size` small.
|
|
76
91
|
* @property {boolean} [loading=false] Whether initial or incremental activity is loading.
|
|
77
92
|
* @property {number} [loadingCount=3] Placeholder rows shown for an empty loading list.
|
|
78
93
|
* @property {string} [loadingText='Loading activity'] Loading status text.
|
|
@@ -97,6 +112,7 @@ export declare class ActivityList extends Component<ActivityListOptions> {
|
|
|
97
112
|
_loading: any;
|
|
98
113
|
_itemComponents: any[];
|
|
99
114
|
_groupSequence: number;
|
|
115
|
+
_variant: ActivityListVariant;
|
|
100
116
|
static cssName: string;
|
|
101
117
|
/** @type {Readonly<ActivityListOptions>} */
|
|
102
118
|
static defaults: Readonly<ActivityListOptions>;
|
|
@@ -188,6 +204,12 @@ export declare function groupActivityItems(items: ActivityItemOptions[], groupBy
|
|
|
188
204
|
* @returns {ActivityItemOptions[]}
|
|
189
205
|
*/
|
|
190
206
|
export declare function normalizeActivityItems(value: unknown): ActivityItemOptions[];
|
|
207
|
+
/**
|
|
208
|
+
* Resolves the entry layout; anything but `'compact'` is the default layout.
|
|
209
|
+
* @param {unknown} value Requested variant.
|
|
210
|
+
* @returns {ActivityListVariant}
|
|
211
|
+
*/
|
|
212
|
+
export declare function normalizeActivityListVariant(value: unknown): ActivityListVariant;
|
|
191
213
|
/**
|
|
192
214
|
* Activity descriptors changed through a list mutation method.
|
|
193
215
|
* @event ActivityList#datachange
|
|
@@ -160,7 +160,11 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
|
|
|
160
160
|
render(): HTMLElement;
|
|
161
161
|
/** Replaces the navigation tree in the active presentation. @param {AppNavItem[]} items @returns {this} */
|
|
162
162
|
setItems(items: AppNavItem[]): this;
|
|
163
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* Returns a copy of the normalized items. A leaf has no `children` property, as it was written,
|
|
165
|
+
* rather than the empty list normalization gives it.
|
|
166
|
+
* @returns {AppNavItem[]}
|
|
167
|
+
*/
|
|
164
168
|
getItems(): AppNavItem[];
|
|
165
169
|
/** Sets the active id without routing. @param {string|number|null} id @returns {this} */
|
|
166
170
|
setActive(id: string | number | null): this;
|
|
@@ -265,7 +269,5 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
|
|
|
265
269
|
/** @returns {void} */
|
|
266
270
|
_reconcileExpanded(): void;
|
|
267
271
|
}
|
|
268
|
-
/** Fired when a destination/action is activated. @event AppSidebar#select @type {CustomEvent<AppNavSelectDetail>} */
|
|
269
|
-
/** Fired when an inline branch changes. @event AppSidebar#branchchange @type {CustomEvent<{item: AppNavItem|null, id: string|number|null, expanded: boolean|null, ids: Array<string|number>}>} */
|
|
270
272
|
/** Fired when expanded/minimized presentation changes. @event AppSidebar#collapsechange @type {CustomEvent<{collapsed: boolean}>} */
|
|
271
273
|
/** Fired when a minimized flyout changes. @event AppSidebar#flyoutchange @type {CustomEvent<{item: AppNavItem, id: string|number, open: boolean}>} */
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Component } from '../../core/component.js';
|
|
2
|
+
export type AvatarTone = 'blue' | 'teal' | 'green' | 'amber' | 'orange' | 'red' | 'pink' | 'violet' | 'slate';
|
|
2
3
|
export type AvatarOptions = {
|
|
3
4
|
/**
|
|
4
5
|
* Image URL.
|
|
5
6
|
*/
|
|
6
7
|
src?: string | null;
|
|
7
8
|
/**
|
|
8
|
-
* Name used to derive fallback initials.
|
|
9
|
+
* Name used to derive the fallback initials and tone.
|
|
9
10
|
*/
|
|
10
11
|
name?: string;
|
|
11
12
|
/**
|
|
@@ -17,13 +18,20 @@ export type AvatarOptions = {
|
|
|
17
18
|
*/
|
|
18
19
|
label?: string | null;
|
|
19
20
|
/**
|
|
20
|
-
* Preset
|
|
21
|
+
* Preset — `sm` 24px, `md` 32px, `lg` 40px at the default
|
|
22
|
+
* spacing unit — or a pixel size. Below 24px the fallback shows a single initial.
|
|
21
23
|
*/
|
|
22
24
|
size?: string | number;
|
|
23
25
|
/**
|
|
24
26
|
* Avatar shape.
|
|
25
27
|
*/
|
|
26
28
|
shape?: 'circle' | 'rounded' | 'square';
|
|
29
|
+
/**
|
|
30
|
+
* Fallback colour from the tone palette. `null` derives a
|
|
31
|
+
* stable tone from the name (or the initials when there is no name), so the same person gets the
|
|
32
|
+
* same colour on every screen; see {@link avatarTone}.
|
|
33
|
+
*/
|
|
34
|
+
tone?: AvatarTone | null;
|
|
27
35
|
/**
|
|
28
36
|
* Optional presence state.
|
|
29
37
|
*/
|
|
@@ -33,19 +41,35 @@ export type AvatarOptions = {
|
|
|
33
41
|
*/
|
|
34
42
|
statusLabel?: string | null;
|
|
35
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* A categorical tone from the design system's tone palette (`--zx-color-tone-*`).
|
|
46
|
+
* @typedef {'blue'|'teal'|'green'|'amber'|'orange'|'red'|'pink'|'violet'|'slate'} AvatarTone
|
|
47
|
+
*/
|
|
36
48
|
/**
|
|
37
49
|
* @typedef {Object} AvatarOptions
|
|
38
50
|
* @property {string|null} [src=null] Image URL.
|
|
39
|
-
* @property {string} [name=''] Name used to derive fallback initials.
|
|
51
|
+
* @property {string} [name=''] Name used to derive the fallback initials and tone.
|
|
40
52
|
* @property {string|null} [initials=null] Explicit fallback initials.
|
|
41
53
|
* @property {string|null} [label=null] Accessible label; null makes the avatar decorative.
|
|
42
|
-
* @property {string|number} [size='md'] Preset
|
|
54
|
+
* @property {string|number} [size='md'] Preset — `sm` 24px, `md` 32px, `lg` 40px at the default
|
|
55
|
+
* spacing unit — or a pixel size. Below 24px the fallback shows a single initial.
|
|
43
56
|
* @property {'circle'|'rounded'|'square'} [shape='circle'] Avatar shape.
|
|
57
|
+
* @property {AvatarTone|null} [tone=null] Fallback colour from the tone palette. `null` derives a
|
|
58
|
+
* stable tone from the name (or the initials when there is no name), so the same person gets the
|
|
59
|
+
* same colour on every screen; see {@link avatarTone}.
|
|
44
60
|
* @property {'online'|'away'|'busy'|'offline'|null} [status=null] Optional presence state.
|
|
45
61
|
* @property {string|null} [statusLabel=null] Text alternative for the presence state.
|
|
46
62
|
*/
|
|
47
63
|
/**
|
|
48
|
-
*
|
|
64
|
+
* The tone palette, in hash order. Every entry is a valid `tone`; the hash picks among the
|
|
65
|
+
* chromatic ones and keeps `slate`, the neutral, for a fallback with no name behind it. Order is
|
|
66
|
+
* part of the contract: changing it moves every derived avatar to a different colour.
|
|
67
|
+
* @type {ReadonlyArray<AvatarTone>}
|
|
68
|
+
*/
|
|
69
|
+
export declare const AVATAR_TONES: ReadonlyArray<AvatarTone>;
|
|
70
|
+
/**
|
|
71
|
+
* Stable-size user image with a deterministic fallback — initials on a tone picked from the name —
|
|
72
|
+
* and an optional presence state.
|
|
49
73
|
* @extends {Component<AvatarOptions>}
|
|
50
74
|
*/
|
|
51
75
|
export declare class Avatar extends Component<AvatarOptions> {
|
|
@@ -61,6 +85,7 @@ export declare class Avatar extends Component<AvatarOptions> {
|
|
|
61
85
|
label: string;
|
|
62
86
|
size: string | number;
|
|
63
87
|
shape: "circle" | "rounded" | "square";
|
|
88
|
+
tone: AvatarTone;
|
|
64
89
|
status: "away" | "busy" | "offline" | "online";
|
|
65
90
|
statusLabel: string;
|
|
66
91
|
};
|
|
@@ -93,8 +118,22 @@ export declare class Avatar extends Component<AvatarOptions> {
|
|
|
93
118
|
_syncStatus(): void;
|
|
94
119
|
}
|
|
95
120
|
/**
|
|
96
|
-
* Derives
|
|
121
|
+
* Derives uppercase initials from the first and last words of a name.
|
|
97
122
|
* @param {unknown} name Name-like value.
|
|
123
|
+
* @param {1|2} [limit=2] How many initials to return: two by default, one for an avatar too small
|
|
124
|
+
* to hold two legibly.
|
|
98
125
|
* @returns {string}
|
|
99
126
|
*/
|
|
100
|
-
export declare function avatarInitials(name: unknown): string;
|
|
127
|
+
export declare function avatarInitials(name: unknown, limit?: 1 | 2): string;
|
|
128
|
+
/**
|
|
129
|
+
* Picks a stable fallback tone for a name.
|
|
130
|
+
*
|
|
131
|
+
* The name is trimmed, NFC-normalised and lower-cased, then hashed with 32-bit FNV-1a over its
|
|
132
|
+
* UTF-16 code units, and the hash picks one of the eight chromatic tones of {@link AVATAR_TONES}.
|
|
133
|
+
* The result depends on nothing but the name — not the locale, the page, or the order avatars
|
|
134
|
+
* render in — so a person keeps their colour everywhere. An empty name is `slate`, the neutral
|
|
135
|
+
* tone, which no name hashes to.
|
|
136
|
+
* @param {unknown} name Name-like value.
|
|
137
|
+
* @returns {AvatarTone}
|
|
138
|
+
*/
|
|
139
|
+
export declare function avatarTone(name: unknown): AvatarTone;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type BadgeTone = 'blue' | 'teal' | 'green' | 'amber' | 'orange' | 'red' | 'pink' | 'violet' | 'slate';
|
|
1
2
|
export type BadgeOptions = {
|
|
2
3
|
/**
|
|
3
4
|
* Visible badge text.
|
|
@@ -11,6 +12,13 @@ export type BadgeOptions = {
|
|
|
11
12
|
* Semantic intent.
|
|
12
13
|
*/
|
|
13
14
|
kind?: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info';
|
|
15
|
+
/**
|
|
16
|
+
* Categorical colour — a project, a label, a module — from
|
|
17
|
+
* the tone palette rather than the status set, so a tag never reads as a warning. When set it
|
|
18
|
+
* decides the colour and `kind` is ignored for it; `variant` still applies. Unknown names are
|
|
19
|
+
* ignored.
|
|
20
|
+
*/
|
|
21
|
+
tone?: BadgeTone | null;
|
|
14
22
|
/**
|
|
15
23
|
* Fill treatment.
|
|
16
24
|
*/
|
|
@@ -29,7 +37,13 @@ export type BadgeOptions = {
|
|
|
29
37
|
title?: string;
|
|
30
38
|
};
|
|
31
39
|
/**
|
|
32
|
-
*
|
|
40
|
+
* Categorical tones, in the order they are documented.
|
|
41
|
+
* @type {ReadonlyArray<BadgeTone>}
|
|
42
|
+
*/
|
|
43
|
+
export declare const BADGE_TONES: ReadonlyArray<BadgeTone>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates a status pill: a small, non-interactive label carrying a semantic colour — or, with
|
|
46
|
+
* `tone`, a categorical one.
|
|
33
47
|
*
|
|
34
48
|
* The badge is plain text content, so it needs no ARIA of its own. A badge without a label but
|
|
35
49
|
* with a `title` is named for assistive technology through `role="img"`.
|
|
@@ -44,3 +58,9 @@ export declare function badge(opts?: BadgeOptions): HTMLSpanElement;
|
|
|
44
58
|
* @returns {HTMLSpanElement}
|
|
45
59
|
*/
|
|
46
60
|
export declare function badgeGroup(badges: HTMLSpanElement[]): HTMLSpanElement;
|
|
61
|
+
/**
|
|
62
|
+
* Resolves a categorical tone name, or null for anything outside the palette.
|
|
63
|
+
* @param {unknown} value Requested tone.
|
|
64
|
+
* @returns {BadgeTone|null}
|
|
65
|
+
*/
|
|
66
|
+
export declare function normalizeBadgeTone(value: unknown): BadgeTone | null;
|
|
@@ -23,6 +23,11 @@ export type ButtonOptions = {
|
|
|
23
23
|
* Whether the button is disabled.
|
|
24
24
|
*/
|
|
25
25
|
disabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Whether the button is working on its action — see
|
|
28
|
+
* `setButtonBusy()`.
|
|
29
|
+
*/
|
|
30
|
+
busy?: boolean;
|
|
26
31
|
/**
|
|
27
32
|
* Native title text.
|
|
28
33
|
*/
|
|
@@ -48,3 +53,13 @@ export declare function button(opts?: ButtonOptions): HTMLButtonElement;
|
|
|
48
53
|
* @returns {HTMLDivElement}
|
|
49
54
|
*/
|
|
50
55
|
export declare function buttonGroup(buttons: HTMLButtonElement[]): HTMLDivElement;
|
|
56
|
+
/**
|
|
57
|
+
* Marks a button as working on its action, or done. A busy button shows a spinner before its
|
|
58
|
+
* label, announces `aria-busy`, and ignores activation — but stays focusable, unlike a disabled
|
|
59
|
+
* one, so focus does not fall to the page while the work runs and the reader hears it finish.
|
|
60
|
+
* Works on any `.zx-btn`, including one the application built itself.
|
|
61
|
+
* @param {HTMLButtonElement} element
|
|
62
|
+
* @param {boolean} busy
|
|
63
|
+
* @returns {HTMLButtonElement} The same button.
|
|
64
|
+
*/
|
|
65
|
+
export declare function setButtonBusy(element: HTMLButtonElement, busy: boolean): HTMLButtonElement;
|