@zeyos/zx 4.3.4 → 4.4.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 +155 -0
- package/README.md +7 -0
- package/dist/types/components/activity-item/activity-item.d.ts +351 -0
- package/dist/types/components/activity-list/activity-list.d.ts +195 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +28 -0
- package/dist/types/components/button/button.d.ts +8 -0
- package/dist/types/components/calendar/calendar.d.ts +19 -0
- package/dist/types/components/card/card.d.ts +7 -0
- package/dist/types/components/card-view/card-view.d.ts +11 -3
- package/dist/types/components/card-view/record-card.d.ts +7 -1
- package/dist/types/components/code-editor/code-editor.d.ts +160 -0
- package/dist/types/components/code-editor/field-adapter.d.ts +5 -0
- package/dist/types/components/context-menu/context-menu.d.ts +18 -2
- package/dist/types/components/date-picker/date-picker.d.ts +8 -0
- package/dist/types/components/date-picker/time-picker.d.ts +7 -0
- package/dist/types/components/dialog/dialog.d.ts +29 -0
- package/dist/types/components/entity-ref/entity-ref.d.ts +331 -0
- package/dist/types/components/file-item/file-item.d.ts +234 -0
- package/dist/types/components/file-list/file-list.d.ts +171 -0
- package/dist/types/components/filter/filter.d.ts +91 -36
- package/dist/types/components/filter-panel/filter-panel.d.ts +449 -0
- package/dist/types/components/kanban-view/kanban-card.d.ts +138 -0
- package/dist/types/components/kanban-view/kanban-view.d.ts +170 -4
- package/dist/types/components/launcher/launcher.d.ts +19 -12
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +599 -0
- package/dist/types/components/menu-button/menu-button.d.ts +4 -37
- package/dist/types/components/message/message.d.ts +7 -0
- package/dist/types/components/modal/modal.d.ts +48 -0
- package/dist/types/components/navigation-bar/navigation-bar.d.ts +105 -21
- package/dist/types/components/panel/panel.d.ts +7 -0
- package/dist/types/components/search/search.d.ts +7 -0
- package/dist/types/components/select/select.d.ts +4 -0
- package/dist/types/components/sort-control/sort-control.d.ts +105 -0
- package/dist/types/components/stat-tile/stat-tile.d.ts +277 -0
- package/dist/types/components/tabbox/tabbox.d.ts +7 -0
- package/dist/types/components/table/table.d.ts +144 -0
- package/dist/types/components/table-view/table-view.d.ts +11 -5
- package/dist/types/components/timebox/timebox.d.ts +7 -0
- package/dist/types/components/value-list/value-list.d.ts +8 -0
- package/dist/types/components/view/record-view.d.ts +96 -5
- package/dist/types/core/icons.d.ts +17 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/internal/app-rail.d.ts +10 -0
- package/dist/types/internal/menu-items.d.ts +134 -0
- package/dist/zx-zeyos.esm.js +616 -77
- package/dist/zx-zeyos.esm.min.js +8 -1
- package/dist/zx.css +2085 -238
- package/dist/zx.esm.js +6704 -1542
- package/dist/zx.esm.min.js +10 -3
- package/dist/zx.global.js +6704 -1542
- package/dist/zx.global.min.js +10 -3
- package/dist/zx.min.css +1 -1
- package/docs/api.json +1479 -127
- package/docs/llms.md +315 -10
- package/docs/llms.txt +11 -5
- package/package.json +1 -1
- package/src/components/activity-item/activity-item.css +137 -0
- package/src/components/activity-item/activity-item.js +599 -0
- package/src/components/activity-list/activity-list.css +64 -0
- package/src/components/activity-list/activity-list.js +375 -0
- package/src/components/app-rail/app-rail.css +227 -19
- package/src/components/app-sidebar/app-sidebar.css +414 -24
- package/src/components/app-sidebar/app-sidebar.js +65 -5
- package/src/components/button/button.css +8 -0
- package/src/components/button/button.js +6 -1
- package/src/components/calendar/calendar.js +33 -3
- package/src/components/card/card.js +12 -1
- package/src/components/card-view/card-view.css +1 -0
- package/src/components/card-view/card-view.js +25 -9
- package/src/components/card-view/record-card.js +7 -3
- package/src/components/code-editor/code-editor.css +67 -0
- package/src/components/code-editor/code-editor.js +288 -0
- package/src/components/code-editor/field-adapter.js +34 -0
- package/src/components/context-menu/context-menu.css +80 -3
- package/src/components/context-menu/context-menu.js +22 -30
- package/src/components/date-picker/date-picker.js +22 -8
- package/src/components/date-picker/month-picker.js +3 -3
- package/src/components/date-picker/time-picker.js +20 -8
- package/src/components/dialog/dialog.js +88 -66
- package/src/components/dropdown/dropdown.js +2 -2
- package/src/components/entity-ref/entity-ref.css +182 -0
- package/src/components/entity-ref/entity-ref.js +496 -0
- package/src/components/file-item/file-item.css +88 -0
- package/src/components/file-item/file-item.js +371 -0
- package/src/components/file-list/file-list.css +51 -0
- package/src/components/file-list/file-list.js +320 -0
- package/src/components/filter/filter.css +27 -1
- package/src/components/filter/filter.js +199 -45
- package/src/components/filter-panel/filter-panel.css +104 -0
- package/src/components/filter-panel/filter-panel.js +964 -0
- package/src/components/kanban-view/kanban-card.js +239 -0
- package/src/components/kanban-view/kanban-view.css +194 -0
- package/src/components/kanban-view/kanban-view.js +251 -8
- package/src/components/launcher/launcher.js +59 -27
- package/src/components/list-toolbar/list-toolbar.css +189 -0
- package/src/components/list-toolbar/list-toolbar.js +851 -0
- package/src/components/menu-button/menu-button.css +80 -3
- package/src/components/menu-button/menu-button.js +21 -37
- package/src/components/message/message.css +5 -2
- package/src/components/message/message.js +13 -2
- package/src/components/modal/modal.css +15 -0
- package/src/components/modal/modal.js +141 -0
- package/src/components/navigation-bar/navigation-bar.css +77 -2
- package/src/components/navigation-bar/navigation-bar.js +171 -4
- package/src/components/panel/panel.js +13 -2
- package/src/components/search/search.js +17 -5
- package/src/components/select/field-adapter.js +4 -1
- package/src/components/select/select.js +3 -0
- package/src/components/sort-control/sort-control.css +17 -0
- package/src/components/sort-control/sort-control.js +140 -0
- package/src/components/stat-tile/stat-tile.css +213 -0
- package/src/components/stat-tile/stat-tile.js +590 -0
- package/src/components/tabbox/tabbox.js +12 -1
- package/src/components/table/table.css +51 -2
- package/src/components/table/table.js +298 -19
- package/src/components/table-view/table-view.css +8 -2
- package/src/components/table-view/table-view.js +21 -6
- package/src/components/tag-picker/tag-picker.css +3 -1
- package/src/components/timebox/timebox.js +18 -5
- package/src/components/value-list/value-list.js +22 -6
- package/src/components/view/record-view.css +5 -0
- package/src/components/view/record-view.js +100 -7
- package/src/core/icons.js +74 -5
- package/src/index.js +25 -0
- package/src/internal/app-rail.js +19 -1
- package/src/internal/menu-items.js +142 -0
- package/styles/print.css +192 -0
- package/styles/zx.css +11 -0
package/docs/llms.md
CHANGED
|
@@ -101,6 +101,13 @@ Define a product theme by overriding **semantic** tokens under a `[data-zx-theme
|
|
|
101
101
|
`--zx-green-*`) or raw color literals in application/component CSS. Prefer the least-specific
|
|
102
102
|
override that works (global token → then, if needed, a component style).
|
|
103
103
|
|
|
104
|
+
**Print.** `zx.css` imports `styles/print.css` last. It releases sticky headers and scroll
|
|
105
|
+
containers, drops fills, shadows, zebra striping and focus rings, hides overlays and navigation
|
|
106
|
+
chrome, repeats table headers across pages, keeps cards and rows from breaking, and prints link
|
|
107
|
+
URLs in prose but never inside a table cell or on a button. Status badges keep their colour,
|
|
108
|
+
because there it carries meaning beside the word. An application that pins `data-zx-theme="dark"`
|
|
109
|
+
still prints the dark token set; `auto` resolves to light under `@media print` and is unaffected.
|
|
110
|
+
|
|
104
111
|
## Talking to ZeyOS — use `@zeyos/client`
|
|
105
112
|
|
|
106
113
|
For ZeyOS business data use the **dedicated client library** `@zeyos/client`
|
|
@@ -271,6 +278,9 @@ accept.
|
|
|
271
278
|
|
|
272
279
|
- **`button(options)`** → `HTMLButtonElement`. Options: `label`, `icon` (an icon name), `kind:
|
|
273
280
|
'default'|'primary'|'danger'|'ghost'`, `size: 'md'|'sm'`, `disabled`, `title`, `onclick`.
|
|
281
|
+
- **Shortcut hints** — `shortcut: {label:'N', keys:'N'}` adds a visible key hint, hover text and
|
|
282
|
+
`aria-keyshortcuts`. The host binds the action and owns editing/modality/permission guards;
|
|
283
|
+
a hint never installs a global handler. Dialog and Sheet footer descriptors accept it too.
|
|
274
284
|
- **`buttonGroup([button(…), …])`** → a container that joins the buttons into one control.
|
|
275
285
|
<!-- /doc -->
|
|
276
286
|
|
|
@@ -521,6 +531,106 @@ announced twice.
|
|
|
521
531
|
status, not the account's accessible name; supply `statusLabel` when it conveys information.
|
|
522
532
|
<!-- /doc -->
|
|
523
533
|
|
|
534
|
+
<!-- doc:entity-ref -->
|
|
535
|
+
### EntityRef
|
|
536
|
+
|
|
537
|
+
Dense record identity for table cells, feeds, selectors, and detail metadata. It owns presentation
|
|
538
|
+
and safe native interaction semantics; the application injects routes, permissions, context menus,
|
|
539
|
+
and record mutations.
|
|
540
|
+
|
|
541
|
+
- **Options** — `id`, `title`, `subtitle` (text, Node, or Component), `icon` (name, Node,
|
|
542
|
+
Component, or lazy renderer), `metadata: [{label,value,icon?,showLabel?}]`, `link` (a URL or
|
|
543
|
+
`{href,target?,rel?,download?,onclick?}`), `actions`, `size: 'sm'|'md'|'lg'`, `wrap: false`, and
|
|
544
|
+
`actionsLabel`.
|
|
545
|
+
- **Actions** — an action is a caller-owned Element or
|
|
546
|
+
`{id,label?,icon?,title?,href?,target?,rel?,kind?,disabled?,onselect?}`. Descriptors with `href`
|
|
547
|
+
remain native anchors; others are buttons. Executable destinations are discarded, `_blank`
|
|
548
|
+
gains `noopener`, and an icon-only action requires `title`.
|
|
549
|
+
- **Methods** — `set(values)`, `setMetadata()`, `setActions()`, `setLink()`, `getEntity()`,
|
|
550
|
+
`focus()`, and `destroy()`.
|
|
551
|
+
- **Events** — cancelable `activate {id,entity,href,event}` before a primary-link callback/native
|
|
552
|
+
navigation and `action {id,action,entity,event}` before an action callback/navigation. The
|
|
553
|
+
bubbling `zx-*` mirrors may cancel the same boundary.
|
|
554
|
+
- **Accessibility** — metadata is a definition list; `showLabel:false` clips its label visually
|
|
555
|
+
while keeping it available to assistive technology. Identity links and secondary controls keep
|
|
556
|
+
native keyboard and modifier-click behavior.
|
|
557
|
+
<!-- /doc -->
|
|
558
|
+
|
|
559
|
+
<!-- doc:file-item -->
|
|
560
|
+
### FileItem
|
|
561
|
+
|
|
562
|
+
A durable or transient file row composed from `EntityRef`, MIME/byte-size metadata, lifecycle
|
|
563
|
+
status, and accessible progress. It never starts a transfer, decides authorization, resolves a
|
|
564
|
+
preview, or persists a file.
|
|
565
|
+
|
|
566
|
+
- **Options** — `id`, `name`, `size` (bytes), `mime`, `subtitle`, `icon: 'file'`, additional
|
|
567
|
+
`metadata`, safe native `link`, `actions`, status (`ready` | `temporary` | `waiting` |
|
|
568
|
+
`uploading` | `processing` | `success` | `error`), `statusLabel`, `progress` (0–100), `indeterminate`,
|
|
569
|
+
`density: 'sm'|'md'|'lg'`, `wrap`, `actionsLabel`, and `locale`.
|
|
570
|
+
- **Methods** — `set(values)`, `setStatus(status,label?)`,
|
|
571
|
+
`setProgress(percent|null,{indeterminate?})`, `getFile()`, `focus()`, and `destroy()`.
|
|
572
|
+
- **Events** — cancelable `activate {id,file,href,event}` and
|
|
573
|
+
`action {id,fileId,action,file,event}`. Cancellation propagates to the composed EntityRef, so it
|
|
574
|
+
suppresses callbacks and navigation rather than merely observing them.
|
|
575
|
+
- **Progress** — determinate work exposes min/max/now and percentage text. Indeterminate work
|
|
576
|
+
omits `aria-valuenow`; status changes are announced separately.
|
|
577
|
+
<!-- /doc -->
|
|
578
|
+
|
|
579
|
+
<!-- doc:file-list -->
|
|
580
|
+
### FileList
|
|
581
|
+
|
|
582
|
+
An accessible ordered collection of `FileItem` rows with loading and empty presentations.
|
|
583
|
+
Explicit duplicate file IDs are rejected; source order is preserved.
|
|
584
|
+
|
|
585
|
+
- **Options** — `items`, `label: 'Files'`, `loading`, `loadingCount: 3`,
|
|
586
|
+
`loadingText: 'Loading files'`, and `emptyText: 'No files'` (text, Node, or Component).
|
|
587
|
+
- **Methods** — `setItems(items,{silent?})`, `getItems()`, `getItem(id)`,
|
|
588
|
+
`addItem(item,index?,{silent?})`, `updateItem(id,values,{silent?})`,
|
|
589
|
+
`removeItem(id,{silent?})`, `setLoading()`, and `destroy()`.
|
|
590
|
+
- **Events** — cancelable `activate {id,index,file,href,event}` and
|
|
591
|
+
`action {id,fileId,index,action,file,event}`, plus `datachange {items}` after a collection
|
|
592
|
+
mutation. Returned items are defensive snapshots.
|
|
593
|
+
<!-- /doc -->
|
|
594
|
+
|
|
595
|
+
<!-- doc:activity-item -->
|
|
596
|
+
### ActivityItem
|
|
597
|
+
|
|
598
|
+
One chronological activity entry. It owns actor/avatar anatomy, semantic time, safe content slots,
|
|
599
|
+
attachments, and actions; the application owns posting, reactions, permissions, routing,
|
|
600
|
+
persistence, and sanitization before any rich content becomes a Node.
|
|
601
|
+
|
|
602
|
+
- **Options** — `id`, `actor`, `avatar` (Avatar options or Element), `title`, `content`,
|
|
603
|
+
`timestamp`, `timeLabel`, `metadata`, `attachments`, `actions`, `kind`, and
|
|
604
|
+
`headingLevel: 1..6`. Content slots accept text, Nodes, or Components and never parse HTML.
|
|
605
|
+
- **Actions** — Elements pass through; descriptors accept
|
|
606
|
+
`{id,label?,icon?,href?,target?,rel?,title?,disabled?,kind?,onselect?}`. Unsafe links and unnamed
|
|
607
|
+
icon-only controls are omitted.
|
|
608
|
+
- **Methods** — `setActivity(values)`, `getActivity()`, and `destroy()`.
|
|
609
|
+
- **Events** — cancelable `action {id,action,event}` before a callback or native navigation; its
|
|
610
|
+
bubbling `zx-action` mirror can cancel the same boundary.
|
|
611
|
+
- **Accessibility** — an entry is a native list item containing an article and semantic heading;
|
|
612
|
+
valid timestamps use `<time datetime>`, while display-only labels remain ordinary text.
|
|
613
|
+
<!-- /doc -->
|
|
614
|
+
|
|
615
|
+
<!-- doc:activity-list -->
|
|
616
|
+
### ActivityList
|
|
617
|
+
|
|
618
|
+
An accessible chronological ordered collection with stable grouping, loading/empty states, and
|
|
619
|
+
incremental host-controlled mutation. It deliberately preserves source order instead of guessing
|
|
620
|
+
whether a feed is newest- or oldest-first.
|
|
621
|
+
|
|
622
|
+
- **Options** — `items`, `groupBy` (property, resolver, or null), `groupLabel`,
|
|
623
|
+
`label: 'Activity'`, `loading`, `loadingCount: 3`, `loadingText`, `emptyText`,
|
|
624
|
+
`groupHeadingLevel`, and `itemHeadingLevel`.
|
|
625
|
+
- **Methods** — `setItems(items,{silent?})`, `getItems()`, `getItem(id)`,
|
|
626
|
+
`appendItems(items,{silent?})`, `prependItems(items,{silent?})`,
|
|
627
|
+
`updateItem(id,values,{silent?})`, `removeItem(id,{silent?})`, `setLoading()`, and `destroy()`.
|
|
628
|
+
- **Events** — `datachange {items}` after mutation. Each child's cancelable `zx-action` bubbles
|
|
629
|
+
naturally through the list for delegated application handling.
|
|
630
|
+
- **Grouping** — groups keep first-seen group order and item source order. The exported pure
|
|
631
|
+
`groupActivityItems()` and `normalizeActivityItems()` helpers do not mutate caller arrays.
|
|
632
|
+
<!-- /doc -->
|
|
633
|
+
|
|
524
634
|
<!-- doc:account-menu -->
|
|
525
635
|
### AccountMenu
|
|
526
636
|
|
|
@@ -547,6 +657,7 @@ Unifies single-select, local filtering, and async loading.
|
|
|
547
657
|
- **Options** — `items: []`, `fixedItems: []`, optional `fixedLabel`, `valueKey: 'ID'` (string key or `(item)=>id`),
|
|
548
658
|
`labelKey: 'name'` (string or `(item)=>string`), `renderItem`, `renderValue`,
|
|
549
659
|
`renderValueAdornment`, `renderNone`, `noneLabel`, `actions`, `value`, `disabled`, `placeholder`,
|
|
660
|
+
`label` (accessible combobox name; defaults to the placeholder or "Select"),
|
|
550
661
|
`clearable: false`, `filter: false | 'local' | async (query)=>items`, `searchKeys`,
|
|
551
662
|
`minQuery: 0`, `debounce: 200`, `listHeight: 280`, `groupKey`.
|
|
552
663
|
- **Getters** — `.value`, `.selected`.
|
|
@@ -577,6 +688,25 @@ Unifies single-select, local filtering, and async loading.
|
|
|
577
688
|
(readonly). `aria-activedescendant` tracks the active option.
|
|
578
689
|
<!-- /doc -->
|
|
579
690
|
|
|
691
|
+
<!-- doc:sort-control -->
|
|
692
|
+
### SortControl
|
|
693
|
+
|
|
694
|
+
A searchable field selector with an adjacent icon button to reverse the direction. Each field
|
|
695
|
+
appears once. Changing fields preserves direction; toggling direction preserves the field. Built
|
|
696
|
+
from `Select`, with its themed popover and keyboard behavior.
|
|
697
|
+
|
|
698
|
+
- **Options** — `fields: [{id,label}]`, `value: {id,dir:'asc'|'desc'}` (null selects the first field
|
|
699
|
+
ascending), `label: 'Sort by'`, `labels: {asc,desc}` for localized direction text, `disabled`.
|
|
700
|
+
- **Methods** — defensive `getValue()`, `setValue(value,{silent})`, `enable()`, `disable()`,
|
|
701
|
+
`focus()`, `destroy()`. Unknown fields or directions are rejected. An empty catalogue disables
|
|
702
|
+
selection and returns null.
|
|
703
|
+
- **Keyboard** — Tab reaches the direction button and field selector; Space/Enter toggle the
|
|
704
|
+
focused direction button. The field retains Select’s combobox keyboard map. The button’s
|
|
705
|
+
accessible name includes the current direction; its hover title shows current → next direction.
|
|
706
|
+
- **Events** — one `change {value:{id,dir}}` event per changed field or direction. Typed search text does
|
|
707
|
+
not change the sort. The application applies the resulting state to its table, data source or route.
|
|
708
|
+
<!-- /doc -->
|
|
709
|
+
|
|
580
710
|
<!-- doc:checklist -->
|
|
581
711
|
### Checklist
|
|
582
712
|
|
|
@@ -800,7 +930,7 @@ panel material; the backdrop uses `--zx-color-overlay-backdrop`, and focus retur
|
|
|
800
930
|
Structured modal: a header with title and close button, a body, and footer buttons.
|
|
801
931
|
|
|
802
932
|
- **Options** — `title`, `size: 'sm'|'md'|'lg'|number`,
|
|
803
|
-
`buttons: [{ label, kind, action: 'close'|'cancel'|fn(dialog), autofocus }]`, `closable: true`.
|
|
933
|
+
`buttons: [{ label, kind, action: 'close'|'cancel'|fn(dialog), autofocus, shortcut }]`, `closable: true`.
|
|
804
934
|
- **Methods** — `setTitle()`, `setContent()`, `setButtons()`,
|
|
805
935
|
`addView(key, { content, buttons? })`, `showView(key)`.
|
|
806
936
|
- **Statics returning Promises** — `Dialog.alert({ title, message })`,
|
|
@@ -928,8 +1058,16 @@ DOM child of the anchor's nearest Zx theme scope while the browser lifts it into
|
|
|
928
1058
|
|
|
929
1059
|
A button that opens a `role="menu"`.
|
|
930
1060
|
|
|
931
|
-
- **Options** — `label`, `icon`, `kind`,
|
|
932
|
-
`
|
|
1061
|
+
- **Options** — `label`, `icon`, `kind`, `placement`, and a shared `items` entry model:
|
|
1062
|
+
- `'-'` or `{type: 'separator'}` draws a separator; `{type: 'heading', label}` draws a visible,
|
|
1063
|
+
non-interactive heading.
|
|
1064
|
+
- Actions keep `label`, `icon`, `value`, `disabled`, `danger`, and `onselect`, and may add
|
|
1065
|
+
`description`, `badge`, `shortcut`, or a text/Node `adornment`.
|
|
1066
|
+
- `href`, `target`, and `rel` render a genuine safe native link, preserving modifier clicks and
|
|
1067
|
+
targets. Executable URL schemes are rejected; `_blank` receives `noopener noreferrer` by
|
|
1068
|
+
default.
|
|
1069
|
+
- `role: 'menuitemcheckbox'|'menuitemradio'` with `checked` exposes an APG checked action. The
|
|
1070
|
+
application owns state changes and calls `setItems()` with the new model.
|
|
933
1071
|
- **Methods** — `setItems()`, `open()`, `close()`, `setLabel()`, `getTrigger()`, `getPanel()`,
|
|
934
1072
|
`focusFirst()`, `focusLast()`.
|
|
935
1073
|
- **Events** — `select {value, item}`, `open`, `close`.
|
|
@@ -949,8 +1087,9 @@ parked at the pointer, so it flips near a viewport edge like every other floatin
|
|
|
949
1087
|
- **Constructor** — `new ContextMenu(target, options)` where `target` is an element or selector.
|
|
950
1088
|
Unlike most components the target is not enhanced or replaced; `destroy()` removes only the
|
|
951
1089
|
anchor the menu created.
|
|
952
|
-
- **Options** — `items: []`
|
|
953
|
-
|
|
1090
|
+
- **Options** — `items: []` uses the same headings, separators, links, descriptions, trailing
|
|
1091
|
+
metadata, checked roles, and ordinary action shape MenuButton takes, **or a function**
|
|
1092
|
+
`(context) => items` called on
|
|
954
1093
|
every opening so a row menu can disable the actions that row does not allow; returning an empty
|
|
955
1094
|
array cancels the opening and leaves the platform menu alone. `selector: null` restricts the
|
|
956
1095
|
menu to matching descendants and reports the matched element as the context — a table passes
|
|
@@ -965,6 +1104,8 @@ parked at the pointer, so it flips near a viewport edge like every other floatin
|
|
|
965
1104
|
half most pointer-only context menus miss. Arrows move between items, typing jumps to one by its
|
|
966
1105
|
first letters, Enter and Space activate, Escape and Tab close — and closing returns focus to
|
|
967
1106
|
wherever it came from.
|
|
1107
|
+
- **Cancellation** — `select` is cancelable just like MenuButton. Preventing it suppresses the
|
|
1108
|
+
item callback and native navigation and leaves the context menu open.
|
|
968
1109
|
<!-- /doc -->
|
|
969
1110
|
|
|
970
1111
|
<!-- doc:tooltip -->
|
|
@@ -996,6 +1137,15 @@ Two panes with a divider the user owns. The layout is a three-track CSS grid dri
|
|
|
996
1137
|
<!-- doc:table -->
|
|
997
1138
|
### Table
|
|
998
1139
|
|
|
1140
|
+
**Group and section rows.** `rowKind` names the field (or a callback) that classifies a row, and
|
|
1141
|
+
`rowKinds` maps a kind to `{span, render, class}`. A `span: true` row renders one
|
|
1142
|
+
`<th scope="colgroup">` across every rendered cell — including the selection and reorder columns —
|
|
1143
|
+
and carries no others, which is what a heading row in a billing document actually is. Both
|
|
1144
|
+
default to null, so a table that sets neither renders exactly as before. While any spanning row is
|
|
1145
|
+
present the header sort controls are withheld and `setSort()` is a no-op: sorting a grouped table
|
|
1146
|
+
scatters its positions out of their sections, and silently doing so is worse than not offering it.
|
|
1147
|
+
The stacked presentation renders the heading alone rather than a row of labelled blanks.
|
|
1148
|
+
|
|
999
1149
|
Sortable, selectable, sticky-header data table. `fr` widths fill the container while px/auto
|
|
1000
1150
|
widths scroll horizontally, and multi-select adds a tri-state header checkbox plus Shift+click
|
|
1001
1151
|
range select.
|
|
@@ -1098,6 +1248,12 @@ range select.
|
|
|
1098
1248
|
<!-- doc:table-view -->
|
|
1099
1249
|
### TableView and the shared RecordView contract
|
|
1100
1250
|
|
|
1251
|
+
**`fieldControls` takes an object.** `true` and `false` behave as they always have; a
|
|
1252
|
+
`{label, target}` object names the chooser's trigger and mounts the disclosure into a host
|
|
1253
|
+
element — a list toolbar, say — instead of the view's own. `label` omitted resolves
|
|
1254
|
+
`recordView.fields`. This is what lets a translated application use the chooser at all: the
|
|
1255
|
+
trigger used to be the literal `Fields`, with no way to change it or move it.
|
|
1256
|
+
|
|
1101
1257
|
`TableView` is the record-oriented entry point above the lower-level `Table`. It extends
|
|
1102
1258
|
`RecordView` and composes one complete `Table`, so editing, hierarchy, growing, row movement,
|
|
1103
1259
|
responsive stacking, loading, and advanced table events remain available through `getTable()`.
|
|
@@ -1130,6 +1286,10 @@ portable state as TableView and KanbanView.
|
|
|
1130
1286
|
- **Options** — the shared RecordView options plus `titleField`, `subtitleField`, `preview`,
|
|
1131
1287
|
`previewAlt`, `link`, `actions`, `groupBy`, `groupOrder`, `minCardWidth`, `maxColumns`,
|
|
1132
1288
|
`variant: 'outlined'|'raised'|'filled'`, `loadingCount`, `headingLevel`, and `label`.
|
|
1289
|
+
- **Selection trigger** — `selectionTrigger:'checkbox'` preserves existing selection behavior.
|
|
1290
|
+
With `'card'`, selectable backgrounds toggle on click, Enter or Space, Shift+click selects a range,
|
|
1291
|
+
and the checkbox is omitted. Links, actions and text selection keep their native behavior. Selection
|
|
1292
|
+
remains announced through the card's ARIA description. This option also works in KanbanView.
|
|
1133
1293
|
- **Cards** — each record is a focusable `<li>` with a native title link, separate secondary
|
|
1134
1294
|
actions, optional native multi-select checkbox, labelled metadata, and a global ARIA selection
|
|
1135
1295
|
description that retains valid listitem semantics.
|
|
@@ -1145,7 +1305,8 @@ portable state as TableView and KanbanView.
|
|
|
1145
1305
|
a stable fallback. Title/action links are normalized; `_blank` links receive `noopener`.
|
|
1146
1306
|
- **Grouping and layout** — `groupBy` is a field ID or callback; `groupOrder` may deliberately show
|
|
1147
1307
|
empty groups. Cards reflow through container queries and may cap columns without viewport logic.
|
|
1148
|
-
- **Interaction** — Enter activates a focused card; Space toggles selection.
|
|
1308
|
+
- **Interaction** — By default Enter activates a focused card; Space toggles selection. With
|
|
1309
|
+
`selectionTrigger:'card'`, Enter also toggles selection. Links, actions,
|
|
1149
1310
|
selection controls, and selected text do not also activate the card. `recordaction` adds the
|
|
1150
1311
|
resolved action to the shared event set.
|
|
1151
1312
|
<!-- /doc -->
|
|
@@ -1161,6 +1322,8 @@ cards, advisory work-in-progress limits, and equivalent pointer/programmatic/key
|
|
|
1161
1322
|
`columnOrder`, `swimlaneOrder`, collapsed IDs, `showCounts`, `showEmptyColumns`, `variant`, and
|
|
1162
1323
|
`label`. Column/lane descriptors use stable `id`, `label`, optional stored `value`, and `accept`;
|
|
1163
1324
|
columns may also declare an advisory `limit`.
|
|
1325
|
+
- **Selection trigger** — `selectionTrigger:'card'` provides the same checkbox-free click and
|
|
1326
|
+
keyboard selection as CardView. The default remains `'checkbox'`.
|
|
1164
1327
|
- **Methods** — configure/get/move columns and swim lanes, collapse either axis, and
|
|
1165
1328
|
`moveRecord(id,{column?,lane?,index?})`. Board-specific order/collapse joins the common view
|
|
1166
1329
|
state; record order, movement history, and selection do not. Saved preferences for data-derived
|
|
@@ -1295,6 +1458,46 @@ Declarative client-side filter bar producing a filtered array, commonly wired to
|
|
|
1295
1458
|
- **Events** — `filter {rows, state}`.
|
|
1296
1459
|
<!-- /doc -->
|
|
1297
1460
|
|
|
1461
|
+
<!-- doc:filter-panel -->
|
|
1462
|
+
### FilterPanel — typed filters from server metadata
|
|
1463
|
+
|
|
1464
|
+
The third filter component, and the one a data-driven application reaches for. `DataFilter`
|
|
1465
|
+
filters a client-side row set; `Filter` builds a backend-neutral AST with groups and operators.
|
|
1466
|
+
`FilterPanel` takes the `{key: {type, label, options, min, max}}` map a list endpoint already
|
|
1467
|
+
publishes and gives back a query object — so the shape the server describes is the shape the
|
|
1468
|
+
form renders, with no per-application translation layer in between.
|
|
1469
|
+
|
|
1470
|
+
- **Options** — `fields: Record<string, {type, label?, options?, min?, max?, step?, search?}>`,
|
|
1471
|
+
`order` (display order; omitted uses object order), `value` (the applied filters, drafted
|
|
1472
|
+
from), `mode: 'draft'|'live'`, `serialize: 'seconds'|'ms'|'iso'|(date, edge) => unknown`,
|
|
1473
|
+
`emptyText`, `msg`.
|
|
1474
|
+
- **Types** — `text`, `select`, `date`, `date:range`, `int`, `float`, `number`, and
|
|
1475
|
+
`int:range` / `float:range` / `number:range`. An unrecognised type renders a visible,
|
|
1476
|
+
labelled placeholder naming it and is excluded from the value — never dropped silently.
|
|
1477
|
+
- **Methods** — `getValue()`, `setValue()`, `apply()`, `reset()`, `clear()`.
|
|
1478
|
+
- **Events** — `apply {value}`, `change {value, field}`.
|
|
1479
|
+
|
|
1480
|
+
Five behaviours are deliberate rather than incidental:
|
|
1481
|
+
|
|
1482
|
+
- **A select is multi-valued.** "Open or waiting" is the common request, and single choice turns
|
|
1483
|
+
it into two visits. It composes `Checklist`, which brings its own search past eight options,
|
|
1484
|
+
and the group is named after the filter rather than after the component.
|
|
1485
|
+
- **Each end of a range carries its own accessible name.** One `<label for>` cannot name two
|
|
1486
|
+
inputs, and a group label that names neither is worse than no group label.
|
|
1487
|
+
- **`clear()` commits; `reset()` does not.** Clear is "no filters" and applies immediately —
|
|
1488
|
+
emptying the controls while the list stays filtered is a panel that lies about what is on
|
|
1489
|
+
screen. Reset restores the constructed value without committing, which is a host sheet's
|
|
1490
|
+
Cancel.
|
|
1491
|
+
- **An empty `fields` map is normal.** An instance that configures no filters for a settings
|
|
1492
|
+
section is the ordinary case; the panel renders `emptyText`, never an error.
|
|
1493
|
+
- **`0` is a value.** `''`, `null`, `[]` and `{from: null, to: null}` are not, and only active
|
|
1494
|
+
constraints reach the emitted value.
|
|
1495
|
+
|
|
1496
|
+
`serialize` decides how a date leaves the component, because the answer is a wire-format
|
|
1497
|
+
decision rather than an application one. A range's upper bound takes the **end** of its day, or
|
|
1498
|
+
a one-day range matches nothing.
|
|
1499
|
+
<!-- /doc -->
|
|
1500
|
+
|
|
1298
1501
|
<!-- doc:filter -->
|
|
1299
1502
|
### Filter — dynamic backend-neutral expressions
|
|
1300
1503
|
|
|
@@ -1310,7 +1513,17 @@ adapter to compile into its own backend query language.
|
|
|
1310
1513
|
priority/country/currency/unit/entity, and tags. Compatible operators and their arity come from
|
|
1311
1514
|
the exported `filterOperators` matrix; applications may explicitly override/add operator IDs.
|
|
1312
1515
|
- **Options** — `fields`, `value`, `operators`, `allowGroups: true`, `maxDepth: 3`,
|
|
1313
|
-
`maxConditions: 50`, `autoApply: false`, `readonly`, `disabled`, `applyLabel`, `clearLabel
|
|
1516
|
+
`maxConditions: 50`, `autoApply: false`, `readonly`, `disabled`, `applyLabel`, `clearLabel`,
|
|
1517
|
+
`searchable: false`, `layout: 'standard'|'compact'`, `rootLogic: null|'and'|'or'`,
|
|
1518
|
+
`showApply: true`, `showRootActions: true`.
|
|
1519
|
+
- **Searchable conditions** — opt in to local-search `Select` controls for fields, operators and
|
|
1520
|
+
static single-choice/boolean values. Uncommitted search text never becomes a condition value.
|
|
1521
|
+
Multi-choice, async and custom editors retain their existing contracts. Compact rows keep field,
|
|
1522
|
+
operator, value and removal together, wrapping the value below on narrow containers.
|
|
1523
|
+
- **Embedding** — hide internal Apply and duplicate root Add controls when the parent drawer owns
|
|
1524
|
+
submission. `rootLogic` fixes the authored root logic; incompatible saved expressions remain
|
|
1525
|
+
visible and invalid until corrected, never silently rewritten. Removing the last condition
|
|
1526
|
+
returns keyboard focus to Add filter.
|
|
1314
1527
|
- **Methods** — `getValue()`, atomic `setValue()`, `addCondition()`, `addGroup()`, `update()`,
|
|
1315
1528
|
`remove()`, `move()`, `validate()`, `apply()`, `clear()`, `focus()`, `setReadonly()`,
|
|
1316
1529
|
`enable()`/`disable()`.
|
|
@@ -1414,6 +1627,26 @@ Beyond the built-in field types, these widget types wrap whole components, used
|
|
|
1414
1627
|
`toggle` (Toggle).
|
|
1415
1628
|
<!-- /doc -->
|
|
1416
1629
|
|
|
1630
|
+
<!-- doc:code-editor -->
|
|
1631
|
+
### CodeEditor — structured text without an editor dependency
|
|
1632
|
+
|
|
1633
|
+
A textarea that behaves like a source editor, and deliberately not more than that: native undo,
|
|
1634
|
+
native IME, and no syntax engine. It never executes or injects the value, so it is the safe
|
|
1635
|
+
surface for structured text — templates, queries, configuration — while rich HTML authoring
|
|
1636
|
+
stays a separate policy decision.
|
|
1637
|
+
|
|
1638
|
+
- **Options** — `value`, `name`, `language` (shown to the reader and exposed as data),
|
|
1639
|
+
`label`, `placeholder`, `rows` (clamped 2–100), `indent` (inserted by Tab, removed by
|
|
1640
|
+
Shift+Tab), `wrap: 'off'|'soft'|'hard'`, `spellcheck`, `readOnly`, `disabled`,
|
|
1641
|
+
`status` (the line/column readout).
|
|
1642
|
+
- **Methods** — `setValue()`.
|
|
1643
|
+
- **Events** — `input {value}`, `change {value}`.
|
|
1644
|
+
|
|
1645
|
+
Tab indents rather than moving focus, which is what a code surface has to do and what makes it a
|
|
1646
|
+
keyboard trap if nothing else is arranged — Escape then Tab leaves the field. A `code` Form field
|
|
1647
|
+
adapter is registered by `registerFieldAdapters()`.
|
|
1648
|
+
<!-- /doc -->
|
|
1649
|
+
|
|
1417
1650
|
<!-- doc:questionnaire -->
|
|
1418
1651
|
### Questionnaire
|
|
1419
1652
|
|
|
@@ -1585,6 +1818,34 @@ so buttons and links in its action, content, and footer regions remain valid sib
|
|
|
1585
1818
|
container query when the card itself becomes narrow.
|
|
1586
1819
|
<!-- /doc -->
|
|
1587
1820
|
|
|
1821
|
+
<!-- doc:stat-tile -->
|
|
1822
|
+
### StatTile — `statTile(options)` / `StatTile`
|
|
1823
|
+
|
|
1824
|
+
A labelled number with optional delta, trend and icon: the most-copied snippet in any
|
|
1825
|
+
application UI, and the reason competing template products advertise a card count rather than a
|
|
1826
|
+
component count. `statTile()` is the convenience form of `new StatTile(null, options)` and
|
|
1827
|
+
returns the component, the way `tooltip()` does; call `.toElement()` for the node to place.
|
|
1828
|
+
|
|
1829
|
+
- **Options** — `label`, `value`, `format: 'number'|'currency'|'percent'|'fileSize'|null|fn`,
|
|
1830
|
+
`currency`, `locale`, `delta`, `deltaKind: 'positive'|'negative'|'neutral'`, `deltaFormat`,
|
|
1831
|
+
`deltaLabel`, `trend: number[]`, `icon`, `kind`, `href`, `clickable`, `loading`, `msg`.
|
|
1832
|
+
- **Methods** — `update(options)`, `getAccessibleName()`.
|
|
1833
|
+
- **Events** — `click {event}`.
|
|
1834
|
+
|
|
1835
|
+
- **A delta is never colour alone.** It carries its sign and a direction glyph, and `deltaKind`
|
|
1836
|
+
decides the colour rather than the sign — rising ticket counts are not a success, and a
|
|
1837
|
+
component that assumes "up is good" is wrong for half the metrics in any business.
|
|
1838
|
+
- **The accessible name is label + value + spoken delta** ("up 2 vs. last week"). The visible
|
|
1839
|
+
`+2` row and the sparkline are `aria-hidden`, because a sparkline nobody can read is
|
|
1840
|
+
decoration and saying the delta twice is worse than saying it once.
|
|
1841
|
+
- **The element follows the behaviour** — `href` renders an `<a>`, `onclick` without `href` a
|
|
1842
|
+
`<button>`, neither a `<div>` with `role="group"`. Never a div with a click handler.
|
|
1843
|
+
- **`loading: true` renders a skeleton shaped like the tile**, not a spinner.
|
|
1844
|
+
|
|
1845
|
+
Nothing in it assumes a fixed set of buckets or a fixed label: the content of a dashboard tile
|
|
1846
|
+
is the instance's, not the library's.
|
|
1847
|
+
<!-- /doc -->
|
|
1848
|
+
|
|
1588
1849
|
<!-- doc:aurora -->
|
|
1589
1850
|
### Aurora
|
|
1590
1851
|
|
|
@@ -1795,6 +2056,37 @@ first and last items.
|
|
|
1795
2056
|
`aria-current="page"` and is deliberately not interactive; separators are `aria-hidden`.
|
|
1796
2057
|
<!-- /doc -->
|
|
1797
2058
|
|
|
2059
|
+
<!-- doc:list-toolbar -->
|
|
2060
|
+
### ListToolbar — the bar above a record view
|
|
2061
|
+
|
|
2062
|
+
Every list carries the same four questions — what am I searching for, which records, which
|
|
2063
|
+
columns, in what shape. The parts have always existed (`Search`, `SortControl`, `badge()`,
|
|
2064
|
+
`button()`); this is the composition, so that every consumer stops assembling it differently and
|
|
2065
|
+
forgetting the same thing.
|
|
2066
|
+
|
|
2067
|
+
- **Options** — `search: {placeholder?, value?, debounce?, clearable?}|false`, `count`,
|
|
2068
|
+
`countText`, `views: Array<string|{id, label?, icon?}>` (string presets `auto|cards|table|list`),
|
|
2069
|
+
`view`, `tools: [{id, label?, icon?, badge?, badgeKind?, pressed?, disabled?, onclick?}]`,
|
|
2070
|
+
`label`, `msg`.
|
|
2071
|
+
- **Methods** — `setCount()`, `setBadge()`, `setPressed()`, `setToolDisabled()`, `setTools()`,
|
|
2072
|
+
`getTool()`, `getToolsElement()`, `addTool()`, `setView()`, `getView()`, `getSearch()`,
|
|
2073
|
+
`setSearch()`, `focusSearch()`, `bind()`, `unbind()`.
|
|
2074
|
+
- **Events** — `search {value}`, `viewchange {view, previous}`, `action {id, pressed, tool}`.
|
|
2075
|
+
|
|
2076
|
+
Three properties are the reason to use this rather than assemble your own:
|
|
2077
|
+
|
|
2078
|
+
- **A tool's badge is part of its accessible name**, not a second thing beside it — a tool
|
|
2079
|
+
showing `2` announces as "Filters (2)". Once filters live behind a panel, a list can show four
|
|
2080
|
+
rows out of twenty with nothing on screen saying why, and the badge is what prevents that.
|
|
2081
|
+
- **The count line is a live region**, and `setCount(null)` clears it. The previous number
|
|
2082
|
+
describes the previous filters; a stale count during a load is worse than none.
|
|
2083
|
+
- **Tool buttons meet the 44 px target** in both densities.
|
|
2084
|
+
|
|
2085
|
+
`bind(view)` is optional sugar for a `TableView` or `CardView`: it feature-detects rather than
|
|
2086
|
+
importing them, adopts the view's shape, and mounts a field chooser built with
|
|
2087
|
+
`fieldControls: {target}` into the toolbar. The toolbar is fully functional without it.
|
|
2088
|
+
<!-- /doc -->
|
|
2089
|
+
|
|
1798
2090
|
<!-- doc:pagination -->
|
|
1799
2091
|
### Pagination
|
|
1800
2092
|
|
|
@@ -1824,9 +2116,16 @@ treated as one empty page rather than zero pages.
|
|
|
1824
2116
|
Application navigation bar: brand, items, and right-aligned actions. Items overflow into a "More"
|
|
1825
2117
|
menu on narrow widths.
|
|
1826
2118
|
|
|
1827
|
-
- **Options** — `title`, `items: [{ name, title, badge? }]`, `active`, `actions: []
|
|
2119
|
+
- **Options** — `title`, `items: [{ name, title, badge? }]`, `active`, `actions: []`,
|
|
2120
|
+
`overflow: true`, `overflowBelow: '44rem'`, `minVisible: 0`.
|
|
1828
2121
|
- **Methods** — `setTitle()`, `setItems()`, `setActive()`, `setBadge()`, `setActions()`.
|
|
1829
2122
|
- **Events** — `change {name}`.
|
|
2123
|
+
|
|
2124
|
+
**Overflow is a default, not a law.** Collapsing every item behind "More" is right for a top app
|
|
2125
|
+
bar and wrong for a phone bottom bar, where the navigation is the point. `overflow: false` keeps
|
|
2126
|
+
every item at every width; `overflowBelow` moves the threshold; `minVisible: n` pins the first `n`
|
|
2127
|
+
items and overflows the rest. At the default the collapse is a container query with no observer
|
|
2128
|
+
installed; any other threshold installs a `ResizeObserver`, which is the cost of asking for one.
|
|
1830
2129
|
<!-- /doc -->
|
|
1831
2130
|
|
|
1832
2131
|
<!-- doc:app-sidebar -->
|
|
@@ -1920,8 +2219,14 @@ built-in names are translated to their Font Awesome counterparts (`x` → `fa-xm
|
|
|
1920
2219
|
`fa-magnifying-glass`, `warning` → `fa-triangle-exclamation`, …), so component code never changes.
|
|
1921
2220
|
Prefixes override: `'fa:user'`, `'fas:user'`/`'regular:user'`/`'duotone:user'`/`'thin:user'`,
|
|
1922
2221
|
`'kit:zeyos-notes'` (custom kit icons), `'builtin:check'` (force the inline SVG). A literal class
|
|
1923
|
-
list — `'fa-sharp fa-solid fa-user'` — is used verbatim. Unknown
|
|
1924
|
-
|
|
2222
|
+
list — `'fa-sharp fa-solid fa-user'` — is used verbatim. Unknown names under Font Awesome are
|
|
2223
|
+
passed through to the kit, which resolves them in the browser.
|
|
2224
|
+
|
|
2225
|
+
**An unknown *built-in* name does not throw.** Icon names routinely arrive from a server, and one
|
|
2226
|
+
unconfigured name must not take down the screen it appears on, so it renders an empty `<svg>` of
|
|
2227
|
+
the requested size — layout does not shift — carrying `data-zx-icon-missing="<name>"`, and reports
|
|
2228
|
+
itself once per distinct name through `console.warn`. Pass `icon(name, { strict: true })` for the
|
|
2229
|
+
old `RangeError`, at a call site that can afford to fail: a test, or a build-time check.
|
|
1925
2230
|
|
|
1926
2231
|
Font Awesome elements are sized with `font-size` and occupy 1em; bundled SVGs use width/height
|
|
1927
2232
|
attributes. Both honour `label` (`null` ⇒ `aria-hidden`, otherwise `role="img"` + `aria-label`).
|
package/docs/llms.txt
CHANGED
|
@@ -26,16 +26,22 @@ exports and as `window.zx.*`.
|
|
|
26
26
|
`copyButton()`/`CopyInput`, `DatePicker`, `MonthPicker`, `TimePicker`,
|
|
27
27
|
`Datebox`/`DateTimeBox`, `DateRangePicker`/`DateRangeBox`, `Timebox`.
|
|
28
28
|
- Overlays: `Message` (toasts/inline/progress), `Modal`, `Dialog` (+ `alert`/`confirm`/`prompt` Promises), `Sheet` (edge-anchored Dialog; `side`, `modal: true|'trap-focus'|false`, `backdrop`, `snap` detents, swipe-to-dismiss), `SheetStack` (drill-down; `stack`/`cascade`), `Dropdown`, `MenuButton`, `ContextMenu` (right-click; `selector` for per-row menus), `Tooltip`/`tooltip()`/`describe()`.
|
|
29
|
-
- Data: `
|
|
29
|
+
- Data: `EntityRef` (dense linked/static identity), `FileItem`/`FileList` (durable and transient
|
|
30
|
+
file presentation), `ActivityItem`/`ActivityList` (chronological entries and grouped feeds),
|
|
31
|
+
`Table` (sortable, selectable, sticky header, opt-in inline cell/row editing, row reorder,
|
|
30
32
|
column visibility), shared `RecordView` state through `TableView`, `CardView`, and `KanbanView`,
|
|
31
33
|
`Grid` with single-click editing and `Grid.BillingItems()`, engine-neutral
|
|
32
34
|
`Chart` with injected `ChartJsAdapter`, `Calendar` (agenda/day/week/month/year, pointer/keyboard
|
|
33
35
|
drag and resize, `optimistic: true|false`), backend-neutral nested `Filter`, simple client-side
|
|
34
|
-
`DataFilter`, `
|
|
35
|
-
`
|
|
36
|
-
|
|
36
|
+
`DataFilter`, `FilterPanel` (typed filter form built from a server's own field metadata;
|
|
37
|
+
`mode: 'draft'|'live'`, `serialize`), `ListToolbar` (search, live result count, view switch, and
|
|
38
|
+
tools whose badge is part of the accessible name), `Pagination` (+ pure `paginationRange()`),
|
|
39
|
+
`SortControl` (searchable field selector with a direction toggle, one atomic `{id,dir}`),
|
|
40
|
+
`TreeView` (APG tree), `Finder` (Miller columns).
|
|
41
|
+
- Forms: `Form`, `Fieldset`, `Questionnaire` (guided one-question-at-a-time flow with branching), `Field` (type registry), `CodeEditor` (structured text in a native textarea; never executes or injects the value), `ValueList`, `MultiValueEditor`, `FieldUpload`.
|
|
37
42
|
- Layout: `stack()`/`grid()`/`aspect()` (spacing, an intrinsically reflowing grid, a fixed-ratio
|
|
38
|
-
box), `Groupbox`, `Card` (media/title link/actions/footer), `
|
|
43
|
+
box), `Groupbox`, `Card` (media/title link/actions/footer), `StatTile`/`statTile()` (labelled
|
|
44
|
+
metric with optional delta, sparkline, and loading state), `AppIcon` (generic tile geometry;
|
|
39
45
|
circular `zeyosAppIcon()` application presets and compact `moduleChip()` identities),
|
|
40
46
|
`Aurora` (one- to four-colour ambient
|
|
41
47
|
canvas light; shared material roles govern chrome and overlays), `Avatar`, `Panel` (header/footer action
|
package/package.json
CHANGED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
.zx-activity-item {
|
|
2
|
+
inline-size: 100%;
|
|
3
|
+
min-inline-size: 0;
|
|
4
|
+
color: var(--zx-color-text);
|
|
5
|
+
list-style: none;
|
|
6
|
+
container-type: inline-size;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.zx-activity-item__article {
|
|
10
|
+
display: grid;
|
|
11
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
12
|
+
gap: var(--zx-space-3);
|
|
13
|
+
min-inline-size: 0;
|
|
14
|
+
padding-block: var(--zx-space-4);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.zx-activity-item__avatar {
|
|
18
|
+
position: relative;
|
|
19
|
+
z-index: 1;
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: start;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.zx-activity-item__main {
|
|
25
|
+
display: grid;
|
|
26
|
+
gap: var(--zx-space-2);
|
|
27
|
+
min-inline-size: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.zx-activity-item__header {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-wrap: wrap;
|
|
33
|
+
align-items: baseline;
|
|
34
|
+
justify-content: space-between;
|
|
35
|
+
gap: var(--zx-space-1) var(--zx-space-3);
|
|
36
|
+
min-inline-size: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.zx-activity-item__heading {
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-wrap: wrap;
|
|
42
|
+
gap: var(--zx-space-1);
|
|
43
|
+
min-inline-size: 0;
|
|
44
|
+
margin: 0;
|
|
45
|
+
font-size: var(--zx-text-md);
|
|
46
|
+
line-height: 1.45;
|
|
47
|
+
overflow-wrap: anywhere;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.zx-activity-item__actor {
|
|
51
|
+
font-weight: 700;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.zx-activity-item__title {
|
|
55
|
+
font-weight: 400;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
* The auto inline-start margin takes the header's free space before `justify-content` can
|
|
60
|
+
* distribute it, so the badge and the timestamp stay together on the trailing edge instead of
|
|
61
|
+
* being spread across the row as a third column.
|
|
62
|
+
*/
|
|
63
|
+
.zx-activity-item__state {
|
|
64
|
+
flex: none;
|
|
65
|
+
margin-inline-start: auto;
|
|
66
|
+
align-self: center;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.zx-activity-item__time {
|
|
70
|
+
flex: none;
|
|
71
|
+
color: var(--zx-color-text-muted);
|
|
72
|
+
font-size: var(--zx-text-xs);
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.zx-activity-item__body {
|
|
77
|
+
min-inline-size: 0;
|
|
78
|
+
color: var(--zx-color-text);
|
|
79
|
+
line-height: 1.55;
|
|
80
|
+
overflow-wrap: anywhere;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.zx-activity-item__metadata {
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-wrap: wrap;
|
|
86
|
+
gap: var(--zx-space-1) var(--zx-space-3);
|
|
87
|
+
margin: 0;
|
|
88
|
+
padding: 0;
|
|
89
|
+
color: var(--zx-color-text-muted);
|
|
90
|
+
font-size: var(--zx-text-sm);
|
|
91
|
+
list-style: none;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.zx-activity-item__metadata-item {
|
|
95
|
+
min-inline-size: 0;
|
|
96
|
+
overflow-wrap: anywhere;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.zx-activity-item__metadata-item:not(:last-child)::after {
|
|
100
|
+
content: "\00b7";
|
|
101
|
+
margin-inline-start: var(--zx-space-3);
|
|
102
|
+
color: var(--zx-color-text-placeholder);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.zx-activity-item__attachments {
|
|
106
|
+
display: grid;
|
|
107
|
+
gap: var(--zx-space-2);
|
|
108
|
+
min-inline-size: 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.zx-activity-item__attachments-item {
|
|
112
|
+
min-inline-size: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.zx-activity-item__actions {
|
|
116
|
+
display: flex;
|
|
117
|
+
flex-wrap: wrap;
|
|
118
|
+
align-items: center;
|
|
119
|
+
gap: var(--zx-space-1);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.zx-activity-item__action {
|
|
123
|
+
text-decoration: none;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@container (max-width: 30rem) {
|
|
127
|
+
.zx-activity-item__header {
|
|
128
|
+
display: grid;
|
|
129
|
+
justify-content: stretch;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Stacked, the header is one column, so the badge reads as its own line at the start edge. */
|
|
133
|
+
.zx-activity-item__state {
|
|
134
|
+
margin-inline-start: 0;
|
|
135
|
+
justify-self: start;
|
|
136
|
+
}
|
|
137
|
+
}
|