@cssints/apg-specs 0.0.0-stage → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +65 -2
- package/dist/apg/accordion.bridge.d.mts +35 -0
- package/dist/apg/accordion.bridge.mjs +326 -0
- package/dist/apg/accordion.model.json +8397 -0
- package/dist/apg/alert.bridge.d.mts +22 -0
- package/dist/apg/alert.bridge.mjs +86 -0
- package/dist/apg/alert.model.json +871 -0
- package/dist/apg/alertdialog.bridge.d.mts +21 -0
- package/dist/apg/alertdialog.bridge.mjs +221 -0
- package/dist/apg/alertdialog.model.json +5232 -0
- package/dist/apg/breadcrumb.bridge.d.mts +26 -0
- package/dist/apg/breadcrumb.bridge.mjs +120 -0
- package/dist/apg/breadcrumb.model.json +574 -0
- package/dist/apg/button.bridge.d.mts +35 -0
- package/dist/apg/button.bridge.mjs +208 -0
- package/dist/apg/button.model.json +5814 -0
- package/dist/apg/carousel.bridge.d.mts +44 -0
- package/dist/apg/carousel.bridge.mjs +262 -0
- package/dist/apg/carousel.model.json +8963 -0
- package/dist/apg/checkbox-group.bridge.d.mts +25 -0
- package/dist/apg/checkbox-group.bridge.mjs +276 -0
- package/dist/apg/checkbox-group.model.json +3863 -0
- package/dist/apg/checkbox.bridge.d.mts +34 -0
- package/dist/apg/checkbox.bridge.mjs +253 -0
- package/dist/apg/checkbox.model.json +3158 -0
- package/dist/apg/combobox-autocomplete.bridge.d.mts +14 -0
- package/dist/apg/combobox-autocomplete.bridge.mjs +326 -0
- package/dist/apg/combobox-autocomplete.model.json +11586 -0
- package/dist/apg/combobox-dialog.bridge.d.mts +17 -0
- package/dist/apg/combobox-dialog.bridge.mjs +250 -0
- package/dist/apg/combobox-dialog.model.json +8981 -0
- package/dist/apg/combobox-grid.bridge.d.mts +17 -0
- package/dist/apg/combobox-grid.bridge.mjs +227 -0
- package/dist/apg/combobox-grid.model.json +8554 -0
- package/dist/apg/combobox-select-only.bridge.d.mts +24 -0
- package/dist/apg/combobox-select-only.bridge.mjs +304 -0
- package/dist/apg/combobox-select-only.model.json +7846 -0
- package/dist/apg/combobox-tree.bridge.d.mts +17 -0
- package/dist/apg/combobox-tree.bridge.mjs +211 -0
- package/dist/apg/combobox-tree.model.json +9345 -0
- package/dist/apg/dialog-modal.bridge.d.mts +35 -0
- package/dist/apg/dialog-modal.bridge.mjs +186 -0
- package/dist/apg/dialog-modal.model.json +7580 -0
- package/dist/apg/disclosure.bridge.d.mts +25 -0
- package/dist/apg/disclosure.bridge.mjs +202 -0
- package/dist/apg/disclosure.model.json +4703 -0
- package/dist/apg/feed.bridge.d.mts +31 -0
- package/dist/apg/feed.bridge.mjs +246 -0
- package/dist/apg/feed.model.json +4523 -0
- package/dist/apg/grid-selection.bridge.d.mts +13 -0
- package/dist/apg/grid-selection.bridge.mjs +160 -0
- package/dist/apg/grid-selection.model.json +6974 -0
- package/dist/apg/grid-sort.bridge.d.mts +12 -0
- package/dist/apg/grid-sort.bridge.mjs +138 -0
- package/dist/apg/grid-sort.model.json +3799 -0
- package/dist/apg/grid.bridge.d.mts +54 -0
- package/dist/apg/grid.bridge.mjs +441 -0
- package/dist/apg/grid.model.json +3802 -0
- package/dist/apg/link.bridge.d.mts +24 -0
- package/dist/apg/link.bridge.mjs +126 -0
- package/dist/apg/link.model.json +694 -0
- package/dist/apg/listbox-multi.bridge.d.mts +10 -0
- package/dist/apg/listbox-multi.bridge.mjs +261 -0
- package/dist/apg/listbox-multi.model.json +10893 -0
- package/dist/apg/listbox-rearrangeable.bridge.d.mts +20 -0
- package/dist/apg/listbox-rearrangeable.bridge.mjs +237 -0
- package/dist/apg/listbox-rearrangeable.model.json +17592 -0
- package/dist/apg/listbox-shared.d.mts +58 -0
- package/dist/apg/listbox-shared.mjs +171 -0
- package/dist/apg/listbox-single.bridge.d.mts +10 -0
- package/dist/apg/listbox-single.bridge.mjs +196 -0
- package/dist/apg/listbox-single.model.json +8024 -0
- package/dist/apg/listbox-typeahead.bridge.d.mts +10 -0
- package/dist/apg/listbox-typeahead.bridge.mjs +153 -0
- package/dist/apg/listbox-typeahead.model.json +5615 -0
- package/dist/apg/menu-button.bridge.d.mts +29 -0
- package/dist/apg/menu-button.bridge.mjs +259 -0
- package/dist/apg/menu-button.model.json +5706 -0
- package/dist/apg/menu-checkable.bridge.d.mts +25 -0
- package/dist/apg/menu-checkable.bridge.mjs +226 -0
- package/dist/apg/menu-checkable.model.json +4277 -0
- package/dist/apg/menu-menubar.bridge.d.mts +27 -0
- package/dist/apg/menu-menubar.bridge.mjs +273 -0
- package/dist/apg/menu-menubar.model.json +9540 -0
- package/dist/apg/meter.bridge.d.mts +28 -0
- package/dist/apg/meter.bridge.mjs +159 -0
- package/dist/apg/meter.model.json +1185 -0
- package/dist/apg/player.bridge.d.mts +24 -0
- package/dist/apg/player.bridge.mjs +342 -0
- package/dist/apg/player.model.json +11013 -0
- package/dist/apg/radio.bridge.d.mts +35 -0
- package/dist/apg/radio.bridge.mjs +371 -0
- package/dist/apg/radio.model.json +5011 -0
- package/dist/apg/slider-multithumb.bridge.d.mts +34 -0
- package/dist/apg/slider-multithumb.bridge.mjs +365 -0
- package/dist/apg/slider-multithumb.model.json +5774 -0
- package/dist/apg/slider.bridge.d.mts +54 -0
- package/dist/apg/slider.bridge.mjs +359 -0
- package/dist/apg/slider.model.json +4881 -0
- package/dist/apg/spinbutton.bridge.d.mts +41 -0
- package/dist/apg/spinbutton.bridge.mjs +327 -0
- package/dist/apg/spinbutton.model.json +7571 -0
- package/dist/apg/switch.bridge.d.mts +30 -0
- package/dist/apg/switch.bridge.mjs +243 -0
- package/dist/apg/switch.model.json +3159 -0
- package/dist/apg/tabs.bridge.d.mts +41 -0
- package/dist/apg/tabs.bridge.mjs +294 -0
- package/dist/apg/tabs.model.json +7659 -0
- package/dist/apg/timeline.bridge.d.mts +36 -0
- package/dist/apg/timeline.bridge.mjs +265 -0
- package/dist/apg/timeline.model.json +6189 -0
- package/dist/apg/toolbar.bridge.d.mts +25 -0
- package/dist/apg/toolbar.bridge.mjs +307 -0
- package/dist/apg/toolbar.model.json +6616 -0
- package/dist/apg/tooltip.bridge.d.mts +36 -0
- package/dist/apg/tooltip.bridge.mjs +208 -0
- package/dist/apg/tooltip.model.json +8295 -0
- package/dist/apg/treegrid.bridge.d.mts +28 -0
- package/dist/apg/treegrid.bridge.mjs +311 -0
- package/dist/apg/treegrid.model.json +17358 -0
- package/dist/apg/treeview.bridge.d.mts +26 -0
- package/dist/apg/treeview.bridge.mjs +396 -0
- package/dist/apg/treeview.model.json +13745 -0
- package/dist/apg/windowsplitter.bridge.d.mts +36 -0
- package/dist/apg/windowsplitter.bridge.mjs +242 -0
- package/dist/apg/windowsplitter.model.json +6253 -0
- package/dist/canvas/camera.model.json +6568 -0
- package/dist/canvas/canvas.bridge.d.mts +190 -0
- package/dist/canvas/canvas.bridge.mjs +729 -0
- package/dist/canvas/pointer.model.json +17095 -0
- package/dist/scenario.d.mts +233 -0
- package/dist/scenario.mjs +313 -0
- package/package.json +57 -4
- package/scenarios/apg/README.md +221 -0
- package/scenarios/apg/accordion.base-ui.json +1005 -0
- package/scenarios/apg/accordion.react-aria.json +929 -0
- package/scenarios/apg/alert.base-ui.json +81 -0
- package/scenarios/apg/alert.react-aria.json +98 -0
- package/scenarios/apg/alertdialog.base-ui.json +331 -0
- package/scenarios/apg/alertdialog.react-aria.json +225 -0
- package/scenarios/apg/breadcrumb.react-aria.json +312 -0
- package/scenarios/apg/button.ariakit.json +136 -0
- package/scenarios/apg/button.base-ui.json +747 -0
- package/scenarios/apg/button.react-aria.json +443 -0
- package/scenarios/apg/carousel.apg.json +909 -0
- package/scenarios/apg/checkbox.ariakit.json +299 -0
- package/scenarios/apg/checkbox.base-ui.json +1126 -0
- package/scenarios/apg/checkbox.react-aria.json +518 -0
- package/scenarios/apg/combobox.ariakit.json +945 -0
- package/scenarios/apg/combobox.base-ui.json +2444 -0
- package/scenarios/apg/combobox.react-aria.json +845 -0
- package/scenarios/apg/dialog-modal.ariakit.json +1102 -0
- package/scenarios/apg/dialog-modal.base-ui.json +775 -0
- package/scenarios/apg/dialog-modal.react-aria.json +638 -0
- package/scenarios/apg/disclosure.apg.json +349 -0
- package/scenarios/apg/disclosure.ariakit.json +163 -0
- package/scenarios/apg/disclosure.base-ui.json +451 -0
- package/scenarios/apg/disclosure.react-aria.json +643 -0
- package/scenarios/apg/feed.apg.json +442 -0
- package/scenarios/apg/grid.ariakit.json +197 -0
- package/scenarios/apg/grid.base-ui.json +720 -0
- package/scenarios/apg/grid.react-aria.json +969 -0
- package/scenarios/apg/landmarks.ariakit.json +93 -0
- package/scenarios/apg/landmarks.react-aria.json +330 -0
- package/scenarios/apg/link.ariakit.json +83 -0
- package/scenarios/apg/link.base-ui.json +88 -0
- package/scenarios/apg/link.react-aria.json +186 -0
- package/scenarios/apg/listbox.ariakit.json +78 -0
- package/scenarios/apg/listbox.base-ui.json +163 -0
- package/scenarios/apg/listbox.react-aria.json +1118 -0
- package/scenarios/apg/menu-button.ariakit.json +924 -0
- package/scenarios/apg/menu-button.base-ui.json +1155 -0
- package/scenarios/apg/menu-button.react-aria.json +1080 -0
- package/scenarios/apg/menubar.ariakit.json +758 -0
- package/scenarios/apg/menubar.base-ui.json +673 -0
- package/scenarios/apg/meter.base-ui.json +243 -0
- package/scenarios/apg/meter.react-aria.json +201 -0
- package/scenarios/apg/radio.ariakit.json +459 -0
- package/scenarios/apg/radio.base-ui.json +581 -0
- package/scenarios/apg/radio.react-aria.json +576 -0
- package/scenarios/apg/slider-multithumb.base-ui.json +316 -0
- package/scenarios/apg/slider-multithumb.react-aria.json +363 -0
- package/scenarios/apg/slider.base-ui.json +544 -0
- package/scenarios/apg/slider.react-aria.json +456 -0
- package/scenarios/apg/spinbutton.base-ui.json +1688 -0
- package/scenarios/apg/spinbutton.react-aria.json +426 -0
- package/scenarios/apg/switch.base-ui.json +456 -0
- package/scenarios/apg/switch.react-aria.json +303 -0
- package/scenarios/apg/table.ariakit.json +65 -0
- package/scenarios/apg/table.react-aria.json +221 -0
- package/scenarios/apg/tabs.ariakit.json +329 -0
- package/scenarios/apg/tabs.base-ui.json +875 -0
- package/scenarios/apg/tabs.react-aria.json +644 -0
- package/scenarios/apg/toolbar.ariakit.json +595 -0
- package/scenarios/apg/toolbar.base-ui.json +1189 -0
- package/scenarios/apg/toolbar.react-aria.json +383 -0
- package/scenarios/apg/tooltip.ariakit.json +441 -0
- package/scenarios/apg/tooltip.base-ui.json +411 -0
- package/scenarios/apg/tooltip.react-aria.json +454 -0
- package/scenarios/apg/treegrid.apg.json +2558 -0
- package/scenarios/apg/treegrid.react-aria.json +5094 -0
- package/scenarios/apg/treeview.apg.json +928 -0
- package/scenarios/apg/windowsplitter.apg.json +557 -0
- package/scenarios/canvas/README.md +69 -0
- package/scenarios/canvas/camera.contract.json +237 -0
- package/scenarios/canvas/camera.excalidraw.json +57 -0
- package/scenarios/canvas/marquee.excalidraw.json +122 -0
- package/scenarios/canvas/pan.excalidraw.json +46 -0
- package/scenarios/canvas/pointer.contract.json +528 -0
- package/scenarios/parts.json +291 -0
- package/shared/aria.qnt +186 -0
- package/shared/details-group.qnt +50 -0
- package/shared/focusgroup.qnt +152 -0
- package/shared/invokers.qnt +81 -0
- package/shared/popover.qnt +71 -0
- package/specs/apg/STATIC.md +103 -0
- package/specs/apg/accordion.qnt +578 -0
- package/specs/apg/alert.qnt +131 -0
- package/specs/apg/alertdialog.qnt +455 -0
- package/specs/apg/breadcrumb.qnt +88 -0
- package/specs/apg/button.qnt +445 -0
- package/specs/apg/carousel.qnt +732 -0
- package/specs/apg/checkbox-group.qnt +388 -0
- package/specs/apg/checkbox.qnt +394 -0
- package/specs/apg/combobox-autocomplete.qnt +764 -0
- package/specs/apg/combobox-dialog.qnt +627 -0
- package/specs/apg/combobox-grid.qnt +632 -0
- package/specs/apg/combobox-select-only.qnt +626 -0
- package/specs/apg/combobox-tree.qnt +633 -0
- package/specs/apg/dialog-modal.qnt +499 -0
- package/specs/apg/disclosure.qnt +309 -0
- package/specs/apg/feed.qnt +485 -0
- package/specs/apg/grid-selection.qnt +512 -0
- package/specs/apg/grid-sort.qnt +330 -0
- package/specs/apg/grid.qnt +360 -0
- package/specs/apg/link.qnt +119 -0
- package/specs/apg/listbox-multi.qnt +799 -0
- package/specs/apg/listbox-rearrangeable.qnt +801 -0
- package/specs/apg/listbox-single.qnt +511 -0
- package/specs/apg/listbox-typeahead.qnt +396 -0
- package/specs/apg/menu-button.qnt +363 -0
- package/specs/apg/menu-checkable.qnt +304 -0
- package/specs/apg/menu-menubar.qnt +531 -0
- package/specs/apg/meter.qnt +129 -0
- package/specs/apg/player.qnt +1081 -0
- package/specs/apg/radio.qnt +394 -0
- package/specs/apg/slider-multithumb.qnt +441 -0
- package/specs/apg/slider.qnt +396 -0
- package/specs/apg/spinbutton.qnt +494 -0
- package/specs/apg/switch.qnt +389 -0
- package/specs/apg/tabs.qnt +412 -0
- package/specs/apg/timeline.qnt +612 -0
- package/specs/apg/toolbar.qnt +364 -0
- package/specs/apg/tooltip.qnt +553 -0
- package/specs/apg/treegrid.qnt +983 -0
- package/specs/apg/treeview.qnt +1004 -0
- package/specs/apg/windowsplitter.qnt +487 -0
- package/specs/canvas/camera.qnt +407 -0
- package/specs/canvas/pointer.qnt +841 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ActionStep, Probe, ScenarioConfig, SpecBridge } from "../scenario.mjs";
|
|
2
|
+
//#region src/apg/timeline.bridge.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Scenario `config` -> what both targets are mounted with. `selected` is the
|
|
5
|
+
* initial selection (uncontrolled, or the accepting host's starting value).
|
|
6
|
+
* `controlled` puts the value in a host that accepts every request (a page that
|
|
7
|
+
* keeps the state in a signal); pinning `value` instead means a fixed prop, so
|
|
8
|
+
* every request is rejected.
|
|
9
|
+
*/
|
|
10
|
+
export interface TimelineConfig {
|
|
11
|
+
readonly defaultExpanded: ReadonlyArray<number>;
|
|
12
|
+
/** Initial selection: uncontrolled default, or the accepting host's start. */
|
|
13
|
+
readonly selected: number;
|
|
14
|
+
readonly viewStart: number;
|
|
15
|
+
readonly viewEnd: number;
|
|
16
|
+
/** The host owns the selection (`value` prop present). */
|
|
17
|
+
readonly controlled: boolean;
|
|
18
|
+
/** Controlled only: the host writes every request's intent back. */
|
|
19
|
+
readonly accepts: boolean;
|
|
20
|
+
/** Controlled only: a pinned value the host holds (rejects every request). */
|
|
21
|
+
readonly pinned: number | null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Timeline vocabulary <-> `specs/apg/timeline.qnt`, shared by the spec driver
|
|
25
|
+
* and the DOM driver.
|
|
26
|
+
*
|
|
27
|
+
* Parts: `row:0`..`row:4` (span ids 1..5) and `ruler` (the zoom window slider).
|
|
28
|
+
* The zoom window is fixed to the full domain (it is not the controlled value);
|
|
29
|
+
* anything else throws `Unsupported`, which skips the scenario on every target.
|
|
30
|
+
*/
|
|
31
|
+
export declare const timelineConfig: (config: ScenarioConfig) => TimelineConfig;
|
|
32
|
+
export declare const timelineBridge: SpecBridge;
|
|
33
|
+
/** The user-level steps a differential walk draws from. */
|
|
34
|
+
export declare const timelineSteps: ReadonlyArray<ActionStep>;
|
|
35
|
+
export declare const timelineProbe: Probe;
|
|
36
|
+
//#endregion
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { Unsupported } from "../scenario.mjs";
|
|
2
|
+
//#region src/apg/timeline.bridge.ts
|
|
3
|
+
const specEvent = (tag, params = {}) => ({
|
|
4
|
+
_tag: tag,
|
|
5
|
+
...params
|
|
6
|
+
});
|
|
7
|
+
const num = (value) => value === void 0 ? 0 : Number(value);
|
|
8
|
+
const LAST_NODE = 5;
|
|
9
|
+
const NODES = [
|
|
10
|
+
1,
|
|
11
|
+
2,
|
|
12
|
+
3,
|
|
13
|
+
4,
|
|
14
|
+
5
|
|
15
|
+
];
|
|
16
|
+
const PARENT_OF = [
|
|
17
|
+
0,
|
|
18
|
+
0,
|
|
19
|
+
1,
|
|
20
|
+
2,
|
|
21
|
+
2,
|
|
22
|
+
1
|
|
23
|
+
];
|
|
24
|
+
const FIRST_CHILD = [
|
|
25
|
+
0,
|
|
26
|
+
2,
|
|
27
|
+
3,
|
|
28
|
+
0,
|
|
29
|
+
0,
|
|
30
|
+
0
|
|
31
|
+
];
|
|
32
|
+
const parentOf = (n) => PARENT_OF[n] ?? 0;
|
|
33
|
+
const firstChild = (n) => FIRST_CHILD[n] ?? 0;
|
|
34
|
+
const isParent = (n) => firstChild(n) !== 0;
|
|
35
|
+
const weight = (n) => n >= 1 && n <= LAST_NODE ? 2 ** (n - 1) : 0;
|
|
36
|
+
const bit = (mask, n) => (mask & weight(n)) !== 0;
|
|
37
|
+
const parentOpen = (n, expanded) => parentOf(n) === 0 || bit(expanded, parentOf(n));
|
|
38
|
+
const visible = (n, expanded) => n >= 1 && n <= LAST_NODE && parentOpen(n, expanded) && parentOpen(parentOf(n), expanded);
|
|
39
|
+
const rowTarget = (n) => `row:${n - 1}`;
|
|
40
|
+
const nodeOf = (target) => {
|
|
41
|
+
const [name = "", index = ""] = (target ?? "").split(":");
|
|
42
|
+
const node = Number(index) + 1;
|
|
43
|
+
if (name === "row" && node >= 1 && node <= LAST_NODE) return node;
|
|
44
|
+
throw new Unsupported(`part ${target ?? ""}`);
|
|
45
|
+
};
|
|
46
|
+
const nodeValue = (key, value) => {
|
|
47
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0 || value > LAST_NODE) throw new Unsupported(`config ${key}=${JSON.stringify(value)}`);
|
|
48
|
+
return value;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Timeline vocabulary <-> `specs/apg/timeline.qnt`, shared by the spec driver
|
|
52
|
+
* and the DOM driver.
|
|
53
|
+
*
|
|
54
|
+
* Parts: `row:0`..`row:4` (span ids 1..5) and `ruler` (the zoom window slider).
|
|
55
|
+
* The zoom window is fixed to the full domain (it is not the controlled value);
|
|
56
|
+
* anything else throws `Unsupported`, which skips the scenario on every target.
|
|
57
|
+
*/
|
|
58
|
+
const timelineConfig = (config) => {
|
|
59
|
+
let selected = 0;
|
|
60
|
+
let controlled = false;
|
|
61
|
+
let pinned = null;
|
|
62
|
+
for (const [key, value] of Object.entries(config)) if (key === "controlled" && typeof value === "boolean") controlled ||= value;
|
|
63
|
+
else if (key === "selected") selected = nodeValue(key, value);
|
|
64
|
+
else if (key === "value") {
|
|
65
|
+
pinned = nodeValue(key, value);
|
|
66
|
+
controlled = true;
|
|
67
|
+
} else throw new Unsupported(`config ${key}=${String(value)}`);
|
|
68
|
+
return {
|
|
69
|
+
defaultExpanded: [],
|
|
70
|
+
selected,
|
|
71
|
+
viewStart: 0,
|
|
72
|
+
viewEnd: 100,
|
|
73
|
+
controlled,
|
|
74
|
+
accepts: controlled && pinned === null,
|
|
75
|
+
pinned
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
const keyEventOf = (key) => {
|
|
79
|
+
switch (key) {
|
|
80
|
+
case "ArrowDown": return "pressDown";
|
|
81
|
+
case "ArrowUp": return "pressUp";
|
|
82
|
+
case "ArrowRight": return "pressRight";
|
|
83
|
+
case "ArrowLeft": return "pressLeft";
|
|
84
|
+
case "Home": return "pressHome";
|
|
85
|
+
case "End": return "pressEnd";
|
|
86
|
+
case "Enter": return "pressEnter";
|
|
87
|
+
default: return;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const programmatic = (step) => {
|
|
91
|
+
switch (step.prop) {
|
|
92
|
+
case "zoomIn":
|
|
93
|
+
case "zoomOut":
|
|
94
|
+
case "zoomReset":
|
|
95
|
+
case "panLeft":
|
|
96
|
+
case "panRight": return [specEvent(step.prop)];
|
|
97
|
+
case "select": {
|
|
98
|
+
const node = nodeValue("select", step.value);
|
|
99
|
+
if (node < 1) throw new Unsupported(`select ${JSON.stringify(step.value)}`);
|
|
100
|
+
return [specEvent("selectNode", { node: BigInt(node) })];
|
|
101
|
+
}
|
|
102
|
+
case "setValue": {
|
|
103
|
+
const value = nodeValue("setValue", step.value);
|
|
104
|
+
return [specEvent("setValue", { v: BigInt(value) })];
|
|
105
|
+
}
|
|
106
|
+
default: throw new Unsupported(`prop ${step.prop ?? ""}`);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const timelineBridge = {
|
|
110
|
+
setup: (config) => {
|
|
111
|
+
const timeline = timelineConfig(config);
|
|
112
|
+
if (timeline.controlled) {
|
|
113
|
+
const initial = timeline.pinned ?? timeline.selected;
|
|
114
|
+
return [
|
|
115
|
+
specEvent("control"),
|
|
116
|
+
...initial === 0 ? [] : [specEvent("setValue", { v: BigInt(initial) })],
|
|
117
|
+
...timeline.accepts ? [specEvent("acceptRequests")] : []
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
return timeline.selected === 0 ? [] : [specEvent("selectNode", { node: BigInt(timeline.selected) })];
|
|
121
|
+
},
|
|
122
|
+
event: (step) => {
|
|
123
|
+
switch (step.event) {
|
|
124
|
+
case "focus": return [specEvent("focusNode", { node: BigInt(nodeOf(step.target)) })];
|
|
125
|
+
case "blur":
|
|
126
|
+
nodeOf(step.target);
|
|
127
|
+
return [specEvent("blurTimeline")];
|
|
128
|
+
case "click": return [specEvent("click", { node: BigInt(nodeOf(step.target)) })];
|
|
129
|
+
case "key": {
|
|
130
|
+
const node = nodeOf(step.target);
|
|
131
|
+
const tag = keyEventOf(step.key ?? "");
|
|
132
|
+
if (tag === void 0) throw new Unsupported(`key ${step.key ?? ""} on ${step.target ?? ""}`);
|
|
133
|
+
return [specEvent("focusNode", { node: BigInt(node) }), specEvent(tag)];
|
|
134
|
+
}
|
|
135
|
+
case "hover":
|
|
136
|
+
case "unhover": return [];
|
|
137
|
+
case "prop": return programmatic(step);
|
|
138
|
+
default: throw new Unsupported(`event ${step.event}`);
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
focus: (state) => state["hasFocus"] === true ? rowTarget(num(state["focus"])) : null,
|
|
142
|
+
attr: (state, target, name) => {
|
|
143
|
+
if (target === "ruler") {
|
|
144
|
+
if (name === "aria-valuemin") return String(num(state["viewStart"]));
|
|
145
|
+
if (name === "aria-valuenow") return String(num(state["viewStart"]));
|
|
146
|
+
if (name === "aria-valuemax") return String(num(state["viewEnd"]));
|
|
147
|
+
throw new Unsupported(`attribute ${name} on ruler`);
|
|
148
|
+
}
|
|
149
|
+
const node = nodeOf(target);
|
|
150
|
+
const expanded = num(state["expanded"]);
|
|
151
|
+
if (name === "aria-expanded") return isParent(node) ? bit(expanded, node) ? "true" : "false" : null;
|
|
152
|
+
if (name === "aria-selected") return num(state["selected"]) === node ? "true" : "false";
|
|
153
|
+
if (name === "tabindex") return num(state["focus"]) === node ? "0" : "-1";
|
|
154
|
+
if (name === "hidden") return visible(node, expanded) ? null : "true";
|
|
155
|
+
throw new Unsupported(`attribute ${name} on ${target}`);
|
|
156
|
+
},
|
|
157
|
+
visible: (state) => {
|
|
158
|
+
const expanded = num(state["expanded"]);
|
|
159
|
+
return NODES.flatMap((node) => visible(node, expanded) ? [rowTarget(node)] : []);
|
|
160
|
+
},
|
|
161
|
+
events: (before, after) => before["requests"] === after["requests"] ? [] : [["onValueChange", num(after["requested"])]]
|
|
162
|
+
};
|
|
163
|
+
/** The user-level steps a differential walk draws from. */
|
|
164
|
+
const timelineSteps = [
|
|
165
|
+
{
|
|
166
|
+
event: "focus",
|
|
167
|
+
target: "row:0"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
event: "key",
|
|
171
|
+
key: "ArrowDown",
|
|
172
|
+
target: "row:0"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
event: "key",
|
|
176
|
+
key: "ArrowUp",
|
|
177
|
+
target: "row:1"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
event: "key",
|
|
181
|
+
key: "ArrowRight",
|
|
182
|
+
target: "row:0"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
event: "key",
|
|
186
|
+
key: "ArrowLeft",
|
|
187
|
+
target: "row:1"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
event: "key",
|
|
191
|
+
key: "Home",
|
|
192
|
+
target: "row:2"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
event: "key",
|
|
196
|
+
key: "End",
|
|
197
|
+
target: "row:2"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
event: "key",
|
|
201
|
+
key: "Enter",
|
|
202
|
+
target: "row:0"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
event: "click",
|
|
206
|
+
target: "row:0"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
event: "prop",
|
|
210
|
+
prop: "select",
|
|
211
|
+
value: 3
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
event: "prop",
|
|
215
|
+
prop: "select",
|
|
216
|
+
value: 1
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
event: "prop",
|
|
220
|
+
prop: "setValue",
|
|
221
|
+
value: 0
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
event: "prop",
|
|
225
|
+
prop: "setValue",
|
|
226
|
+
value: 4
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
event: "prop",
|
|
230
|
+
prop: "zoomIn"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
event: "prop",
|
|
234
|
+
prop: "zoomOut"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
event: "prop",
|
|
238
|
+
prop: "zoomReset"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
event: "prop",
|
|
242
|
+
prop: "panLeft"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
event: "prop",
|
|
246
|
+
prop: "panRight"
|
|
247
|
+
}
|
|
248
|
+
];
|
|
249
|
+
const rowProbe = (node) => [
|
|
250
|
+
[rowTarget(node), "aria-expanded"],
|
|
251
|
+
[rowTarget(node), "aria-selected"],
|
|
252
|
+
[rowTarget(node), "tabindex"],
|
|
253
|
+
[rowTarget(node), "hidden"]
|
|
254
|
+
];
|
|
255
|
+
const timelineProbe = {
|
|
256
|
+
attrs: [
|
|
257
|
+
...NODES.flatMap(rowProbe),
|
|
258
|
+
["ruler", "aria-valuemin"],
|
|
259
|
+
["ruler", "aria-valuenow"],
|
|
260
|
+
["ruler", "aria-valuemax"]
|
|
261
|
+
],
|
|
262
|
+
events: ["onValueChange"]
|
|
263
|
+
};
|
|
264
|
+
//#endregion
|
|
265
|
+
export { timelineBridge, timelineConfig, timelineProbe, timelineSteps };
|