@cssints/apg-specs 0.0.0-stage → 0.5.2

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 (260) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -2
  3. package/dist/apg/accordion.bridge.d.mts +35 -0
  4. package/dist/apg/accordion.bridge.mjs +326 -0
  5. package/dist/apg/accordion.model.json +8397 -0
  6. package/dist/apg/alert.bridge.d.mts +22 -0
  7. package/dist/apg/alert.bridge.mjs +86 -0
  8. package/dist/apg/alert.model.json +871 -0
  9. package/dist/apg/alertdialog.bridge.d.mts +21 -0
  10. package/dist/apg/alertdialog.bridge.mjs +221 -0
  11. package/dist/apg/alertdialog.model.json +5232 -0
  12. package/dist/apg/breadcrumb.bridge.d.mts +26 -0
  13. package/dist/apg/breadcrumb.bridge.mjs +120 -0
  14. package/dist/apg/breadcrumb.model.json +574 -0
  15. package/dist/apg/button.bridge.d.mts +35 -0
  16. package/dist/apg/button.bridge.mjs +208 -0
  17. package/dist/apg/button.model.json +5814 -0
  18. package/dist/apg/carousel.bridge.d.mts +44 -0
  19. package/dist/apg/carousel.bridge.mjs +262 -0
  20. package/dist/apg/carousel.model.json +8963 -0
  21. package/dist/apg/checkbox-group.bridge.d.mts +25 -0
  22. package/dist/apg/checkbox-group.bridge.mjs +276 -0
  23. package/dist/apg/checkbox-group.model.json +3863 -0
  24. package/dist/apg/checkbox.bridge.d.mts +34 -0
  25. package/dist/apg/checkbox.bridge.mjs +253 -0
  26. package/dist/apg/checkbox.model.json +3158 -0
  27. package/dist/apg/combobox-autocomplete.bridge.d.mts +14 -0
  28. package/dist/apg/combobox-autocomplete.bridge.mjs +326 -0
  29. package/dist/apg/combobox-autocomplete.model.json +11586 -0
  30. package/dist/apg/combobox-dialog.bridge.d.mts +17 -0
  31. package/dist/apg/combobox-dialog.bridge.mjs +250 -0
  32. package/dist/apg/combobox-dialog.model.json +8981 -0
  33. package/dist/apg/combobox-grid.bridge.d.mts +17 -0
  34. package/dist/apg/combobox-grid.bridge.mjs +227 -0
  35. package/dist/apg/combobox-grid.model.json +8554 -0
  36. package/dist/apg/combobox-select-only.bridge.d.mts +24 -0
  37. package/dist/apg/combobox-select-only.bridge.mjs +304 -0
  38. package/dist/apg/combobox-select-only.model.json +7846 -0
  39. package/dist/apg/combobox-tree.bridge.d.mts +17 -0
  40. package/dist/apg/combobox-tree.bridge.mjs +211 -0
  41. package/dist/apg/combobox-tree.model.json +9345 -0
  42. package/dist/apg/dialog-modal.bridge.d.mts +35 -0
  43. package/dist/apg/dialog-modal.bridge.mjs +186 -0
  44. package/dist/apg/dialog-modal.model.json +7580 -0
  45. package/dist/apg/disclosure.bridge.d.mts +25 -0
  46. package/dist/apg/disclosure.bridge.mjs +202 -0
  47. package/dist/apg/disclosure.model.json +4703 -0
  48. package/dist/apg/feed.bridge.d.mts +31 -0
  49. package/dist/apg/feed.bridge.mjs +246 -0
  50. package/dist/apg/feed.model.json +4523 -0
  51. package/dist/apg/grid-selection.bridge.d.mts +13 -0
  52. package/dist/apg/grid-selection.bridge.mjs +160 -0
  53. package/dist/apg/grid-selection.model.json +6974 -0
  54. package/dist/apg/grid-sort.bridge.d.mts +12 -0
  55. package/dist/apg/grid-sort.bridge.mjs +138 -0
  56. package/dist/apg/grid-sort.model.json +3799 -0
  57. package/dist/apg/grid.bridge.d.mts +54 -0
  58. package/dist/apg/grid.bridge.mjs +441 -0
  59. package/dist/apg/grid.model.json +3802 -0
  60. package/dist/apg/link.bridge.d.mts +24 -0
  61. package/dist/apg/link.bridge.mjs +126 -0
  62. package/dist/apg/link.model.json +694 -0
  63. package/dist/apg/listbox-multi.bridge.d.mts +10 -0
  64. package/dist/apg/listbox-multi.bridge.mjs +261 -0
  65. package/dist/apg/listbox-multi.model.json +10893 -0
  66. package/dist/apg/listbox-rearrangeable.bridge.d.mts +20 -0
  67. package/dist/apg/listbox-rearrangeable.bridge.mjs +237 -0
  68. package/dist/apg/listbox-rearrangeable.model.json +17592 -0
  69. package/dist/apg/listbox-shared.d.mts +58 -0
  70. package/dist/apg/listbox-shared.mjs +171 -0
  71. package/dist/apg/listbox-single.bridge.d.mts +10 -0
  72. package/dist/apg/listbox-single.bridge.mjs +196 -0
  73. package/dist/apg/listbox-single.model.json +8024 -0
  74. package/dist/apg/listbox-typeahead.bridge.d.mts +10 -0
  75. package/dist/apg/listbox-typeahead.bridge.mjs +153 -0
  76. package/dist/apg/listbox-typeahead.model.json +5615 -0
  77. package/dist/apg/menu-button.bridge.d.mts +29 -0
  78. package/dist/apg/menu-button.bridge.mjs +259 -0
  79. package/dist/apg/menu-button.model.json +5706 -0
  80. package/dist/apg/menu-checkable.bridge.d.mts +25 -0
  81. package/dist/apg/menu-checkable.bridge.mjs +226 -0
  82. package/dist/apg/menu-checkable.model.json +4277 -0
  83. package/dist/apg/menu-menubar.bridge.d.mts +27 -0
  84. package/dist/apg/menu-menubar.bridge.mjs +273 -0
  85. package/dist/apg/menu-menubar.model.json +9540 -0
  86. package/dist/apg/meter.bridge.d.mts +28 -0
  87. package/dist/apg/meter.bridge.mjs +159 -0
  88. package/dist/apg/meter.model.json +1185 -0
  89. package/dist/apg/player.bridge.d.mts +24 -0
  90. package/dist/apg/player.bridge.mjs +342 -0
  91. package/dist/apg/player.model.json +11013 -0
  92. package/dist/apg/radio.bridge.d.mts +35 -0
  93. package/dist/apg/radio.bridge.mjs +371 -0
  94. package/dist/apg/radio.model.json +5011 -0
  95. package/dist/apg/slider-multithumb.bridge.d.mts +34 -0
  96. package/dist/apg/slider-multithumb.bridge.mjs +365 -0
  97. package/dist/apg/slider-multithumb.model.json +5774 -0
  98. package/dist/apg/slider.bridge.d.mts +54 -0
  99. package/dist/apg/slider.bridge.mjs +359 -0
  100. package/dist/apg/slider.model.json +4881 -0
  101. package/dist/apg/spinbutton.bridge.d.mts +41 -0
  102. package/dist/apg/spinbutton.bridge.mjs +327 -0
  103. package/dist/apg/spinbutton.model.json +7571 -0
  104. package/dist/apg/switch.bridge.d.mts +30 -0
  105. package/dist/apg/switch.bridge.mjs +243 -0
  106. package/dist/apg/switch.model.json +3159 -0
  107. package/dist/apg/tabs.bridge.d.mts +41 -0
  108. package/dist/apg/tabs.bridge.mjs +294 -0
  109. package/dist/apg/tabs.model.json +7659 -0
  110. package/dist/apg/timeline.bridge.d.mts +36 -0
  111. package/dist/apg/timeline.bridge.mjs +265 -0
  112. package/dist/apg/timeline.model.json +6189 -0
  113. package/dist/apg/toolbar.bridge.d.mts +25 -0
  114. package/dist/apg/toolbar.bridge.mjs +307 -0
  115. package/dist/apg/toolbar.model.json +6616 -0
  116. package/dist/apg/tooltip.bridge.d.mts +36 -0
  117. package/dist/apg/tooltip.bridge.mjs +208 -0
  118. package/dist/apg/tooltip.model.json +8295 -0
  119. package/dist/apg/treegrid.bridge.d.mts +28 -0
  120. package/dist/apg/treegrid.bridge.mjs +311 -0
  121. package/dist/apg/treegrid.model.json +17358 -0
  122. package/dist/apg/treeview.bridge.d.mts +26 -0
  123. package/dist/apg/treeview.bridge.mjs +396 -0
  124. package/dist/apg/treeview.model.json +13745 -0
  125. package/dist/apg/windowsplitter.bridge.d.mts +36 -0
  126. package/dist/apg/windowsplitter.bridge.mjs +242 -0
  127. package/dist/apg/windowsplitter.model.json +6253 -0
  128. package/dist/canvas/camera.model.json +6568 -0
  129. package/dist/canvas/canvas.bridge.d.mts +190 -0
  130. package/dist/canvas/canvas.bridge.mjs +729 -0
  131. package/dist/canvas/pointer.model.json +17095 -0
  132. package/dist/scenario.d.mts +233 -0
  133. package/dist/scenario.mjs +313 -0
  134. package/package.json +57 -4
  135. package/scenarios/apg/README.md +221 -0
  136. package/scenarios/apg/accordion.base-ui.json +1005 -0
  137. package/scenarios/apg/accordion.react-aria.json +929 -0
  138. package/scenarios/apg/alert.base-ui.json +81 -0
  139. package/scenarios/apg/alert.react-aria.json +98 -0
  140. package/scenarios/apg/alertdialog.base-ui.json +331 -0
  141. package/scenarios/apg/alertdialog.react-aria.json +225 -0
  142. package/scenarios/apg/breadcrumb.react-aria.json +312 -0
  143. package/scenarios/apg/button.ariakit.json +136 -0
  144. package/scenarios/apg/button.base-ui.json +747 -0
  145. package/scenarios/apg/button.react-aria.json +443 -0
  146. package/scenarios/apg/carousel.apg.json +909 -0
  147. package/scenarios/apg/checkbox.ariakit.json +299 -0
  148. package/scenarios/apg/checkbox.base-ui.json +1126 -0
  149. package/scenarios/apg/checkbox.react-aria.json +518 -0
  150. package/scenarios/apg/combobox.ariakit.json +945 -0
  151. package/scenarios/apg/combobox.base-ui.json +2444 -0
  152. package/scenarios/apg/combobox.react-aria.json +845 -0
  153. package/scenarios/apg/dialog-modal.ariakit.json +1102 -0
  154. package/scenarios/apg/dialog-modal.base-ui.json +775 -0
  155. package/scenarios/apg/dialog-modal.react-aria.json +638 -0
  156. package/scenarios/apg/disclosure.apg.json +349 -0
  157. package/scenarios/apg/disclosure.ariakit.json +163 -0
  158. package/scenarios/apg/disclosure.base-ui.json +451 -0
  159. package/scenarios/apg/disclosure.react-aria.json +643 -0
  160. package/scenarios/apg/feed.apg.json +442 -0
  161. package/scenarios/apg/grid.ariakit.json +197 -0
  162. package/scenarios/apg/grid.base-ui.json +720 -0
  163. package/scenarios/apg/grid.react-aria.json +969 -0
  164. package/scenarios/apg/landmarks.ariakit.json +93 -0
  165. package/scenarios/apg/landmarks.react-aria.json +330 -0
  166. package/scenarios/apg/link.ariakit.json +83 -0
  167. package/scenarios/apg/link.base-ui.json +88 -0
  168. package/scenarios/apg/link.react-aria.json +186 -0
  169. package/scenarios/apg/listbox.ariakit.json +78 -0
  170. package/scenarios/apg/listbox.base-ui.json +163 -0
  171. package/scenarios/apg/listbox.react-aria.json +1118 -0
  172. package/scenarios/apg/menu-button.ariakit.json +924 -0
  173. package/scenarios/apg/menu-button.base-ui.json +1155 -0
  174. package/scenarios/apg/menu-button.react-aria.json +1080 -0
  175. package/scenarios/apg/menubar.ariakit.json +758 -0
  176. package/scenarios/apg/menubar.base-ui.json +673 -0
  177. package/scenarios/apg/meter.base-ui.json +243 -0
  178. package/scenarios/apg/meter.react-aria.json +201 -0
  179. package/scenarios/apg/radio.ariakit.json +459 -0
  180. package/scenarios/apg/radio.base-ui.json +581 -0
  181. package/scenarios/apg/radio.react-aria.json +576 -0
  182. package/scenarios/apg/slider-multithumb.base-ui.json +316 -0
  183. package/scenarios/apg/slider-multithumb.react-aria.json +363 -0
  184. package/scenarios/apg/slider.base-ui.json +544 -0
  185. package/scenarios/apg/slider.react-aria.json +456 -0
  186. package/scenarios/apg/spinbutton.base-ui.json +1688 -0
  187. package/scenarios/apg/spinbutton.react-aria.json +426 -0
  188. package/scenarios/apg/switch.base-ui.json +456 -0
  189. package/scenarios/apg/switch.react-aria.json +303 -0
  190. package/scenarios/apg/table.ariakit.json +65 -0
  191. package/scenarios/apg/table.react-aria.json +221 -0
  192. package/scenarios/apg/tabs.ariakit.json +329 -0
  193. package/scenarios/apg/tabs.base-ui.json +875 -0
  194. package/scenarios/apg/tabs.react-aria.json +644 -0
  195. package/scenarios/apg/toolbar.ariakit.json +595 -0
  196. package/scenarios/apg/toolbar.base-ui.json +1189 -0
  197. package/scenarios/apg/toolbar.react-aria.json +383 -0
  198. package/scenarios/apg/tooltip.ariakit.json +441 -0
  199. package/scenarios/apg/tooltip.base-ui.json +411 -0
  200. package/scenarios/apg/tooltip.react-aria.json +454 -0
  201. package/scenarios/apg/treegrid.apg.json +2558 -0
  202. package/scenarios/apg/treegrid.react-aria.json +5094 -0
  203. package/scenarios/apg/treeview.apg.json +928 -0
  204. package/scenarios/apg/windowsplitter.apg.json +557 -0
  205. package/scenarios/canvas/README.md +69 -0
  206. package/scenarios/canvas/camera.contract.json +237 -0
  207. package/scenarios/canvas/camera.excalidraw.json +57 -0
  208. package/scenarios/canvas/marquee.excalidraw.json +122 -0
  209. package/scenarios/canvas/pan.excalidraw.json +46 -0
  210. package/scenarios/canvas/pointer.contract.json +528 -0
  211. package/scenarios/parts.json +291 -0
  212. package/shared/aria.qnt +186 -0
  213. package/shared/details-group.qnt +50 -0
  214. package/shared/focusgroup.qnt +152 -0
  215. package/shared/invokers.qnt +81 -0
  216. package/shared/popover.qnt +71 -0
  217. package/specs/apg/STATIC.md +103 -0
  218. package/specs/apg/accordion.qnt +578 -0
  219. package/specs/apg/alert.qnt +131 -0
  220. package/specs/apg/alertdialog.qnt +455 -0
  221. package/specs/apg/breadcrumb.qnt +88 -0
  222. package/specs/apg/button.qnt +445 -0
  223. package/specs/apg/carousel.qnt +732 -0
  224. package/specs/apg/checkbox-group.qnt +388 -0
  225. package/specs/apg/checkbox.qnt +394 -0
  226. package/specs/apg/combobox-autocomplete.qnt +764 -0
  227. package/specs/apg/combobox-dialog.qnt +627 -0
  228. package/specs/apg/combobox-grid.qnt +632 -0
  229. package/specs/apg/combobox-select-only.qnt +626 -0
  230. package/specs/apg/combobox-tree.qnt +633 -0
  231. package/specs/apg/dialog-modal.qnt +499 -0
  232. package/specs/apg/disclosure.qnt +309 -0
  233. package/specs/apg/feed.qnt +485 -0
  234. package/specs/apg/grid-selection.qnt +512 -0
  235. package/specs/apg/grid-sort.qnt +330 -0
  236. package/specs/apg/grid.qnt +360 -0
  237. package/specs/apg/link.qnt +119 -0
  238. package/specs/apg/listbox-multi.qnt +799 -0
  239. package/specs/apg/listbox-rearrangeable.qnt +801 -0
  240. package/specs/apg/listbox-single.qnt +511 -0
  241. package/specs/apg/listbox-typeahead.qnt +396 -0
  242. package/specs/apg/menu-button.qnt +363 -0
  243. package/specs/apg/menu-checkable.qnt +304 -0
  244. package/specs/apg/menu-menubar.qnt +531 -0
  245. package/specs/apg/meter.qnt +129 -0
  246. package/specs/apg/player.qnt +1081 -0
  247. package/specs/apg/radio.qnt +394 -0
  248. package/specs/apg/slider-multithumb.qnt +441 -0
  249. package/specs/apg/slider.qnt +396 -0
  250. package/specs/apg/spinbutton.qnt +494 -0
  251. package/specs/apg/switch.qnt +389 -0
  252. package/specs/apg/tabs.qnt +412 -0
  253. package/specs/apg/timeline.qnt +612 -0
  254. package/specs/apg/toolbar.qnt +364 -0
  255. package/specs/apg/tooltip.qnt +553 -0
  256. package/specs/apg/treegrid.qnt +983 -0
  257. package/specs/apg/treeview.qnt +1004 -0
  258. package/specs/apg/windowsplitter.qnt +487 -0
  259. package/specs/canvas/camera.qnt +407 -0
  260. package/specs/canvas/pointer.qnt +841 -0
@@ -0,0 +1,44 @@
1
+ import { ActionStep, Probe, ScenarioConfig, SpecBridge } from "../scenario.mjs";
2
+ //#region src/apg/carousel.bridge.d.ts
3
+ export interface CarouselConfig {
4
+ /** DOM slide count (the generated model caps at three; the page may render more). */
5
+ readonly items: number;
6
+ /** Spec slide count (1..3). */
7
+ readonly slides: number;
8
+ /** DOM shown slide (`initialIndex`, for the page). */
9
+ readonly initialIndex: number;
10
+ /** Spec current slide (`initialIndex % slides`). */
11
+ readonly index: number;
12
+ readonly tabbed: boolean;
13
+ readonly autoRotate: boolean;
14
+ readonly playing: boolean;
15
+ readonly hovering: boolean;
16
+ readonly reducedMotion: boolean;
17
+ readonly stickyFocusPause: boolean;
18
+ readonly role: "region" | "group";
19
+ readonly labelledBy: string | undefined;
20
+ /** The host owns the shown slide (`value` prop present). */
21
+ readonly controlled: boolean;
22
+ /** Controlled only: the host writes every request's intent back. */
23
+ readonly accepts: boolean;
24
+ /** Controlled only: a pinned slide the host holds (rejects). */
25
+ readonly pinned: number | null;
26
+ }
27
+ /**
28
+ * Scenario `config` -> what both targets are mounted with. The generated model
29
+ * caps at three slides; a page may render more, so `items` is only clamped for
30
+ * the spec side. `labelledBy` / `role` are static attributes the model does not
31
+ * carry (the primitive still renders them).
32
+ */
33
+ export declare const carouselConfig: (config: ScenarioConfig) => CarouselConfig;
34
+ /**
35
+ * Carousel vocabulary <-> `specs/apg/carousel.qnt`, shared by the spec driver
36
+ * and the DOM driver. Parts: `carousel` (container), `rotation`, `prev`,
37
+ * `next`, `tab:i`, `slide:i`. A rotation interval is a `wait` of the example's
38
+ * 5000 ms, one `tick` per interval.
39
+ */
40
+ export declare const carouselBridge: SpecBridge;
41
+ /** The user-level steps a differential walk draws from. */
42
+ export declare const carouselSteps: ReadonlyArray<ActionStep>;
43
+ export declare const carouselProbe: Probe;
44
+ //#endregion
@@ -0,0 +1,262 @@
1
+ import { Unsupported } from "../scenario.mjs";
2
+ //#region src/apg/carousel.bridge.ts
3
+ const specEvent = (tag, params = {}) => ({
4
+ _tag: tag,
5
+ ...params
6
+ });
7
+ /** The generator caps the modelled carousel at three slides. */
8
+ const SLIDES = 3;
9
+ const partOf = (target) => {
10
+ const [name = "carousel", indexText] = (target ?? "carousel").split(":");
11
+ return {
12
+ kind: name,
13
+ index: Number(indexText ?? "0")
14
+ };
15
+ };
16
+ const bool = (key, value) => {
17
+ if (typeof value !== "boolean") throw new Unsupported(`config ${key}=${JSON.stringify(value)}`);
18
+ return value;
19
+ };
20
+ /**
21
+ * Scenario `config` -> what both targets are mounted with. The generated model
22
+ * caps at three slides; a page may render more, so `items` is only clamped for
23
+ * the spec side. `labelledBy` / `role` are static attributes the model does not
24
+ * carry (the primitive still renders them).
25
+ */
26
+ const carouselConfig = (config) => {
27
+ let items = 6;
28
+ let tabbed = false;
29
+ let autoRotate = true;
30
+ let playing = true;
31
+ let hovering = false;
32
+ let reducedMotion = false;
33
+ let stickyFocusPause = true;
34
+ let role = "group";
35
+ let initialIndex = 0;
36
+ let labelledBy;
37
+ let controlled = false;
38
+ let pinned = null;
39
+ for (const [key, value] of Object.entries(config)) if (key === "items") {
40
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 1) throw new Unsupported(`config items=${JSON.stringify(value)}`);
41
+ items = value;
42
+ } else if (key === "variant") {
43
+ if (value !== "basic" && value !== "tabbed") throw new Unsupported(`config variant=${JSON.stringify(value)}`);
44
+ tabbed = value === "tabbed";
45
+ } else if (key === "autoRotate") autoRotate = bool(key, value);
46
+ else if (key === "playing") playing = bool(key, value);
47
+ else if (key === "hovering") hovering = bool(key, value);
48
+ else if (key === "reducedMotion") reducedMotion = bool(key, value);
49
+ else if (key === "stickyFocusPause") stickyFocusPause = bool(key, value);
50
+ else if (key === "focusInside") bool(key, value);
51
+ else if (key === "role") {
52
+ if (value !== "region" && value !== "group") throw new Unsupported(`config role=${JSON.stringify(value)}`);
53
+ role = value;
54
+ } else if (key === "initialIndex") {
55
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 0) throw new Unsupported(`config initialIndex=${JSON.stringify(value)}`);
56
+ initialIndex = value;
57
+ } else if (key === "labelledBy") {
58
+ if (typeof value !== "string") throw new Unsupported(`config labelledBy=${JSON.stringify(value)}`);
59
+ labelledBy = value;
60
+ } else if (key === "controlled") {
61
+ if (typeof value !== "boolean") throw new Unsupported(`config controlled=${JSON.stringify(value)}`);
62
+ controlled ||= value;
63
+ } else if (key === "value") {
64
+ if (typeof value !== "number" || !Number.isInteger(value)) throw new Unsupported(`config value=${JSON.stringify(value)}`);
65
+ pinned = value;
66
+ controlled = true;
67
+ } else throw new Unsupported(`config ${key}=${JSON.stringify(value)}`);
68
+ const slides = Math.min(items, SLIDES);
69
+ if (pinned !== null && (pinned < 0 || pinned >= slides)) throw new Unsupported(`value ${pinned} is not a slide`);
70
+ return {
71
+ items,
72
+ slides,
73
+ initialIndex: initialIndex % items,
74
+ index: initialIndex % slides,
75
+ tabbed,
76
+ autoRotate,
77
+ playing,
78
+ hovering,
79
+ reducedMotion,
80
+ stickyFocusPause,
81
+ role,
82
+ labelledBy,
83
+ controlled,
84
+ accepts: controlled && pinned === null,
85
+ pinned
86
+ };
87
+ };
88
+ const rotating = (state) => state["autoRotate"] === true && state["rotate"] === true && (state["forced"] === true || state["focus"] === 0n && state["hover"] !== true);
89
+ const focusSlot = (target) => {
90
+ const { kind } = partOf(target);
91
+ if (kind === "rotation") return 1n;
92
+ if (kind === "prev") return 2n;
93
+ if (kind === "next") return 3n;
94
+ if (kind === "tab") return 4n;
95
+ if (kind === "slide") return 7n;
96
+ throw new Unsupported(`focus on ${target ?? ""}`);
97
+ };
98
+ const ACTIVATION_KEYS = /* @__PURE__ */ new Set([
99
+ "Enter",
100
+ " ",
101
+ "Space"
102
+ ]);
103
+ /**
104
+ * Carousel vocabulary <-> `specs/apg/carousel.qnt`, shared by the spec driver
105
+ * and the DOM driver. Parts: `carousel` (container), `rotation`, `prev`,
106
+ * `next`, `tab:i`, `slide:i`. A rotation interval is a `wait` of the example's
107
+ * 5000 ms, one `tick` per interval.
108
+ */
109
+ const carouselBridge = {
110
+ setup: (config) => {
111
+ const c = carouselConfig(config);
112
+ const events = [];
113
+ if (c.slides !== SLIDES) events.push(specEvent("set_slide_count", { m: BigInt(c.slides) }));
114
+ if (!c.autoRotate) events.push(specEvent("set_auto_rotate", { on: false }));
115
+ if (c.tabbed) events.push(specEvent("set_tabbed", { on: true }));
116
+ if (c.reducedMotion || !c.playing) events.push(specEvent("set_reduced_motion"));
117
+ if (c.hovering) events.push(specEvent("pointer_enter"));
118
+ if (c.controlled) {
119
+ events.push(specEvent("control"));
120
+ const initial = c.pinned ?? c.index;
121
+ if (initial !== 0) events.push(specEvent("setValue", { v: BigInt(initial) }));
122
+ if (c.accepts) events.push(specEvent("acceptRequests"));
123
+ } else for (let step = 0; step < c.index; step += 1) events.push(specEvent("click_next"));
124
+ return events;
125
+ },
126
+ event: (step) => {
127
+ switch (step.event) {
128
+ case "focus": return [specEvent("focus_control", { t: focusSlot(step.target) })];
129
+ case "blur": return [specEvent("blur_out")];
130
+ case "hover": return [specEvent("pointer_enter")];
131
+ case "unhover": return [specEvent("pointer_leave")];
132
+ case "click": {
133
+ const { kind, index } = partOf(step.target);
134
+ if (kind === "rotation") return [specEvent("click_rotation")];
135
+ if (kind === "prev") return [specEvent("click_prev")];
136
+ if (kind === "next") return [specEvent("click_next")];
137
+ if (kind === "tab") return [specEvent("click_tab", { i: BigInt(index) })];
138
+ throw new Unsupported(`click on ${step.target ?? ""}`);
139
+ }
140
+ case "key": {
141
+ if (step.key === "Tab") return [specEvent("key_tab")];
142
+ if (step.key === "Shift+Tab") return [specEvent("key_shift_tab")];
143
+ const { kind } = partOf(step.target);
144
+ const slot = focusSlot(step.target);
145
+ if (step.key === "ArrowRight" && kind === "tab") return [specEvent("focus_control", { t: slot }), specEvent("key_arrow_right")];
146
+ if (step.key === "ArrowLeft" && kind === "tab") return [specEvent("focus_control", { t: slot }), specEvent("key_arrow_left")];
147
+ if (step.key === "Home" && kind === "tab") return [specEvent("focus_control", { t: slot }), specEvent("key_home")];
148
+ if (step.key === "End" && kind === "tab") return [specEvent("focus_control", { t: slot }), specEvent("key_end")];
149
+ if (step.key !== void 0 && ACTIVATION_KEYS.has(step.key) && (kind === "rotation" || kind === "prev" || kind === "next")) return [specEvent("focus_control", { t: slot }), specEvent("key_activate")];
150
+ throw new Unsupported(`key ${step.key ?? ""} on ${step.target ?? ""}`);
151
+ }
152
+ case "wait": {
153
+ const ms = step.ms ?? 0;
154
+ if (ms < 5e3 || ms % 5e3 !== 0) throw new Unsupported(`wait ${ms}`);
155
+ return Array.from({ length: ms / 5e3 }, () => specEvent("tick"));
156
+ }
157
+ case "prop":
158
+ if (step.prop === "setValue") {
159
+ const index = typeof step.value === "number" ? step.value : -1;
160
+ if (!Number.isInteger(index) || index < 0 || index >= SLIDES) throw new Unsupported(`setValue ${JSON.stringify(step.value)}`);
161
+ return [specEvent("setValue", { v: BigInt(index) })];
162
+ }
163
+ throw new Unsupported(`prop ${step.prop ?? ""}`);
164
+ default: throw new Unsupported(`event ${step.event}`);
165
+ }
166
+ },
167
+ focus: (state) => {
168
+ const slot = Number(state["focus"]);
169
+ if (slot === 0) return null;
170
+ if (slot === 1) return "rotation";
171
+ if (slot === 2) return "prev";
172
+ if (slot === 3) return "next";
173
+ if (slot >= 4 && slot <= 6) return `tab:${slot - 4}`;
174
+ return `slide:${state["current"]}`;
175
+ },
176
+ attr: (state, target, name) => {
177
+ const { kind, index } = partOf(target);
178
+ if (kind === "carousel") {
179
+ if (name === "aria-roledescription") return "carousel";
180
+ if (name === "aria-live") return rotating(state) ? "off" : "polite";
181
+ } else if (kind === "rotation") {
182
+ if (name === "aria-label") return rotating(state) ? "Stop automatic slide show" : "Start automatic slide show";
183
+ if (name === "hidden") return state["autoRotate"] === true ? null : "true";
184
+ } else if (kind === "slide") {
185
+ if (name === "hidden") return Number(state["current"]) === index ? null : "true";
186
+ if (name === "aria-roledescription") return "slide";
187
+ if (name === "role") return state["tabbed"] === true ? "tabpanel" : "group";
188
+ } else if (kind === "tab") {
189
+ if (name === "aria-selected") return Number(state["current"]) === index ? "true" : "false";
190
+ if (name === "tabindex") return Number(state["current"]) === index ? null : "-1";
191
+ }
192
+ throw new Unsupported(`attribute ${name} on ${target}`);
193
+ },
194
+ visible: (state) => [`slide:${state["current"]}`],
195
+ events: (before, after) => before["requests"] === after["requests"] ? [] : [["onIndexChange", Number(after["requested"])]]
196
+ };
197
+ /** The user-level steps a differential walk draws from. */
198
+ const carouselSteps = [
199
+ {
200
+ event: "focus",
201
+ target: "rotation"
202
+ },
203
+ {
204
+ event: "focus",
205
+ target: "prev"
206
+ },
207
+ {
208
+ event: "focus",
209
+ target: "next"
210
+ },
211
+ {
212
+ event: "key",
213
+ key: "Enter",
214
+ target: "rotation"
215
+ },
216
+ {
217
+ event: "key",
218
+ key: " ",
219
+ target: "rotation"
220
+ },
221
+ {
222
+ event: "key",
223
+ key: "Enter",
224
+ target: "next"
225
+ },
226
+ {
227
+ event: "key",
228
+ key: " ",
229
+ target: "prev"
230
+ },
231
+ {
232
+ event: "wait",
233
+ ms: 5e3
234
+ },
235
+ {
236
+ event: "prop",
237
+ prop: "setValue",
238
+ value: 2
239
+ },
240
+ {
241
+ event: "prop",
242
+ prop: "setValue",
243
+ value: 0
244
+ }
245
+ ];
246
+ const carouselProbe = {
247
+ attrs: [
248
+ ["carousel", "aria-live"],
249
+ ["carousel", "aria-roledescription"],
250
+ ["rotation", "aria-label"],
251
+ ["rotation", "hidden"],
252
+ ["slide:0", "hidden"],
253
+ ["slide:1", "hidden"],
254
+ ["slide:2", "hidden"],
255
+ ["tab:0", "aria-selected"],
256
+ ["tab:1", "aria-selected"],
257
+ ["tab:2", "aria-selected"]
258
+ ],
259
+ events: ["onIndexChange"]
260
+ };
261
+ //#endregion
262
+ export { carouselBridge, carouselConfig, carouselProbe, carouselSteps };