@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.
Files changed (128) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/README.md +7 -0
  3. package/dist/types/components/activity-item/activity-item.d.ts +351 -0
  4. package/dist/types/components/activity-list/activity-list.d.ts +195 -0
  5. package/dist/types/components/app-sidebar/app-sidebar.d.ts +28 -0
  6. package/dist/types/components/button/button.d.ts +8 -0
  7. package/dist/types/components/calendar/calendar.d.ts +19 -0
  8. package/dist/types/components/card/card.d.ts +7 -0
  9. package/dist/types/components/card-view/card-view.d.ts +11 -3
  10. package/dist/types/components/card-view/record-card.d.ts +7 -1
  11. package/dist/types/components/code-editor/code-editor.d.ts +160 -0
  12. package/dist/types/components/code-editor/field-adapter.d.ts +5 -0
  13. package/dist/types/components/context-menu/context-menu.d.ts +18 -2
  14. package/dist/types/components/date-picker/date-picker.d.ts +8 -0
  15. package/dist/types/components/date-picker/time-picker.d.ts +7 -0
  16. package/dist/types/components/dialog/dialog.d.ts +29 -0
  17. package/dist/types/components/entity-ref/entity-ref.d.ts +331 -0
  18. package/dist/types/components/file-item/file-item.d.ts +234 -0
  19. package/dist/types/components/file-list/file-list.d.ts +171 -0
  20. package/dist/types/components/filter/filter.d.ts +91 -36
  21. package/dist/types/components/filter-panel/filter-panel.d.ts +449 -0
  22. package/dist/types/components/kanban-view/kanban-card.d.ts +138 -0
  23. package/dist/types/components/kanban-view/kanban-view.d.ts +170 -4
  24. package/dist/types/components/launcher/launcher.d.ts +19 -12
  25. package/dist/types/components/list-toolbar/list-toolbar.d.ts +599 -0
  26. package/dist/types/components/menu-button/menu-button.d.ts +4 -37
  27. package/dist/types/components/message/message.d.ts +7 -0
  28. package/dist/types/components/modal/modal.d.ts +48 -0
  29. package/dist/types/components/navigation-bar/navigation-bar.d.ts +105 -21
  30. package/dist/types/components/panel/panel.d.ts +7 -0
  31. package/dist/types/components/search/search.d.ts +7 -0
  32. package/dist/types/components/select/select.d.ts +4 -0
  33. package/dist/types/components/sort-control/sort-control.d.ts +105 -0
  34. package/dist/types/components/stat-tile/stat-tile.d.ts +277 -0
  35. package/dist/types/components/tabbox/tabbox.d.ts +7 -0
  36. package/dist/types/components/table/table.d.ts +144 -0
  37. package/dist/types/components/table-view/table-view.d.ts +11 -5
  38. package/dist/types/components/timebox/timebox.d.ts +7 -0
  39. package/dist/types/components/value-list/value-list.d.ts +8 -0
  40. package/dist/types/components/view/record-view.d.ts +96 -5
  41. package/dist/types/core/icons.d.ts +17 -0
  42. package/dist/types/index.d.ts +11 -0
  43. package/dist/types/internal/app-rail.d.ts +10 -0
  44. package/dist/types/internal/menu-items.d.ts +134 -0
  45. package/dist/zx-zeyos.esm.js +616 -77
  46. package/dist/zx-zeyos.esm.min.js +8 -1
  47. package/dist/zx.css +2085 -238
  48. package/dist/zx.esm.js +6704 -1542
  49. package/dist/zx.esm.min.js +10 -3
  50. package/dist/zx.global.js +6704 -1542
  51. package/dist/zx.global.min.js +10 -3
  52. package/dist/zx.min.css +1 -1
  53. package/docs/api.json +1479 -127
  54. package/docs/llms.md +315 -10
  55. package/docs/llms.txt +11 -5
  56. package/package.json +1 -1
  57. package/src/components/activity-item/activity-item.css +137 -0
  58. package/src/components/activity-item/activity-item.js +599 -0
  59. package/src/components/activity-list/activity-list.css +64 -0
  60. package/src/components/activity-list/activity-list.js +375 -0
  61. package/src/components/app-rail/app-rail.css +227 -19
  62. package/src/components/app-sidebar/app-sidebar.css +414 -24
  63. package/src/components/app-sidebar/app-sidebar.js +65 -5
  64. package/src/components/button/button.css +8 -0
  65. package/src/components/button/button.js +6 -1
  66. package/src/components/calendar/calendar.js +33 -3
  67. package/src/components/card/card.js +12 -1
  68. package/src/components/card-view/card-view.css +1 -0
  69. package/src/components/card-view/card-view.js +25 -9
  70. package/src/components/card-view/record-card.js +7 -3
  71. package/src/components/code-editor/code-editor.css +67 -0
  72. package/src/components/code-editor/code-editor.js +288 -0
  73. package/src/components/code-editor/field-adapter.js +34 -0
  74. package/src/components/context-menu/context-menu.css +80 -3
  75. package/src/components/context-menu/context-menu.js +22 -30
  76. package/src/components/date-picker/date-picker.js +22 -8
  77. package/src/components/date-picker/month-picker.js +3 -3
  78. package/src/components/date-picker/time-picker.js +20 -8
  79. package/src/components/dialog/dialog.js +88 -66
  80. package/src/components/dropdown/dropdown.js +2 -2
  81. package/src/components/entity-ref/entity-ref.css +182 -0
  82. package/src/components/entity-ref/entity-ref.js +496 -0
  83. package/src/components/file-item/file-item.css +88 -0
  84. package/src/components/file-item/file-item.js +371 -0
  85. package/src/components/file-list/file-list.css +51 -0
  86. package/src/components/file-list/file-list.js +320 -0
  87. package/src/components/filter/filter.css +27 -1
  88. package/src/components/filter/filter.js +199 -45
  89. package/src/components/filter-panel/filter-panel.css +104 -0
  90. package/src/components/filter-panel/filter-panel.js +964 -0
  91. package/src/components/kanban-view/kanban-card.js +239 -0
  92. package/src/components/kanban-view/kanban-view.css +194 -0
  93. package/src/components/kanban-view/kanban-view.js +251 -8
  94. package/src/components/launcher/launcher.js +59 -27
  95. package/src/components/list-toolbar/list-toolbar.css +189 -0
  96. package/src/components/list-toolbar/list-toolbar.js +851 -0
  97. package/src/components/menu-button/menu-button.css +80 -3
  98. package/src/components/menu-button/menu-button.js +21 -37
  99. package/src/components/message/message.css +5 -2
  100. package/src/components/message/message.js +13 -2
  101. package/src/components/modal/modal.css +15 -0
  102. package/src/components/modal/modal.js +141 -0
  103. package/src/components/navigation-bar/navigation-bar.css +77 -2
  104. package/src/components/navigation-bar/navigation-bar.js +171 -4
  105. package/src/components/panel/panel.js +13 -2
  106. package/src/components/search/search.js +17 -5
  107. package/src/components/select/field-adapter.js +4 -1
  108. package/src/components/select/select.js +3 -0
  109. package/src/components/sort-control/sort-control.css +17 -0
  110. package/src/components/sort-control/sort-control.js +140 -0
  111. package/src/components/stat-tile/stat-tile.css +213 -0
  112. package/src/components/stat-tile/stat-tile.js +590 -0
  113. package/src/components/tabbox/tabbox.js +12 -1
  114. package/src/components/table/table.css +51 -2
  115. package/src/components/table/table.js +298 -19
  116. package/src/components/table-view/table-view.css +8 -2
  117. package/src/components/table-view/table-view.js +21 -6
  118. package/src/components/tag-picker/tag-picker.css +3 -1
  119. package/src/components/timebox/timebox.js +18 -5
  120. package/src/components/value-list/value-list.js +22 -6
  121. package/src/components/view/record-view.css +5 -0
  122. package/src/components/view/record-view.js +100 -7
  123. package/src/core/icons.js +74 -5
  124. package/src/index.js +25 -0
  125. package/src/internal/app-rail.js +19 -1
  126. package/src/internal/menu-items.js +142 -0
  127. package/styles/print.css +192 -0
  128. package/styles/zx.css +11 -0
package/CHANGELOG.md CHANGED
@@ -8,6 +8,161 @@ and friends remain the complete record.
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ ## 4.4.0 — 2026-09-22
12
+
13
+ A large release in two halves. The first adds capability: a dependency-free code editor, the
14
+ record primitives (`EntityRef`, `FileItem`/`FileList`, `ActivityItem`/`ActivityList`), kanban
15
+ movement and workflow policy, and richer action menus. The second is what building a real
16
+ application on the library found missing — group rows, list controls, a filter panel driven by
17
+ server metadata, a metric tile, and the long tail of strings a translated product could not
18
+ reach.
19
+
20
+ Nothing here is a breaking change. Every new option defaults to the previous behaviour, and every
21
+ English string a translator can now reach keeps its exact previous wording when no translator is
22
+ installed.
23
+
24
+ ### Added
25
+
26
+ - **Structured text no longer requires an editor dependency.** `CodeEditor` keeps source in a
27
+ native textarea with browser undo and IME behavior, adds Tab/Shift+Tab indentation, language
28
+ metadata, line/column feedback, read-only and disabled states, and a `code` Form field adapter.
29
+ It never executes or injects the value; rich HTML authoring remains a separate policy surface.
30
+ - **Reusable record primitives cover dense identity, files, and activity.** `EntityRef` presents
31
+ linked or static identity with labelled metadata and injected actions; `FileItem`/`FileList`
32
+ cover durable, temporary, waiting, progress, MIME, size, download, loading, and empty states;
33
+ `ActivityItem`/`ActivityList` cover actor, time, content, attachments, actions, stable grouping,
34
+ and incremental feed updates. Zx owns safe presentation and cancelable interaction boundaries;
35
+ applications retain routing, authorization, transport, posting, reactions, and persistence.
36
+ - **Action menus now carry business metadata without becoming free-form popovers.** MenuButton and
37
+ ContextMenu share headings, object separators, safe native links, descriptions, badges,
38
+ shortcuts, text/Node adornments, and checked/radio menu-item roles. Existing flat items and
39
+ `'-'` separators are unchanged.
40
+ - **Kanban cards carry the anatomy an operational board needs.** New read-only projections put an
41
+ `entityIcon` and `identifier` on a card head beside `status` and `priority` indicators, and a
42
+ `progress` meter and `assignees` avatars on a card footer. `priorityTones` and `statusTones` map
43
+ a value to a semantic tone as data rather than through a renderer, `progressMax` sets the
44
+ completion scale explicitly, and `maxAvatars` bounds the avatar stack. A board that sets none of
45
+ them renders exactly the card it rendered in 4.3.4.
46
+
47
+ - **`FilterPanel` — typed filters from server metadata.** Takes the `{key: {type, label,
48
+ options, min, max}}` map a list endpoint already publishes and returns a query object. Ten
49
+ field types including both range forms, multi-valued selects on `Checklist`, draft-then-apply
50
+ by default, and `serialize` for the Unix-seconds / ISO / epoch-ms question. `DataFilter`
51
+ filters a client-side row set and `Filter` builds an AST; this is the third shape, and the one
52
+ a data-driven application needs.
53
+ - **`ListToolbar` — the bar above a record view.** Search, a live result count, a view switch and
54
+ badged tools. A tool's badge is part of its accessible name rather than a second thing beside
55
+ it, `setCount(null)` clears the live region during a load, and `bind()` feature-detects a
56
+ `TableView`/`CardView` instead of importing it.
57
+ - **`StatTile` / `statTile()` — the labelled metric.** Formats through the core formatters, never
58
+ encodes "up is good" (`deltaKind` decides the colour, not the sign), marks its sparkline
59
+ `aria-hidden`, and picks `<a>` / `<button>` / `<div role="group">` from the behaviour it was
60
+ given rather than wrapping a click handler round a div.
61
+ - **`Table` group and section rows.** `rowKind` and `rowKinds` render a `<th scope="colgroup">`
62
+ spanning every rendered cell, including the selection and reorder columns. `CardView` has had
63
+ `groupBy`; `Table` had nothing, while `Grid.BillingItems()` already modelled the row kind for
64
+ editability and simply never drew it. Sort controls are withheld while a spanning row is
65
+ present, because sorting a grouped table scatters its positions out of their sections.
66
+ - **`ActivityItem.state`** — `pending` and `failed`, for an entry rendered optimistically before
67
+ its request resolves and for one whose send failed. An entry that disappears on failure tells
68
+ the reader their message was sent when nobody was told.
69
+
70
+ ### Changed
71
+
72
+ - **The move handle is no longer pointer furniture.** Since 4.3.4 the card itself is the drag
73
+ source, so the knob is decoration that competes with the card's content. The new
74
+ `moveHandle: 'keyboard' | 'always'` defaults to `keyboard`: the button stays in the DOM, in tab
75
+ order, and fully announced, but is clipped out of sight and out of the layout until it takes
76
+ focus or holds a grabbed card. `always` restores the 4.3.4 presentation, and `dragFrom: 'handle'`
77
+ keeps the handle visible regardless, since it is then the only thing a pointer user can grab.
78
+ - **An empty column now reads as a drop target.** `labels.columnEmpty` defaults to
79
+ "Drop a card here" in a dashed zone instead of an empty gap; `labels.columnEmpty: ''` restores
80
+ the previous blank column, and `renderColumnEmpty` still replaces it.
81
+ - **A field the card head or footer projects no longer repeats itself as a metadata row.** Set
82
+ `duplicate: true` on the field descriptor to show it in both places.
83
+
84
+ - **`fieldControls` accepts `{label, target}`** on `TableView`, `CardView` and `KanbanView`.
85
+ `true`/`false` are unchanged. The chooser's trigger can now be named, and mounted into a host
86
+ toolbar instead of the view's own — which is what made it usable in a translated product at
87
+ all.
88
+ - **`DialogButton.disabled`**, honoured by the constructor, `setButtons()` and per-view buttons,
89
+ and skipped by `autofocus`. `Sheet` inherits it. A form a client cannot render completely must
90
+ not be submittable, and until now the only way to show that was to reach into the rendered
91
+ footer.
92
+ - **Roughly ninety-six user-visible strings across sixteen components now route through
93
+ `_message()`**, which falls back to `translate()` — so installing a host translator is enough.
94
+ Most are `aria-label` and `title`, which is the half that does not show up in a screenshot: a
95
+ German application previously announced "Clear search", "Close message" and "Previous month" in
96
+ the middle of its own chrome, with no option to prevent it. Every English fallback is
97
+ byte-identical to the previous literal.
98
+ - **`Launcher` and `Filter` label options default to `null`** and resolve through the translator,
99
+ so an application that installs one and passes no labels gets a translated component. The
100
+ rendered words are unchanged without a translator.
101
+ - **`AppSidebar` visual pass.** A filled active pill with an edge marker and a weight change, so
102
+ nothing rests on colour alone; one spacing scale; a fixed icon gutter that collapses when no
103
+ item has an icon; labels that wrap and hyphenate rather than truncate; badges that survive
104
+ minimization as a dot with the number still in the accessible name. Options, events, methods,
105
+ DOM and the keyboard map are unchanged.
106
+ - **`NavigationBar` overflow is configurable.** `overflow: false` keeps every item at every
107
+ width; `overflowBelow` moves the collapse threshold; `minVisible: n` pins the first `n` items.
108
+ Defaults are unchanged — every item still collapses below 44 rem through the same container
109
+ query, with no observer installed. Collapsing all of a navigation into one button is right for
110
+ a top app bar and wrong for a phone bottom bar, and there was no way to say so.
111
+ - **A print stylesheet ships.** `styles/print.css`, imported last, releases sticky headers and
112
+ scroll containers, drops fills, shadows, zebra striping and focus rings, hides overlays and
113
+ navigation chrome, repeats table headers across pages, keeps cards and rows from breaking, and
114
+ prints link URLs in prose but never inside a table cell or on a button. Status badges keep
115
+ their colour, because there it carries meaning beside the word. An application that sets
116
+ `data-zx-theme="dark"` explicitly still prints dark text tokens; `auto` is unaffected.
117
+
118
+ ### Fixed
119
+
120
+ - **Context-menu selection could not be cancelled.** Preventing its `select` event now suppresses
121
+ the item callback and native link navigation and leaves the menu open, matching MenuButton.
122
+ - **The keyboard move handle could take focus while staying invisible.** It revealed itself on
123
+ `:focus-visible`, which does not match after pointer input — so the focus a committed pointer
124
+ drop moves onto the handle landed on a one-pixel control. It now reveals on `:focus`, and
125
+ `dragFrom: 'handle'` keeps the handle visible regardless of `moveHandle`.
126
+ - **A literal indicator descriptor rendered nothing.** `priority: {label: 'Blocked'}` was read as
127
+ a record property name and resolved `undefined`.
128
+ - **A blank progress label produced an unnamed progressbar.** An empty or whitespace label now
129
+ falls back to the localized default instead of becoming `aria-label=""`.
130
+ - **A fractional `maxAvatars` hid every face** while the overflow chip still counted from the raw
131
+ option. The faces and the chip now come from one normalization.
132
+ - **The card identifier named itself with `aria-label` on a `<span>`**, which the generic role
133
+ prohibits. Identifier and indicator prefixes are visually hidden text instead.
134
+ - **An assignee with an image but no name rendered an unidentifiable face.** Entries without a
135
+ name are now dropped rather than announced as "Assigned to ".
136
+ - **Board rendering rebuilt the whole field-descriptor array for every axis read.** A string
137
+ column or lane accessor was resolved through `getFields()` — which clones every descriptor —
138
+ once per record per column per lane. Descriptors are now indexed once per refresh.
139
+
140
+ - **`Modal` and `Dialog` place and restore focus.** Both have always built a native `<dialog>`
141
+ and opened it with `showModal()`, so focus containment, page inertness, Escape and the top
142
+ layer were the platform's — a reading of the source that greps for a focus trap and finds
143
+ none draws the wrong conclusion, and one did. What was genuinely missing is now there:
144
+ initial focus lands on the first focusable control inside the panel rather than on the panel,
145
+ focus returns to the opener on every close path including the non-native presentation, and
146
+ `aria-modal` is set while modal. `Sheet` keeps its own trap for the non-modal case and is not
147
+ double-trapped. Candidates inside a `hidden`, `aria-hidden` or `inert` subtree are now skipped,
148
+ so a dialog whose close button is suppressed focuses its first real control instead of nothing.
149
+ - **`icon()` no longer throws on a name it cannot resolve.** Icon names routinely arrive from a
150
+ server, and one unconfigured name should not take down the screen it appears on. An
151
+ unresolvable inline glyph renders an empty `<svg>` of the requested size — so layout does not
152
+ shift — carrying `data-zx-icon-missing="<name>"`, and reports itself once per distinct name.
153
+ `icon(name, { strict: true })` keeps the old `RangeError` for callers that can afford to fail.
154
+ Font Awesome paths are unaffected: a kit resolves names in the browser, so nothing under one
155
+ is "unknown" here and nothing warns.
156
+ - **The minimized rail's flyout matches the expanded sidebar.** The visual pass in this release
157
+ could not reach it — the panel is portaled into a `Dropdown`, so the sidebar's descendant
158
+ selectors do not apply to it. It now carries the same spacing scale, icon gutter, wrapping
159
+ labels and active-item treatment, derived from the same tokens. Fixing it surfaced a cascade
160
+ bug: `app-rail.css` is imported before `dropdown.css`, so the popover's own padding had never
161
+ won and the panel had been rendering with the generic overlay's.
162
+ - **One physical-direction declaration** remained in the component tree (`table.css`), plus four
163
+ asymmetric box shorthands that pin an edge physically. All are logical now, and a test scans
164
+ for both so the state is enforced rather than accidental.
165
+
11
166
  ## 4.3.4 — 2026-08-31
12
167
 
13
168
  ### Added
package/README.md CHANGED
@@ -127,6 +127,9 @@ ZeyOS binding — see `src/zeyos/modules.js`.
127
127
 
128
128
  | API | Description |
129
129
  | --- | --- |
130
+ | `EntityRef` | Dense linked/static entity identity with labelled metadata and injected actions. |
131
+ | `FileItem`, `FileList` | Durable and transient file presentation with MIME/size metadata, status, progress, downloads, and collection states. |
132
+ | `ActivityItem`, `ActivityList` | Chronological activity entries and grouped collections with actor, time, attachment, action, loading, and empty slots. |
130
133
  | `Table` | Sortable/selectable table with typed transaction columns, flat-data hierarchy/treegrid projection, and opt-in cell/row editing. |
131
134
  | `TableView` | Record-oriented Table composition with shared fields, portable state, column visibility/order, sorting, and selection. |
132
135
  | `CardView` | Responsive record cards with configurable fields, safe preview media, grouping, actions, sorting, and selection. |
@@ -135,6 +138,8 @@ ZeyOS binding — see `src/zeyos/modules.js`.
135
138
  | `Chart`, `ChartJsAdapter` | Accessible engine-neutral chart host and explicitly injected Chart.js adapter. |
136
139
  | `Calendar` | Agenda/day/week/month/year scheduling with timed collisions, spanning events, range selection, and configurable optimistic drag/resize editing. |
137
140
  | `DataFilter` | Declarative select, text, and custom filters for client-side row sets. |
141
+ | `FilterPanel` | Typed filter form built from a server's own field metadata, drafted then applied. |
142
+ | `ListToolbar` | Search, result count, view switch, and badged tools above a record view. |
138
143
  | `TreeView` | APG tree with lazy children, filtering, and tri-state checkboxes. |
139
144
  | `Finder` | Miller-columns hierarchy browser with an optional preview pane. |
140
145
  | `Pagination` | Page, page-size, and load-more pager, with the pure `paginationRange()` helper. |
@@ -146,6 +151,7 @@ ZeyOS binding — see `src/zeyos/modules.js`.
146
151
  | `Field` | Label, description, validation state, and adapter-backed form control. |
147
152
  | `Fieldset` | Native fieldset that owns and coordinates fields. |
148
153
  | `Form` | Form composition, values, validation, highlighting, and actions. |
154
+ | `CodeEditor` | Text-safe structured-text/source editor with native undo, Tab indentation, and position feedback. |
149
155
  | `Questionnaire` | Guided one-question-at-a-time flow: branching, path-aware progress, review. |
150
156
  | `ValueList` | Validated, sortable tag/chip editor. |
151
157
  | `MultiValueEditor` | Ordered editable rows with add, remove, and move controls. |
@@ -160,6 +166,7 @@ ZeyOS binding — see `src/zeyos/modules.js`.
160
166
  | `Avatar` | Fixed-size user image with initials fallback and optional presence. |
161
167
  | `Groupbox` | Collapsible section backed by native `<details>`. |
162
168
  | `Card` | Semantic content/record surface with media, native title link, actions, and footer. |
169
+ | `StatTile`, `statTile()` | Labelled metric with optional delta, sparkline, and loading state. |
163
170
  | `Aurora` | One- to four-colour ambient canvas light; chrome, raised content, and overlays respond through shared material tokens. |
164
171
  | `Launcher` | Cmd/Ctrl+K application and record launcher with ranked local items and abortable grouped sources. |
165
172
  | `Panel` | Framed, optionally collapsible section with a footer. |
@@ -0,0 +1,351 @@
1
+ import { Component } from '../../core/component.js';
2
+ import { Avatar } from '../avatar/avatar.js';
3
+ export type ActivityContent = string | number | Node | Component | null;
4
+ export type AvatarOptions = import('../avatar/avatar.js').AvatarOptions;
5
+ export type ActivityAvatar = AvatarOptions | Element | null;
6
+ export type ActivityAction = {
7
+ /**
8
+ * Stable action identifier.
9
+ */
10
+ id: string | number;
11
+ /**
12
+ * Visible label.
13
+ */
14
+ label?: string;
15
+ /**
16
+ * Icon name.
17
+ */
18
+ icon?: string | null;
19
+ /**
20
+ * Optional safe native-link destination.
21
+ */
22
+ href?: string | null;
23
+ /**
24
+ * Native browsing context.
25
+ */
26
+ target?: string;
27
+ /**
28
+ * Native link relationship.
29
+ */
30
+ rel?: string;
31
+ /**
32
+ * Native title and icon-only accessible label.
33
+ */
34
+ title?: string;
35
+ /**
36
+ * Whether the action is unavailable.
37
+ */
38
+ disabled?: boolean;
39
+ /**
40
+ * Visual intent.
41
+ */
42
+ kind?: 'default' | 'primary' | 'danger' | 'ghost';
43
+ /**
44
+ * Host-owned activation callback.
45
+ */
46
+ onselect?: (event: MouseEvent) => void;
47
+ };
48
+ export type ActivityActionSlot = Element | ActivityAction;
49
+ export type NormalizedActivityAction = {
50
+ /**
51
+ * Stable action identifier.
52
+ */
53
+ id: string;
54
+ /**
55
+ * Visible label.
56
+ */
57
+ label: string;
58
+ /**
59
+ * Icon name.
60
+ */
61
+ icon: string | null;
62
+ /**
63
+ * Safe native-link destination.
64
+ */
65
+ href: string | null;
66
+ /**
67
+ * Native browsing context.
68
+ */
69
+ target: string | undefined;
70
+ /**
71
+ * Native link relationship.
72
+ */
73
+ rel: string | undefined;
74
+ /**
75
+ * Native title.
76
+ */
77
+ title: string | undefined;
78
+ /**
79
+ * Whether the action is unavailable.
80
+ */
81
+ disabled: boolean;
82
+ /**
83
+ * Visual intent.
84
+ */
85
+ kind: 'default' | 'primary' | 'danger' | 'ghost';
86
+ /**
87
+ * Host callback.
88
+ */
89
+ onselect: ((event: MouseEvent) => void) | undefined;
90
+ };
91
+ export type ActivityTime = {
92
+ /**
93
+ * Machine-readable ISO timestamp when valid.
94
+ */
95
+ dateTime: string | null;
96
+ /**
97
+ * Human-readable timestamp.
98
+ */
99
+ label: string;
100
+ };
101
+ export type ActivityState = 'default' | 'pending' | 'failed';
102
+ export type ActivityStateDescriptor = {
103
+ /**
104
+ * Resolved state.
105
+ */
106
+ state: ActivityState;
107
+ /**
108
+ * Whether the entry is still waiting on its request.
109
+ */
110
+ busy: boolean;
111
+ /**
112
+ * Message key for the built-in word, or null when no badge is shown.
113
+ */
114
+ key: string | null;
115
+ /**
116
+ * Built-in English word, or null when no badge is shown.
117
+ */
118
+ fallback: string | null;
119
+ /**
120
+ * Badge intent.
121
+ */
122
+ kind: 'neutral' | 'danger';
123
+ /**
124
+ * Host-supplied word replacing the built-in one.
125
+ */
126
+ label: string | null;
127
+ };
128
+ export type ActivityItemOptions = {
129
+ /**
130
+ * Host-owned activity identifier.
131
+ */
132
+ id?: unknown;
133
+ /**
134
+ * Actor identity text or presentation slot.
135
+ */
136
+ actor?: ActivityContent;
137
+ /**
138
+ * Avatar descriptor or host-owned avatar element.
139
+ */
140
+ avatar?: ActivityAvatar;
141
+ /**
142
+ * Activity summary.
143
+ */
144
+ title?: ActivityContent;
145
+ /**
146
+ * Optional body slot.
147
+ */
148
+ content?: ActivityContent;
149
+ /**
150
+ * Date, parseable date string, or epoch milliseconds.
151
+ */
152
+ timestamp?: Date | string | number | null;
153
+ /**
154
+ * Explicit human-readable timestamp.
155
+ */
156
+ timeLabel?: string | null;
157
+ /**
158
+ * Compact metadata slots.
159
+ */
160
+ metadata?: ActivityContent[];
161
+ /**
162
+ * Attachment presentation slots, commonly FileItem elements.
163
+ */
164
+ attachments?: ActivityContent[];
165
+ /**
166
+ * Native action descriptors or host-owned controls.
167
+ */
168
+ actions?: ActivityActionSlot[];
169
+ /**
170
+ * Product-neutral activity kind exposed as `data-kind`.
171
+ */
172
+ kind?: string;
173
+ /**
174
+ * Delivery state exposed as `data-state`.
175
+ */
176
+ state?: ActivityState;
177
+ /**
178
+ * Word shown in the state badge instead of the built-in one.
179
+ */
180
+ stateLabel?: string | null;
181
+ /**
182
+ * Semantic heading level for the activity summary.
183
+ */
184
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
185
+ onaction?: (event: CustomEvent<{
186
+ id: string;
187
+ action: NormalizedActivityAction;
188
+ event: MouseEvent;
189
+ }>) => void;
190
+ };
191
+ /** @typedef {string|number|Node|Component|null} ActivityContent */
192
+ /** @typedef {import('../avatar/avatar.js').AvatarOptions} AvatarOptions */
193
+ /** @typedef {AvatarOptions|Element|null} ActivityAvatar */
194
+ /**
195
+ * @typedef {Object} ActivityAction
196
+ * @property {string|number} id Stable action identifier.
197
+ * @property {string} [label=''] Visible label.
198
+ * @property {string|null} [icon=null] Icon name.
199
+ * @property {string|null} [href=null] Optional safe native-link destination.
200
+ * @property {string} [target] Native browsing context.
201
+ * @property {string} [rel] Native link relationship.
202
+ * @property {string} [title] Native title and icon-only accessible label.
203
+ * @property {boolean} [disabled=false] Whether the action is unavailable.
204
+ * @property {'default'|'primary'|'danger'|'ghost'} [kind='ghost'] Visual intent.
205
+ * @property {(event:MouseEvent)=>void} [onselect] Host-owned activation callback.
206
+ */
207
+ /** @typedef {Element|ActivityAction} ActivityActionSlot */
208
+ /**
209
+ * @typedef {Object} NormalizedActivityAction
210
+ * @property {string} id Stable action identifier.
211
+ * @property {string} label Visible label.
212
+ * @property {string|null} icon Icon name.
213
+ * @property {string|null} href Safe native-link destination.
214
+ * @property {string|undefined} target Native browsing context.
215
+ * @property {string|undefined} rel Native link relationship.
216
+ * @property {string|undefined} title Native title.
217
+ * @property {boolean} disabled Whether the action is unavailable.
218
+ * @property {'default'|'primary'|'danger'|'ghost'} kind Visual intent.
219
+ * @property {((event:MouseEvent)=>void)|undefined} onselect Host callback.
220
+ */
221
+ /**
222
+ * @typedef {Object} ActivityTime
223
+ * @property {string|null} dateTime Machine-readable ISO timestamp when valid.
224
+ * @property {string} label Human-readable timestamp.
225
+ */
226
+ /** @typedef {'default'|'pending'|'failed'} ActivityState Delivery state of one entry. */
227
+ /**
228
+ * @typedef {Object} ActivityStateDescriptor
229
+ * @property {ActivityState} state Resolved state.
230
+ * @property {boolean} busy Whether the entry is still waiting on its request.
231
+ * @property {string|null} key Message key for the built-in word, or null when no badge is shown.
232
+ * @property {string|null} fallback Built-in English word, or null when no badge is shown.
233
+ * @property {'neutral'|'danger'} kind Badge intent.
234
+ * @property {string|null} label Host-supplied word replacing the built-in one.
235
+ */
236
+ /**
237
+ * @typedef {Object} ActivityItemOptions
238
+ * @property {unknown} [id=null] Host-owned activity identifier.
239
+ * @property {ActivityContent} [actor=''] Actor identity text or presentation slot.
240
+ * @property {ActivityAvatar} [avatar=null] Avatar descriptor or host-owned avatar element.
241
+ * @property {ActivityContent} [title=''] Activity summary.
242
+ * @property {ActivityContent} [content=null] Optional body slot.
243
+ * @property {Date|string|number|null} [timestamp=null] Date, parseable date string, or epoch milliseconds.
244
+ * @property {string|null} [timeLabel=null] Explicit human-readable timestamp.
245
+ * @property {ActivityContent[]} [metadata=[]] Compact metadata slots.
246
+ * @property {ActivityContent[]} [attachments=[]] Attachment presentation slots, commonly FileItem elements.
247
+ * @property {ActivityActionSlot[]} [actions=[]] Native action descriptors or host-owned controls.
248
+ * @property {string} [kind='default'] Product-neutral activity kind exposed as `data-kind`.
249
+ * @property {ActivityState} [state='default'] Delivery state exposed as `data-state`.
250
+ * @property {string|null} [stateLabel=null] Word shown in the state badge instead of the built-in one.
251
+ * @property {1|2|3|4|5|6} [headingLevel=3] Semantic heading level for the activity summary.
252
+ * @property {(event:CustomEvent<{id:string,action:NormalizedActivityAction,event:MouseEvent}>)=>void} [onaction]
253
+ */
254
+ /**
255
+ * One chronological activity entry with safe content slots, timestamp semantics, and native
256
+ * actions. Posting, reactions, routing, permissions, persistence, and content sanitization remain
257
+ * host responsibilities; server HTML is never interpreted by this component.
258
+ *
259
+ * @fires ActivityItem#action
260
+ * @extends {Component<ActivityItemOptions>}
261
+ */
262
+ export declare class ActivityItem extends Component<ActivityItemOptions> {
263
+ _createdRoot: boolean;
264
+ _original: import("../../core/dom.js").TargetSnapshot;
265
+ _cleaned: boolean;
266
+ _headingId: string;
267
+ _avatarComponent: Avatar;
268
+ _actionsByKey: Map<any, any>;
269
+ _activity: ActivityItemOptions;
270
+ static cssName: string;
271
+ /** @type {Readonly<ActivityItemOptions>} */
272
+ static defaults: Readonly<ActivityItemOptions>;
273
+ /**
274
+ * Creates or enhances an activity item.
275
+ * @param {Element|string|null} [target=null] Existing list item/container, selector, or null.
276
+ * @param {ActivityItemOptions} [options={}] Activity presentation options.
277
+ */
278
+ constructor(target?: Element | string | null, options?: ActivityItemOptions);
279
+ /** @returns {HTMLElement} */
280
+ render(): HTMLElement;
281
+ /**
282
+ * Replaces any subset of the activity presentation.
283
+ * @param {Partial<ActivityItemOptions>} values New values.
284
+ * @returns {this}
285
+ */
286
+ setActivity(values?: Partial<ActivityItemOptions>): this;
287
+ /** Returns a shallow, host-safe copy of the current descriptor. @returns {ActivityItemOptions} */
288
+ getActivity(): ActivityItemOptions;
289
+ /** Restores an enhanced target exactly, or removes an owned item. @returns {void} */
290
+ destroy(): void;
291
+ /** @private @returns {void} */
292
+ private _renderActivity;
293
+ /**
294
+ * Builds the delivery badge, or nothing for an ordinary entry.
295
+ * @private
296
+ * @param {ActivityStateDescriptor} state Resolved state.
297
+ * @returns {HTMLElement|null}
298
+ */
299
+ private _createStateBadge;
300
+ /** @private @param {ActivityAvatar} value @param {ActivityContent} actor @returns {Element|null} */
301
+ private _createAvatar;
302
+ /** @private @param {ActivityActionSlot[]} value @returns {HTMLElement|null} */
303
+ private _createActions;
304
+ /**
305
+ * Resolves a message through the host translator, falling back to the built-in English text.
306
+ * @param {string} key Message key.
307
+ * @param {string} fallback Built-in text, with `%1`-style placeholders.
308
+ * @param {...unknown} args Interpolation values.
309
+ * @returns {string}
310
+ */
311
+ _message(key: string, fallback: string, ...args: unknown[]): string;
312
+ /** @private @param {MouseEvent} event @returns {void} */
313
+ private _onClick;
314
+ }
315
+ /**
316
+ * Normalizes action descriptors without mutating the caller's array or objects. Invalid entries
317
+ * and duplicate descriptor IDs are discarded; host-owned Elements pass through unchanged.
318
+ * @param {unknown} value Candidate action array.
319
+ * @returns {Array<Element|NormalizedActivityAction>}
320
+ */
321
+ export declare function resolveActivityActions(value: unknown): Array<Element | NormalizedActivityAction>;
322
+ /**
323
+ * Normalizes one action descriptor and rejects unsafe native destinations.
324
+ * @param {unknown} value Candidate action.
325
+ * @returns {NormalizedActivityAction|null}
326
+ */
327
+ export declare function normalizeActivityAction(value: unknown): NormalizedActivityAction | null;
328
+ /**
329
+ * Resolves the delivery state of one entry.
330
+ *
331
+ * `failed` is a first-class state and not the absence of `pending`: an optimistic entry that
332
+ * simply disappears when its request fails tells the customer their message was sent when nobody
333
+ * was told, so the component keeps the entry and says what happened to it.
334
+ * @param {unknown} state Requested state.
335
+ * @param {unknown} stateLabel Host-supplied word replacing the built-in one.
336
+ * @returns {ActivityStateDescriptor}
337
+ */
338
+ export declare function resolveActivityState(state: unknown, stateLabel: unknown): ActivityStateDescriptor;
339
+ /**
340
+ * Resolves a timestamp for native `<time>` markup without treating invalid input as a real date.
341
+ * @param {Date|string|number|null|undefined} timestamp Date-like value.
342
+ * @param {string|null|undefined} timeLabel Explicit display label.
343
+ * @returns {ActivityTime|null}
344
+ */
345
+ export declare function normalizeActivityTimestamp(timestamp: Date | string | number | null | undefined, timeLabel: string | null | undefined): ActivityTime | null;
346
+ /**
347
+ * Activity action selected before the host callback or native navigation runs. Cancellation from
348
+ * either the component event or bubbling `zx-action` event prevents both callback and navigation.
349
+ * @event ActivityItem#action
350
+ * @type {CustomEvent<{id:string,action:NormalizedActivityAction,event:MouseEvent}>}
351
+ */