@zeyos/zx 2.3.0 → 4.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.
Files changed (150) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/DESIGN-SYSTEM.md +96 -0
  3. package/README.md +29 -39
  4. package/dist/types/components/account-menu/account-menu.d.ts +144 -0
  5. package/dist/types/components/app-sidebar/app-sidebar.d.ts +243 -0
  6. package/dist/types/components/avatar/avatar.d.ts +100 -0
  7. package/dist/types/components/card/card.d.ts +128 -0
  8. package/dist/types/components/chart/chart.d.ts +322 -0
  9. package/dist/types/components/date-picker/month-picker.d.ts +6 -0
  10. package/dist/types/components/dialog/dialog.d.ts +9 -0
  11. package/dist/types/components/dock/dock.d.ts +495 -0
  12. package/dist/types/components/dropdown/dropdown.d.ts +2 -2
  13. package/dist/types/components/field/field.d.ts +14 -0
  14. package/dist/types/components/field-upload/field-upload.d.ts +37 -4
  15. package/dist/types/components/form/form.d.ts +25 -3
  16. package/dist/types/components/grid/grid.d.ts +172 -0
  17. package/dist/types/components/launcher/launcher.d.ts +359 -0
  18. package/dist/types/components/layout/layout.d.ts +4 -4
  19. package/dist/types/components/menu-button/menu-button.d.ts +10 -2
  20. package/dist/types/components/modal/modal.d.ts +25 -0
  21. package/dist/types/components/multi-value-editor/multi-value-editor.d.ts +7 -1
  22. package/dist/types/components/questionnaire/items.d.ts +327 -0
  23. package/dist/types/components/questionnaire/questionnaire.d.ts +449 -0
  24. package/dist/types/components/select/select.d.ts +51 -0
  25. package/dist/types/components/sheet/sheet-stack.d.ts +167 -0
  26. package/dist/types/components/sheet/sheet.d.ts +294 -0
  27. package/dist/types/components/split-view/split-view.d.ts +2 -21
  28. package/dist/types/components/table/table.d.ts +223 -15
  29. package/dist/types/components/tooltip/tooltip.d.ts +2 -2
  30. package/dist/types/components/value-list/value-list.d.ts +24 -3
  31. package/dist/types/core/dom.d.ts +122 -0
  32. package/dist/types/core/drag-axis.d.ts +111 -0
  33. package/dist/types/core/position.d.ts +4 -2
  34. package/dist/types/index.d.ts +13 -2
  35. package/dist/types/internal/app-rail.d.ts +265 -0
  36. package/dist/types/zeyos/icons.d.ts +5 -0
  37. package/dist/types/zeyos/index.d.ts +2 -1
  38. package/dist/types/zeyos/launcher.d.ts +147 -0
  39. package/dist/types/zeyos/select.d.ts +39 -0
  40. package/dist/zx-zeyos.esm.js +1870 -133
  41. package/dist/zx-zeyos.esm.min.js +1 -1
  42. package/dist/zx.css +2006 -267
  43. package/dist/zx.esm.js +8987 -2757
  44. package/dist/zx.esm.min.js +3 -3
  45. package/dist/zx.global.js +8987 -2757
  46. package/dist/zx.global.min.js +3 -3
  47. package/dist/zx.min.css +1 -1
  48. package/docs/api.json +4396 -2344
  49. package/docs/llms.md +463 -86
  50. package/docs/llms.txt +32 -19
  51. package/package.json +10 -17
  52. package/src/components/account-menu/account-menu.css +70 -0
  53. package/src/components/account-menu/account-menu.js +208 -0
  54. package/src/components/app-rail/app-rail.css +107 -0
  55. package/src/components/app-sidebar/app-sidebar.css +80 -0
  56. package/src/components/app-sidebar/app-sidebar.js +588 -0
  57. package/src/components/avatar/avatar.css +61 -0
  58. package/src/components/avatar/avatar.js +222 -0
  59. package/src/components/button/button.css +0 -1
  60. package/src/components/card/card.css +149 -0
  61. package/src/components/card/card.js +285 -0
  62. package/src/components/chart/chart.css +61 -0
  63. package/src/components/chart/chart.js +523 -0
  64. package/src/components/date-picker/month-picker.js +9 -0
  65. package/src/components/dialog/dialog.js +11 -4
  66. package/src/components/dock/dock.css +228 -0
  67. package/src/components/dock/dock.js +977 -0
  68. package/src/components/dropdown/dropdown.js +1 -1
  69. package/src/components/field/field.js +2 -0
  70. package/src/components/field-upload/field-upload.js +9 -4
  71. package/src/components/form/form.js +6 -3
  72. package/src/components/grid/grid.css +6 -0
  73. package/src/components/grid/grid.js +220 -0
  74. package/src/components/launcher/launcher.css +210 -0
  75. package/src/components/launcher/launcher.js +765 -0
  76. package/src/components/layout/layout.js +2 -2
  77. package/src/components/menu-button/menu-button.js +27 -2
  78. package/src/components/modal/modal.css +5 -1
  79. package/src/components/modal/modal.js +37 -2
  80. package/src/components/multi-value-editor/multi-value-editor.js +2 -1
  81. package/src/components/questionnaire/items.js +370 -0
  82. package/src/components/questionnaire/questionnaire.css +387 -0
  83. package/src/components/questionnaire/questionnaire.js +1033 -0
  84. package/src/components/select/field-adapter.js +9 -4
  85. package/src/components/select/select.css +144 -11
  86. package/src/components/select/select.js +259 -27
  87. package/src/components/sheet/sheet-stack.js +304 -0
  88. package/src/components/sheet/sheet.css +351 -0
  89. package/src/components/sheet/sheet.js +551 -0
  90. package/src/components/split-view/split-view.js +76 -161
  91. package/src/components/table/table.css +43 -0
  92. package/src/components/table/table.js +531 -52
  93. package/src/components/tooltip/tooltip.js +5 -2
  94. package/src/components/value-list/value-list.js +6 -3
  95. package/src/core/dom.js +322 -0
  96. package/src/core/drag-axis.js +203 -0
  97. package/src/core/position.js +68 -22
  98. package/src/index.js +20 -2
  99. package/src/internal/app-rail.js +718 -0
  100. package/src/zeyos/icons.js +8 -3
  101. package/src/zeyos/index.js +7 -1
  102. package/src/zeyos/launcher.js +338 -0
  103. package/src/zeyos/modules.js +1 -0
  104. package/src/zeyos/select.js +115 -1
  105. package/styles/tokens/dark.css +2 -3
  106. package/styles/tokens/global.css +6 -6
  107. package/styles/tokens/modules.css +1 -0
  108. package/styles/tokens/semantic.css +5 -3
  109. package/styles/tokens/themes.css +1 -1
  110. package/styles/zx.css +11 -1
  111. package/MIGRATION.md +0 -598
  112. package/dist/types/compat/base.d.ts +0 -156
  113. package/dist/types/compat/globals.d.ts +0 -20
  114. package/dist/types/compat/index.d.ts +0 -128
  115. package/dist/types/compat/map/basic.d.ts +0 -175
  116. package/dist/types/compat/map/data.d.ts +0 -102
  117. package/dist/types/compat/map/date-time.d.ts +0 -80
  118. package/dist/types/compat/map/factory.d.ts +0 -9
  119. package/dist/types/compat/map/form.d.ts +0 -98
  120. package/dist/types/compat/map/helpers.d.ts +0 -12
  121. package/dist/types/compat/map/http.d.ts +0 -36
  122. package/dist/types/compat/map/layout.d.ts +0 -106
  123. package/dist/types/compat/map/options.d.ts +0 -80
  124. package/dist/types/compat/map/select.d.ts +0 -95
  125. package/dist/types/compat/map/stubs.d.ts +0 -32
  126. package/dist/types/compat/map/utilities.d.ts +0 -37
  127. package/dist/types/compat-entry.d.ts +0 -5
  128. package/dist/types/components/permission/permission.d.ts +0 -96
  129. package/dist/zx-compat.esm.js +0 -17484
  130. package/dist/zx-compat.esm.min.js +0 -1
  131. package/dist/zx-compat.global.js +0 -23635
  132. package/dist/zx-compat.global.min.js +0 -3
  133. package/src/compat/base.js +0 -291
  134. package/src/compat/globals.js +0 -165
  135. package/src/compat/index.js +0 -84
  136. package/src/compat/map/basic.js +0 -464
  137. package/src/compat/map/data.js +0 -232
  138. package/src/compat/map/date-time.js +0 -177
  139. package/src/compat/map/factory.js +0 -45
  140. package/src/compat/map/form.js +0 -330
  141. package/src/compat/map/helpers.js +0 -46
  142. package/src/compat/map/http.js +0 -117
  143. package/src/compat/map/layout.js +0 -256
  144. package/src/compat/map/options.js +0 -267
  145. package/src/compat/map/select.js +0 -198
  146. package/src/compat/map/stubs.js +0 -26
  147. package/src/compat/map/utilities.js +0 -113
  148. package/src/compat-entry.js +0 -11
  149. package/src/components/permission/permission.css +0 -47
  150. package/src/components/permission/permission.js +0 -201
package/CHANGELOG.md CHANGED
@@ -8,6 +8,144 @@ and friends remain the complete record.
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ ## 4.0.0 — 2026-08-24
12
+
13
+ ### Added
14
+
15
+ - **`Card`.** A semantic, product-agnostic content and record surface with optional media, native
16
+ title link, secondary actions, footer metadata, three variants, horizontal/vertical layout, and
17
+ exact enhanced-target restoration. The root never impersonates a link or button, so nested
18
+ controls remain valid and independently keyboard-accessible.
19
+
20
+ ### Changed
21
+
22
+ - **One public application-navigation component.** `AppSidebar` now owns expanded vertical, minimized
23
+ vertical, and horizontal rail presentations over one active/branch state model. Descendants are
24
+ inline only while expanded and use pointer-, focus-, and keyboard-accessible flyouts in rail
25
+ states; its minimized renderer is an implementation detail, not a second public component.
26
+ - **Richer Select presets.** `Select.priority()` now uses the five-square ZeyOS scale;
27
+ `Select.status()` adds shape- and semantic-color-distinct workflow states; and the optional
28
+ `zeyosEntitySelect()` binding adds grouped remote records, module-colored icons, an explicit
29
+ empty choice, and application-owned command rows without changing the selected-ID contract.
30
+ - **Full launcher parity.** `Launcher` now distinguishes application tiles from record rows,
31
+ exposes current and pinned state, spatial keyboard movement, visible hints, query-state/source
32
+ ordering, and injected icon factories. The optional ZeyOS adapter maps all 29 prototype
33
+ applications, forks/weblets, cached or async recent records, and grouped abortable search while
34
+ leaving permissions, icons, destinations, and routing with the host application.
35
+ - The documentation now has a global destination search, a clearer uppercase green
36
+ Presets/Examples hierarchy, and product-agnostic Xenon positioning. The internal rollout guide
37
+ is no longer shipped or linked from public surfaces.
38
+
39
+ ### Removed
40
+
41
+ - **The separate `AppRail` constructor.** Use `AppSidebar` with `collapsed: true` for a vertical
42
+ rail or `orientation: 'horizontal'` for a horizontal rail. This completes the single-owner
43
+ navigation contract instead of maintaining two public root-DOM models.
44
+ - **Public gx compatibility entry points and bundles.** The compact `__()` DOM builder is part of
45
+ the Zx core; gx adapter source remains repository-internal and is no longer exported, built, or
46
+ included in the npm package.
47
+
48
+ ### Fixed
49
+
50
+ - Late Launcher sources preserve the current keyboard choice only while completing the same query;
51
+ a new query resets to its own best match.
52
+ - Card rejects control-obfuscated unsafe URL schemes; Launcher and every AppSidebar presentation
53
+ strip executable/data destinations and disable inert descriptors. AppSidebar also relocates focus,
54
+ emits its effective collapse state across layout changes, and releases obsolete mode listeners.
55
+ - Card restores an enhanced target after failed construction, releases callbacks when links or
56
+ actions are replaced, and keeps the full non-interactive body inside the primary-link target.
57
+ - Status shortcut hints now activate their options, async permission group loaders cannot be
58
+ disconnected by a filter override, and enhanced billing grids restore every target attribute.
59
+ - Billing totals now distinguish a missing operand from an explicit zero, and Chart renders a
60
+ consistent error state for falsy payloads and errors without a message.
61
+
62
+ ## 3.0.0 — 2026-08-24
63
+
64
+ ### Added
65
+
66
+ - **Xenon application shell components.** `Launcher` combines deterministic local ranking with
67
+ abortable grouped sources and a Cmd/Ctrl+K dialog; `Avatar` provides a stable initials fallback;
68
+ `AccountMenu` composes identity with an APG menu; `AppSidebar` is expanded vertical navigation;
69
+ and minimized `AppRail` keeps descendants in pointer-, focus-, and keyboard-accessible flyouts
70
+ for both vertical and horizontal placement. All route, permission, session, and persistence work
71
+ remains application-owned behind cancelable events.
72
+ - **`Grid` and `Grid.BillingItems()`.** The public Table specialization keeps every Table feature
73
+ while providing a conventional editable billing schema for currencies, units, line totals, and
74
+ flat parent rows. The default line formula is quantity × unit price; tax, discount, rounding,
75
+ subtotal, validation, and persistence policy remain caller-owned.
76
+ - **Engine-neutral `Chart` and injected `ChartJsAdapter`.** Chart owns responsive canvas lifecycle,
77
+ loading/empty/error states, Xenon theme defaults, point-selection events, and a synchronized
78
+ semantic data table. Chart.js 4.5.1 is pinned only as a development/documentation asset; the Zx
79
+ runtime has no chart import and no runtime dependency.
80
+ - **Lateral anchored-overlay placement.** `position()`, `Dropdown`, `MenuButton`, and `Tooltip` now
81
+ accept left/right start/end variants for rail and account surfaces.
82
+
83
+ - **`Questionnaire`** — a guided, one-question-at-a-time flow for onboarding intake, service
84
+ checklists, audits and surveys, where a `Form` full of fieldsets is the wrong shape. The root is
85
+ a real `<form>` and the choices are native radios and checkboxes carrying the item name, so
86
+ `new FormData(questionnaire.toElement())` reads the answers and the keyboard contract inside a
87
+ choice group is the browser's. Three things go beyond a stack of fieldsets: an item carries a
88
+ `when` predicate and a `next` target, so the flow **branches** — conditions cascade, an
89
+ abandoned branch's answers drop out of `getAnswers()`, progress counts the questions actually
90
+ reachable, and Back retraces the path walked rather than an array index; an item's answer control
91
+ can be **any registered `Field` type** (`field: {type: 'date'}`), which is what lets a question
92
+ ask for a date, a number, a rating or an upload; and `validate` may return a **promise**, so a
93
+ question can be gated on a server check. `review: true` adds a summary screen with jump-back-to-
94
+ edit, `advance: 'auto'` moves on by itself after a single choice, and `1`–`9`/`a`–`z` shortcuts
95
+ are assigned and shown on each answer.
96
+
97
+ - **`Sheet`** — an edge-anchored `Dialog` covering both side-sheet and mobile-drawer patterns;
98
+ the two differ only in which edge they take, so `side` (`'start' | 'end' | 'top' | 'bottom'`,
99
+ logical) replaces a second component. `modal` is three-way rather than a boolean because the
100
+ three real behaviours do not collapse into two: `true` hands focus containment, page inertness,
101
+ Escape and the backdrop to the browser via `showModal()`, while `'trap-focus'` and `false` open
102
+ non-modally and re-implement only what they still want. `backdrop: 'dim'|'blur'|'none'` applies
103
+ to modal sheets alone — `::backdrop` does not render for a non-modal dialog, and a painted
104
+ stand-in would make a non-blocking sheet look blocking. Entry **and exit** animate, which a
105
+ `<dialog>` normally cannot do, via `@starting-style` and `transition-behavior: allow-discrete`
106
+ on `display`/`overlay`. `resizable`, `snap` detents and swipe-to-dismiss are deliberately one
107
+ gesture whose meaning is decided when the pointer settles, so the sheet follows the pointer the
108
+ whole way instead of pinning at its minimum and then vanishing.
109
+ - **`SheetStack`** — several sheets as one drill-down. Small on purpose: nested dialogs already
110
+ stack in the top layer by open order and Escape already closes only the topmost, so no z-index
111
+ bookkeeping and no unwinding logic. `stack` slides covered sheets back, scales them down and
112
+ makes them `inert`; `cascade` shifts each clear of the ones in front by their **measured** size
113
+ so they sit side by side and all stay usable — usually the right one for an ERP screen, where
114
+ the parent record should stay readable while a line item is edited.
115
+ - **`Dock`** — a stack of collapsible, resizable panes: the docked inspector column of a design
116
+ tool, and the detail side of a master–detail screen. A pane is either titled or a **tab group**
117
+ whose strip replaces the title. Giving the dock a `content` turns it into a region with panes on
118
+ either `side` of it, and nesting one dock in another's pane gives a workbench. Sizes, collapsed
119
+ panes and active tabs persist through `storageKey`; content factories run on first reveal.
120
+ - **`Dock.adopt(sheet)`** — a dock can take over a `Sheet`'s positioning, so the sheet becomes a
121
+ track in the dock's flow instead of an overlay. A dock is a flex container by construction and
122
+ therefore always a valid host, which is why docking needs no arrangement from the application.
123
+ `dockAt` hands the sheet back to a free overlay below a breakpoint measured on the **dock's own
124
+ width**, so a dock inside a split pane behaves correctly where a viewport media query would not.
125
+ Nothing is rebuilt across the handoff: the element moves and reopens in place, so DOM state and
126
+ listeners survive and no `open`/`close` is emitted for what is only a change of address.
127
+ - **`--zx-overlay-blur`** — tier-2 semantic token behind `Sheet`'s `'blur'` backdrop, default `8px`.
128
+
129
+ ### Changed
130
+
131
+ - **`SplitView` now shares one axis-drag engine with `Sheet` and `Dock`**, extracted to
132
+ `core/drag-axis.js`: pointer capture, one write per frame, telling a click from a zero-distance
133
+ drag, and the WAI-ARIA keyboard map. Behaviour is unchanged. `resolveSize` moved to the kernel
134
+ and is re-exported from `split-view.js`, so every existing import keeps working.
135
+ - **`Modal` gained three protected seams** — `mountTarget()`, `_show()` and `_isRealClose()` — so a
136
+ subclass can live somewhere other than `document.body`, open non-modally, and re-host itself.
137
+ `Dialog`'s size application became the overridable `_applySize()`. No public behaviour changed.
138
+ - **The modal scroll lock keys off `:modal` rather than `[open]`**, so a non-modal dialog no longer
139
+ locks the page behind it. `Modal` and `Dialog` always open modally, so neither is affected.
140
+
141
+ ### Removed
142
+
143
+ - **`Permission` is removed**, not just deprecated. 2.3.0 kept the class around for
144
+ `gx.zeyos.Permission` while pointing new code at `Select.permission()`; there is no longer a
145
+ second implementation to keep in sync, and `gx.zeyos.Permission` now builds directly on
146
+ `Select.permission()` instead of wrapping the removed class. The legacy constructor, options,
147
+ `get()`/`set()`, and the `change` event are unchanged — only the `zx.Permission` export is gone.
148
+
11
149
  ## 2.3.0 — 2026-08-23
12
150
 
13
151
  ### Added
@@ -0,0 +1,96 @@
1
+ # Xenon Design System
2
+
3
+ Xenon is a product-agnostic design system for browser applications; Zx is its dependency-free
4
+ JavaScript implementation. It provides shared foundations, accessible components, interaction
5
+ patterns, and application layouts without taking ownership of an application's routing or domain
6
+ logic.
7
+
8
+ ## System boundary
9
+
10
+ Xenon has four layers:
11
+
12
+ 1. **Foundations** — semantic tokens, typography, spacing, density, themes, icons, motion, i18n,
13
+ accessibility rules, and the safe DOM kernel.
14
+ 2. **Components** — lifecycle-safe controls and containers with one options/events/destroy model.
15
+ 3. **Patterns** — repeatable business interactions such as global launch, account/preferences,
16
+ record detail, transaction entry, filtering, and empty/loading/error handling.
17
+ 4. **Application layouts** — rails, bars, workspaces, master/detail, dashboards, inboxes, wizards,
18
+ and responsive shell geometry.
19
+
20
+ This separation keeps foundations, components, patterns, and layouts independently reusable while
21
+ preserving a coherent API and visual language.
22
+
23
+ Zx has a generated API reference, live examples, bundled local icons, and no runtime dependency.
24
+ Its compact `__()` DOM builder and pure append/property/event helpers let established applications
25
+ adopt the system without introducing a framework runtime. Domain policy, transport, persistence,
26
+ and navigation remain application-owned.
27
+
28
+ ## Coverage ledger
29
+
30
+ | Front-end capability | Xenon/Zx status | Design-system boundary |
31
+ | --- | --- | --- |
32
+ | Buttons, inputs, toggles, dates, selects, checklists, tags | Covered by public components | Components preserve native semantics and expose consistent value/event contracts. |
33
+ | Forms and fieldsets | Covered, including component-backed field adapters | Use for record editors; keep validation/business rules application-owned. |
34
+ | Dialogs, sheets, dropdowns, context menus, tooltips, messages | Covered | Consolidate duplicate menu behavior before building account/launcher surfaces. |
35
+ | Tabs, panels, toolbar, breadcrumbs, stepper, split view, dock | Covered | Compose layouts; do not let navigation components own routes. |
36
+ | Sorting, selection, filtering, pagination, trees/finder | Covered | Suitable for generic data screens. |
37
+ | 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. |
38
+ | Global launcher/search | Covered | `Launcher` combines an application grid, current/pinned state, recent records, and abortable grouped sources. The optional ZeyOS adapter maps the complete 29-app shell catalogue while the host retains permissions, icons, and routing. |
39
+ | Account/profile/preferences menu | Covered at presentation level | `Avatar` and `AccountMenu` provide identity and action UI. The host supplies permitted actions and owns preferences, authentication, and logout. |
40
+ | Persistent app rail / side navigation | Covered | One route-agnostic `AppSidebar` owns expanded, minimized, and horizontal presentations. Only expanded vertical branches render inline; every rail presentation uses flyouts. |
41
+ | 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. |
42
+ | Local product/module icons | Partial | Use bundled icons or registered local assets; do not require the optional remote Font Awesome kit. |
43
+ | Domain entity selectors/cards/links | Covered at generic presentation level | `Card` provides media, native primary links, secondary actions, and metadata; applications own entity routing and policy. |
44
+ | Persistent notification/activity center | Missing, lower priority | `Message` covers ephemeral feedback, not read/unread activity history. |
45
+
46
+ ### Launcher contract
47
+
48
+ The launcher searches applications, recent records, and grouped remote record types. The generic
49
+ component supplies the tile/list layouts, pinned-order ranking, current-route marker, request
50
+ cancellation, spatial keyboard movement, visible keyboard hints, native link metadata, and a
51
+ cancelable action. The optional ZeyOS adapter accepts all 29 prototype modules plus forks and
52
+ weblets, cached or async recent items, grouped legacy search payloads, permission/current state,
53
+ and host icon renderers. All state is injected; the adapter reads no shell globals and deliberately
54
+ does not become a second router.
55
+
56
+ ### Account contract
57
+
58
+ A typical account surface includes identity, role-dependent links, language, authentication and
59
+ logout, preferences, and About/version content. `AccountMenu` composes `Avatar` with the existing
60
+ menu behavior and emits actions without owning routes or session state. The host decides which
61
+ actions exist and what each one does.
62
+
63
+ ## Table and transaction follow-ups
64
+
65
+ The enhanced `Table` now keeps values numeric while formatting per-row locales, currencies, units,
66
+ and decimals; numeric types infer `NumberField` editors. Flat `parentId` data is projected into a
67
+ cycle-safe ARIA treegrid with local sibling sorting and expand/collapse APIs.
68
+
69
+ `Grid.BillingItems()` now packages the conventional description, quantity, unit, unit-price,
70
+ currency, line-total, and hierarchy schema while retaining Table's editing contract. Useful
71
+ follow-ups, deliberately separate from this generic preset:
72
+
73
+ - summary/footer rows and grouped subtotals;
74
+ - column reorder and user-persisted column state;
75
+ - product-specific invoice/transaction presets with tax, discount, rounding, and formula golden tests;
76
+ - server persistence, optimistic rejection, and undo owned by the application/controller layer.
77
+
78
+ ## Chart-engine candidates
79
+
80
+ Chart.js was selected for the first adapter. It is pinned at 4.5.1 as a development dependency for
81
+ tests and the documentation asset, but is never imported by Zx runtime source. Applications inject
82
+ their chosen engine into the adapter. Published browser artifact sizes below are approximate and
83
+ remain useful when choosing a different future adapter.
84
+
85
+ | Engine | Current state at audit | Approx. browser cost | Best fit | Main trade-off |
86
+ | --- | --- | ---: | --- | --- |
87
+ | [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. |
88
+ | [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. |
89
+ | [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. |
90
+ | [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. |
91
+
92
+ Implemented architecture: `Chart` accepts an injected engine adapter, maps Xenon semantic tokens,
93
+ owns loading/empty/error states, and mirrors its data in an accessible table. Chart.js is the broad
94
+ default adapter; Frappe Charts remains the lean ERP-oriented alternative, uPlot a specialized
95
+ time-series candidate, and ECharts an opt-in advanced adapter. Any additional package still
96
+ requires explicit dependency approval.
package/README.md CHANGED
@@ -1,10 +1,13 @@
1
- # Zx
1
+ # Xenon Design System (Zx)
2
2
 
3
- Zx is the dependency-free, vanilla-JavaScript component library for ZeyOS business applications:
4
- ES2022 modules, accessible native controls, semantic design tokens, and lifecycle-safe components.
5
- Source modules run directly in a browser; the distribution also provides ESM and classic-script
6
- bundles. An opt-in compatibility layer keeps existing MooTools-era `gx` code running while it is
7
- modernised.
3
+ Xenon is a dependency-free design system for browser applications; Zx is its vanilla-JavaScript
4
+ implementation. It combines foundations, accessible components, repeatable workflow patterns,
5
+ and application layouts in plain ES2022 modules. Source modules run directly in a browser; the
6
+ distribution also provides ESM and classic-script bundles. Xenon originated at ZeyOS, while its
7
+ components and contracts remain product- and framework-agnostic.
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
 
@@ -38,15 +41,15 @@ For an application built from classic scripts, the IIFE bundle exposes the same
38
41
  </script>
39
42
  ```
40
43
 
41
- Import one component instead of the library when a bundler is doing the work:
44
+ Import a component source module directly when a bundler needs the narrowest possible graph:
42
45
 
43
46
  ```js
44
47
  import { Slider } from '@zeyos/zx/src/components/slider/slider.js';
45
48
  ```
46
49
 
47
- An application using two components bundles 26 kB minified this way against 157 kB through the
48
- package entry point. Load the one stylesheet either way — it is 13 kB gzipped whole, and splitting
49
- it per component costs more than it saves.
50
+ The package also exposes the bundled ESM entry for ordinary named imports. Load the complete
51
+ stylesheet either way: it contains the shared tokens and cross-component states that make the
52
+ system coherent, while JavaScript can still be tree-shaken or imported component by component.
50
53
 
51
54
  TypeScript definitions ship with the package. They are generated from the JSDoc that documents
52
55
  every option, method, and event, so `new Slider(null, { … })` is checked against `SliderOptions`
@@ -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
- | `Select` | APG combobox with local or async filtering and a priority preset. |
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 items, priority/status/permission presets, and an optional ZeyOS entity picker. |
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` | Semantic sortable table with local/server sorting, row selection, and opt-in inline cell/row editing. |
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. |
@@ -150,10 +158,12 @@ ZeyOS binding — see `src/zeyos/modules.js`.
150
158
  | API | Description |
151
159
  | --- | --- |
152
160
  | `Groupbox` | Collapsible section backed by native `<details>`. |
161
+ | `Card` | Semantic content/record surface with media, native title link, actions, and footer. |
153
162
  | `Panel` | Framed, optionally collapsible section with a footer. |
154
163
  | `MasterPanel` | Full-height application panel with fixed header actions and footer. |
155
164
  | `Tabbox` | APG tabs in four appearances, with lazy content, closing, badges, and disabled states. |
156
165
  | `NavigationBar` | Responsive application navigation with optional tab panels and overflow. |
166
+ | `AppSidebar` | Expanded or minimized vertical application navigation plus horizontal rails; descendants are inline only while expanded. |
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 single development dependency and start the no-build demo server:
286
+ Install the development toolchain and start the no-build demo server:
277
287
 
278
288
  ```sh
279
289
  npm install
@@ -287,7 +297,7 @@ classic-script distribution tests.
287
297
 
288
298
  ```sh
289
299
  npm test # Node unit tests plus semantic-token lint
290
- npm run build # writes ESM, global, compatibility, and CSS assets to dist/
300
+ npm run build # writes ESM, ZeyOS, global, CSS, and declaration assets to dist/
291
301
  npm run build:site # assembles the deployable documentation site into site/
292
302
  npm run serve:site # serves site/ exactly as it will be deployed
293
303
  ```
@@ -303,27 +313,7 @@ import { Table, Message } from '@zeyos/zx';
303
313
  import '@zeyos/zx/zx.css';
304
314
  ```
305
315
 
306
- Additional entry points: `@zeyos/zx/zeyos` (the schema-driven ZeyOS binding), `@zeyos/zx/compat`
307
- (the gx compatibility namespace), and `@zeyos/zx/global` for classic script tags.
308
-
309
- Documentation lives at <https://zx.zeyos.com>; see `docs/RELEASING.md` for how the site and the
310
- package are published.
311
-
312
- ## `gx` compatibility layer
313
-
314
- During an incremental migration, load the global API before the compatibility bundle:
315
-
316
- ```html
317
- <link rel="stylesheet" href="/assets/zx.css">
318
- <script src="/assets/zx.global.js"></script>
319
- <script src="/assets/zx-compat.global.js"></script>
320
- <script>
321
- // Only when old code relies on __(), _(), or prototype conveniences:
322
- gx.compat.installGlobals();
323
- </script>
324
- ```
316
+ Additional entry points: `@zeyos/zx/zeyos` (the schema-driven ZeyOS binding) and
317
+ `@zeyos/zx/global` for classic script tags.
325
318
 
326
- The compatibility bundle always exposes `window.gx` and installs only the element
327
- `store`/`retrieve`/`eliminate` shim automatically. Legacy globals and prototype conveniences are
328
- an explicit opt-in through `gx.compat.installGlobals()`. See [MIGRATION.md](./MIGRATION.md) for
329
- class mappings, script replacement, deliberate behavior changes, and unsupported legacy APIs.
319
+ Documentation lives at <https://zx.zeyos.com>.
@@ -0,0 +1,144 @@
1
+ import { Component } from '../../core/component.js';
2
+ import { Avatar } from '../avatar/avatar.js';
3
+ import { MenuButton } from '../menu-button/menu-button.js';
4
+ export type MenuButtonItem = import('../menu-button/menu-button.js').MenuButtonItem;
5
+ export type AccountIdentity = {
6
+ /**
7
+ * Primary identity.
8
+ */
9
+ name?: string;
10
+ /**
11
+ * Email, company, or other secondary identity.
12
+ */
13
+ secondary?: string;
14
+ /**
15
+ * Avatar image URL.
16
+ */
17
+ src?: string | null;
18
+ /**
19
+ * Explicit avatar initials.
20
+ */
21
+ initials?: string | null;
22
+ /**
23
+ * Presence state.
24
+ */
25
+ status?: 'online' | 'away' | 'busy' | 'offline' | null;
26
+ /**
27
+ * Presence text alternative.
28
+ */
29
+ statusLabel?: string | null;
30
+ };
31
+ export type AccountMenuOptions = {
32
+ /**
33
+ * Account presentation supplied by the application.
34
+ */
35
+ account?: AccountIdentity;
36
+ /**
37
+ * Account actions and `'-'` separators.
38
+ */
39
+ items?: MenuButtonItem[];
40
+ /**
41
+ * Whether only the avatar is visually shown in the trigger.
42
+ */
43
+ compact?: boolean;
44
+ /**
45
+ * Trigger label; defaults to `Account menu for <name>`.
46
+ */
47
+ label?: string | null;
48
+ /**
49
+ * Popup placement.
50
+ */
51
+ placement?: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end' | 'bottom' | 'top' | 'right-start' | 'right-end' | 'left-start' | 'left-end' | 'right' | 'left';
52
+ /**
53
+ * Preventable action listener.
54
+ */
55
+ onselect?: (event: CustomEvent<{
56
+ value: unknown;
57
+ item: object;
58
+ }>) => void;
59
+ /**
60
+ * Open listener.
61
+ */
62
+ onopen?: (event: CustomEvent<Record<string, never>>) => void;
63
+ /**
64
+ * Close listener.
65
+ */
66
+ onclose?: (event: CustomEvent<Record<string, never>>) => void;
67
+ };
68
+ /** @typedef {import('../menu-button/menu-button.js').MenuButtonItem} MenuButtonItem */
69
+ /**
70
+ * @typedef {Object} AccountIdentity
71
+ * @property {string} [name=''] Primary identity.
72
+ * @property {string} [secondary=''] Email, company, or other secondary identity.
73
+ * @property {string|null} [src=null] Avatar image URL.
74
+ * @property {string|null} [initials=null] Explicit avatar initials.
75
+ * @property {'online'|'away'|'busy'|'offline'|null} [status=null] Presence state.
76
+ * @property {string|null} [statusLabel=null] Presence text alternative.
77
+ */
78
+ /**
79
+ * @typedef {Object} AccountMenuOptions
80
+ * @property {AccountIdentity} [account={}] Account presentation supplied by the application.
81
+ * @property {MenuButtonItem[]} [items=[]] Account actions and `'-'` separators.
82
+ * @property {boolean} [compact=false] Whether only the avatar is visually shown in the trigger.
83
+ * @property {string|null} [label=null] Trigger label; defaults to `Account menu for <name>`.
84
+ * @property {'bottom-start'|'bottom-end'|'top-start'|'top-end'|'bottom'|'top'|'right-start'|'right-end'|'left-start'|'left-end'|'right'|'left'} [placement='top-start'] Popup placement.
85
+ * @property {(event: CustomEvent<{value: unknown, item: object}>) => void} [onselect] Preventable action listener.
86
+ * @property {(event: CustomEvent<Record<string, never>>) => void} [onopen] Open listener.
87
+ * @property {(event: CustomEvent<Record<string, never>>) => void} [onclose] Close listener.
88
+ */
89
+ /**
90
+ * Avatar-backed APG account action menu; session/authentication behavior remains application-owned.
91
+ * @fires AccountMenu#select
92
+ * @fires AccountMenu#open
93
+ * @fires AccountMenu#close
94
+ * @extends {Component<AccountMenuOptions>}
95
+ */
96
+ export declare class AccountMenu extends Component<AccountMenuOptions> {
97
+ _avatar: Avatar;
98
+ _menu: MenuButton;
99
+ _createdRoot: boolean;
100
+ _original: {
101
+ attributes: string[][];
102
+ children: ChildNode[];
103
+ };
104
+ _account: AccountIdentity & {
105
+ name: string;
106
+ secondary: string;
107
+ };
108
+ static cssName: string;
109
+ /** @type {Readonly<AccountMenuOptions>} */
110
+ static defaults: Readonly<AccountMenuOptions>;
111
+ /**
112
+ * Creates or enhances an account-menu host.
113
+ * @param {Element|string|null} target Host target.
114
+ * @param {AccountMenuOptions} [options={}] Account-menu options.
115
+ */
116
+ constructor(target?: Element | string | null, options?: AccountMenuOptions);
117
+ /** @returns {HTMLElement} */
118
+ render(): HTMLElement;
119
+ /** Opens the account menu. @returns {this} */
120
+ open(): this;
121
+ /** Closes the account menu. @returns {this} */
122
+ close(): this;
123
+ /** Toggles the account menu. @returns {this} */
124
+ toggle(): this;
125
+ /** Reports whether the menu is open. @returns {boolean} */
126
+ isOpen(): boolean;
127
+ /** Replaces account presentation without touching session state. @param {AccountIdentity} account @returns {this} */
128
+ setAccount(account: AccountIdentity): this;
129
+ /** Replaces account actions. @param {MenuButtonItem[]} items @returns {this} */
130
+ setItems(items: MenuButtonItem[]): this;
131
+ /** Focuses the account trigger. @returns {this} */
132
+ focus(): this;
133
+ /** Returns the underlying menu panel for shell hover/focus coordination. @returns {HTMLElement} */
134
+ getPanel(): HTMLElement;
135
+ /** Destroys child components and restores/removes the host. @returns {void} */
136
+ destroy(): void;
137
+ /** @returns {void} */
138
+ _renderIdentity(): void;
139
+ /** @returns {void} */
140
+ _renderPanelHeader(): void;
141
+ }
142
+ /** Fired when an action is activated. @event AccountMenu#select @type {CustomEvent<{value: unknown, item: object}>} */
143
+ /** Fired after the popup opens. @event AccountMenu#open @type {CustomEvent<Record<string, never>>} */
144
+ /** Fired after the popup closes. @event AccountMenu#close @type {CustomEvent<Record<string, never>>} */