@zeyos/zx 2.3.0 → 3.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 +87 -0
- package/DESIGN-SYSTEM.md +136 -0
- package/MIGRATION.md +155 -4
- package/README.md +24 -13
- package/dist/types/compat/map/data.d.ts +3 -2
- package/dist/types/components/account-menu/account-menu.d.ts +144 -0
- package/dist/types/components/app-rail/app-rail.d.ts +250 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +169 -0
- package/dist/types/components/avatar/avatar.d.ts +100 -0
- package/dist/types/components/chart/chart.d.ts +321 -0
- package/dist/types/components/date-picker/month-picker.d.ts +6 -0
- package/dist/types/components/dialog/dialog.d.ts +9 -0
- package/dist/types/components/dock/dock.d.ts +495 -0
- package/dist/types/components/dropdown/dropdown.d.ts +2 -2
- package/dist/types/components/field/field.d.ts +14 -0
- package/dist/types/components/field-upload/field-upload.d.ts +37 -4
- package/dist/types/components/form/form.d.ts +25 -3
- package/dist/types/components/grid/grid.d.ts +172 -0
- package/dist/types/components/launcher/launcher.d.ts +300 -0
- package/dist/types/components/layout/layout.d.ts +4 -4
- package/dist/types/components/menu-button/menu-button.d.ts +10 -2
- package/dist/types/components/modal/modal.d.ts +25 -0
- package/dist/types/components/multi-value-editor/multi-value-editor.d.ts +7 -1
- package/dist/types/components/questionnaire/items.d.ts +327 -0
- package/dist/types/components/questionnaire/questionnaire.d.ts +449 -0
- package/dist/types/components/sheet/sheet-stack.d.ts +167 -0
- package/dist/types/components/sheet/sheet.d.ts +294 -0
- package/dist/types/components/split-view/split-view.d.ts +2 -21
- package/dist/types/components/table/table.d.ts +219 -12
- package/dist/types/components/tooltip/tooltip.d.ts +2 -2
- package/dist/types/components/value-list/value-list.d.ts +24 -3
- package/dist/types/core/dom.d.ts +114 -0
- package/dist/types/core/drag-axis.d.ts +111 -0
- package/dist/types/core/position.d.ts +4 -2
- package/dist/types/index.d.ts +12 -2
- package/dist/zx-compat.esm.js +641 -277
- package/dist/zx-compat.esm.min.js +1 -1
- package/dist/zx-compat.global.js +7609 -2236
- package/dist/zx-compat.global.min.js +3 -3
- package/dist/zx-zeyos.esm.js +546 -87
- package/dist/zx-zeyos.esm.min.js +1 -1
- package/dist/zx.css +1452 -101
- package/dist/zx.esm.js +7952 -2592
- package/dist/zx.esm.min.js +3 -3
- package/dist/zx.global.js +7952 -2592
- package/dist/zx.global.min.js +3 -3
- package/dist/zx.min.css +1 -1
- package/docs/api.json +2276 -337
- package/docs/llms.md +426 -30
- package/docs/llms.txt +21 -9
- package/package.json +4 -2
- package/src/compat/globals.js +3 -1
- package/src/compat/map/data.js +31 -9
- package/src/components/account-menu/account-menu.css +70 -0
- package/src/components/account-menu/account-menu.js +208 -0
- package/src/components/app-rail/app-rail.css +107 -0
- package/src/components/app-rail/app-rail.js +668 -0
- package/src/components/app-sidebar/app-sidebar.css +68 -0
- package/src/components/app-sidebar/app-sidebar.js +388 -0
- package/src/components/avatar/avatar.css +61 -0
- package/src/components/avatar/avatar.js +222 -0
- package/src/components/button/button.css +0 -1
- package/src/components/chart/chart.css +61 -0
- package/src/components/chart/chart.js +518 -0
- package/src/components/date-picker/month-picker.js +9 -0
- package/src/components/dialog/dialog.js +11 -4
- package/src/components/dock/dock.css +228 -0
- package/src/components/dock/dock.js +977 -0
- package/src/components/dropdown/dropdown.js +1 -1
- package/src/components/field/field.js +2 -0
- package/src/components/field-upload/field-upload.js +9 -4
- package/src/components/form/form.js +6 -3
- package/src/components/grid/grid.css +6 -0
- package/src/components/grid/grid.js +213 -0
- package/src/components/launcher/launcher.css +100 -0
- package/src/components/launcher/launcher.js +557 -0
- package/src/components/layout/layout.js +2 -2
- package/src/components/menu-button/menu-button.js +27 -2
- package/src/components/modal/modal.css +5 -1
- package/src/components/modal/modal.js +37 -2
- package/src/components/multi-value-editor/multi-value-editor.js +2 -1
- package/src/components/questionnaire/items.js +370 -0
- package/src/components/questionnaire/questionnaire.css +387 -0
- package/src/components/questionnaire/questionnaire.js +1033 -0
- package/src/components/select/select.css +0 -1
- package/src/components/sheet/sheet-stack.js +304 -0
- package/src/components/sheet/sheet.css +351 -0
- package/src/components/sheet/sheet.js +551 -0
- package/src/components/split-view/split-view.js +76 -161
- package/src/components/table/table.css +43 -0
- package/src/components/table/table.js +523 -45
- package/src/components/tooltip/tooltip.js +5 -2
- package/src/components/value-list/value-list.js +6 -3
- package/src/core/dom.js +302 -0
- package/src/core/drag-axis.js +203 -0
- package/src/core/position.js +68 -22
- package/src/index.js +19 -2
- package/styles/tokens/dark.css +2 -3
- package/styles/tokens/global.css +5 -5
- package/styles/tokens/semantic.css +5 -3
- package/styles/tokens/themes.css +1 -1
- package/styles/zx.css +10 -1
- package/dist/types/components/permission/permission.d.ts +0 -96
- package/src/components/permission/permission.css +0 -47
- package/src/components/permission/permission.js +0 -201
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,93 @@ and friends remain the complete record.
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## 3.0.0 — 2026-08-24
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Xenon application shell components.** `Launcher` combines deterministic local ranking with
|
|
16
|
+
abortable grouped sources and a Cmd/Ctrl+K dialog; `Avatar` provides a stable initials fallback;
|
|
17
|
+
`AccountMenu` composes identity with an APG menu; `AppSidebar` is expanded vertical navigation;
|
|
18
|
+
and minimized `AppRail` keeps descendants in pointer-, focus-, and keyboard-accessible flyouts
|
|
19
|
+
for both vertical and horizontal placement. All route, permission, session, and persistence work
|
|
20
|
+
remains application-owned behind cancelable events.
|
|
21
|
+
- **`Grid` and `Grid.BillingItems()`.** The public Table specialization keeps every Table feature
|
|
22
|
+
while providing a conventional editable billing schema for currencies, units, line totals, and
|
|
23
|
+
flat parent rows. The default line formula is quantity × unit price; tax, discount, rounding,
|
|
24
|
+
subtotal, validation, and persistence policy remain caller-owned.
|
|
25
|
+
- **Engine-neutral `Chart` and injected `ChartJsAdapter`.** Chart owns responsive canvas lifecycle,
|
|
26
|
+
loading/empty/error states, Xenon theme defaults, point-selection events, and a synchronized
|
|
27
|
+
semantic data table. Chart.js 4.5.1 is pinned only as a development/documentation asset; the Zx
|
|
28
|
+
runtime has no chart import and no runtime dependency.
|
|
29
|
+
- **Lateral anchored-overlay placement.** `position()`, `Dropdown`, `MenuButton`, and `Tooltip` now
|
|
30
|
+
accept left/right start/end variants for rail and account surfaces.
|
|
31
|
+
|
|
32
|
+
- **`Questionnaire`** — a guided, one-question-at-a-time flow for onboarding intake, service
|
|
33
|
+
checklists, audits and surveys, where a `Form` full of fieldsets is the wrong shape. The root is
|
|
34
|
+
a real `<form>` and the choices are native radios and checkboxes carrying the item name, so
|
|
35
|
+
`new FormData(questionnaire.toElement())` reads the answers and the keyboard contract inside a
|
|
36
|
+
choice group is the browser's. Three things go beyond a stack of fieldsets: an item carries a
|
|
37
|
+
`when` predicate and a `next` target, so the flow **branches** — conditions cascade, an
|
|
38
|
+
abandoned branch's answers drop out of `getAnswers()`, progress counts the questions actually
|
|
39
|
+
reachable, and Back retraces the path walked rather than an array index; an item's answer control
|
|
40
|
+
can be **any registered `Field` type** (`field: {type: 'date'}`), which is what lets a question
|
|
41
|
+
ask for a date, a number, a rating or an upload; and `validate` may return a **promise**, so a
|
|
42
|
+
question can be gated on a server check. `review: true` adds a summary screen with jump-back-to-
|
|
43
|
+
edit, `advance: 'auto'` moves on by itself after a single choice, and `1`–`9`/`a`–`z` shortcuts
|
|
44
|
+
are assigned and shown on each answer.
|
|
45
|
+
|
|
46
|
+
- **`Sheet`** — an edge-anchored `Dialog` covering both side-sheet and mobile-drawer patterns;
|
|
47
|
+
the two differ only in which edge they take, so `side` (`'start' | 'end' | 'top' | 'bottom'`,
|
|
48
|
+
logical) replaces a second component. `modal` is three-way rather than a boolean because the
|
|
49
|
+
three real behaviours do not collapse into two: `true` hands focus containment, page inertness,
|
|
50
|
+
Escape and the backdrop to the browser via `showModal()`, while `'trap-focus'` and `false` open
|
|
51
|
+
non-modally and re-implement only what they still want. `backdrop: 'dim'|'blur'|'none'` applies
|
|
52
|
+
to modal sheets alone — `::backdrop` does not render for a non-modal dialog, and a painted
|
|
53
|
+
stand-in would make a non-blocking sheet look blocking. Entry **and exit** animate, which a
|
|
54
|
+
`<dialog>` normally cannot do, via `@starting-style` and `transition-behavior: allow-discrete`
|
|
55
|
+
on `display`/`overlay`. `resizable`, `snap` detents and swipe-to-dismiss are deliberately one
|
|
56
|
+
gesture whose meaning is decided when the pointer settles, so the sheet follows the pointer the
|
|
57
|
+
whole way instead of pinning at its minimum and then vanishing.
|
|
58
|
+
- **`SheetStack`** — several sheets as one drill-down. Small on purpose: nested dialogs already
|
|
59
|
+
stack in the top layer by open order and Escape already closes only the topmost, so no z-index
|
|
60
|
+
bookkeeping and no unwinding logic. `stack` slides covered sheets back, scales them down and
|
|
61
|
+
makes them `inert`; `cascade` shifts each clear of the ones in front by their **measured** size
|
|
62
|
+
so they sit side by side and all stay usable — usually the right one for an ERP screen, where
|
|
63
|
+
the parent record should stay readable while a line item is edited.
|
|
64
|
+
- **`Dock`** — a stack of collapsible, resizable panes: the docked inspector column of a design
|
|
65
|
+
tool, and the detail side of a master–detail screen. A pane is either titled or a **tab group**
|
|
66
|
+
whose strip replaces the title. Giving the dock a `content` turns it into a region with panes on
|
|
67
|
+
either `side` of it, and nesting one dock in another's pane gives a workbench. Sizes, collapsed
|
|
68
|
+
panes and active tabs persist through `storageKey`; content factories run on first reveal.
|
|
69
|
+
- **`Dock.adopt(sheet)`** — a dock can take over a `Sheet`'s positioning, so the sheet becomes a
|
|
70
|
+
track in the dock's flow instead of an overlay. A dock is a flex container by construction and
|
|
71
|
+
therefore always a valid host, which is why docking needs no arrangement from the application.
|
|
72
|
+
`dockAt` hands the sheet back to a free overlay below a breakpoint measured on the **dock's own
|
|
73
|
+
width**, so a dock inside a split pane behaves correctly where a viewport media query would not.
|
|
74
|
+
Nothing is rebuilt across the handoff: the element moves and reopens in place, so DOM state and
|
|
75
|
+
listeners survive and no `open`/`close` is emitted for what is only a change of address.
|
|
76
|
+
- **`--zx-overlay-blur`** — tier-2 semantic token behind `Sheet`'s `'blur'` backdrop, default `8px`.
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
|
|
80
|
+
- **`SplitView` now shares one axis-drag engine with `Sheet` and `Dock`**, extracted to
|
|
81
|
+
`core/drag-axis.js`: pointer capture, one write per frame, telling a click from a zero-distance
|
|
82
|
+
drag, and the WAI-ARIA keyboard map. Behaviour is unchanged. `resolveSize` moved to the kernel
|
|
83
|
+
and is re-exported from `split-view.js`, so every existing import keeps working.
|
|
84
|
+
- **`Modal` gained three protected seams** — `mountTarget()`, `_show()` and `_isRealClose()` — so a
|
|
85
|
+
subclass can live somewhere other than `document.body`, open non-modally, and re-host itself.
|
|
86
|
+
`Dialog`'s size application became the overridable `_applySize()`. No public behaviour changed.
|
|
87
|
+
- **The modal scroll lock keys off `:modal` rather than `[open]`**, so a non-modal dialog no longer
|
|
88
|
+
locks the page behind it. `Modal` and `Dialog` always open modally, so neither is affected.
|
|
89
|
+
|
|
90
|
+
### Removed
|
|
91
|
+
|
|
92
|
+
- **`Permission` is removed**, not just deprecated. 2.3.0 kept the class around for
|
|
93
|
+
`gx.zeyos.Permission` while pointing new code at `Select.permission()`; there is no longer a
|
|
94
|
+
second implementation to keep in sync, and `gx.zeyos.Permission` now builds directly on
|
|
95
|
+
`Select.permission()` instead of wrapping the removed class. The legacy constructor, options,
|
|
96
|
+
`get()`/`set()`, and the `change` event are unchanged — only the `zx.Permission` export is gone.
|
|
97
|
+
|
|
11
98
|
## 2.3.0 — 2026-08-23
|
|
12
99
|
|
|
13
100
|
### Added
|
package/DESIGN-SYSTEM.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Xenon design-system audit
|
|
2
|
+
|
|
3
|
+
Audit date: 2026-08-24. Xenon is the design system; Zx is its dependency-free JavaScript
|
|
4
|
+
implementation. This document records the current coverage against ZeyOS Classic and the work
|
|
5
|
+
needed for an incremental adoption that keeps the existing routing and business logic.
|
|
6
|
+
|
|
7
|
+
## System boundary
|
|
8
|
+
|
|
9
|
+
Xenon has four layers:
|
|
10
|
+
|
|
11
|
+
1. **Foundations** — semantic tokens, typography, spacing, density, themes, icons, motion, i18n,
|
|
12
|
+
accessibility rules, and the safe DOM kernel.
|
|
13
|
+
2. **Components** — lifecycle-safe controls and containers with one options/events/destroy model.
|
|
14
|
+
3. **Patterns** — repeatable business interactions such as global launch, account/preferences,
|
|
15
|
+
record detail, transaction entry, filtering, and empty/loading/error handling.
|
|
16
|
+
4. **Application layouts** — rails, bars, workspaces, master/detail, dashboards, inboxes, wizards,
|
|
17
|
+
and responsive shell geometry.
|
|
18
|
+
|
|
19
|
+
This separation follows the enterprise-system intent described by the
|
|
20
|
+
[Carbon Design System](https://carbondesignsystem.com/all-about-carbon/what-is-carbon/) and
|
|
21
|
+
[SAP Fiori design principles](https://experience.sap.com/fiori-design-web/design-principles/),
|
|
22
|
+
without copying either system's code, assets, or component contracts.
|
|
23
|
+
|
|
24
|
+
Zx currently has more than 50 public component classes, 63 registered documentation/demo entries,
|
|
25
|
+
a generated API reference, bundled local icons, and no runtime dependency. The foundations,
|
|
26
|
+
component layer, and persistent application shell now cover the first ZeyOS adoption wave; domain
|
|
27
|
+
patterns remain intentionally application-owned until their business invariants are specified.
|
|
28
|
+
|
|
29
|
+
## ZeyOS adoption boundary
|
|
30
|
+
|
|
31
|
+
ZeyOS Classic does not use `gx`. Across its 30 module files it has roughly 2,500 `UI.*` calls and
|
|
32
|
+
2,600 `PG.*` calls. `PG` already owns navigation, transport, history, exit guards, and page
|
|
33
|
+
lifecycle and remains authoritative.
|
|
34
|
+
|
|
35
|
+
The existing compact DOM surface has 2,668 executable builder calls: 871 bare `__()` calls, 1,710
|
|
36
|
+
parent-returning `parent.__()` calls, and 87 child-returning `parent.$__()` calls. Zx now provides
|
|
37
|
+
the exact compact builder plus pure append/property/event helpers. Existing global and prototype
|
|
38
|
+
names remain application-owned delegation seams; Zx does not install or replace them.
|
|
39
|
+
|
|
40
|
+
Migration therefore replaces `UI.new*` implementations one family at a time, keeps their current
|
|
41
|
+
DOM/value contracts until call sites reach zero, and leaves `PG`, `MD`, routes, and server payloads
|
|
42
|
+
in place. See [MIGRATION.md](./MIGRATION.md) for the ordering and shell invariants.
|
|
43
|
+
|
|
44
|
+
## Coverage ledger
|
|
45
|
+
|
|
46
|
+
| Capability in current ZeyOS | Xenon/Zx status | Decision |
|
|
47
|
+
| --- | --- | --- |
|
|
48
|
+
| Buttons, inputs, toggles, dates, selects, checklists, tags | Covered by public components | Replace `UI.new*` families incrementally and preserve value/event contracts. |
|
|
49
|
+
| Forms and fieldsets | Covered, including component-backed field adapters | Use for record editors; keep validation/business rules application-owned. |
|
|
50
|
+
| Dialogs, sheets, dropdowns, context menus, tooltips, messages | Covered | Consolidate duplicate menu behavior before building account/launcher surfaces. |
|
|
51
|
+
| Tabs, panels, toolbar, breadcrumbs, stepper, split view, dock | Covered | Compose layouts; do not let navigation components own routes. |
|
|
52
|
+
| Sorting, selection, filtering, pagination, trees/finder | Covered | Suitable for generic data screens. |
|
|
53
|
+
| Editable billing/transaction rows | Covered at generic-grid level | `Grid.BillingItems()` composes typed editable currency/unit columns and flat hierarchy over `Table`. Tax, subtotal, posting, rounding, and persistence stay domain code. |
|
|
54
|
+
| Global launcher/search | Covered | `Launcher` combines ranked local applications with abortable grouped sources. ZeyOS still filters the catalogue and resolves selection through `PG`. |
|
|
55
|
+
| Account/profile/preferences menu | Covered at presentation level | `Avatar` and `AccountMenu` provide identity and action UI. ZeyOS supplies role-filtered actions and owns preferences, authentication, and logout. |
|
|
56
|
+
| Persistent app rail / side navigation | Covered | `AppSidebar` is the expanded vertical tree; minimized `AppRail` uses flyouts in every orientation. Both are route- and persistence-agnostic. |
|
|
57
|
+
| Charts and analytical summaries | Covered through an adapter | `Chart` is engine-neutral and accessible; `ChartJsAdapter` accepts an injected Chart.js 4 engine. Chart.js is documentation/test tooling only. |
|
|
58
|
+
| Local product/module icons | Partial | Use bundled icons or registered local assets; do not require the optional remote Font Awesome kit. |
|
|
59
|
+
| Domain entity selectors/cards/links | Partial | Build patterns on `Select`, Table, Panel, and ContextMenu after the shell blockers. |
|
|
60
|
+
| Persistent notification/activity center | Missing, lower priority | `Message` covers ephemeral feedback, not read/unread activity history. |
|
|
61
|
+
|
|
62
|
+
### Launcher contract
|
|
63
|
+
|
|
64
|
+
The current launcher searches applications, recent records, and grouped remote record types. A
|
|
65
|
+
replacement supplies pinned-order ranking, request cancellation, Cmd/Ctrl+K, listbox keyboard
|
|
66
|
+
behavior, native link metadata, and a cancelable action. Permission filtering, active-route state,
|
|
67
|
+
cache and recent-history policy remain inputs from ZeyOS, which resolves actions through `PG.go()`.
|
|
68
|
+
The component is deliberately not a second router.
|
|
69
|
+
|
|
70
|
+
### Account contract
|
|
71
|
+
|
|
72
|
+
The current account surface includes identity, role-dependent links, language, authentication and
|
|
73
|
+
logout, theme and menu-position preferences, and About/version content. A shared `Menu` should
|
|
74
|
+
first centralize the keyboard/typeahead/selection behavior currently duplicated by `MenuButton`
|
|
75
|
+
and `ContextMenu`; `AccountMenu` then composes that primitive with `Avatar`/`Identity` and emits
|
|
76
|
+
actions without owning routes or session state. `AccountMenu` now provides that composition over
|
|
77
|
+
`MenuButton`; a future shared low-level `Menu` remains an internal consolidation opportunity, not
|
|
78
|
+
an adoption blocker.
|
|
79
|
+
|
|
80
|
+
## Table and transaction follow-ups
|
|
81
|
+
|
|
82
|
+
The enhanced `Table` now keeps values numeric while formatting per-row locales, currencies, units,
|
|
83
|
+
and decimals; numeric types infer `NumberField` editors. Flat `parentId` data is projected into a
|
|
84
|
+
cycle-safe ARIA treegrid with local sibling sorting and expand/collapse APIs.
|
|
85
|
+
|
|
86
|
+
`Grid.BillingItems()` now packages the conventional description, quantity, unit, unit-price,
|
|
87
|
+
currency, line-total, and hierarchy schema while retaining Table's editing contract. Useful
|
|
88
|
+
follow-ups, deliberately separate from this generic preset:
|
|
89
|
+
|
|
90
|
+
- summary/footer rows and grouped subtotals;
|
|
91
|
+
- column reorder and user-persisted column state;
|
|
92
|
+
- product-specific invoice/transaction presets with tax, discount, rounding, and formula golden tests;
|
|
93
|
+
- server persistence, optimistic rejection, and undo owned by the application/controller layer.
|
|
94
|
+
|
|
95
|
+
## Chart-engine candidates
|
|
96
|
+
|
|
97
|
+
Chart.js was selected for the first adapter. It is pinned at 4.5.1 as a development dependency for
|
|
98
|
+
tests and the documentation asset, but is never imported by Zx runtime source. Applications inject
|
|
99
|
+
their chosen engine into the adapter. Published browser artifact sizes below are approximate and
|
|
100
|
+
remain useful when choosing a different future adapter.
|
|
101
|
+
|
|
102
|
+
| Engine | Current state at audit | Approx. browser cost | Best fit | Main trade-off |
|
|
103
|
+
| --- | --- | ---: | --- | --- |
|
|
104
|
+
| [Chart.js](https://github.com/chartjs/Chart.js/releases) 4.5.1 | Mature, active, MIT | 209 kB / 71 kB gzip (UMD) | Broad default: bar, line, doughnut, mixed business charts | Larger than focused engines; canvas requires a separate accessible data summary. |
|
|
105
|
+
| [Frappe Charts](https://github.com/frappe/charts/releases) 1.6.x | Zero-dependency SVG, ERP-oriented, MIT | 69 kB / 18 kB gzip (UMD) | Lean dashboards with common chart types | GitHub release and npm publication were out of step; ecosystem and extension surface are smaller. |
|
|
106
|
+
| [uPlot](https://github.com/leeoniya/uPlot) 1.6.32 | Active, MIT, highly optimized | 51 kB JS + 2 kB CSS / about 23 kB gzip | Dense time-series and operational telemetry | Deliberately narrow; not a general categorical/stacked business-chart toolkit. |
|
|
107
|
+
| [Apache ECharts](https://echarts.apache.org/en/changelog.html) 6.1.0 | Very capable, active, Apache-2.0 | 1.12 MB / 369 kB gzip (full build) | Advanced analytical visualization | Too large as Xenon's default; only sensible as an opt-in advanced adapter or custom build. |
|
|
108
|
+
|
|
109
|
+
Implemented architecture: `Chart` accepts an injected engine adapter, maps Xenon semantic tokens,
|
|
110
|
+
owns loading/empty/error states, and mirrors its data in an accessible table. Chart.js is the broad
|
|
111
|
+
default adapter; Frappe Charts remains the lean ERP-oriented alternative, uPlot a specialized
|
|
112
|
+
time-series candidate, and ECharts an opt-in advanced adapter. Any additional package still
|
|
113
|
+
requires explicit dependency approval.
|
|
114
|
+
|
|
115
|
+
## Review corrections completed
|
|
116
|
+
|
|
117
|
+
- Generated API records no longer let helper typedefs overwrite component options; inline JSDoc
|
|
118
|
+
tags are parsed, and audited runtime events are present in types and documentation.
|
|
119
|
+
- Form documentation exposes `Form`, `Fieldset`, and `Field`; `MonthPicker` has its own constructor
|
|
120
|
+
type.
|
|
121
|
+
- Theme Studio destroys registered component instances on every rebuild and describes its honest
|
|
122
|
+
family-level coverage.
|
|
123
|
+
- Documentation separates Presets from green-accent Examples and uses callable preset names.
|
|
124
|
+
- Current source and documentation no longer carry branding from the retired framework experiment.
|
|
125
|
+
|
|
126
|
+
## Recommended sequence
|
|
127
|
+
|
|
128
|
+
1. Ship the Zx runtime and delegate the current compact DOM/event seams; verify no navigation or
|
|
129
|
+
listener regressions.
|
|
130
|
+
2. Mount `Launcher`, `Avatar`/`AccountMenu`, and `AppSidebar`/`AppRail` behind the current shell
|
|
131
|
+
fixtures, permission filters, and preference store.
|
|
132
|
+
3. Replace high-volume `UI.new*` families, one discriminating fixture set at a time.
|
|
133
|
+
4. Introduce `Grid.BillingItems()` where its generic schema fits; add domain presets only with
|
|
134
|
+
formula and rounding fixtures.
|
|
135
|
+
5. Inject Chart.js into `ChartJsAdapter` only on analytical surfaces that need it; keep the engine
|
|
136
|
+
out of the base Zx runtime bundle.
|
package/MIGRATION.md
CHANGED
|
@@ -4,6 +4,136 @@ Zx replaces the MooTools-era `gx` UI libraries with dependency-free ES2022 modul
|
|
|
4
4
|
compatibility bundle lets mapped legacy code keep running while classes are migrated one at a
|
|
5
5
|
time. Compatibility constructors warn once per legacy class so remaining call sites are visible.
|
|
6
6
|
|
|
7
|
+
Xenon is the ZeyOS design system; Zx is its browser implementation. A complete migration therefore
|
|
8
|
+
means more than swapping constructors: foundations, components, application patterns, and layout
|
|
9
|
+
contracts must move together while routing and business behavior stay authoritative.
|
|
10
|
+
|
|
11
|
+
## Introducing Xenon into ZeyOS Classic
|
|
12
|
+
|
|
13
|
+
The current ZeyOS Classic application is **not** a `gx.*` application. Its modules call the global
|
|
14
|
+
`UI` factories, use `PG` for routing and page lifecycle, and rely on an extended DOM API including a
|
|
15
|
+
CSS-like `__()` element builder. Do not call `gx.compat.installGlobals()` there: that opt-in helper
|
|
16
|
+
preserves an existing `__()` but installs unrelated `gx` globals and prototype compatibility that
|
|
17
|
+
the current application does not need.
|
|
18
|
+
|
|
19
|
+
The migration does not need a separate application bridge. Zx now exports the established builder
|
|
20
|
+
directly, including its exact compact tag and property conventions:
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
const node = zx.__('button#save.primary', {
|
|
24
|
+
Daction: 'save',
|
|
25
|
+
onclick: () => save()
|
|
26
|
+
}, 'Save');
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Zx does not install globals or alter DOM prototypes. The current runtime keeps owning its global
|
|
30
|
+
`__`, `_`, `Node._`, `Node.__`, `Node.$__`, and `Element.be` seams during the migration and delegates
|
|
31
|
+
their bodies to `zx.compactElement()`, `zx.appendContent()`, `zx.appendCompact()`,
|
|
32
|
+
`zx.appendCompactChild()`, and `zx.applyCompactProperties()`. Its `DOM.on`, `DOM.remEvt`, and
|
|
33
|
+
`DOM.fireEvt` facade likewise delegates to Zx's shared compact-event helpers, so registration,
|
|
34
|
+
removal, and synthetic firing always see the same handlers. Replace the implementations of
|
|
35
|
+
`UI.new*` component families progressively with Zx components; do not insert a second routing or
|
|
36
|
+
application abstraction between those components and `PG`.
|
|
37
|
+
|
|
38
|
+
### Keep these authorities in place
|
|
39
|
+
|
|
40
|
+
- `PG` remains responsible for URL construction, history, transport, exit guards, page dispatch,
|
|
41
|
+
and the `page:beforeUnmount` / `page:mounted` lifecycle.
|
|
42
|
+
- Existing `MD` handlers and business logic continue receiving the same page data.
|
|
43
|
+
- Existing `UI.new*` call sites keep their DOM return values and `getV` / `setV` / chaining
|
|
44
|
+
contracts while each factory implementation is replaced. New code uses the Zx component API
|
|
45
|
+
directly; the old factory is removed when its call-site count reaches zero.
|
|
46
|
+
- Zx owns only the mounted component subtree and tears that subtree down exactly once.
|
|
47
|
+
- New client/schema-driven screens may use `@zeyos/zx/zeyos`; adopting that optional layer is not a
|
|
48
|
+
prerequisite for converting current server-rendered screens.
|
|
49
|
+
|
|
50
|
+
Safe bootstrap order is the normal Zx bundle, the current Classic runtime delegating its compact
|
|
51
|
+
DOM seams to Zx, then the existing `Z(data)` application bootstrap. Component actions must call
|
|
52
|
+
`PG.go()` for internal routes; do not let a navigation component fall back to `location.assign()`.
|
|
53
|
+
|
|
54
|
+
### Recommended adoption waves
|
|
55
|
+
|
|
56
|
+
1. Mount persistent shell components behind current lifecycle events: launcher, account menu,
|
|
57
|
+
application rail, detail chrome, and overlays.
|
|
58
|
+
2. Replace the highest-volume `UI.new*` implementations—inputs, Selects, tabs, menus, dialogs, and
|
|
59
|
+
tables—one family at a time while preserving their existing call-site contract.
|
|
60
|
+
3. Move record and transaction patterns only after old/new behavior has discriminating fixtures.
|
|
61
|
+
4. Use direct Zx and the ZeyOS schema binding for new surfaces; retire an old factory only after its
|
|
62
|
+
remaining call-site count reaches zero.
|
|
63
|
+
|
|
64
|
+
### Shell components and ownership
|
|
65
|
+
|
|
66
|
+
`Search` remains a field-level input. `Launcher` is the shell-level application/record surface: it
|
|
67
|
+
ranks local items, debounces and aborts grouped sources, ignores stale responses, and supplies the
|
|
68
|
+
Cmd/Ctrl+K dialog/listbox interaction. ZeyOS filters permissions, supplies apps/recent records,
|
|
69
|
+
decides caching, and handles the cancelable selection through `PG`; Launcher never becomes a
|
|
70
|
+
router.
|
|
71
|
+
|
|
72
|
+
`Avatar` and `AccountMenu` provide the identity trigger, profile header, grouped actions, focus
|
|
73
|
+
return, and compact rail presentation. ZeyOS still decides permission-dependent routes, language
|
|
74
|
+
and theme choices, authentication/logout, and About/version data. A selection is a request to the
|
|
75
|
+
application, not a session mutation.
|
|
76
|
+
|
|
77
|
+
`AppSidebar` is the expanded vertical application tree and is the only presentation with inline
|
|
78
|
+
children. Its collapsed state renders `AppRail`. A standalone rail may be vertical or horizontal,
|
|
79
|
+
but every child collection remains a hover/focus/keyboard flyout. Both components accept native
|
|
80
|
+
links or cancelable actions and expose active/collapsed/expanded state without persisting it.
|
|
81
|
+
|
|
82
|
+
Use bundled Zx icons or explicitly registered local assets. The optional ZeyOS icon helper's
|
|
83
|
+
remote Font Awesome kit is not appropriate for a dependency-free production shell.
|
|
84
|
+
|
|
85
|
+
### Persistent shell contract
|
|
86
|
+
|
|
87
|
+
These invariants were validated while prototyping the replacement shell and remain binding for a
|
|
88
|
+
Xenon implementation:
|
|
89
|
+
|
|
90
|
+
- Application-menu position is `top`, `bottom`, `left`, `right`, or `none`, defaulting to `left`.
|
|
91
|
+
Persist it under `zeyos.appMenu.position` (scope-suffixed where separate workspaces share an
|
|
92
|
+
origin) and publish the resolved value on `:root[data-app-menu-effective]`.
|
|
93
|
+
- Sidebar minimization is a user choice, never a hover side effect. Keep the existing
|
|
94
|
+
`zeyos.appRail.expanded` preference while migrating and map it to
|
|
95
|
+
`AppSidebar.setCollapsed(!expanded)`. `AppRail` itself never expands labels or inline children.
|
|
96
|
+
- The minimized rail is 48 px and the expanded sidebar 184 px. The application bar is 48 px; tiles
|
|
97
|
+
are 30 px, glyphs 22 px, and compact controls 31 px. Workspace tools in a side layout remain
|
|
98
|
+
inside the rail, and page insets derive from the effective rail/bar geometry.
|
|
99
|
+
- Theme preference is `auto`, `light`, or `dark`, persisted under `zeyos.theme` and applied before
|
|
100
|
+
paint. `auto` follows the system color-scheme media query.
|
|
101
|
+
- The dark neutral ramp is a coal surface rebased from Carbon Gray 100 toward `#0b0c0e`. Avoid a
|
|
102
|
+
cyan/slate cast that competes with ZeyOS module colors; module accents must retain clear contrast
|
|
103
|
+
on both shell and content surfaces.
|
|
104
|
+
|
|
105
|
+
### Migration proof points
|
|
106
|
+
|
|
107
|
+
Before replacing any Classic surface, verify that internal navigation and browser history still use
|
|
108
|
+
`PG.go()` without a full reload; page-scoped instances are destroyed exactly once; persistent shell
|
|
109
|
+
listeners do not multiply across navigation or language changes; launcher output matches permission,
|
|
110
|
+
app, recent, and search fixtures; account content matches ordinary/admin/developer roles; and the
|
|
111
|
+
production shell loads no remote UI or icon dependency.
|
|
112
|
+
|
|
113
|
+
The shell wiring stays direct:
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
const launcher = new zx.Launcher(null, {
|
|
117
|
+
items: applicationCatalogue,
|
|
118
|
+
sources: recordSources,
|
|
119
|
+
onselect(event) {
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
PG.go(resolveLauncherRoute(event.detail.item));
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const sidebar = new zx.AppSidebar(shellHost, {
|
|
126
|
+
items: applicationTree,
|
|
127
|
+
active: currentRouteId,
|
|
128
|
+
collapsed: !savedAppRailExpanded,
|
|
129
|
+
footer: accountMenu,
|
|
130
|
+
onselect(event) {
|
|
131
|
+
event.preventDefault();
|
|
132
|
+
PG.go(event.detail.href);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
7
137
|
## Deployment script swap
|
|
8
138
|
|
|
9
139
|
For deployments that serve the old libraries directly from
|
|
@@ -25,8 +155,9 @@ with this order:
|
|
|
25
155
|
```
|
|
26
156
|
|
|
27
157
|
The compatibility entry exposes both `window.zx` and `window.gx`. Element
|
|
28
|
-
`store`/`retrieve`/`eliminate` is installed automatically. If
|
|
29
|
-
`String.prototype.htmlSpecialChars`, or `Array.prototype.findBy`, opt in after
|
|
158
|
+
`store`/`retrieve`/`eliminate` is installed automatically. If a genuine gx application uses its
|
|
159
|
+
free parser, `_()`, `String.prototype.htmlSpecialChars`, or `Array.prototype.findBy`, opt in after
|
|
160
|
+
both scripts load. An existing `__()` is deliberately never replaced:
|
|
30
161
|
|
|
31
162
|
```js
|
|
32
163
|
gx.compat.installGlobals();
|
|
@@ -251,14 +382,14 @@ list.setValues([1, 2]);
|
|
|
251
382
|
|
|
252
383
|
For remote data pass `load: () => Promise<items>` and listen for `loaded`.
|
|
253
384
|
|
|
254
|
-
### `gx.zeyos.Permission` → `zx.
|
|
385
|
+
### `gx.zeyos.Permission` → `zx.Select.permission()`
|
|
255
386
|
|
|
256
387
|
```js
|
|
257
388
|
// gx
|
|
258
389
|
const permission = new gx.zeyos.Permission(host, { value: true, groups });
|
|
259
390
|
|
|
260
391
|
// Zx
|
|
261
|
-
const permission =
|
|
392
|
+
const permission = zx.Select.permission(host, { value: true, groups });
|
|
262
393
|
permission.on('change', (event) => save(event.detail.value));
|
|
263
394
|
```
|
|
264
395
|
|
|
@@ -295,6 +426,26 @@ table.addData([{ ID: 1, name: 'Ada' }]);
|
|
|
295
426
|
|
|
296
427
|
Use `setData`, `addData`, `updateRow`, `removeRow`, and `getData` for row operations.
|
|
297
428
|
|
|
429
|
+
### Billing/transaction rows → `zx.Grid.BillingItems()`
|
|
430
|
+
|
|
431
|
+
Use the generic preset when the existing screen has description, quantity, unit, unit price,
|
|
432
|
+
currency, total, and optional parent rows:
|
|
433
|
+
|
|
434
|
+
```js
|
|
435
|
+
const items = zx.Grid.BillingItems(host, {
|
|
436
|
+
data: rows,
|
|
437
|
+
units: unitChoices,
|
|
438
|
+
currencies: currencyChoices,
|
|
439
|
+
oneditcommit(event) {
|
|
440
|
+
if (!controller.accept(event.detail.changes)) event.preventDefault();
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
The default line total is quantity × unit price. Keep taxes, discounts, subtotal/group updates,
|
|
446
|
+
rounding policy, posting, server persistence, and undo in the existing controller. Override
|
|
447
|
+
`lineTotal` only when that calculation is a stable screen-level rule.
|
|
448
|
+
|
|
298
449
|
### `gx.zeyos.Tabbox` and `gx.bootstrap.Tabbox` → `zx.Tabbox`
|
|
299
450
|
|
|
300
451
|
```js
|
package/README.md
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
# Zx
|
|
1
|
+
# Xenon Design System (Zx)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
modernised.
|
|
3
|
+
Xenon is the dependency-free design system for ZeyOS business applications; Zx is its
|
|
4
|
+
vanilla-JavaScript implementation. It combines foundations, accessible components, repeatable
|
|
5
|
+
workflow patterns, and application layouts in plain ES2022 modules. Source modules run directly in
|
|
6
|
+
a browser; the distribution also provides ESM and classic-script bundles. An opt-in compatibility
|
|
7
|
+
layer remains available for genuine MooTools-era `gx` applications while they are modernised.
|
|
8
|
+
|
|
9
|
+
The [design-system audit](./DESIGN-SYSTEM.md) records current ZeyOS coverage, missing shell
|
|
10
|
+
patterns, the adoption boundary, transaction-grid follow-ups, and chart-engine candidates.
|
|
8
11
|
|
|
9
12
|
## Quick start
|
|
10
13
|
|
|
@@ -95,7 +98,8 @@ ZeyOS binding — see `src/zeyos/modules.js`.
|
|
|
95
98
|
| `CheckButton` | Two-state pressed button with optional state-specific labels. |
|
|
96
99
|
| `Toggle` | Native-button switch with a separate submitted value. |
|
|
97
100
|
| `Search` | Search input with debounced input, submit, and clear events. |
|
|
98
|
-
| `
|
|
101
|
+
| `Launcher` | Cmd/Ctrl+K application and record launcher with ranked local items and abortable grouped sources. |
|
|
102
|
+
| `Select` | APG combobox with local or async filtering, pinned fixed items, and priority/permission presets. |
|
|
99
103
|
| `Checklist` | Searchable checkbox group with optional async loading. |
|
|
100
104
|
| `TagPicker` | Multi-select combobox that keeps its selection as removable tags. |
|
|
101
105
|
| `NumberField` | APG spinbutton with step buttons, ranges, units, and wrapping. |
|
|
@@ -122,12 +126,16 @@ ZeyOS binding — see `src/zeyos/modules.js`.
|
|
|
122
126
|
| `MenuButton` | APG menu button built on `Dropdown`. |
|
|
123
127
|
| `ContextMenu` | APG right-click menu for a region or, via `selector`, per row. |
|
|
124
128
|
| `Tooltip`, `tooltip()`, `describe()` | Hover/focus description bubble anchored with `position()`. |
|
|
129
|
+
| `Avatar` | Fixed-size user image with initials fallback and optional presence. |
|
|
130
|
+
| `AccountMenu` | Identity trigger and grouped account actions over `MenuButton`. |
|
|
125
131
|
|
|
126
132
|
### Data
|
|
127
133
|
|
|
128
134
|
| API | Description |
|
|
129
135
|
| --- | --- |
|
|
130
|
-
| `Table` |
|
|
136
|
+
| `Table` | Sortable/selectable table with typed transaction columns, flat-data hierarchy/treegrid projection, and opt-in cell/row editing. |
|
|
137
|
+
| `Grid`, `Grid.BillingItems()` | Table-compatible preset surface with editable currencies, units, totals, and sub-items. |
|
|
138
|
+
| `Chart`, `ChartJsAdapter` | Accessible engine-neutral chart host and explicitly injected Chart.js adapter. |
|
|
131
139
|
| `DataFilter` | Declarative select, text, and custom filters for client-side row sets. |
|
|
132
140
|
| `TreeView` | APG tree with lazy children, filtering, and tri-state checkboxes. |
|
|
133
141
|
| `Finder` | Miller-columns hierarchy browser with an optional preview pane. |
|
|
@@ -137,10 +145,10 @@ ZeyOS binding — see `src/zeyos/modules.js`.
|
|
|
137
145
|
|
|
138
146
|
| API | Description |
|
|
139
147
|
| --- | --- |
|
|
140
|
-
| `Permission` | Private, public, or group-level permission selector. |
|
|
141
148
|
| `Field` | Label, description, validation state, and adapter-backed form control. |
|
|
142
149
|
| `Fieldset` | Native fieldset that owns and coordinates fields. |
|
|
143
150
|
| `Form` | Form composition, values, validation, highlighting, and actions. |
|
|
151
|
+
| `Questionnaire` | Guided one-question-at-a-time flow: branching, path-aware progress, review. |
|
|
144
152
|
| `ValueList` | Validated, sortable tag/chip editor. |
|
|
145
153
|
| `MultiValueEditor` | Ordered editable rows with add, remove, and move controls. |
|
|
146
154
|
| `FieldUpload` | Click/drop file upload with progress, abort, validation, and preview. |
|
|
@@ -154,6 +162,8 @@ ZeyOS binding — see `src/zeyos/modules.js`.
|
|
|
154
162
|
| `MasterPanel` | Full-height application panel with fixed header actions and footer. |
|
|
155
163
|
| `Tabbox` | APG tabs in four appearances, with lazy content, closing, badges, and disabled states. |
|
|
156
164
|
| `NavigationBar` | Responsive application navigation with optional tab panels and overflow. |
|
|
165
|
+
| `AppSidebar` | Expanded vertical application navigation with inline disclosure children. |
|
|
166
|
+
| `AppRail` | Minimized vertical/horizontal application navigation with flyout-only descendants. |
|
|
157
167
|
| `Toolbar` | APG toolbar: one tab stop, arrow-key movement, and overflow into a menu. |
|
|
158
168
|
| `SplitView` | Resizable two-pane split with a keyboard-operable separator. |
|
|
159
169
|
| `Stepper` | Linear multi-step progress with completed, active, and error states. |
|
|
@@ -241,7 +251,7 @@ through, so a preset rethemes light, dark, and auto at once:
|
|
|
241
251
|
|
|
242
252
|
Light surfaces take the 600 and 700 stops, dark ones take 300, 400, and 500 — so keep 600 legible
|
|
243
253
|
against white and 400 against near-black, and `--zx-color-on-accent` stays correct in both. The
|
|
244
|
-
[theme studio](https://zx.zeyos.com/theme.html) renders every component under a live theme and
|
|
254
|
+
[theme studio](https://zx.zeyos.com/theme.html) renders every component family under a live theme and
|
|
245
255
|
exports the result.
|
|
246
256
|
|
|
247
257
|
Anything beyond the accent is a semantic token override, without reaching into component CSS:
|
|
@@ -273,7 +283,7 @@ JavaScript positioning fallback.
|
|
|
273
283
|
|
|
274
284
|
## Development
|
|
275
285
|
|
|
276
|
-
Install the
|
|
286
|
+
Install the development toolchain and start the no-build demo server:
|
|
277
287
|
|
|
278
288
|
```sh
|
|
279
289
|
npm install
|
|
@@ -318,12 +328,13 @@ During an incremental migration, load the global API before the compatibility bu
|
|
|
318
328
|
<script src="/assets/zx.global.js"></script>
|
|
319
329
|
<script src="/assets/zx-compat.global.js"></script>
|
|
320
330
|
<script>
|
|
321
|
-
// Only
|
|
331
|
+
// Only for gx-era free functions; an existing ZeyOS __() is preserved:
|
|
322
332
|
gx.compat.installGlobals();
|
|
323
333
|
</script>
|
|
324
334
|
```
|
|
325
335
|
|
|
326
336
|
The compatibility bundle always exposes `window.gx` and installs only the element
|
|
327
337
|
`store`/`retrieve`/`eliminate` shim automatically. Legacy globals and prototype conveniences are
|
|
328
|
-
an explicit opt-in through `gx.compat.installGlobals()
|
|
338
|
+
an explicit opt-in through `gx.compat.installGlobals()`; it never replaces an existing `__`.
|
|
339
|
+
See [MIGRATION.md](./MIGRATION.md) for
|
|
329
340
|
class mappings, script replacement, deliberate behavior changes, and unsupported legacy APIs.
|
|
@@ -30,13 +30,14 @@ export declare class Checklist extends ChecklistBase {
|
|
|
30
30
|
export declare class BootstrapChecklist extends ChecklistBase {
|
|
31
31
|
static legacyName: string;
|
|
32
32
|
}
|
|
33
|
-
/** Legacy permission selector. */
|
|
33
|
+
/** Legacy permission selector, backed by the `Select.permission()` preset. */
|
|
34
34
|
export declare class Permission extends GxWrapper {
|
|
35
35
|
static legacyName: string;
|
|
36
36
|
/** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
|
|
37
37
|
constructor(display: Element | string | null, options?: Record<string, any>);
|
|
38
38
|
/** @returns {unknown} */ get(): unknown;
|
|
39
|
-
/** @param {unknown} value @param {boolean} [silent=false] @returns {this} */
|
|
39
|
+
/** @param {unknown} value @param {boolean} [silent=false] @returns {this} */
|
|
40
|
+
set(value: unknown, silent?: boolean): this;
|
|
40
41
|
}
|
|
41
42
|
/** Shared full Table wrapper. */
|
|
42
43
|
declare class TableBase extends GxWrapper {
|