@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,29 @@
1
+ import { ActionStep, Probe, ScenarioConfig, SpecBridge } from "../scenario.mjs";
2
+ //#region src/apg/menu-button.bridge.d.ts
3
+ /**
4
+ * Menu button vocabulary <-> `specs/apg/menu-button.qnt`. The spec's fixture is
5
+ * fixed: 4 items, item 3 (DOM index 2) aria-disabled, typeahead codes
6
+ * item1=1, item2=2, item3=1, item4=2. `items` is only a length gate (the spec
7
+ * cannot model a menu longer than four); the labels never reach the model.
8
+ *
9
+ * The spec's `menuOpen` axis is its own controlled contract (`controlled` /
10
+ * `accepts` / `value`), separate from `createMenu`'s packed checked `value`.
11
+ * `createMenu`'s open state is still uncontrolled, so the differential walk
12
+ * stays uncontrolled and `setValue` / `hostToggle` are inert on both sides; the
13
+ * controlled vocabulary is accepted here only so a scenario carrying it is
14
+ * modelled instead of silently dropped (see the menu-button DIVERGENCES).
15
+ */
16
+ export interface MenuButtonConfig {
17
+ readonly items: ReadonlyArray<string>;
18
+ readonly disabled: ReadonlyArray<number>;
19
+ readonly controlled: boolean;
20
+ readonly accepts: boolean;
21
+ /** The controlled open value (meaningful while controlled). */
22
+ readonly value: boolean;
23
+ }
24
+ export declare const menuButtonConfig: (config: ScenarioConfig) => MenuButtonConfig;
25
+ export declare const menuButtonBridge: SpecBridge;
26
+ /** The user-level steps a differential walk draws from. */
27
+ export declare const menuButtonSteps: ReadonlyArray<ActionStep>;
28
+ export declare const menuButtonProbe: Probe;
29
+ //#endregion
@@ -0,0 +1,259 @@
1
+ import { Unsupported } from "../scenario.mjs";
2
+ //#region src/apg/menu-button.bridge.ts
3
+ const specEvent = (tag, params = {}) => ({
4
+ _tag: tag,
5
+ ...params
6
+ });
7
+ const CONFIG_KEYS = /* @__PURE__ */ new Set([
8
+ "items",
9
+ "disabled",
10
+ "controlled",
11
+ "accepts",
12
+ "value"
13
+ ]);
14
+ const toItems = (value) => {
15
+ if (Array.isArray(value) && value.every((v) => typeof v === "string")) return value;
16
+ throw new Unsupported(`items ${JSON.stringify(value)}`);
17
+ };
18
+ const toIndices = (value) => {
19
+ if (Array.isArray(value) && value.every((v) => typeof v === "number" && Number.isInteger(v))) return value;
20
+ throw new Unsupported(`disabled ${JSON.stringify(value)}`);
21
+ };
22
+ const menuButtonConfig = (config) => {
23
+ let items = [];
24
+ let disabled = [];
25
+ let controlled = false;
26
+ let accepts = true;
27
+ let value = false;
28
+ for (const [key, raw] of Object.entries(config)) {
29
+ if (!CONFIG_KEYS.has(key)) throw new Unsupported(`config ${key}=${JSON.stringify(raw)}`);
30
+ if (key === "items") items = toItems(raw);
31
+ else if (key === "disabled") disabled = toIndices(raw);
32
+ else if (key === "controlled") controlled = raw === true;
33
+ else if (key === "accepts") {
34
+ controlled = true;
35
+ accepts = raw === true;
36
+ } else if (typeof raw === "boolean") {
37
+ controlled = true;
38
+ value = raw;
39
+ } else throw new Unsupported(`value ${JSON.stringify(raw)}`);
40
+ }
41
+ if (items.length === 0) throw new Unsupported("config has no items");
42
+ if (items.length > 4) throw new Unsupported(`items ${items.length}`);
43
+ if (disabled.some((i) => i < 0 || i >= items.length)) throw new Unsupported(`disabled ${JSON.stringify(disabled)}`);
44
+ return {
45
+ items,
46
+ disabled,
47
+ controlled,
48
+ accepts,
49
+ value
50
+ };
51
+ };
52
+ const keyEvent = (key) => {
53
+ switch (key) {
54
+ case "Enter": return specEvent("activate", { key: "Enter" });
55
+ case " ":
56
+ case "Space": return specEvent("activate", { key: "Space" });
57
+ case "ArrowDown": return specEvent("arrow_down");
58
+ case "ArrowUp": return specEvent("arrow_up");
59
+ case "Home": return specEvent("key_home");
60
+ case "End": return specEvent("key_end");
61
+ case "Escape": return specEvent("escape");
62
+ case "Tab": return specEvent("tab_out");
63
+ default: throw new Unsupported(`key ${key ?? ""}`);
64
+ }
65
+ };
66
+ const charCode = (text) => {
67
+ switch ((text ?? "").slice(0, 1).toLowerCase()) {
68
+ case "a":
69
+ case "1": return 1n;
70
+ case "b":
71
+ case "2": return 2n;
72
+ case "c":
73
+ case "3": return 3n;
74
+ default: return 1n;
75
+ }
76
+ };
77
+ const programmatic = (step) => {
78
+ switch (step.prop) {
79
+ case "focus": return [specEvent("focus_in")];
80
+ case "leave": return [specEvent("tab_out")];
81
+ case "key": {
82
+ const key = step.value?.["key"];
83
+ if (typeof key !== "string") throw new Unsupported(`prop key ${JSON.stringify(step.value)}`);
84
+ return [keyEvent(key)];
85
+ }
86
+ case "typeahead": return [specEvent("typeahead", { ch: BigInt(Number(step.value)) })];
87
+ case "type": return [specEvent("typeahead", { ch: charCode(String(step.value)) })];
88
+ case "setValue":
89
+ if (typeof step.value !== "boolean") throw new Unsupported(`prop setValue=${JSON.stringify(step.value)}`);
90
+ return [specEvent("setValue", { v: step.value })];
91
+ case "hostToggle": return [specEvent("hostToggle")];
92
+ default: throw new Unsupported(`prop ${step.prop ?? ""}`);
93
+ }
94
+ };
95
+ const ITEM = /^menuitem:(\d+)$/;
96
+ let armed = false;
97
+ const assertTarget = (target) => {
98
+ if (target === void 0 || target === "trigger" || target === "menu") return;
99
+ const match = ITEM.exec(target);
100
+ if (match?.[1] !== void 0 && Number(match[1]) < 4) return;
101
+ throw new Unsupported(`target ${target}`);
102
+ };
103
+ const menuButtonBridge = {
104
+ setup: (config) => {
105
+ const mount = menuButtonConfig(config);
106
+ armed = false;
107
+ return [
108
+ ...mount.controlled ? [specEvent("control")] : [],
109
+ ...mount.controlled && mount.accepts ? [specEvent("acceptRequests")] : [],
110
+ ...mount.controlled && mount.value ? [specEvent("setValue", { v: true })] : []
111
+ ];
112
+ },
113
+ event: (step) => {
114
+ if (step.repeat === true) throw new Unsupported("key repeat");
115
+ assertTarget(step.target);
116
+ switch (step.event) {
117
+ case "focus": return [specEvent("focus_in")];
118
+ case "blur": return [specEvent("tab_out")];
119
+ case "click":
120
+ if (step.target === "trigger" || step.target === void 0) {
121
+ armed = true;
122
+ return [specEvent("click_button")];
123
+ }
124
+ if (!armed) throw new Unsupported("click on a closed menu");
125
+ return [specEvent("activate", { key: "Enter" })];
126
+ case "key":
127
+ if (step.target === "trigger" || step.target === void 0) {
128
+ if (step.key === "Enter" || step.key === " " || step.key === "Space" || step.key === "ArrowDown" || step.key === "ArrowUp") armed = true;
129
+ }
130
+ return [keyEvent(step.key)];
131
+ case "type": throw new Unsupported(`type ${step.text ?? ""}`);
132
+ case "hover":
133
+ case "unhover": throw new Unsupported(`event ${step.event}`);
134
+ case "wait": return [];
135
+ case "prop": return programmatic(step);
136
+ default: throw new Unsupported(`event ${step.event}`);
137
+ }
138
+ },
139
+ focus: (state) => {
140
+ const level = Number(state["focusLevel"]);
141
+ if (level === 1) return "trigger";
142
+ if (level === 2) return `menuitem:${Number(state["focusIdx"]) - 1}`;
143
+ return null;
144
+ },
145
+ attr: (state, target, name) => {
146
+ if (target === "trigger") {
147
+ if (name === "aria-haspopup") return "menu";
148
+ if (name === "aria-expanded") return String(state["menuOpen"]);
149
+ throw new Unsupported(`attribute ${name} on trigger`);
150
+ }
151
+ if (target === "menu") {
152
+ if (name === "hidden") return state["menuOpen"] === true ? null : "true";
153
+ throw new Unsupported(`attribute ${name} on menu`);
154
+ }
155
+ const match = ITEM.exec(target);
156
+ if (match?.[1] === void 0) throw new Unsupported(`attribute ${name} on ${target}`);
157
+ const index = Number(match[1]);
158
+ if (name === "role") return "menuitem";
159
+ if (name === "aria-disabled") return index === 2 ? "true" : null;
160
+ if (name === "tabindex") return Number(state["focusLevel"]) === 2 && Number(state["focusIdx"]) - 1 === index ? "0" : "-1";
161
+ throw new Unsupported(`attribute ${name} on ${target}`);
162
+ },
163
+ visible: (state) => state["menuOpen"] === true ? ["menu"] : [],
164
+ events: () => []
165
+ };
166
+ /** The user-level steps a differential walk draws from. */
167
+ const menuButtonSteps = [
168
+ {
169
+ event: "prop",
170
+ prop: "focus"
171
+ },
172
+ {
173
+ event: "prop",
174
+ prop: "leave"
175
+ },
176
+ {
177
+ event: "prop",
178
+ prop: "key",
179
+ value: { key: "Enter" }
180
+ },
181
+ {
182
+ event: "prop",
183
+ prop: "key",
184
+ value: { key: "Space" }
185
+ },
186
+ {
187
+ event: "prop",
188
+ prop: "key",
189
+ value: { key: "ArrowDown" }
190
+ },
191
+ {
192
+ event: "prop",
193
+ prop: "key",
194
+ value: { key: "ArrowUp" }
195
+ },
196
+ {
197
+ event: "prop",
198
+ prop: "key",
199
+ value: { key: "Home" }
200
+ },
201
+ {
202
+ event: "prop",
203
+ prop: "key",
204
+ value: { key: "End" }
205
+ },
206
+ {
207
+ event: "prop",
208
+ prop: "key",
209
+ value: { key: "Escape" }
210
+ },
211
+ {
212
+ event: "prop",
213
+ prop: "key",
214
+ value: { key: "Tab" }
215
+ },
216
+ {
217
+ event: "prop",
218
+ prop: "typeahead",
219
+ value: 1
220
+ },
221
+ {
222
+ event: "prop",
223
+ prop: "typeahead",
224
+ value: 2
225
+ },
226
+ {
227
+ event: "prop",
228
+ prop: "setValue",
229
+ value: true
230
+ },
231
+ {
232
+ event: "prop",
233
+ prop: "setValue",
234
+ value: false
235
+ },
236
+ {
237
+ event: "prop",
238
+ prop: "hostToggle"
239
+ }
240
+ ];
241
+ const menuButtonProbe = {
242
+ attrs: [
243
+ ["trigger", "aria-haspopup"],
244
+ ["trigger", "aria-expanded"],
245
+ ["menu", "hidden"],
246
+ ["menuitem:0", "role"],
247
+ ["menuitem:0", "aria-disabled"],
248
+ ["menuitem:1", "aria-disabled"],
249
+ ["menuitem:2", "aria-disabled"],
250
+ ["menuitem:3", "aria-disabled"],
251
+ ["menuitem:0", "tabindex"],
252
+ ["menuitem:1", "tabindex"],
253
+ ["menuitem:2", "tabindex"],
254
+ ["menuitem:3", "tabindex"]
255
+ ],
256
+ events: []
257
+ };
258
+ //#endregion
259
+ export { menuButtonBridge, menuButtonConfig, menuButtonProbe, menuButtonSteps };