@vectoriox/iox-ui 5.36.0 → 5.37.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.
@@ -1,3 +1,5 @@
1
+ import { CompositeItemAction } from '@vectoriox/iox-ui/composite-core';
2
+
1
3
  /**
2
4
  * The ONE descriptor shape for everything an author can put in an ordered action list —
3
5
  * a form's after-submit steps today, element behaviour actions (A1) next. Promoted out of
@@ -8,7 +10,7 @@
8
10
  /** How a step executes — decides which editor fields appear (timing only for `animated`). */
9
11
  type ActionKind = 'animated' | 'instant' | 'server';
10
12
  /** Picker grouping. Flat lists die at ~10 entries; the group is data, never a second list. */
11
- type ActionGroup = 'motion' | 'visibility' | 'navigate' | 'dialog' | 'form' | 'data' | 'consent' | 'service';
13
+ type ActionGroup = 'motion' | 'visibility' | 'navigate' | 'dialog' | 'item' | 'form' | 'data' | 'consent' | 'service';
12
14
  /**
13
15
  * What a step does inside the live builder canvas (the canvas RUNS interactions):
14
16
  * `run` for real (open the dialog), `simulate` announce-only (navigate), `inert` with a
@@ -26,10 +28,12 @@ interface ActionParamSpec {
26
28
  labelKey: string;
27
29
  }[];
28
30
  }
29
- /** Does this action point at another node — and may it be any node or only certain types? */
31
+ /** Does this action point at another node — and may it be any node, or only certain types / composite roles? */
30
32
  interface ActionTargetSpec {
31
33
  required: boolean;
32
34
  types?: string[];
35
+ /** Only nodes playing one of these composite roles (`openItem` targets an accordion item or a disclosure). */
36
+ roles?: string[];
33
37
  }
34
38
  /**
35
39
  * One row of an action catalog. Every field beyond `type`/`labelKey` is optional so the
@@ -105,6 +109,11 @@ declare const SERVER_ELEMENT_ACTION_TYPES: ReadonlySet<string>;
105
109
  /** The Tier-A behaviour executors' dispatch set (A1c) — the engines branch on it beside
106
110
  * DIALOG/SWIPER. Dialog actions have their own set; context/visibility stay in the legacy path. */
107
111
  declare const BEHAVIOUR_ACTION_TYPES: ReadonlySet<string>;
112
+ /** The item actions' dispatch set (T14) and what each does to its item — the engines branch on it beside
113
+ * DIALOG/BEHAVIOUR, and composite-core `runCompositeItemAction` runs it on the target item's own runtime. */
114
+ declare const ITEM_ACTION_TYPES: Readonly<Record<string, CompositeItemAction>>;
115
+ /** The item action an action type runs, or null when it is not one. */
116
+ declare function itemActionOf(type: string | null | undefined): CompositeItemAction | null;
108
117
  /** The consent actions' dispatch set (C3) — the engines branch on it beside DIALOG/BEHAVIOUR.
109
118
  * `openConsentPreferences` is dialog-opening by nature and included so ONE branch owns consent. */
110
119
  declare const CONSENT_ACTION_TYPES: ReadonlySet<string>;
@@ -166,5 +175,5 @@ declare function dialogOpenerAttributes(node: OpenerNodeLike | null | undefined,
166
175
  /** The selector of every opener of one dialog (by its DOM id) — what a runtime updates on open/close. */
167
176
  declare function dialogOpenersSelector(dialogDomIdValue: string): string;
168
177
 
169
- export { BEHAVIOUR_ACTION_TYPES, CONSENT_ACTION_TYPES, DIALOG_ACTION_TYPE_SET, DIALOG_OPENER_ACTION_TYPES, DIALOG_OPENER_TRIGGER, DIALOG_SELECTOR, ELEMENT_ACTION_DESCRIPTORS, ELEMENT_ACTION_GROUP_ORDER, FORM_SUBMIT_ACTION_DESCRIPTORS, OpenerAttribute, SERVER_ELEMENT_ACTION_TYPES, addableActions, dialogDomId, dialogOpenerAttributes, dialogOpenersSelector, groupedElementActions, nodeIdOfDialogDomId, openedDialogId, resolveActionAvailability };
178
+ export { BEHAVIOUR_ACTION_TYPES, CONSENT_ACTION_TYPES, DIALOG_ACTION_TYPE_SET, DIALOG_OPENER_ACTION_TYPES, DIALOG_OPENER_TRIGGER, DIALOG_SELECTOR, ELEMENT_ACTION_DESCRIPTORS, ELEMENT_ACTION_GROUP_ORDER, FORM_SUBMIT_ACTION_DESCRIPTORS, ITEM_ACTION_TYPES, OpenerAttribute, SERVER_ELEMENT_ACTION_TYPES, addableActions, dialogDomId, dialogOpenerAttributes, dialogOpenersSelector, groupedElementActions, itemActionOf, nodeIdOfDialogDomId, openedDialogId, resolveActionAvailability };
170
179
  export type { ActionAvailability, ActionAvailabilityContext, ActionAvailabilityState, ActionDescriptor, ActionGroup, ActionKind, ActionParamSpec, ActionTargetSpec, BuilderBehaviour, OpenerActionLike, OpenerInteractionLike, OpenerNodeLike };
@@ -41,6 +41,9 @@ interface CompositeNodeSpec {
41
41
  elementStyle?: string | null;
42
42
  }
43
43
  type CompositeNodeFactory = (spec: CompositeNodeSpec) => CompositeNode;
44
+ /** A recipe part: a NEW node (`create`) playing `role` under `label`, with the layout `base` styles its recipe
45
+ * gives it — its LOOK is its element style. Shared by every recipe (Accordion, Disclosure). */
46
+ declare function makeCompositePart(create: CompositeNodeFactory, spec: CompositeNodeSpec, role: string | null, label: string | undefined, base?: Readonly<Record<string, string>>): CompositeNode;
44
47
  /** A content trait's value — `traits[].default` on a builder node, `props[name]` on a saved one. */
45
48
  declare function readProp(node: CompositeNode, name: string): unknown;
46
49
  /** Write a content trait. False when a builder node has no such trait (the value would be dropped). */
@@ -68,6 +71,68 @@ declare function parentInComposite(root: CompositeNode, node: CompositeNode): Co
68
71
  /** Detach `node` from its parent inside `root`. True when it was found. */
69
72
  declare function removeFromComposite(root: CompositeNode, node: CompositeNode): boolean;
70
73
 
74
+ /**
75
+ * The open/close composites' kinds and roles (CC2 Accordion, CC2.1 Disclosure — composite plan T9 / T21). ONE
76
+ * family: a Disclosure is a one-item accordion whose ROOT is its item, so both run the same state machine, the
77
+ * same attribute planners and the same runtime (`accordion-runtime.ts`). Every consumer that treats "an item",
78
+ * "a header" or "a panel" alike asks these predicates, never a role literal.
79
+ */
80
+ declare enum CompositeKind {
81
+ Accordion = "accordion",
82
+ Disclosure = "disclosure"
83
+ }
84
+ declare enum AccordionRole {
85
+ Accordion = "accordion",
86
+ Item = "accordion.item",
87
+ Trigger = "accordion.trigger",
88
+ Icon = "accordion.icon",
89
+ Panel = "accordion.panel"
90
+ }
91
+ /**
92
+ * DISCLOSURE ("Read more") — one trigger, one panel. The root IS its item (it carries the item key and
93
+ * `data-iox-on`); the trigger holds two words, the one shown while closed (`more`) and the one shown while open
94
+ * (`less`), swapped by the Item open state — never by script.
95
+ */
96
+ declare enum DisclosureRole {
97
+ Disclosure = "disclosure",
98
+ Trigger = "disclosure.trigger",
99
+ More = "disclosure.more",
100
+ Less = "disclosure.less",
101
+ Icon = "disclosure.icon",
102
+ Panel = "disclosure.panel"
103
+ }
104
+ interface RoleLike$1 {
105
+ role?: string | null;
106
+ }
107
+ /** The roles each kind plays in the shared runtime. */
108
+ interface CompositeKindRoles {
109
+ root: string;
110
+ item: string;
111
+ trigger: string;
112
+ panel: string;
113
+ icon: string;
114
+ }
115
+ declare const COMPOSITE_KIND_ROLES: Readonly<Record<CompositeKind, CompositeKindRoles>>;
116
+ /** The kind a role belongs to (`disclosure.panel` → Disclosure), or null for any other role. */
117
+ declare function compositeKindOfRole(role: string | null | undefined): CompositeKind | null;
118
+ /** A root that runs the open/close runtime (an Accordion or a Disclosure). */
119
+ declare function isCompositeRoot(node: RoleLike$1 | null | undefined): boolean;
120
+ /** An ITEM — an accordion's item, or a disclosure (its own item). */
121
+ declare function isCompositeItem(node: RoleLike$1 | null | undefined): boolean;
122
+ /** A trigger — rendered as a `<button>` that opens its item, never a link. */
123
+ declare function isCompositeTrigger(node: RoleLike$1 | null | undefined): boolean;
124
+ /** A panel — rendered inside the track + region the one hiding rule collapses. */
125
+ declare function isCompositePanel(node: RoleLike$1 | null | undefined): boolean;
126
+ declare function isDisclosureRoot(node: RoleLike$1 | null | undefined): boolean;
127
+ /** True for any part of a disclosure (its root included). */
128
+ declare function isDisclosurePart(node: RoleLike$1 | null | undefined): boolean;
129
+ /** The composite root a node belongs to: the nearest ancestor (or the node itself) that is one. `path` = the
130
+ * node's ancestors, root first. */
131
+ declare function compositeRootOf<T extends RoleLike$1>(node: T, path: ReadonlyArray<T>): T | null;
132
+ /** The item a node sits in — the nearest item of either kind (itself when it is one) — or null. An accordion
133
+ * root ends the walk (its items are below it). */
134
+ declare function compositeItemOf<T extends RoleLike$1>(node: T, path: ReadonlyArray<T>): T | null;
135
+
71
136
  /**
72
137
  * ACCORDION (CC2 — composite K1; complex-components boards 3, 4 and 9, APPROVED 2026-10-20). Not a
73
138
  * component: a recipe of ordinary nodes, each part carrying a role, so every part is selectable on the
@@ -86,13 +151,6 @@ declare function removeFromComposite(root: CompositeNode, node: CompositeNode):
86
151
  * (`nextAccordionState`), the ARIA and DOM state one planner (`accordionItemState` and the attribute
87
152
  * functions), the keyboard one key map — read by the builder canvas, both engine paths and the composer.
88
153
  */
89
- declare enum AccordionRole {
90
- Accordion = "accordion",
91
- Item = "accordion.item",
92
- Trigger = "accordion.trigger",
93
- Icon = "accordion.icon",
94
- Panel = "accordion.panel"
95
- }
96
154
  /** The behaviour options a composite root stores as ordinary TRAITS (composite plan §3). */
97
155
  declare enum CompositeBehaviourTrait {
98
156
  /** Several items may be open at once ("Allow several open"). */
@@ -138,6 +196,9 @@ interface AccordionOptions {
138
196
  defaultOn?: AccordionDefaultOn;
139
197
  icon?: AccordionIcon;
140
198
  }
199
+ /** The icon of an item (an accordion's, or a disclosure's — `role`); its Item-open state (the turn) is driven by
200
+ * ITS item (`stateTriggers`). ONE builder for both kinds. */
201
+ declare function buildCompositeIcon(create: CompositeNodeFactory, key: string, icon: Exclude<AccordionIcon, AccordionIcon.None>, itemId?: string, role?: string): CompositeNode;
141
202
  /** One item: header (question + icon) and panel (answer). `key` makes every part's recipe key unique. */
142
203
  declare function buildAccordionItem(create: CompositeNodeFactory, words: AccordionWords, itemKey: string, icon?: AccordionIcon): CompositeNode;
143
204
  /** A fresh Accordion: three items, one open at a time, the first open by default (board 4). */
@@ -170,11 +231,14 @@ interface AccordionBehaviour {
170
231
  declare function accordionBehaviour(root: CompositeNode | null | undefined): AccordionBehaviour;
171
232
  /** Behaviour ▸ Allow several open / Open by default. False when the node has no such trait. */
172
233
  declare function setAccordionBehaviour(root: CompositeNode, patch: Partial<AccordionBehaviour>): boolean;
173
- /** The header of an item. */
234
+ /** The header of an item (either kind). */
174
235
  declare function accordionTriggerOf(item: CompositeNode): CompositeNode | undefined;
175
- /** The panel of an item. */
236
+ /** The panel of an item (either kind). */
176
237
  declare function accordionPanelOf(item: CompositeNode): CompositeNode | undefined;
177
- /** The question: the first Heading inside the header. */
238
+ /** A root's items — an accordion's (`accordionItems`), or a disclosure, which is its own one item. */
239
+ declare function compositeItems(root: CompositeNode): CompositeNode[];
240
+ /** The question: the first Heading inside the header — a disclosure's toggle holds no heading, so its first word
241
+ * (the Text shown while closed, "Read more"). */
178
242
  declare function accordionQuestionOf(item: CompositeNode): CompositeNode | undefined;
179
243
  /** The answer: the first Text inside the panel. */
180
244
  declare function accordionAnswerOf(item: CompositeNode): CompositeNode | undefined;
@@ -199,7 +263,7 @@ declare enum AccordionEditRefusal {
199
263
  }
200
264
  /** Why removing `item` from `root` is refused, or null. */
201
265
  declare function accordionRemovalRefusal(root: CompositeNode | null | undefined, item: CompositeNode | null | undefined): AccordionEditRefusal | null;
202
- /** The icon the accordion's items wear now (the first item's; None when it has no icon). */
266
+ /** The icon the composite's items wear now (the first item's; None when it has no icon). Either kind. */
203
267
  declare function detectAccordionIcon(root: CompositeNode): AccordionIcon;
204
268
  /**
205
269
  * Behaviour ▸ Icon: every item's header shows the chevron, the plus, or no icon. A switch between glyphs
@@ -213,8 +277,10 @@ declare function itemOpenTriggerIds(root: CompositeNode): void;
213
277
  declare function initialAccordionOpen(keys: ReadonlyArray<string>, defaultOn: AccordionDefaultOn): Set<string>;
214
278
  /** The open keys after toggling `key`: one at a time closes the others; several leaves them. */
215
279
  declare function nextAccordionState(open: ReadonlySet<string>, key: string, behaviour: Pick<AccordionBehaviour, 'multiple'>): Set<string>;
216
- /** The open keys after OPENING `key` (find-in-page, selecting into a closed panel). */
280
+ /** The open keys after OPENING `key` (find-in-page, selecting into a closed panel, the `openItem` action). */
217
281
  declare function openAccordionItem(open: ReadonlySet<string>, key: string, behaviour: Pick<AccordionBehaviour, 'multiple'>): Set<string>;
282
+ /** The open keys after CLOSING `key` (the `closeItem` action). */
283
+ declare function closeAccordionItem(open: ReadonlySet<string>, key: string): Set<string>;
218
284
  declare enum AccordionKeyAction {
219
285
  Next = "next",
220
286
  Previous = "previous",
@@ -233,23 +299,32 @@ interface AccordionDomIds {
233
299
  trigger: string;
234
300
  panel: string;
235
301
  }
236
- /** The ARIA pairing ids of an item: unique per accordion (its root's node id) and per item (its key). */
237
- declare function accordionDomIds(rootId: string, itemKey: string): AccordionDomIds;
302
+ /** The ARIA pairing ids of an item: unique per composite (its SCOPE id — `compositeScopeId`) and per item (its key). */
303
+ declare function accordionDomIds(rootId: string, itemKey: string, kind?: CompositeKind): AccordionDomIds;
304
+ /**
305
+ * The id a rendered composite's ARIA ids are built from: its node id, and — when it sits inside repeated rows —
306
+ * every enclosing row's identity, outermost first (vectoriox/iox-ui#20: an accordion repeated per card used to
307
+ * pair every row's header with the FIRST row's panel). The engine folds each row's `rowItemKey`; the builder
308
+ * canvas its preview row's index. Unrepeated, it is the node id unchanged.
309
+ */
310
+ declare function compositeScopeId(rootId: string, rowKeys?: ReadonlyArray<string>): string;
238
311
  /** One item's render state: its identity, whether it is open, and its ARIA ids. */
239
312
  interface AccordionItemState {
313
+ kind: CompositeKind;
240
314
  key: string;
241
315
  index: number;
242
316
  on: boolean;
243
317
  ids: AccordionDomIds;
244
318
  }
245
- /** The render scope of one accordion: its root id, behaviour and every item key in order. */
319
+ /** The render scope of one composite: its kind, scope id, behaviour and every item key in order. */
246
320
  interface AccordionScope {
321
+ kind: CompositeKind;
247
322
  rootId: string;
248
323
  behaviour: AccordionBehaviour;
249
324
  keys: ReadonlyArray<string>;
250
325
  open: ReadonlySet<string>;
251
326
  }
252
- declare function accordionScope(rootId: string, behaviour: AccordionBehaviour, keys: ReadonlyArray<string>): AccordionScope;
327
+ declare function accordionScope(rootId: string, behaviour: AccordionBehaviour, keys: ReadonlyArray<string>, kind?: CompositeKind): AccordionScope;
253
328
  declare function accordionItemState(scope: AccordionScope, index: number): AccordionItemState;
254
329
  /** Attribute values: a string, or '' for a present boolean attribute. Absent attributes are left out. */
255
330
  type DomAttributes = Record<string, string>;
@@ -259,6 +334,9 @@ declare const ITEM_KEY_ATTRIBUTE = "data-iox-item-key";
259
334
  declare const COMPOSITE_ATTRIBUTE = "data-iox-composite";
260
335
  declare const MULTIPLE_ATTRIBUTE = "data-iox-multiple";
261
336
  declare const DEFAULT_ON_ATTRIBUTE = "data-iox-default-on";
337
+ /** The scope id the ARIA ids are built from (`compositeScopeId`), written by the engine so the runtime re-stamps
338
+ * exactly the ids the server rendered. */
339
+ declare const SCOPE_ATTRIBUTE = "data-iox-scope";
262
340
  /** The value a closed panel's region carries: find-in-page can still reveal it (D9, board 4). */
263
341
  declare const UNTIL_FOUND = "until-found";
264
342
  /** The structural classes the renderers write around an accordion's parts (no node owns them). */
@@ -268,13 +346,16 @@ declare enum AccordionClass {
268
346
  Track = "iox-accordion-track",
269
347
  Region = "iox-accordion-region"
270
348
  }
271
- declare function accordionRootAttributes(behaviour: AccordionBehaviour): DomAttributes;
349
+ declare function accordionRootAttributes(behaviour: AccordionBehaviour, kind?: CompositeKind, scopeId?: string): DomAttributes;
272
350
  declare function accordionItemAttributes(state: AccordionItemState): DomAttributes;
273
351
  declare function accordionTriggerAttributes(state: AccordionItemState): DomAttributes;
274
352
  /** The track wrapping a panel: its row collapses to 0 while closed (the ONE hiding rule, iox-design.css). */
275
353
  declare function accordionTrackAttributes(state: AccordionItemState): DomAttributes;
276
- /** The region the panel sits in: `hidden="until-found"` while closed, so its words stay in the page. */
354
+ /** The region the panel sits in: `hidden="until-found"` while closed, so its words stay in the page. An accordion's
355
+ * is a labelled `region` (APG accordion); a disclosure's is a plain block (APG disclosure: the button names it). */
277
356
  declare function accordionRegionAttributes(state: AccordionItemState): DomAttributes;
357
+ /** True when a region of this kind is a labelled `role=region`. */
358
+ declare function hasLabelledRegion(kind: CompositeKind): boolean;
278
359
  declare function accordionPanelAttributes(state: AccordionItemState): DomAttributes;
279
360
  /** `attrs` as an HTML attribute string (` a="b" c`), values escaped by `esc`. */
280
361
  declare function serializeDomAttributes(attrs: DomAttributes, esc: (v: string) => string): string;
@@ -322,13 +403,17 @@ declare function accordionPartStyle(node: CompositeNode, name: string): unknown;
322
403
  * paths render the same markup). It reads the markup the renderers write (iox-design.css + accordion.ts's
323
404
  * attribute planners), so the server's first paint and every later state agree:
324
405
  *
325
- * [root] data-iox-composite="accordion" data-iox-default-on [data-iox-multiple] (the node's own element —
326
- * its role class may sit on a wrapper host, as the engine's component-path Repeater draws it)
406
+ * [root] data-iox-composite="accordion" data-iox-default-on [data-iox-multiple] [data-iox-scope] (the node's
407
+ * own element — its role class may sit on a wrapper host, as the engine's component-path Repeater draws it)
327
408
  * .iox-role-accordion-item data-iox-item-key [data-iox-on]
328
409
  * hN.iox-accordion-heading > button.iox-accordion-button id aria-expanded aria-controls
329
410
  * .iox-accordion-track [data-iox-on] > .iox-accordion-region role=region [hidden=until-found]
330
411
  * .iox-role-accordion-panel
331
412
  *
413
+ * The DISCLOSURE (CC2.1) runs on this same runtime: `data-iox-composite="disclosure"` on a root that IS its one
414
+ * item (it carries the key and `data-iox-on`), its button straight inside it (no heading), its panel in the same
415
+ * track + region (a plain block — no `role=region`), and no arrow keys (one button).
416
+ *
332
417
  * It owns: a click on a header toggles its item; ↓ ↑ Home End move between the headers of THIS accordion
333
418
  * (a nested one keeps its own); find-in-page (`beforematch`) opens the item that holds the match; a closed
334
419
  * panel gets `hidden="until-found"` after its track has collapsed (at once under reduced motion). Every
@@ -339,8 +424,11 @@ declare function accordionPartStyle(node: CompositeNode, name: string): unknown;
339
424
  declare const ITEM_ON_EVENT = "iox-item-on";
340
425
  declare const ITEM_OFF_EVENT = "iox-item-off";
341
426
  interface AccordionRuntimeOptions {
342
- /** The root's node id — the ARIA ids' prefix (else read from the root's `iox-node-<id>` class). */
343
- rootId?: string;
427
+ /** The composite's scope id — the ARIA ids' prefix (else the root's `data-iox-scope`, else its `iox-node-<id>`). A
428
+ * function is read at every stamp (the builder canvas: a preview row's index is known once it is in the page). */
429
+ rootId?: string | (() => string);
430
+ /** Accordion or Disclosure (else read from the root's `data-iox-composite`). */
431
+ kind?: CompositeKind;
344
432
  /** The behaviour (else read from the root's data attributes). */
345
433
  behaviour?: AccordionBehaviour;
346
434
  /** Keys forced open on top of the live state (the builder's design state). */
@@ -350,9 +438,9 @@ interface AccordionRuntimeOptions {
350
438
  /** True to stop motion (default: the visitor's reduced-motion setting). */
351
439
  reducedMotion?: () => boolean;
352
440
  }
353
- /** The accordion an element belongs to (the element itself when it is a root). */
441
+ /** The composite (accordion or disclosure) an element belongs to (the element itself when it is a root). */
354
442
  declare function closestAccordion(el: Element | null | undefined): HTMLElement | null;
355
- /** The item an element sits in (itself when it is one). */
443
+ /** The item an element sits in (itself when it is one) — an accordion item, or a disclosure. */
356
444
  declare function closestAccordionItem(el: Element | null | undefined): HTMLElement | null;
357
445
  /** Subscribe to an item turning on / off — what the `itemOn` / `itemOff` interaction triggers listen to. The
358
446
  * item is the element's own item (the element itself when it is one). Returns the unsubscribe. */
@@ -370,11 +458,12 @@ declare class AccordionRuntime {
370
458
  private behaviourValue;
371
459
  /** The builder attaches a root before its items render: the saved default is applied once they do. */
372
460
  private awaitingItems;
461
+ readonly kind: CompositeKind;
373
462
  constructor(root: HTMLElement, options?: AccordionRuntimeOptions);
374
463
  get behaviour(): AccordionBehaviour;
375
464
  /** The behaviour changed in the panel: re-read, and start from the new default. */
376
465
  setBehaviour(behaviour: AccordionBehaviour): void;
377
- /** THIS accordion's items, in document order (a nested accordion's items are its own). */
466
+ /** THIS composite's items, in document order (a nested composite's items are its own); a disclosure's is itself. */
378
467
  items(): HTMLElement[];
379
468
  /** The open keys the live state holds (before anything forced). */
380
469
  get liveKeys(): ReadonlySet<string>;
@@ -383,6 +472,9 @@ declare class AccordionRuntime {
383
472
  keyOf(item: Element, items?: HTMLElement[]): string;
384
473
  toggle(key: string): void;
385
474
  open(key: string): void;
475
+ close(key: string): void;
476
+ /** Run an item action (`openItem` / `closeItem` / `toggleItem`, T14) on `key`. True when it shows open after. */
477
+ run(action: CompositeItemAction, key: string): boolean;
386
478
  /** Back to the saved default ("Showing on canvas ▸ As saved"). */
387
479
  resetLive(): void;
388
480
  /** The forced set changed (builder design state): show it. */
@@ -401,13 +493,73 @@ declare class AccordionRuntime {
401
493
  private readonly onKeydown;
402
494
  private readonly onBeforeMatch;
403
495
  }
404
- /** Attach the runtime to one rendered accordion root, unless it already runs one. Returns the NEW runtime, or
496
+ /** Attach the runtime to one rendered composite root, unless it already runs one. Returns the NEW runtime, or
405
497
  * null when the root already had one (so a caller destroys only what it created). */
406
498
  declare function attachAccordionAt(root: HTMLElement, options?: Omit<AccordionRuntimeOptions, 'rootId' | 'behaviour'>): AccordionRuntime | null;
407
499
  /** Attach the runtime to every accordion under `container` that has none yet. Returns the new runtimes. */
408
500
  declare function attachAccordions(container: ParentNode, options?: Omit<AccordionRuntimeOptions, 'rootId' | 'behaviour'>): AccordionRuntime[];
409
501
  /** Detach a runtime `attachAccordions` created. */
410
502
  declare function detachAccordion(runtime: AccordionRuntime): void;
503
+ /** The repeated rows an element sits in, outermost first — each row's index as its row wrappers stamp it
504
+ * (`data-iox-row-idx`: the builder's Repeater rows, the engine's component path). The builder folds them into a
505
+ * composite's scope id (`compositeScopeId`, vectoriox/iox-ui#20); the element itself is not counted. */
506
+ declare function compositeRowKeys(el: Element | null | undefined): string[];
507
+ /** The runtime running a composite root, or null. */
508
+ declare function accordionRuntimeOf(root: Element | null | undefined): AccordionRuntime | null;
509
+ /** What an item action does to its target item (actions-core `openItem` / `closeItem` / `toggleItem`). */
510
+ declare enum CompositeItemAction {
511
+ Open = "open",
512
+ Close = "close",
513
+ Toggle = "toggle"
514
+ }
515
+ /**
516
+ * Run an item action on the element of an ITEM (an accordion item, or a disclosure) — the `openItem` /
517
+ * `closeItem` / `toggleItem` interaction actions, on the canvas and on the live site through this one function.
518
+ * Returns whether the item shows open afterwards, or null when `el` is in no running composite.
519
+ */
520
+ declare function runCompositeItemAction(el: Element | null | undefined, action: CompositeItemAction): boolean | null;
521
+ /** True when an item an action just opened is out of view and the page should scroll to it (T14: "opens that item
522
+ * and scrolls to it") — never when its head is already on screen, so a button beside it does not jolt the page. */
523
+ declare function shouldScrollToItem(top: number, viewportHeight: number): boolean;
524
+
525
+ /**
526
+ * DISCLOSURE / "Read more" (CC2.1 — composite T21). Not a component: a recipe of ordinary nodes on the
527
+ * ACCORDION's machinery — a disclosure is a one-item accordion whose root is its item, so it runs the same
528
+ * state machine, attribute planners and runtime (`accordion-runtime.ts`), on the canvas and on the live site.
529
+ *
530
+ * Container `box` role disclosure itemKey k1 · trait defaultOn (none | first)
531
+ * ├─ LinkedContainer `accordion-trigger` role disclosure.trigger → <button aria-expanded aria-controls>
532
+ * │ ├─ Text `body` (span) role disclosure.more "Read more" — hidden while open
533
+ * │ ├─ Text `body` (span) role disclosure.less "Read less" — shown only while open
534
+ * │ └─ Icon `icon` role disclosure.icon Item open → turns
535
+ * └─ Container `accordion-panel` role disclosure.panel inside a hidden="until-found" track
536
+ * └─ Text `body` the rest of the text
537
+ *
538
+ * The words swap through the ordinary Item open state (`trigger-on` → the root), so the label an author sees on
539
+ * the canvas is the one the visitor gets, with no script and nothing to break. The look is the accordion's own
540
+ * element styles (no `disclosure-*` contract: the boards draw none) — the header's ink, hover ink and focus ring;
541
+ * the panel's padding and muted ink — and the words are `body` text: the site's body type, with `color: inherit`, so
542
+ * the toggle's ink and its hover ink reach them.
543
+ */
544
+ interface DisclosureWords {
545
+ more: string;
546
+ less: string;
547
+ body: string;
548
+ }
549
+ /** The words a fresh disclosure starts with — generic, the author's to replace. */
550
+ declare const DISCLOSURE_WORDS: Readonly<DisclosureWords>;
551
+ interface DisclosureOptions {
552
+ words?: Partial<DisclosureWords>;
553
+ /** Open on first render (default: closed). */
554
+ open?: boolean;
555
+ icon?: AccordionIcon;
556
+ }
557
+ /** A disclosure's one item key — its root IS its item. */
558
+ declare const DISCLOSURE_ITEM_KEY = "k1";
559
+ /** A fresh Disclosure: "Read more" opens the text below and reads "Read less" while it is open; closed by default. */
560
+ declare function buildDisclosureRecipe(create: CompositeNodeFactory, options?: DisclosureOptions): CompositeNode;
561
+ /** Behaviour ▸ Open by default (a disclosure: on or off). */
562
+ declare function disclosureOpenByDefault(root: CompositeNode): boolean;
411
563
 
412
564
  /**
413
565
  * BADGE + CHIP (composite T25; complex-components board 8). A Badge is a Container wearing
@@ -615,5 +767,5 @@ declare function structureRefusal(node: RoleLike | null | undefined, edit: Struc
615
767
  * composite is always allowed — only its locked parts are refused. */
616
768
  declare function isLockedPart(node: RoleLike | null | undefined): boolean;
617
769
 
618
- export { ACCORDION_BIND_PROP, ACCORDION_CONTENT_LIMIT, ACCORDION_DEFAULT_ONS, ACCORDION_ICONS, ACCORDION_ICON_GLYPH, ACCORDION_NEW_ITEM_WORDS, ACCORDION_WORDS, AccordionClass, AccordionDefaultOn, AccordionEditRefusal, AccordionIcon, AccordionKeyAction, AccordionRole, AccordionRuntime, BADGE_TONES, BADGE_TONE_ICONS, BadgeTone, CARD_LAYOUTS, CARD_LAYOUT_CUSTOM, CARD_PARTS, CARD_PART_ROLE, CARD_STACK_BREAKPOINT, CARD_WORDS, CHIP_ICON, CHIP_STYLE, COMPOSITE_ATTRIBUTE, COMPOSITE_ROLE_SPECS, CardLayout, CardPart, CardRole, CompositeBehaviourTrait, DEFAULT_ON_ATTRIBUTE, ITEM_KEY_ATTRIBUTE, ITEM_OFF_EVENT, ITEM_ON_EVENT, ITEM_OPEN_STATE, MULTIPLE_ATTRIBUTE, ON_ATTRIBUTE, ON_STATE, PILL_LABEL_STYLE, StructureEdit, StructureRefusal, UNTIL_FOUND, accordionAnswerOf, accordionBehaviour, accordionDomIds, accordionFocusIndex, accordionHeadingLevel, accordionItemAttributes, accordionItemLabel, accordionItemOf, accordionItemState, accordionItems, accordionKeyAction, accordionPanelAttributes, accordionPanelOf, accordionPartStyle, accordionQuestionOf, accordionRegionAttributes, accordionRemovalRefusal, accordionRootAttributes, accordionRootOf, accordionScope, accordionToContent, accordionToManual, accordionTrackAttributes, accordionTriggerAttributes, accordionTriggerOf, addAccordionItem, applyCardLayout, attachAccordionAt, attachAccordions, badgeStyleId, badgeToneOf, buildAccordionItem, buildAccordionRecipe, buildBadge, buildCardRecipe, buildChip, cardPartsOf, cardRootOf, cardTitleOf, clearLayerStyles, closestAccordion, closestAccordionItem, detachAccordion, detectAccordionIcon, detectCardLayout, domSafeKey, findByRole, initialAccordionOpen, isAccordionFromContent, isAccordionItemOn, isAccordionPart, isAccordionRoot, isCardLinked, isCardRoot, isLockedPart, isPillNode, itemOpenTriggerIds, moveAccordionItem, nextAccordionState, nextItemKey, onAccordionItemState, openAccordionItem, parentInComposite, pickAccordionAutoBinds, readLayerStyle, readProp, readStyle, removeFromComposite, renameAccordionItem, rowItemKey, serializeDomAttributes, setAccordionBehaviour, setAccordionIcon, setBadgeTone, setCardLinked, setCardPart, structureRefusal, walkComposite, writeLayerStyles, writeProp, writeStyles };
619
- export type { AccordionAutoBinds, AccordionBehaviour, AccordionDomIds, AccordionItemState, AccordionOptions, AccordionRuntimeOptions, AccordionScope, AccordionWords, BaselineStyles, CardEditOptions, CardLayoutResult, CardLayoutState, CardOptions, CardPartChange, CardWords, CompositeBinding, CompositeLayer, CompositeNode, CompositeNodeFactory, CompositeNodeSpec, CompositeRoleSpec, CompositeTrait, ContentFieldLike, DomAttributes, PillOptions };
770
+ export { ACCORDION_BIND_PROP, ACCORDION_CONTENT_LIMIT, ACCORDION_DEFAULT_ONS, ACCORDION_ICONS, ACCORDION_ICON_GLYPH, ACCORDION_NEW_ITEM_WORDS, ACCORDION_WORDS, AccordionClass, AccordionDefaultOn, AccordionEditRefusal, AccordionIcon, AccordionKeyAction, AccordionRole, AccordionRuntime, BADGE_TONES, BADGE_TONE_ICONS, BadgeTone, CARD_LAYOUTS, CARD_LAYOUT_CUSTOM, CARD_PARTS, CARD_PART_ROLE, CARD_STACK_BREAKPOINT, CARD_WORDS, CHIP_ICON, CHIP_STYLE, COMPOSITE_ATTRIBUTE, COMPOSITE_KIND_ROLES, COMPOSITE_ROLE_SPECS, CardLayout, CardPart, CardRole, CompositeBehaviourTrait, CompositeItemAction, CompositeKind, DEFAULT_ON_ATTRIBUTE, DISCLOSURE_ITEM_KEY, DISCLOSURE_WORDS, DisclosureRole, ITEM_KEY_ATTRIBUTE, ITEM_OFF_EVENT, ITEM_ON_EVENT, ITEM_OPEN_STATE, MULTIPLE_ATTRIBUTE, ON_ATTRIBUTE, ON_STATE, PILL_LABEL_STYLE, SCOPE_ATTRIBUTE, StructureEdit, StructureRefusal, UNTIL_FOUND, accordionAnswerOf, accordionBehaviour, accordionDomIds, accordionFocusIndex, accordionHeadingLevel, accordionItemAttributes, accordionItemLabel, accordionItemOf, accordionItemState, accordionItems, accordionKeyAction, accordionPanelAttributes, accordionPanelOf, accordionPartStyle, accordionQuestionOf, accordionRegionAttributes, accordionRemovalRefusal, accordionRootAttributes, accordionRootOf, accordionRuntimeOf, accordionScope, accordionToContent, accordionToManual, accordionTrackAttributes, accordionTriggerAttributes, accordionTriggerOf, addAccordionItem, applyCardLayout, attachAccordionAt, attachAccordions, badgeStyleId, badgeToneOf, buildAccordionItem, buildAccordionRecipe, buildBadge, buildCardRecipe, buildChip, buildCompositeIcon, buildDisclosureRecipe, cardPartsOf, cardRootOf, cardTitleOf, clearLayerStyles, closeAccordionItem, closestAccordion, closestAccordionItem, compositeItemOf, compositeItems, compositeKindOfRole, compositeRootOf, compositeRowKeys, compositeScopeId, detachAccordion, detectAccordionIcon, detectCardLayout, disclosureOpenByDefault, domSafeKey, findByRole, hasLabelledRegion, initialAccordionOpen, isAccordionFromContent, isAccordionItemOn, isAccordionPart, isAccordionRoot, isCardLinked, isCardRoot, isCompositeItem, isCompositePanel, isCompositeRoot, isCompositeTrigger, isDisclosurePart, isDisclosureRoot, isLockedPart, isPillNode, itemOpenTriggerIds, makeCompositePart, moveAccordionItem, nextAccordionState, nextItemKey, onAccordionItemState, openAccordionItem, parentInComposite, pickAccordionAutoBinds, readLayerStyle, readProp, readStyle, removeFromComposite, renameAccordionItem, rowItemKey, runCompositeItemAction, serializeDomAttributes, setAccordionBehaviour, setAccordionIcon, setBadgeTone, setCardLinked, setCardPart, shouldScrollToItem, structureRefusal, walkComposite, writeLayerStyles, writeProp, writeStyles };
771
+ export type { AccordionAutoBinds, AccordionBehaviour, AccordionDomIds, AccordionItemState, AccordionOptions, AccordionRuntimeOptions, AccordionScope, AccordionWords, BaselineStyles, CardEditOptions, CardLayoutResult, CardLayoutState, CardOptions, CardPartChange, CardWords, CompositeBinding, CompositeKindRoles, CompositeLayer, CompositeNode, CompositeNodeFactory, CompositeNodeSpec, CompositeRoleSpec, CompositeTrait, ContentFieldLike, DisclosureOptions, DisclosureWords, DomAttributes, PillOptions };
@@ -1,3 +1,5 @@
1
+ import { AccordionRole, DisclosureRole, CompositeItemAction } from '@vectoriox/iox-ui/composite-core';
2
+
1
3
  /**
2
4
  * The ONE descriptor shape for everything an author can put in an ordered action list —
3
5
  * a form's after-submit steps today, element behaviour actions (A1) next. Promoted out of
@@ -38,6 +40,8 @@ function resolveActionAvailability(descriptor, ctx = {}) {
38
40
  return { state: 'available' };
39
41
  }
40
42
 
43
+ /** The items an item action may target: an accordion's item, or a disclosure (its own one item). */
44
+ const ITEM_TARGET_ROLES = [AccordionRole.Item, DisclosureRole.Disclosure];
41
45
  /**
42
46
  * The ELEMENT action catalog (actions plan A1) — what a node can DO, as data. One list feeds the
43
47
  * grouped picker, the two interaction engines, and the AI composer's validation (§9: the model
@@ -81,6 +85,15 @@ const ELEMENT_ACTION_DESCRIPTORS = Object.freeze([
81
85
  target: { required: true, types: ['Dialog'] } },
82
86
  { type: 'toggleDialog', labelKey: 'builder.actions.toggleDialog', kind: 'instant', group: 'dialog', builderBehaviour: 'run',
83
87
  target: { required: true, types: ['Dialog'] } },
88
+ // ── Item (CC2.1 — composite T14): drive an accordion item or a disclosure from anywhere ("See shipping"
89
+ // opens FAQ item 3). The canvas RUNS them, like the dialog actions: it is the same runtime, and an item you
90
+ // cannot open from the button is a button you cannot design.
91
+ { type: 'openItem', labelKey: 'builder.actions.openItem', kind: 'instant', group: 'item', builderBehaviour: 'run',
92
+ target: { required: true, roles: ITEM_TARGET_ROLES } },
93
+ { type: 'closeItem', labelKey: 'builder.actions.closeItem', kind: 'instant', group: 'item', builderBehaviour: 'run',
94
+ target: { required: true, roles: ITEM_TARGET_ROLES } },
95
+ { type: 'toggleItem', labelKey: 'builder.actions.toggleItem', kind: 'instant', group: 'item', builderBehaviour: 'run',
96
+ target: { required: true, roles: ITEM_TARGET_ROLES } },
84
97
  // ── Form (A1 — Tier A; the submit transport is the forms module's, I7 of its plan) ──
85
98
  // simulate in the CANVAS: the builder's Form is a container twin with no real <form>,
86
99
  // so there is nothing honest to run — the live engine requestSubmit()s the real one.
@@ -137,11 +150,22 @@ const SERVER_ELEMENT_ACTION_TYPES = new Set(['sendEmail', 'callWebhook', 'create
137
150
  /** The Tier-A behaviour executors' dispatch set (A1c) — the engines branch on it beside
138
151
  * DIALOG/SWIPER. Dialog actions have their own set; context/visibility stay in the legacy path. */
139
152
  const BEHAVIOUR_ACTION_TYPES = new Set(['navigate', 'scrollTo', 'submitForm', 'copyToClipboard']);
153
+ /** The item actions' dispatch set (T14) and what each does to its item — the engines branch on it beside
154
+ * DIALOG/BEHAVIOUR, and composite-core `runCompositeItemAction` runs it on the target item's own runtime. */
155
+ const ITEM_ACTION_TYPES = Object.freeze({
156
+ openItem: CompositeItemAction.Open,
157
+ closeItem: CompositeItemAction.Close,
158
+ toggleItem: CompositeItemAction.Toggle,
159
+ });
160
+ /** The item action an action type runs, or null when it is not one. */
161
+ function itemActionOf(type) {
162
+ return (type && ITEM_ACTION_TYPES[type]) || null;
163
+ }
140
164
  /** The consent actions' dispatch set (C3) — the engines branch on it beside DIALOG/BEHAVIOUR.
141
165
  * `openConsentPreferences` is dialog-opening by nature and included so ONE branch owns consent. */
142
166
  const CONSENT_ACTION_TYPES = new Set(['grantConsent', 'denyConsent', 'setConsentCategory', 'openConsentPreferences']);
143
167
  /** Picker order — most-used groups first, services last (they are the shop window, not the shop). */
144
- const ELEMENT_ACTION_GROUP_ORDER = Object.freeze(['motion', 'visibility', 'navigate', 'dialog', 'form', 'data', 'consent', 'service']);
168
+ const ELEMENT_ACTION_GROUP_ORDER = Object.freeze(['motion', 'visibility', 'navigate', 'dialog', 'item', 'form', 'data', 'consent', 'service']);
145
169
  /** The catalog, grouped and ordered for the picker — one derivation, no hand-kept second list. */
146
170
  function groupedElementActions() {
147
171
  return ELEMENT_ACTION_GROUP_ORDER
@@ -232,5 +256,5 @@ function dialogOpenersSelector(dialogDomIdValue) {
232
256
  * Generated bundle index. Do not edit.
233
257
  */
234
258
 
235
- export { BEHAVIOUR_ACTION_TYPES, CONSENT_ACTION_TYPES, DIALOG_ACTION_TYPE_SET, DIALOG_OPENER_ACTION_TYPES, DIALOG_OPENER_TRIGGER, DIALOG_SELECTOR, ELEMENT_ACTION_DESCRIPTORS, ELEMENT_ACTION_GROUP_ORDER, FORM_SUBMIT_ACTION_DESCRIPTORS, OpenerAttribute, SERVER_ELEMENT_ACTION_TYPES, addableActions, dialogDomId, dialogOpenerAttributes, dialogOpenersSelector, groupedElementActions, nodeIdOfDialogDomId, openedDialogId, resolveActionAvailability };
259
+ export { BEHAVIOUR_ACTION_TYPES, CONSENT_ACTION_TYPES, DIALOG_ACTION_TYPE_SET, DIALOG_OPENER_ACTION_TYPES, DIALOG_OPENER_TRIGGER, DIALOG_SELECTOR, ELEMENT_ACTION_DESCRIPTORS, ELEMENT_ACTION_GROUP_ORDER, FORM_SUBMIT_ACTION_DESCRIPTORS, ITEM_ACTION_TYPES, OpenerAttribute, SERVER_ELEMENT_ACTION_TYPES, addableActions, dialogDomId, dialogOpenerAttributes, dialogOpenersSelector, groupedElementActions, itemActionOf, nodeIdOfDialogDomId, openedDialogId, resolveActionAvailability };
236
260
  //# sourceMappingURL=vectoriox-iox-ui-actions-core.mjs.map