@cssints/headless 0.5.2 → 0.6.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/README.md +37 -3
- package/dist/index.d.mts +93 -68
- package/dist/index.mjs +328 -80
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ A primitive that has a seam honours an optional `prefs` entry (a `Partial<Prefs>
|
|
|
65
65
|
- **menu / menubar** — `typeaheadDelayMs` (the typeahead buffer timeout).
|
|
66
66
|
- **tooltip** — `tooltipShowDelayMs` / `tooltipHideDelayMs`, exposed as `showDelayMs()` / `hideDelayMs()` for the host to wire its `setTimeout` from (the spec keeps timers as events).
|
|
67
67
|
|
|
68
|
-
Everything else **ignores** prefs: accordion, alert, alertdialog, breadcrumb, button, carousel, checkbox, checkbox-group, combobox, dialog-modal, disclosure, feed, grid, link, listbox, meter, player, radio, slider, slider-multithumb, spinbutton, switch, tabs, timeline, toolbar, treegrid, treeview, windowsplitter — they expose no timing / motion / live-region / camera seam. `listbox` / `treeview` / `timeline` typeahead timeouts are host-driven via their reset methods, so they take no delay here either.
|
|
68
|
+
Everything else **ignores** prefs: accordion, alert, alertdialog, breadcrumb, button, carousel, checkbox, checkbox-group, combobox, dialog-modal, disclosure, feed, grid, link, listbox, meter, player, radio, resizable-panels, slider, slider-multithumb, spinbutton, switch, tabs, timeline, toolbar, treegrid, treeview, windowsplitter — they expose no timing / motion / live-region / camera seam. `listbox` / `treeview` / `timeline` typeahead timeouts are host-driven via their reset methods, so they take no delay here either.
|
|
69
69
|
|
|
70
70
|
`motionDurationMs` is **not consumed**: canvas tweens are tick-driven, not millisecond-driven, and the look layer owns durations. It stays in `Prefs` only so a host's preference record fits the type.
|
|
71
71
|
|
|
@@ -89,12 +89,46 @@ Membership, sizes and z-order are **not modelled** in `pointer.qnt` (its node se
|
|
|
89
89
|
|
|
90
90
|
**Nested canvases** are two instances the host composes: a `#canvas` node holds a second `createCanvas`, and the inner viewport stops propagation of its own pointer, wheel and key events. The innermost canvas under the pointer owns the event, so a press or zoom inside it never starts an outer gesture or moves the outer camera. A nested canvas is a single tab stop in its parent.
|
|
91
91
|
|
|
92
|
+
## Resizable panels
|
|
93
|
+
|
|
94
|
+
`createResizablePanels` is a group of N panes and N-1 separators: react-resizable-panels' layout on the APG window splitter's keyboard. Its behaviour is `packages/apg-specs/specs/patterns/resizable-panels.qnt` — not an APG pattern, so it lives under `patterns/` — and the DOM is checked against it by the differential walk. The spec is the three-pane instance (10/80 bounds, 10% steps, pane 0 collapsible at 0); the primitive takes N panes and any bounds.
|
|
95
|
+
|
|
96
|
+
**The contract.** Sizes are percentages of the group and always sum to 100. Each pane has `min` / `max`; a `collapsible` pane sits at `collapsedSize` (0) while collapsed. A move — an arrow, Home/End, a drag — changes only the two panes around the separator, clamped by both bounds. Collapsing hands the pane's space to the nearest pane that can take it and cascades outward; restoring takes it back in the same order, so a restore always returns the remembered size.
|
|
97
|
+
|
|
98
|
+
**The separator is the widget**: `role=separator`, `tabindex=0`, `aria-orientation`, `aria-valuenow` = the size of the pane it resizes, `aria-valuemin` / `-max` that pane's bounds, `aria-controls` it. Arrows move by `step` (10%), Home/End jump the pair to its bounds, Enter collapses and restores. A separator next to a collapsed pane is inert (only Enter restores).
|
|
99
|
+
|
|
100
|
+
**The drag is snapshot + delta**: pointerdown remembers the layout, every move re-solves from it, so dragging back past a clamp recovers exactly. It uses pointer capture and ends on pointerup / pointercancel; a host write of `sizes` ends it too. Keyboard input is a no-op while a drag runs.
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
const panels = createResizablePanels({
|
|
104
|
+
panes: [{ label: "Sidebar", collapsible: true }, { label: "Content" }, { label: "Inspector" }],
|
|
105
|
+
defaultSizes: [20, 40, 40],
|
|
106
|
+
storageKey: "app-layout",
|
|
107
|
+
onSizesChange: (sizes) => save(sizes), // ignored while uncontrolled
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
<div {...panels.groupProps} style={{ display: "flex" }}>
|
|
111
|
+
{[0, 1, 2].map((index) => (
|
|
112
|
+
<>
|
|
113
|
+
<div {...panels.paneProps(index)} style={{ flex: `${panels.sizes()[index]}%` }}>
|
|
114
|
+
…
|
|
115
|
+
</div>
|
|
116
|
+
{index < 2 && <div {...panels.separatorProps(index)} />}
|
|
117
|
+
</>
|
|
118
|
+
))}
|
|
119
|
+
</div>;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Controlled is `sizes` + `onSizesChange` (the request), like every other primitive. `storageKey` persists the layout in localStorage — host storage, so the key belongs to the host's namespace.
|
|
123
|
+
|
|
124
|
+
Left to the host: pane bounds in pixels (percent only), nested groups, and F6 (with three panes a Tab is enough). Not modelled: react-resizable-panels' collapse-on-drag threshold (a pane collapses on Enter or a host write, never by dragging through MIN) and restoring a pane that was mounted already collapsed (it returns to its own `min`).
|
|
125
|
+
|
|
92
126
|
## Commands
|
|
93
127
|
|
|
94
128
|
```sh
|
|
95
129
|
cd packages/headless
|
|
96
130
|
bun run test # vp test run: vitest browser mode, real Chromium (playwright; needs the browser installed: bunx playwright install chromium)
|
|
97
|
-
bun run typecheck #
|
|
131
|
+
bun run typecheck # effect-tsrs
|
|
98
132
|
bun run build # vp pack: dist/ (ESM and declarations; solid-js is a peer)
|
|
99
133
|
```
|
|
100
134
|
|
|
@@ -104,7 +138,7 @@ The specs, bridges and scenarios the tests replay are [`@cssints/apg-specs`](../
|
|
|
104
138
|
|
|
105
139
|
## Status
|
|
106
140
|
|
|
107
|
-
|
|
141
|
+
Published with the Changesets `fixed` group (one version with the other packages, RELEASING.md). Its manifest follows the other packages (`development` condition on `src`, `dist` for consumers, `publishConfig.directory`).
|
|
108
142
|
|
|
109
143
|
Solid 2 reminders: setters apply on the microtask flush (the DOM driver waits a frame after each step); pass props objects/getters, never destructure options.
|
|
110
144
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Accessor } from "solid-js";
|
|
2
|
-
//#region src/canvas-math.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* The fixed-point math of the canvas, copied from the Quint specs. Integers only, power-of-two
|
|
5
4
|
* denominators, every intermediate below 2^53, so doubles are exact and the DOM implementation can
|
|
@@ -49,8 +48,6 @@ interface SnapContext extends SnapNode {
|
|
|
49
48
|
type SnapCandidates = (context: SnapContext) => readonly number[];
|
|
50
49
|
/** The default policy and the one `specs/canvas/pointer.qnt` models: every `GRID` units. */
|
|
51
50
|
export declare const gridCandidates: SnapCandidates;
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region src/prefs.d.ts
|
|
54
51
|
/**
|
|
55
52
|
* The user preferences a primitive honours. The host resolves them from
|
|
56
53
|
* wherever it keeps them and injects a `Partial<Prefs>` per primitive;
|
|
@@ -74,8 +71,6 @@ export interface Prefs {
|
|
|
74
71
|
export declare const DEFAULT_PREFS: Prefs;
|
|
75
72
|
/** Merge an injected partial with the defaults; never mutates the input. */
|
|
76
73
|
export declare const withPrefs: (partial?: Partial<Prefs>) => Prefs;
|
|
77
|
-
//#endregion
|
|
78
|
-
//#region src/canvas.d.ts
|
|
79
74
|
/**
|
|
80
75
|
* Headless infinite canvas: camera, selection and node-move state plus attribute / prop objects
|
|
81
76
|
* for a viewport, a camera layer, the nodes and a live region. No elements, no styling beyond the
|
|
@@ -376,8 +371,6 @@ interface Canvas {
|
|
|
376
371
|
readonly removeNodes: (ids: readonly string[]) => void;
|
|
377
372
|
}
|
|
378
373
|
export declare const createCanvas: (options: CanvasOptions) => Canvas;
|
|
379
|
-
//#endregion
|
|
380
|
-
//#region src/disclosure.d.ts
|
|
381
374
|
/**
|
|
382
375
|
* Options are read lazily: pass a component's `props` (or an object with
|
|
383
376
|
* getters), never destructured values, so `disabled` stays reactive.
|
|
@@ -431,8 +424,6 @@ interface Disclosure {
|
|
|
431
424
|
* pass `value` + `onValueChange` to own the state.
|
|
432
425
|
*/
|
|
433
426
|
export declare const createDisclosure: (options?: DisclosureOptions) => Disclosure;
|
|
434
|
-
//#endregion
|
|
435
|
-
//#region src/player.d.ts
|
|
436
427
|
/**
|
|
437
428
|
* A playback engine the primitive drives. Mediabunny is one; the primitive
|
|
438
429
|
* never imports a media library (`@cssints/headless` stays `solid-js`-only).
|
|
@@ -556,8 +547,6 @@ interface Player {
|
|
|
556
547
|
* no elements live here.
|
|
557
548
|
*/
|
|
558
549
|
export declare const createPlayer: (options: PlayerOptions) => Player;
|
|
559
|
-
//#endregion
|
|
560
|
-
//#region src/accordion.d.ts
|
|
561
550
|
/**
|
|
562
551
|
* Options are read lazily (getters) so `multiple` / `disabled` stay reactive;
|
|
563
552
|
* pass a component's `props`, never destructured values.
|
|
@@ -641,8 +630,6 @@ export interface Accordion {
|
|
|
641
630
|
* while uncontrolled.
|
|
642
631
|
*/
|
|
643
632
|
export declare const createAccordion: (options?: AccordionOptions) => Accordion;
|
|
644
|
-
//#endregion
|
|
645
|
-
//#region src/alert.d.ts
|
|
646
633
|
export interface AlertOptions {
|
|
647
634
|
/** Rendered at mount; `undefined` starts with no live region. */
|
|
648
635
|
readonly message?: string | undefined;
|
|
@@ -675,8 +662,6 @@ export interface Alert {
|
|
|
675
662
|
* region is live; the primitive keeps the region mounted and unhides it.
|
|
676
663
|
*/
|
|
677
664
|
export declare const createAlert: (options?: AlertOptions) => Alert;
|
|
678
|
-
//#endregion
|
|
679
|
-
//#region src/alertdialog.d.ts
|
|
680
665
|
export interface AlertDialogOptions {
|
|
681
666
|
/** Controlled: the host owns the open state and this is the only thing that changes it. */
|
|
682
667
|
readonly value?: boolean | undefined;
|
|
@@ -765,8 +750,6 @@ declare const YES_POS = 2;
|
|
|
765
750
|
* open state through an effect, so a rejected request leaves them untouched.
|
|
766
751
|
*/
|
|
767
752
|
export declare const createAlertDialog: (options?: AlertDialogOptions) => AlertDialog;
|
|
768
|
-
//#endregion
|
|
769
|
-
//#region src/breadcrumb.d.ts
|
|
770
753
|
export interface BreadcrumbItem {
|
|
771
754
|
readonly label: string;
|
|
772
755
|
readonly href?: string | undefined;
|
|
@@ -813,8 +796,6 @@ export interface Breadcrumb {
|
|
|
813
796
|
* markup; the navigation landmark is a UA/AT concern).
|
|
814
797
|
*/
|
|
815
798
|
export declare const createBreadcrumb: (options: BreadcrumbOptions) => Breadcrumb;
|
|
816
|
-
//#endregion
|
|
817
|
-
//#region src/button.d.ts
|
|
818
799
|
export interface ButtonOptions {
|
|
819
800
|
/** A toggle button carries `aria-pressed`; a command button does not. */
|
|
820
801
|
readonly isToggle?: boolean;
|
|
@@ -862,8 +843,6 @@ export interface Button {
|
|
|
862
843
|
* uncontrolled. A command button's activation never carries a value.
|
|
863
844
|
*/
|
|
864
845
|
export declare const createButton: (options?: ButtonOptions) => Button;
|
|
865
|
-
//#endregion
|
|
866
|
-
//#region src/carousel.d.ts
|
|
867
846
|
export type CarouselRole = "region" | "group";
|
|
868
847
|
/**
|
|
869
848
|
* Options are read lazily (getters); pass a component's `props`.
|
|
@@ -995,8 +974,6 @@ export interface Carousel {
|
|
|
995
974
|
* (and `prefers-reduced-motion`) in the consumer.
|
|
996
975
|
*/
|
|
997
976
|
export declare const createCarousel: (options?: CarouselOptions) => Carousel;
|
|
998
|
-
//#endregion
|
|
999
|
-
//#region src/checkbox.d.ts
|
|
1000
977
|
export type CheckboxState = "true" | "false" | "mixed";
|
|
1001
978
|
export interface CheckboxOptions {
|
|
1002
979
|
/** Controlled: the host owns the value and this is the only thing that changes it. */
|
|
@@ -1053,8 +1030,6 @@ export interface Checkbox {
|
|
|
1053
1030
|
* pass `value` + `onValueChange` to own the state.
|
|
1054
1031
|
*/
|
|
1055
1032
|
export declare const createCheckbox: (options?: CheckboxOptions) => Checkbox;
|
|
1056
|
-
//#endregion
|
|
1057
|
-
//#region src/checkbox-group.d.ts
|
|
1058
1033
|
export type CheckboxGroupFocus = "none" | "parent" | "c0" | "c1" | "c2";
|
|
1059
1034
|
export type ParentChecked = "true" | "false" | "mixed";
|
|
1060
1035
|
export interface CheckboxGroupOptions<T = unknown> {
|
|
@@ -1131,8 +1106,6 @@ export interface CheckboxGroup<T = unknown> {
|
|
|
1131
1106
|
* Behaviour is checked against `specs/apg/checkbox-group.qnt` by the bridge.
|
|
1132
1107
|
*/
|
|
1133
1108
|
export declare const createCheckboxGroup: <T = unknown>(options: CheckboxGroupOptions<T>) => CheckboxGroup<T>;
|
|
1134
|
-
//#endregion
|
|
1135
|
-
//#region src/combobox.d.ts
|
|
1136
1109
|
/**
|
|
1137
1110
|
* APG combobox (https://www.w3.org/WAI/ARIA/apg/patterns/combobox/): state plus
|
|
1138
1111
|
* getter-backed attribute objects for a listbox popup. No elements, no styling.
|
|
@@ -1253,8 +1226,6 @@ export interface ComboboxOptions {
|
|
|
1253
1226
|
readonly onFocusRelease?: () => void;
|
|
1254
1227
|
}
|
|
1255
1228
|
export declare const createCombobox: (options: ComboboxOptions) => Combobox;
|
|
1256
|
-
//#endregion
|
|
1257
|
-
//#region src/dialog-modal.d.ts
|
|
1258
1229
|
export type DialogRole = "dialog" | "alertdialog";
|
|
1259
1230
|
export interface DialogModalOptions {
|
|
1260
1231
|
/** Controlled: the host owns the open state and this is the only thing that changes it. */
|
|
@@ -1323,8 +1294,6 @@ export interface DialogModal {
|
|
|
1323
1294
|
* are requests the host may ignore.
|
|
1324
1295
|
*/
|
|
1325
1296
|
export declare const createDialogModal: (options?: DialogModalOptions) => DialogModal;
|
|
1326
|
-
//#endregion
|
|
1327
|
-
//#region src/feed.d.ts
|
|
1328
1297
|
/**
|
|
1329
1298
|
* Options are read lazily (getters); pass a component's `props`.
|
|
1330
1299
|
*/
|
|
@@ -1412,8 +1381,6 @@ export interface Feed {
|
|
|
1412
1381
|
* request; `loadStart` / `loadFail` are adapter lifecycle events.
|
|
1413
1382
|
*/
|
|
1414
1383
|
export declare const createFeed: (options?: FeedOptions) => Feed;
|
|
1415
|
-
//#endregion
|
|
1416
|
-
//#region src/grid.d.ts
|
|
1417
1384
|
/**
|
|
1418
1385
|
* APG grid primitive on Solid 2: roving focus, 2-D navigation, edit mode, a
|
|
1419
1386
|
* cell/row/column selection rectangle and sortable column headers. State plus
|
|
@@ -1584,8 +1551,6 @@ export declare const packSort: (column: number, dir: GridSortDirection) => numbe
|
|
|
1584
1551
|
* snapshot); `rows`/`cols`/`page` are captured once.
|
|
1585
1552
|
*/
|
|
1586
1553
|
export declare const createGrid: (options?: GridOptions) => Grid;
|
|
1587
|
-
//#endregion
|
|
1588
|
-
//#region src/link.d.ts
|
|
1589
1554
|
export interface LinkOptions {
|
|
1590
1555
|
readonly href?: string | undefined;
|
|
1591
1556
|
/** Render a native `<a href>` (the default when `href` is set). */
|
|
@@ -1622,8 +1587,6 @@ export interface Link {
|
|
|
1622
1587
|
* cause browsers to enhance the element". Platform: native.
|
|
1623
1588
|
*/
|
|
1624
1589
|
export declare const createLink: (options?: LinkOptions) => Link;
|
|
1625
|
-
//#endregion
|
|
1626
|
-
//#region src/listbox.d.ts
|
|
1627
1590
|
export type ListboxSelectionMode = "single" | "multiple" | "none";
|
|
1628
1591
|
export interface ListboxItem {
|
|
1629
1592
|
readonly id: string;
|
|
@@ -1729,8 +1692,6 @@ export interface Listbox {
|
|
|
1729
1692
|
* move is a request the host may ignore.
|
|
1730
1693
|
*/
|
|
1731
1694
|
export declare const createListbox: (options: ListboxOptions) => Listbox;
|
|
1732
|
-
//#endregion
|
|
1733
|
-
//#region src/menu.d.ts
|
|
1734
1695
|
/**
|
|
1735
1696
|
* APG menu family on Solid 2: `createMenu` (menu button + the checkable /
|
|
1736
1697
|
* menuitemcheckbox / menuitemradio capability) and `createMenubar` (roving
|
|
@@ -1953,8 +1914,6 @@ export interface Menubar {
|
|
|
1953
1914
|
};
|
|
1954
1915
|
}
|
|
1955
1916
|
export declare const createMenubar: (options: MenubarOptions) => Menubar;
|
|
1956
|
-
//#endregion
|
|
1957
|
-
//#region src/meter.d.ts
|
|
1958
1917
|
/**
|
|
1959
1918
|
* A controlled numeric display; the consumer feeds `value`/`min`/`max`.
|
|
1960
1919
|
* `valueText` overrides the default percentage `aria-valuetext`.
|
|
@@ -1992,8 +1951,6 @@ export interface Meter {
|
|
|
1992
1951
|
* this primitive only derives the ARIA contract; no state machine runs here.
|
|
1993
1952
|
*/
|
|
1994
1953
|
export declare const createMeter: (options?: MeterOptions) => Meter;
|
|
1995
|
-
//#endregion
|
|
1996
|
-
//#region src/radio.d.ts
|
|
1997
1954
|
export type RadioFlavor = "roving" | "activedescendant";
|
|
1998
1955
|
export interface RadioGroupOptions<T = unknown> {
|
|
1999
1956
|
/** Radio values, one per radio; the observable `value` is the checked one. */
|
|
@@ -2075,8 +2032,99 @@ export interface RadioGroup<T = unknown> {
|
|
|
2075
2032
|
* callback, which `createControllable` does not expose.
|
|
2076
2033
|
*/
|
|
2077
2034
|
export declare const createRadioGroup: <T = unknown>(options: RadioGroupOptions<T>) => RadioGroup<T>;
|
|
2078
|
-
|
|
2079
|
-
|
|
2035
|
+
export type PanelsOrientation = "vertical" | "horizontal";
|
|
2036
|
+
/** One pane of the group. Sizes are percentages of the group (0..100). */
|
|
2037
|
+
export interface ResizablePaneOptions {
|
|
2038
|
+
readonly id?: string;
|
|
2039
|
+
/** Smallest expanded size, in percent. */
|
|
2040
|
+
readonly min?: number;
|
|
2041
|
+
/** Largest size, in percent. */
|
|
2042
|
+
readonly max?: number;
|
|
2043
|
+
/** The uncontrolled start; defaults to an equal split. */
|
|
2044
|
+
readonly defaultSize?: number;
|
|
2045
|
+
/** Collapses to `collapsedSize` on Enter and restores the remembered size. */
|
|
2046
|
+
readonly collapsible?: boolean;
|
|
2047
|
+
readonly collapsedSize?: number;
|
|
2048
|
+
/** Accessible name fragment: the separator becomes "Resize <label>". */
|
|
2049
|
+
readonly label?: string;
|
|
2050
|
+
}
|
|
2051
|
+
/** Options are read lazily: pass an object with getters, never destructured values. */
|
|
2052
|
+
export interface ResizablePanelsOptions {
|
|
2053
|
+
readonly panes: ReadonlyArray<ResizablePaneOptions>;
|
|
2054
|
+
readonly orientation?: PanelsOrientation;
|
|
2055
|
+
/** Controlled: the host owns the layout. A new array per change. */
|
|
2056
|
+
readonly sizes?: ReadonlyArray<number> | undefined;
|
|
2057
|
+
/** The uncontrolled start; ignored while `sizes` is set. */
|
|
2058
|
+
readonly defaultSizes?: ReadonlyArray<number>;
|
|
2059
|
+
/** Keyboard step, in percent. */
|
|
2060
|
+
readonly step?: number;
|
|
2061
|
+
/** Base for the generated group / pane / separator ids. */
|
|
2062
|
+
readonly id?: string;
|
|
2063
|
+
/** Accessible name of the group. */
|
|
2064
|
+
readonly label?: string | undefined;
|
|
2065
|
+
/** Persist the layout in localStorage under this key (host storage, not modelled). */
|
|
2066
|
+
readonly storageKey?: string | undefined;
|
|
2067
|
+
/** A request to change the layout the host may ignore. */
|
|
2068
|
+
readonly onSizesChange?: (sizes: ReadonlyArray<number>) => void;
|
|
2069
|
+
}
|
|
2070
|
+
export interface ResizablePanelsGroupProps {
|
|
2071
|
+
readonly role: "group";
|
|
2072
|
+
readonly "aria-label": string | undefined;
|
|
2073
|
+
}
|
|
2074
|
+
export interface ResizablePaneProps {
|
|
2075
|
+
readonly id: string;
|
|
2076
|
+
}
|
|
2077
|
+
/** Spread onto the focusable `role=separator` bar between pane `index` and `index + 1`. */
|
|
2078
|
+
export interface ResizableSeparatorProps {
|
|
2079
|
+
readonly id: string;
|
|
2080
|
+
readonly role: "separator";
|
|
2081
|
+
readonly "aria-orientation": PanelsOrientation;
|
|
2082
|
+
readonly "aria-valuenow": number;
|
|
2083
|
+
readonly "aria-valuemin": number;
|
|
2084
|
+
readonly "aria-valuemax": number;
|
|
2085
|
+
/** The pane this separator resizes (the one on its left). */
|
|
2086
|
+
readonly "aria-controls": string;
|
|
2087
|
+
readonly "aria-label": string;
|
|
2088
|
+
readonly tabindex: 0;
|
|
2089
|
+
readonly onKeyDown: (event: KeyboardEvent) => void;
|
|
2090
|
+
readonly onFocus: () => void;
|
|
2091
|
+
readonly onBlur: () => void;
|
|
2092
|
+
readonly onPointerDown: (event: PointerEvent) => void;
|
|
2093
|
+
readonly onPointerMove: (event: PointerEvent) => void;
|
|
2094
|
+
readonly onPointerUp: (event: PointerEvent) => void;
|
|
2095
|
+
readonly onPointerCancel: (event: PointerEvent) => void;
|
|
2096
|
+
}
|
|
2097
|
+
export interface ResizablePanels {
|
|
2098
|
+
/** The committed layout, in percent; always sums to 100. */
|
|
2099
|
+
readonly sizes: Accessor<ReadonlyArray<number>>;
|
|
2100
|
+
readonly collapsed: (index: number) => boolean;
|
|
2101
|
+
/** The separator being dragged, or `null`. */
|
|
2102
|
+
readonly resizing: Accessor<number | null>;
|
|
2103
|
+
readonly focusSeparator: Accessor<number | null>;
|
|
2104
|
+
readonly setFocusSeparator: (index: number | null) => void;
|
|
2105
|
+
readonly keyDown: (index: number, key: string) => void;
|
|
2106
|
+
readonly groupProps: ResizablePanelsGroupProps;
|
|
2107
|
+
readonly paneProps: (index: number) => ResizablePaneProps;
|
|
2108
|
+
readonly separatorProps: (index: number) => ResizableSeparatorProps;
|
|
2109
|
+
}
|
|
2110
|
+
/**
|
|
2111
|
+
* A group of N panes and N-1 separators, react-resizable-panels' model on the
|
|
2112
|
+
* APG window splitter's keyboard: sizes in percent of the group, always summing
|
|
2113
|
+
* to 100, each pane within `min..max`, a collapsible pane landing on
|
|
2114
|
+
* `collapsedSize`. The separator is the focusable widget (`role=separator`,
|
|
2115
|
+
* its `aria-valuenow` is the pane on its left); arrows/Home/End move the pair
|
|
2116
|
+
* around a separator and Enter collapses / restores, all as requests.
|
|
2117
|
+
*
|
|
2118
|
+
* A move only ever changes the separator's two neighbours, clamped by both
|
|
2119
|
+
* bounds. Collapsing hands the pane's space to the nearest pane that can take
|
|
2120
|
+
* it and cascades outward; restoring takes it back in the same order. The drag
|
|
2121
|
+
* is snapshot + delta: pointerdown remembers the layout, every move re-solves
|
|
2122
|
+
* from it, so dragging back past a clamp recovers exactly.
|
|
2123
|
+
*
|
|
2124
|
+
* Behaviour is `packages/apg-specs/specs/patterns/resizable-panels.qnt`; the
|
|
2125
|
+
* DOM is checked against it by the differential walk.
|
|
2126
|
+
*/
|
|
2127
|
+
export declare const createResizablePanels: (options: ResizablePanelsOptions) => ResizablePanels;
|
|
2080
2128
|
export type SliderOrientation = "horizontal" | "vertical";
|
|
2081
2129
|
export type SliderDirection = "ltr" | "rtl";
|
|
2082
2130
|
export interface SliderOptions {
|
|
@@ -2148,8 +2196,6 @@ export interface Slider {
|
|
|
2148
2196
|
* deliberately only fixes a discrete rail press.
|
|
2149
2197
|
*/
|
|
2150
2198
|
export declare const createSlider: (options?: SliderOptions) => Slider;
|
|
2151
|
-
//#endregion
|
|
2152
|
-
//#region src/slider-multithumb.d.ts
|
|
2153
2199
|
export type SliderMultiThumbIndex = 0 | 1;
|
|
2154
2200
|
export interface SliderMultiThumbOptions {
|
|
2155
2201
|
readonly min?: number;
|
|
@@ -2217,8 +2263,6 @@ export interface SliderMultiThumb {
|
|
|
2217
2263
|
* omits them (the event names the thumb).
|
|
2218
2264
|
*/
|
|
2219
2265
|
export declare const createSliderMultiThumb: (options?: SliderMultiThumbOptions) => SliderMultiThumb;
|
|
2220
|
-
//#endregion
|
|
2221
|
-
//#region src/spinbutton.d.ts
|
|
2222
2266
|
export interface SpinbuttonOptions {
|
|
2223
2267
|
readonly min?: number;
|
|
2224
2268
|
readonly max?: number;
|
|
@@ -2307,8 +2351,6 @@ export interface Spinbutton {
|
|
|
2307
2351
|
* APG text.
|
|
2308
2352
|
*/
|
|
2309
2353
|
export declare const createSpinbutton: (options?: SpinbuttonOptions) => Spinbutton;
|
|
2310
|
-
//#endregion
|
|
2311
|
-
//#region src/switch.d.ts
|
|
2312
2354
|
export interface SwitchOptions {
|
|
2313
2355
|
/** Controlled: the host owns the state and this is the only thing that changes it. */
|
|
2314
2356
|
readonly value?: boolean | undefined;
|
|
@@ -2363,8 +2405,6 @@ export interface Switch {
|
|
|
2363
2405
|
* pass `value` + `onValueChange` to own the state.
|
|
2364
2406
|
*/
|
|
2365
2407
|
export declare const createSwitch: (options?: SwitchOptions) => Switch;
|
|
2366
|
-
//#endregion
|
|
2367
|
-
//#region src/tabs.d.ts
|
|
2368
2408
|
export type TabsOrientation = "horizontal" | "vertical";
|
|
2369
2409
|
export type TabsActivation = "automatic" | "manual";
|
|
2370
2410
|
/**
|
|
@@ -2449,8 +2489,6 @@ export interface Tabs {
|
|
|
2449
2489
|
* Programmatic methods (`select`, `setSelected`, `keyDown`) are requests too.
|
|
2450
2490
|
*/
|
|
2451
2491
|
export declare const createTabs: (options?: TabsOptions) => Tabs;
|
|
2452
|
-
//#endregion
|
|
2453
|
-
//#region src/timeline.d.ts
|
|
2454
2492
|
/**
|
|
2455
2493
|
* APG has no waterfall pattern. This is the span timeline the o11y dashboard
|
|
2456
2494
|
* needs: spans laid out on a shared tick axis with nesting/indentation, a
|
|
@@ -2558,8 +2596,6 @@ export interface Timeline {
|
|
|
2558
2596
|
* reactive.
|
|
2559
2597
|
*/
|
|
2560
2598
|
export declare const createTimeline: (options?: TimelineOptions) => Timeline;
|
|
2561
|
-
//#endregion
|
|
2562
|
-
//#region src/toolbar.d.ts
|
|
2563
2599
|
/**
|
|
2564
2600
|
* APG Toolbar on Solid 2: state plus attribute objects, no elements, no
|
|
2565
2601
|
* styling. A faithful transcription of `specs/apg/toolbar.qnt`.
|
|
@@ -2631,8 +2667,6 @@ export interface Toolbar {
|
|
|
2631
2667
|
readonly itemProps: (index: number) => ToolbarItemProps;
|
|
2632
2668
|
}
|
|
2633
2669
|
export declare const createToolbar: (options: ToolbarOptions) => Toolbar;
|
|
2634
|
-
//#endregion
|
|
2635
|
-
//#region src/tooltip.d.ts
|
|
2636
2670
|
export interface TooltipTriggerInput {
|
|
2637
2671
|
readonly id?: string;
|
|
2638
2672
|
/** Id of this trigger's tooltip element (needed for `aria-describedby`). */
|
|
@@ -2731,8 +2765,6 @@ export interface TooltipGroup {
|
|
|
2731
2765
|
* gated, so a rejected request leaves the visible tooltip untouched.
|
|
2732
2766
|
*/
|
|
2733
2767
|
export declare const createTooltipGroup: (options: TooltipGroupOptions) => TooltipGroup;
|
|
2734
|
-
//#endregion
|
|
2735
|
-
//#region src/treegrid.d.ts
|
|
2736
2768
|
/**
|
|
2737
2769
|
* APG treegrid primitive on Solid 2: a fixed tree of rows, row/cell roving focus
|
|
2738
2770
|
* across the three APG navigation models, expansion and row selection. State plus
|
|
@@ -2824,8 +2856,6 @@ export declare const treegridCellPart: (row: number, col: number) => string;
|
|
|
2824
2856
|
export declare const createTreegrid: (options?: TreegridOptions) => Treegrid;
|
|
2825
2857
|
/** The `data-part` target the treegrid roving tab stop should focus. */
|
|
2826
2858
|
export declare const treegridFocusTargetPart: (grid: Treegrid) => string | null;
|
|
2827
|
-
//#endregion
|
|
2828
|
-
//#region src/treeview.d.ts
|
|
2829
2859
|
/** A tree node: `parent` is 0 for a root; order in `nodes` is document order. */
|
|
2830
2860
|
export interface TreeviewNode {
|
|
2831
2861
|
readonly id: number;
|
|
@@ -2920,8 +2950,6 @@ export interface Treeview {
|
|
|
2920
2950
|
* explicit `resetTypeahead` method; add a timer when a consumer wants one.
|
|
2921
2951
|
*/
|
|
2922
2952
|
export declare const createTreeview: (options?: TreeviewOptions) => Treeview;
|
|
2923
|
-
//#endregion
|
|
2924
|
-
//#region src/windowsplitter.d.ts
|
|
2925
2953
|
export type SplitterOrientation = "vertical" | "horizontal";
|
|
2926
2954
|
export type SplitterFocus = "none" | "splitter" | "primary" | "secondary";
|
|
2927
2955
|
/** Options are read lazily: pass an object with getters, never destructured values. */
|
|
@@ -2999,8 +3027,6 @@ export interface WindowSplitter {
|
|
|
2999
3027
|
* `collapsed` is derived from the controlled value plus the last request.
|
|
3000
3028
|
*/
|
|
3001
3029
|
export declare const createWindowSplitter: (options?: WindowSplitterOptions) => WindowSplitter;
|
|
3002
|
-
//#endregion
|
|
3003
|
-
//#region src/listbox-rearrangeable.d.ts
|
|
3004
3030
|
export type RearrangeableList = "a" | "b";
|
|
3005
3031
|
export interface RearrangeableListboxOptions {
|
|
3006
3032
|
/** Option labels; the option id is the index, and every option starts in list A. */
|
|
@@ -3064,5 +3090,4 @@ export interface RearrangeableListbox {
|
|
|
3064
3090
|
* host that holds the value moves nothing.
|
|
3065
3091
|
*/
|
|
3066
3092
|
export declare const createRearrangeableListbox: (options: RearrangeableListboxOptions) => RearrangeableListbox;
|
|
3067
|
-
//#endregion
|
|
3068
3093
|
export { type Canvas, type CanvasGoal, type CanvasLayerProps, type CanvasLiveRegionProps, type CanvasMessages, type CanvasMode, type CanvasMove, type CanvasNodeGeometry, type CanvasNodeInput, type CanvasNodeProps, type CanvasNodeRole, type CanvasOptions, type CanvasSnapshot, type CanvasViewportProps, type Disclosure, type DisclosureOptions, type DisclosurePanelProps, type DisclosureTriggerProps, type MarqueeMode, NO_POS, type PlaybackAdapter, type PlaybackAdapterEvent, type Player, type PlayerButtonProps, type PlayerOptions, type PlayerPlayProps, type PlayerSeekProps, type PlayerStage, type PlayerSurfaceProps, type PlayerToggleProps, type PointerInput, type SnapAxis, type SnapCandidates, type SnapContext, YES_POS };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createEffect, createMemo, createRoot, createSignal, createUniqueId, getOwner, onCleanup, onSettled, runWithOwner, untrack } from "solid-js";
|
|
2
|
-
|
|
2
|
+
// src/canvas-math.ts
|
|
3
3
|
/**
|
|
4
4
|
* The fixed-point math of the canvas, copied from the Quint specs. Integers only, power-of-two
|
|
5
5
|
* denominators, every intermediate below 2^53, so doubles are exact and the DOM implementation can
|
|
@@ -108,8 +108,7 @@ const snapNudge = (v, on, zf, nearest) => (snapTarget(v, on, zf, nearest) ?? v)
|
|
|
108
108
|
/** Live drag delta on one axis; `base` is the dragged node's committed position on it. */
|
|
109
109
|
const liveDD = (w, g, base, on, zf, nearest) => rawD(w, g) + snapNudge(base + rawD(w, g), on, zf, nearest);
|
|
110
110
|
const clampPos = (value, extent) => clampI(value, -1e6, WORLD_BOUND - extent);
|
|
111
|
-
|
|
112
|
-
//#region src/prefs.ts
|
|
111
|
+
// src/prefs.ts
|
|
113
112
|
/** Today's behaviour, used for every pref the host does not inject. */
|
|
114
113
|
const DEFAULT_PREFS = {
|
|
115
114
|
motion: "full",
|
|
@@ -125,13 +124,12 @@ const withPrefs = (partial) => ({
|
|
|
125
124
|
...DEFAULT_PREFS,
|
|
126
125
|
...partial
|
|
127
126
|
});
|
|
128
|
-
|
|
129
|
-
//#region src/canvas.ts
|
|
127
|
+
// src/canvas.ts
|
|
130
128
|
const DEFAULT_VIEWPORT = {
|
|
131
129
|
width: 800,
|
|
132
130
|
height: 600
|
|
133
131
|
};
|
|
134
|
-
const DEFAULT_STEP = 10;
|
|
132
|
+
const DEFAULT_STEP$1 = 10;
|
|
135
133
|
const DEFAULT_SHIFT_MULTIPLIER = 5;
|
|
136
134
|
const PRIMARY_BUTTON = 0;
|
|
137
135
|
const DEFAULT_MESSAGES = {
|
|
@@ -761,7 +759,7 @@ const createCanvas = (options) => {
|
|
|
761
759
|
const arrow = ARROWS.get(event.key);
|
|
762
760
|
if (arrow !== void 0) {
|
|
763
761
|
event.preventDefault();
|
|
764
|
-
const step = (options.keyboardStep ?? DEFAULT_STEP) * (event.shiftKey ? options.keyboardShiftMultiplier ?? DEFAULT_SHIFT_MULTIPLIER : 1);
|
|
762
|
+
const step = (options.keyboardStep ?? DEFAULT_STEP$1) * (event.shiftKey ? options.keyboardShiftMultiplier ?? DEFAULT_SHIFT_MULTIPLIER : 1);
|
|
765
763
|
moveFrom(index, arrow[0] * step, arrow[1] * step, arrow[2]);
|
|
766
764
|
} else if (event.key === "Enter") {
|
|
767
765
|
event.preventDefault();
|
|
@@ -967,8 +965,7 @@ const createCanvas = (options) => {
|
|
|
967
965
|
removeNodes
|
|
968
966
|
};
|
|
969
967
|
};
|
|
970
|
-
|
|
971
|
-
//#region src/controllable.ts
|
|
968
|
+
// src/controllable.ts
|
|
972
969
|
/**
|
|
973
970
|
* The request/commit split (map ticket `rt1p`): `request` is what a user
|
|
974
971
|
* event does. A change of intent calls `onChange`; uncontrolled it also
|
|
@@ -982,8 +979,9 @@ const createControllable = (options) => {
|
|
|
982
979
|
version();
|
|
983
980
|
return options.value() ?? local;
|
|
984
981
|
};
|
|
982
|
+
const same = options.same ?? Object.is;
|
|
985
983
|
const request = (next) => {
|
|
986
|
-
if (next
|
|
984
|
+
if (same(next, current())) return;
|
|
987
985
|
if (options.value() === void 0) {
|
|
988
986
|
local = next;
|
|
989
987
|
setVersion((count) => count + 1);
|
|
@@ -992,8 +990,7 @@ const createControllable = (options) => {
|
|
|
992
990
|
};
|
|
993
991
|
return [current, request];
|
|
994
992
|
};
|
|
995
|
-
|
|
996
|
-
//#region src/disclosure.ts
|
|
993
|
+
// src/disclosure.ts
|
|
997
994
|
/**
|
|
998
995
|
* APG Disclosure (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/):
|
|
999
996
|
* state plus attribute objects for a trigger and a panel. No styling, no
|
|
@@ -1041,8 +1038,7 @@ const createDisclosure = (options = {}) => {
|
|
|
1041
1038
|
}
|
|
1042
1039
|
};
|
|
1043
1040
|
};
|
|
1044
|
-
|
|
1045
|
-
//#region src/player.ts
|
|
1041
|
+
// src/player.ts
|
|
1046
1042
|
const RATE_PERCENTS = [
|
|
1047
1043
|
50,
|
|
1048
1044
|
100,
|
|
@@ -1052,7 +1048,7 @@ const RATE_PERCENTS = [
|
|
|
1052
1048
|
const SURFACE_SEEK_SECONDS = 5;
|
|
1053
1049
|
const SEEK_STEP_SECONDS = 1;
|
|
1054
1050
|
const SEEK_PAGE_SECONDS = 15;
|
|
1055
|
-
const clamp$
|
|
1051
|
+
const clamp$2 = (value, max) => value < 0 ? 0 : value > max ? max : value;
|
|
1056
1052
|
const mss = (seconds) => `${Math.floor(seconds / 60)}:${String(Math.floor(seconds) % 60).padStart(2, "0")}`;
|
|
1057
1053
|
/**
|
|
1058
1054
|
* APG media player primitive on Solid 2: playback state + attribute objects.
|
|
@@ -1089,7 +1085,7 @@ const createPlayer = (options) => {
|
|
|
1089
1085
|
const isActive = () => stage() === "playing" || stage() === "buffering";
|
|
1090
1086
|
const canPlay = () => stage() === "ready" || stage() === "paused" || stage() === "ended" || stage() === "buffering";
|
|
1091
1087
|
const moveTo = (seconds) => {
|
|
1092
|
-
setPosition(clamp$
|
|
1088
|
+
setPosition(clamp$2(seconds, duration()));
|
|
1093
1089
|
};
|
|
1094
1090
|
const play = () => {
|
|
1095
1091
|
if (!canPlay()) return;
|
|
@@ -1110,14 +1106,14 @@ const createPlayer = (options) => {
|
|
|
1110
1106
|
};
|
|
1111
1107
|
const commit = (seconds) => {
|
|
1112
1108
|
if (!known()) return;
|
|
1113
|
-
const target = clamp$
|
|
1109
|
+
const target = clamp$2(seconds, duration());
|
|
1114
1110
|
if (stage() === "ended") setStage("paused");
|
|
1115
1111
|
moveTo(target);
|
|
1116
1112
|
options.onSeek?.(target);
|
|
1117
1113
|
options.adapter.seek(target);
|
|
1118
1114
|
};
|
|
1119
1115
|
const setVolume = (value) => {
|
|
1120
|
-
requestVolume(clamp$
|
|
1116
|
+
requestVolume(clamp$2(value, 100));
|
|
1121
1117
|
};
|
|
1122
1118
|
const toggleMute = () => {
|
|
1123
1119
|
requestMuted(!muted());
|
|
@@ -1296,8 +1292,7 @@ const createPlayer = (options) => {
|
|
|
1296
1292
|
}
|
|
1297
1293
|
};
|
|
1298
1294
|
};
|
|
1299
|
-
|
|
1300
|
-
//#region src/accordion.ts
|
|
1295
|
+
// src/accordion.ts
|
|
1301
1296
|
const HEADING_LEVELS = 6;
|
|
1302
1297
|
const count = (expanded) => expanded.filter(Boolean).length;
|
|
1303
1298
|
/** Re-establish the mode's constraints, exactly as the spec's `normExpanded`. */
|
|
@@ -1408,8 +1403,7 @@ const createAccordion = (options = {}) => {
|
|
|
1408
1403
|
})
|
|
1409
1404
|
};
|
|
1410
1405
|
};
|
|
1411
|
-
|
|
1412
|
-
//#region src/alert.ts
|
|
1406
|
+
// src/alert.ts
|
|
1413
1407
|
/**
|
|
1414
1408
|
* APG Alert (https://www.w3.org/WAI/ARIA/apg/patterns/alert/): a brief message
|
|
1415
1409
|
* in a `role=alert` live region. Platform: native live-region markup
|
|
@@ -1449,8 +1443,7 @@ const createAlert = (options = {}) => {
|
|
|
1449
1443
|
}
|
|
1450
1444
|
};
|
|
1451
1445
|
};
|
|
1452
|
-
|
|
1453
|
-
//#region src/alertdialog.ts
|
|
1446
|
+
// src/alertdialog.ts
|
|
1454
1447
|
const NO_POS = 1;
|
|
1455
1448
|
const YES_POS = 2;
|
|
1456
1449
|
/**
|
|
@@ -1683,8 +1676,7 @@ const createAlertDialog = (options = {}) => {
|
|
|
1683
1676
|
}
|
|
1684
1677
|
};
|
|
1685
1678
|
};
|
|
1686
|
-
|
|
1687
|
-
//#region src/breadcrumb.ts
|
|
1679
|
+
// src/breadcrumb.ts
|
|
1688
1680
|
/**
|
|
1689
1681
|
* APG Breadcrumb (https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/): a trail
|
|
1690
1682
|
* of links in hierarchical order, the current page LAST and marked
|
|
@@ -1730,8 +1722,7 @@ const createBreadcrumb = (options) => {
|
|
|
1730
1722
|
})
|
|
1731
1723
|
};
|
|
1732
1724
|
};
|
|
1733
|
-
|
|
1734
|
-
//#region src/button.ts
|
|
1725
|
+
// src/button.ts
|
|
1735
1726
|
/**
|
|
1736
1727
|
* APG Button (https://www.w3.org/WAI/ARIA/apg/patterns/button/): a command
|
|
1737
1728
|
* button and (with `isToggle`) a toggle button exposing `aria-pressed`.
|
|
@@ -1775,8 +1766,7 @@ const createButton = (options = {}) => {
|
|
|
1775
1766
|
}
|
|
1776
1767
|
};
|
|
1777
1768
|
};
|
|
1778
|
-
|
|
1779
|
-
//#region src/carousel.ts
|
|
1769
|
+
// src/carousel.ts
|
|
1780
1770
|
/**
|
|
1781
1771
|
* APG Carousel (https://www.w3.org/WAI/ARIA/apg/patterns/carousel/): state plus
|
|
1782
1772
|
* prop objects for the rotation/prev/next controls, slides and the optional
|
|
@@ -1966,8 +1956,7 @@ const createCarousel = (options = {}) => {
|
|
|
1966
1956
|
})
|
|
1967
1957
|
};
|
|
1968
1958
|
};
|
|
1969
|
-
|
|
1970
|
-
//#region src/checkbox.ts
|
|
1959
|
+
// src/checkbox.ts
|
|
1971
1960
|
/**
|
|
1972
1961
|
* APG Checkbox (https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/): one
|
|
1973
1962
|
* dual-state, optionally tri-state, checkbox. Platform choice (packages/headless/docs/
|
|
@@ -2062,8 +2051,7 @@ const createCheckbox = (options = {}) => {
|
|
|
2062
2051
|
}
|
|
2063
2052
|
};
|
|
2064
2053
|
};
|
|
2065
|
-
|
|
2066
|
-
//#region src/checkbox-group.ts
|
|
2054
|
+
// src/checkbox-group.ts
|
|
2067
2055
|
const CHILDREN = [
|
|
2068
2056
|
"c0",
|
|
2069
2057
|
"c1",
|
|
@@ -2231,8 +2219,7 @@ const createCheckboxGroup = (options) => {
|
|
|
2231
2219
|
})
|
|
2232
2220
|
};
|
|
2233
2221
|
};
|
|
2234
|
-
|
|
2235
|
-
//#region src/combobox.ts
|
|
2222
|
+
// src/combobox.ts
|
|
2236
2223
|
const PAGE_SIZE = 4;
|
|
2237
2224
|
const toOption = (input) => typeof input === "string" ? {
|
|
2238
2225
|
value: input,
|
|
@@ -2520,8 +2507,7 @@ const createCombobox = (options) => {
|
|
|
2520
2507
|
}
|
|
2521
2508
|
};
|
|
2522
2509
|
};
|
|
2523
|
-
|
|
2524
|
-
//#region src/dialog-modal.ts
|
|
2510
|
+
// src/dialog-modal.ts
|
|
2525
2511
|
/**
|
|
2526
2512
|
* APG Dialog (Modal) on Solid 2. `modal` adds `aria-modal`. Focus moves into
|
|
2527
2513
|
* the dialog on open and is the host's to restore on close (the fixture does,
|
|
@@ -2598,8 +2584,7 @@ const createDialogModal = (options = {}) => {
|
|
|
2598
2584
|
}
|
|
2599
2585
|
};
|
|
2600
2586
|
};
|
|
2601
|
-
|
|
2602
|
-
//#region src/feed.ts
|
|
2587
|
+
// src/feed.ts
|
|
2603
2588
|
/**
|
|
2604
2589
|
* APG Feed (https://www.w3.org/WAI/ARIA/apg/patterns/feed/): state plus prop
|
|
2605
2590
|
* objects for the feed container, its articles and the two outside focus
|
|
@@ -2734,8 +2719,7 @@ const createFeed = (options = {}) => {
|
|
|
2734
2719
|
}
|
|
2735
2720
|
};
|
|
2736
2721
|
};
|
|
2737
|
-
|
|
2738
|
-
//#region src/grid.ts
|
|
2722
|
+
// src/grid.ts
|
|
2739
2723
|
const GRID_KEYS = /* @__PURE__ */ new Set([
|
|
2740
2724
|
"ArrowRight",
|
|
2741
2725
|
"ArrowLeft",
|
|
@@ -3144,8 +3128,7 @@ const createGrid = (options = {}) => {
|
|
|
3144
3128
|
}
|
|
3145
3129
|
};
|
|
3146
3130
|
};
|
|
3147
|
-
|
|
3148
|
-
//#region src/link.ts
|
|
3131
|
+
// src/link.ts
|
|
3149
3132
|
/**
|
|
3150
3133
|
* APG Link (https://www.w3.org/WAI/ARIA/apg/patterns/link/): a native `<a href>`
|
|
3151
3134
|
* brings focus and activation for free; a custom element takes `role=link` and
|
|
@@ -3194,8 +3177,7 @@ const createLink = (options = {}) => {
|
|
|
3194
3177
|
}
|
|
3195
3178
|
};
|
|
3196
3179
|
};
|
|
3197
|
-
|
|
3198
|
-
//#region src/listbox.ts
|
|
3180
|
+
// src/listbox.ts
|
|
3199
3181
|
const normalizeSelected = (indices, count) => [...new Set(indices)].filter((index) => index >= 0 && index < count).sort((a, b) => a - b);
|
|
3200
3182
|
const sameSelection = (a, b) => a.length === b.length && a.every((value, index) => value === b[index]);
|
|
3201
3183
|
/**
|
|
@@ -3542,8 +3524,7 @@ const createListbox = (options) => {
|
|
|
3542
3524
|
})
|
|
3543
3525
|
};
|
|
3544
3526
|
};
|
|
3545
|
-
|
|
3546
|
-
//#region src/menu.ts
|
|
3527
|
+
// src/menu.ts
|
|
3547
3528
|
const toItem = (input, index, base) => {
|
|
3548
3529
|
if (typeof input === "string") return {
|
|
3549
3530
|
label: input,
|
|
@@ -4247,9 +4228,8 @@ const createMenubar = (options) => {
|
|
|
4247
4228
|
})
|
|
4248
4229
|
};
|
|
4249
4230
|
};
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
const clamp = (value, lo, hi) => value < lo ? lo : value > hi ? hi : value;
|
|
4231
|
+
// src/meter.ts
|
|
4232
|
+
const clamp$1 = (value, lo, hi) => value < lo ? lo : value > hi ? hi : value;
|
|
4253
4233
|
/**
|
|
4254
4234
|
* APG Meter (https://www.w3.org/WAI/ARIA/apg/patterns/meter/): a graphical
|
|
4255
4235
|
* display of a numeric value within a range. Platform: native (`<meter>`), so
|
|
@@ -4262,7 +4242,7 @@ const createMeter = (options = {}) => {
|
|
|
4262
4242
|
const value = () => {
|
|
4263
4243
|
const lo = min();
|
|
4264
4244
|
const hi = max();
|
|
4265
|
-
return hi <= lo ? lo : clamp(options.value ?? 0, lo, hi);
|
|
4245
|
+
return hi <= lo ? lo : clamp$1(options.value ?? 0, lo, hi);
|
|
4266
4246
|
};
|
|
4267
4247
|
const percent = () => {
|
|
4268
4248
|
const width = span();
|
|
@@ -4296,8 +4276,7 @@ const createMeter = (options = {}) => {
|
|
|
4296
4276
|
}
|
|
4297
4277
|
};
|
|
4298
4278
|
};
|
|
4299
|
-
|
|
4300
|
-
//#region src/radio.ts
|
|
4279
|
+
// src/radio.ts
|
|
4301
4280
|
/**
|
|
4302
4281
|
* APG Radio Group (https://www.w3.org/WAI/ARIA/apg/patterns/radio/): a
|
|
4303
4282
|
* `radiogroup` with `role=radio` items. Platform choice (packages/headless/docs/
|
|
@@ -4483,8 +4462,289 @@ const createRadioGroup = (options) => {
|
|
|
4483
4462
|
})
|
|
4484
4463
|
};
|
|
4485
4464
|
};
|
|
4486
|
-
|
|
4487
|
-
|
|
4465
|
+
// src/resizable-panels.ts
|
|
4466
|
+
const DEFAULT_MIN = 10;
|
|
4467
|
+
const DEFAULT_MAX = 80;
|
|
4468
|
+
const DEFAULT_STEP = 10;
|
|
4469
|
+
const FULL = 100;
|
|
4470
|
+
const clamp = (value, low, high) => Math.min(high, Math.max(low, value));
|
|
4471
|
+
/** Percentages are reported at a hundredth: a pointer delta is never exact. */
|
|
4472
|
+
const round2 = (value) => Math.round(value * 100) / 100;
|
|
4473
|
+
const sameSizes = (a, b) => a.length === b.length && a.every((value, index) => value === b[index]);
|
|
4474
|
+
const KEY_TAGS$1 = /* @__PURE__ */ new Set([
|
|
4475
|
+
"ArrowLeft",
|
|
4476
|
+
"ArrowRight",
|
|
4477
|
+
"ArrowUp",
|
|
4478
|
+
"ArrowDown",
|
|
4479
|
+
"Home",
|
|
4480
|
+
"End",
|
|
4481
|
+
"Enter"
|
|
4482
|
+
]);
|
|
4483
|
+
const capture = (element, pointerId) => {
|
|
4484
|
+
try {
|
|
4485
|
+
element.setPointerCapture(pointerId);
|
|
4486
|
+
} catch {}
|
|
4487
|
+
};
|
|
4488
|
+
const release = (element, pointerId) => {
|
|
4489
|
+
try {
|
|
4490
|
+
element.releasePointerCapture(pointerId);
|
|
4491
|
+
} catch {}
|
|
4492
|
+
};
|
|
4493
|
+
const readStored = (key, count) => {
|
|
4494
|
+
if (typeof localStorage === "undefined") return;
|
|
4495
|
+
try {
|
|
4496
|
+
const raw = localStorage.getItem(key);
|
|
4497
|
+
if (raw === null) return;
|
|
4498
|
+
const parsed = JSON.parse(raw);
|
|
4499
|
+
if (Array.isArray(parsed) && parsed.length === count && parsed.every((value) => typeof value === "number" && Number.isFinite(value))) return parsed;
|
|
4500
|
+
} catch {}
|
|
4501
|
+
};
|
|
4502
|
+
const writeStored = (key, sizes) => {
|
|
4503
|
+
if (typeof localStorage === "undefined") return;
|
|
4504
|
+
try {
|
|
4505
|
+
localStorage.setItem(key, JSON.stringify(sizes));
|
|
4506
|
+
} catch {}
|
|
4507
|
+
};
|
|
4508
|
+
/**
|
|
4509
|
+
* A group of N panes and N-1 separators, react-resizable-panels' model on the
|
|
4510
|
+
* APG window splitter's keyboard: sizes in percent of the group, always summing
|
|
4511
|
+
* to 100, each pane within `min..max`, a collapsible pane landing on
|
|
4512
|
+
* `collapsedSize`. The separator is the focusable widget (`role=separator`,
|
|
4513
|
+
* its `aria-valuenow` is the pane on its left); arrows/Home/End move the pair
|
|
4514
|
+
* around a separator and Enter collapses / restores, all as requests.
|
|
4515
|
+
*
|
|
4516
|
+
* A move only ever changes the separator's two neighbours, clamped by both
|
|
4517
|
+
* bounds. Collapsing hands the pane's space to the nearest pane that can take
|
|
4518
|
+
* it and cascades outward; restoring takes it back in the same order. The drag
|
|
4519
|
+
* is snapshot + delta: pointerdown remembers the layout, every move re-solves
|
|
4520
|
+
* from it, so dragging back past a clamp recovers exactly.
|
|
4521
|
+
*
|
|
4522
|
+
* Behaviour is `packages/apg-specs/specs/patterns/resizable-panels.qnt`; the
|
|
4523
|
+
* DOM is checked against it by the differential walk.
|
|
4524
|
+
*/
|
|
4525
|
+
const createResizablePanels = (options) => {
|
|
4526
|
+
const panes = () => options.panes;
|
|
4527
|
+
const count = () => panes().length;
|
|
4528
|
+
const orientation = () => options.orientation ?? "vertical";
|
|
4529
|
+
const step = () => options.step ?? DEFAULT_STEP;
|
|
4530
|
+
const base = options.id ?? createUniqueId();
|
|
4531
|
+
const paneId = (index) => panes()[index]?.id ?? `${base}-pane-${index}`;
|
|
4532
|
+
const collapsedSize = (index) => panes()[index]?.collapsible === true ? panes()[index]?.collapsedSize ?? 0 : 0;
|
|
4533
|
+
/** The smallest expanded size (a move never collapses through it). */
|
|
4534
|
+
const minOf = (index) => panes()[index]?.min ?? DEFAULT_MIN;
|
|
4535
|
+
/** The smallest committed size (a collapsible pane may sit at collapsedSize). */
|
|
4536
|
+
const lowOf = (index) => panes()[index]?.collapsible === true ? collapsedSize(index) : minOf(index);
|
|
4537
|
+
const highOf = (index) => panes()[index]?.max ?? DEFAULT_MAX;
|
|
4538
|
+
/** Clamp every pane, then push the residual into the panes in order. */
|
|
4539
|
+
const fit = (raw) => {
|
|
4540
|
+
const next = panes().map((_, index) => clamp(round2(raw[index] ?? FULL / Math.max(count(), 1)), lowOf(index), highOf(index)));
|
|
4541
|
+
let residual = round2(FULL - next.reduce((sum, value) => sum + value, 0));
|
|
4542
|
+
for (let index = 0; index < next.length && residual !== 0; index += 1) {
|
|
4543
|
+
const room = residual > 0 ? highOf(index) - (next[index] ?? 0) : (next[index] ?? 0) - lowOf(index);
|
|
4544
|
+
const move = residual > 0 ? Math.min(residual, room) : Math.max(residual, -room);
|
|
4545
|
+
next[index] = round2((next[index] ?? 0) + move);
|
|
4546
|
+
residual = round2(residual - move);
|
|
4547
|
+
}
|
|
4548
|
+
return next;
|
|
4549
|
+
};
|
|
4550
|
+
/** Move `amount` percent into pane `index` (negative: out of it), taking from or
|
|
4551
|
+
* giving to its neighbours nearest-first (right, then left), each within bounds. */
|
|
4552
|
+
const shift = (sizes, index, amount) => {
|
|
4553
|
+
const next = [...sizes];
|
|
4554
|
+
let left = round2(amount);
|
|
4555
|
+
const order = [];
|
|
4556
|
+
for (let other = index + 1; other < next.length; other += 1) order.push(other);
|
|
4557
|
+
for (let other = index - 1; other >= 0; other -= 1) order.push(other);
|
|
4558
|
+
for (const other of order) {
|
|
4559
|
+
if (left === 0) break;
|
|
4560
|
+
const value = next[other] ?? 0;
|
|
4561
|
+
const room = left > 0 ? Math.max(0, value - minOf(other)) : Math.max(0, highOf(other) - value);
|
|
4562
|
+
const move = left > 0 ? Math.min(left, room) : Math.max(left, -room);
|
|
4563
|
+
next[other] = round2(value - move);
|
|
4564
|
+
left = round2(left - move);
|
|
4565
|
+
}
|
|
4566
|
+
next[index] = round2((next[index] ?? 0) + (round2(amount) - left));
|
|
4567
|
+
return next;
|
|
4568
|
+
};
|
|
4569
|
+
/** Move the boundary between pane `index` and `index + 1` by `delta`. */
|
|
4570
|
+
const movePair = (sizes, index, delta) => {
|
|
4571
|
+
const a = sizes[index] ?? 0;
|
|
4572
|
+
const b = sizes[index + 1] ?? 0;
|
|
4573
|
+
const low = Math.max(minOf(index), round2(a + b - highOf(index + 1)));
|
|
4574
|
+
const high = Math.min(highOf(index), round2(a + b - minOf(index + 1)));
|
|
4575
|
+
const nextA = round2(clamp(a + delta, low, high));
|
|
4576
|
+
const next = [...sizes];
|
|
4577
|
+
next[index] = nextA;
|
|
4578
|
+
next[index + 1] = round2(a + b - nextA);
|
|
4579
|
+
return next;
|
|
4580
|
+
};
|
|
4581
|
+
const initialSizes = () => {
|
|
4582
|
+
const stored = options.storageKey === void 0 ? void 0 : readStored(options.storageKey, count());
|
|
4583
|
+
return fit(stored ?? options.defaultSizes ?? panes().map((pane) => pane.defaultSize ?? round2(FULL / Math.max(count(), 1))));
|
|
4584
|
+
};
|
|
4585
|
+
const start = initialSizes();
|
|
4586
|
+
const [sizes, request] = createControllable({
|
|
4587
|
+
value: () => options.sizes,
|
|
4588
|
+
initial: start,
|
|
4589
|
+
onChange: () => options.onSizesChange,
|
|
4590
|
+
same: sameSizes
|
|
4591
|
+
});
|
|
4592
|
+
const [focusSeparator, setFocusSeparator] = createSignal(null);
|
|
4593
|
+
const [resizing, setResizing] = createSignal(null);
|
|
4594
|
+
const lastExpanded = start.map((value, index) => Math.max(value, minOf(index)));
|
|
4595
|
+
createEffect(() => sizes(), (now) => {
|
|
4596
|
+
now.forEach((value, index) => {
|
|
4597
|
+
if (value > collapsedSize(index)) lastExpanded[index] = value;
|
|
4598
|
+
});
|
|
4599
|
+
});
|
|
4600
|
+
const collapsed = (index) => panes()[index]?.collapsible === true && (sizes()[index] ?? 0) <= collapsedSize(index);
|
|
4601
|
+
const movable = (index) => index >= 0 && index + 1 < count() && !collapsed(index) && !collapsed(index + 1);
|
|
4602
|
+
let asked;
|
|
4603
|
+
const commit = (next) => {
|
|
4604
|
+
const fitted = fit(next);
|
|
4605
|
+
asked = fitted;
|
|
4606
|
+
request(fitted);
|
|
4607
|
+
};
|
|
4608
|
+
const move = (index, delta) => {
|
|
4609
|
+
if (drag !== void 0 || !movable(index)) return;
|
|
4610
|
+
commit(movePair(sizes(), index, delta));
|
|
4611
|
+
};
|
|
4612
|
+
const toggle = (index) => {
|
|
4613
|
+
const pane = panes()[index];
|
|
4614
|
+
if (drag !== void 0 || pane?.collapsible !== true) return;
|
|
4615
|
+
if (collapsed(index)) commit(shift(sizes(), index, (lastExpanded[index] ?? lowOf(index)) - (sizes()[index] ?? 0)));
|
|
4616
|
+
else commit(shift(sizes(), index, collapsedSize(index) - (sizes()[index] ?? 0)));
|
|
4617
|
+
};
|
|
4618
|
+
const keyDown = (index, key) => {
|
|
4619
|
+
if (!KEY_TAGS$1.has(key)) return;
|
|
4620
|
+
const vertical = orientation() === "vertical";
|
|
4621
|
+
switch (key) {
|
|
4622
|
+
case "ArrowLeft":
|
|
4623
|
+
if (vertical) move(index, 0 - step());
|
|
4624
|
+
break;
|
|
4625
|
+
case "ArrowRight":
|
|
4626
|
+
if (vertical) move(index, step());
|
|
4627
|
+
break;
|
|
4628
|
+
case "ArrowUp":
|
|
4629
|
+
if (!vertical) move(index, 0 - step());
|
|
4630
|
+
break;
|
|
4631
|
+
case "ArrowDown":
|
|
4632
|
+
if (!vertical) move(index, step());
|
|
4633
|
+
break;
|
|
4634
|
+
case "Home":
|
|
4635
|
+
move(index, -100);
|
|
4636
|
+
break;
|
|
4637
|
+
case "End":
|
|
4638
|
+
move(index, FULL);
|
|
4639
|
+
break;
|
|
4640
|
+
default: toggle(index);
|
|
4641
|
+
}
|
|
4642
|
+
};
|
|
4643
|
+
let drag;
|
|
4644
|
+
const axisOf = (event, axis) => axis === "x" ? event.clientX : event.clientY;
|
|
4645
|
+
const lengthOf = (element) => {
|
|
4646
|
+
const group = element.parentElement;
|
|
4647
|
+
if (group === null) return 0;
|
|
4648
|
+
const rect = group.getBoundingClientRect();
|
|
4649
|
+
return orientation() === "vertical" ? rect.width : rect.height;
|
|
4650
|
+
};
|
|
4651
|
+
const onPointerDown = (index, event) => {
|
|
4652
|
+
if (event.button !== 0) return;
|
|
4653
|
+
if (drag !== void 0) {
|
|
4654
|
+
release(drag.element, drag.pointerId);
|
|
4655
|
+
drag = void 0;
|
|
4656
|
+
setResizing(null);
|
|
4657
|
+
}
|
|
4658
|
+
setFocusSeparator(index);
|
|
4659
|
+
if (!movable(index)) return;
|
|
4660
|
+
const length = lengthOf(event.currentTarget);
|
|
4661
|
+
if (length <= 0) return;
|
|
4662
|
+
const axis = orientation() === "vertical" ? "x" : "y";
|
|
4663
|
+
drag = {
|
|
4664
|
+
separator: index,
|
|
4665
|
+
element: event.currentTarget,
|
|
4666
|
+
pointerId: event.pointerId,
|
|
4667
|
+
start: axisOf(event, axis),
|
|
4668
|
+
axis,
|
|
4669
|
+
from: sizes(),
|
|
4670
|
+
length
|
|
4671
|
+
};
|
|
4672
|
+
setResizing(index);
|
|
4673
|
+
capture(event.currentTarget, event.pointerId);
|
|
4674
|
+
event.preventDefault();
|
|
4675
|
+
};
|
|
4676
|
+
const onPointerMove = (event) => {
|
|
4677
|
+
if (drag === void 0 || drag.pointerId !== event.pointerId) return;
|
|
4678
|
+
const delta = (axisOf(event, drag.axis) - drag.start) / drag.length * FULL;
|
|
4679
|
+
commit(movePair(drag.from, drag.separator, delta));
|
|
4680
|
+
};
|
|
4681
|
+
const onPointerEnd = (event) => {
|
|
4682
|
+
if (drag === void 0 || drag.pointerId !== event.pointerId) return;
|
|
4683
|
+
drag = void 0;
|
|
4684
|
+
setResizing(null);
|
|
4685
|
+
release(event.currentTarget, event.pointerId);
|
|
4686
|
+
};
|
|
4687
|
+
createEffect(() => options.sizes, (now) => {
|
|
4688
|
+
if (now === void 0 || asked !== void 0 && sameSizes(now, asked)) return;
|
|
4689
|
+
drag = void 0;
|
|
4690
|
+
setResizing(null);
|
|
4691
|
+
});
|
|
4692
|
+
if (options.storageKey !== void 0) {
|
|
4693
|
+
const storageKey = options.storageKey;
|
|
4694
|
+
createEffect(() => sizes(), (now) => writeStored(storageKey, now));
|
|
4695
|
+
}
|
|
4696
|
+
const separatorProps = (index) => ({
|
|
4697
|
+
id: `${base}-separator-${index}`,
|
|
4698
|
+
role: "separator",
|
|
4699
|
+
get "aria-orientation"() {
|
|
4700
|
+
return orientation();
|
|
4701
|
+
},
|
|
4702
|
+
get "aria-valuenow"() {
|
|
4703
|
+
return round2(sizes()[index] ?? 0);
|
|
4704
|
+
},
|
|
4705
|
+
get "aria-valuemin"() {
|
|
4706
|
+
return panes()[index]?.min ?? DEFAULT_MIN;
|
|
4707
|
+
},
|
|
4708
|
+
get "aria-valuemax"() {
|
|
4709
|
+
return highOf(index);
|
|
4710
|
+
},
|
|
4711
|
+
get "aria-controls"() {
|
|
4712
|
+
return paneId(index);
|
|
4713
|
+
},
|
|
4714
|
+
get "aria-label"() {
|
|
4715
|
+
const label = panes()[index]?.label;
|
|
4716
|
+
return label === void 0 ? "Resize" : `Resize ${label}`;
|
|
4717
|
+
},
|
|
4718
|
+
tabindex: 0,
|
|
4719
|
+
onKeyDown: (event) => {
|
|
4720
|
+
if (KEY_TAGS$1.has(event.key)) event.preventDefault();
|
|
4721
|
+
keyDown(index, event.key);
|
|
4722
|
+
},
|
|
4723
|
+
onFocus: () => setFocusSeparator(index),
|
|
4724
|
+
onBlur: () => setFocusSeparator(null),
|
|
4725
|
+
onPointerDown: (event) => onPointerDown(index, event),
|
|
4726
|
+
onPointerMove,
|
|
4727
|
+
onPointerUp: onPointerEnd,
|
|
4728
|
+
onPointerCancel: onPointerEnd
|
|
4729
|
+
});
|
|
4730
|
+
return {
|
|
4731
|
+
sizes,
|
|
4732
|
+
collapsed,
|
|
4733
|
+
resizing,
|
|
4734
|
+
focusSeparator,
|
|
4735
|
+
setFocusSeparator,
|
|
4736
|
+
keyDown,
|
|
4737
|
+
groupProps: {
|
|
4738
|
+
role: "group",
|
|
4739
|
+
get "aria-label"() {
|
|
4740
|
+
return options.label;
|
|
4741
|
+
}
|
|
4742
|
+
},
|
|
4743
|
+
paneProps: (index) => ({ id: paneId(index) }),
|
|
4744
|
+
separatorProps
|
|
4745
|
+
};
|
|
4746
|
+
};
|
|
4747
|
+
// src/slider.ts
|
|
4488
4748
|
const valueTextFor$1 = (value) => value <= 3 ? "low" : value <= 7 ? "medium" : "high";
|
|
4489
4749
|
/**
|
|
4490
4750
|
* APG Slider (https://www.w3.org/WAI/ARIA/apg/patterns/slider/): a single
|
|
@@ -4590,8 +4850,7 @@ const createSlider = (options = {}) => {
|
|
|
4590
4850
|
} }
|
|
4591
4851
|
};
|
|
4592
4852
|
};
|
|
4593
|
-
|
|
4594
|
-
//#region src/slider-multithumb.ts
|
|
4853
|
+
// src/slider-multithumb.ts
|
|
4595
4854
|
const valueTextFor = (value) => value <= 3 ? "low" : value <= 7 ? "medium" : "high";
|
|
4596
4855
|
const keyOf = (pair) => `${pair[0]},${pair[1]}`;
|
|
4597
4856
|
const pairOf = (key) => {
|
|
@@ -4721,8 +4980,7 @@ const createSliderMultiThumb = (options = {}) => {
|
|
|
4721
4980
|
})
|
|
4722
4981
|
};
|
|
4723
4982
|
};
|
|
4724
|
-
|
|
4725
|
-
//#region src/spinbutton.ts
|
|
4983
|
+
// src/spinbutton.ts
|
|
4726
4984
|
/**
|
|
4727
4985
|
* APG Spinbutton (https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/): a text
|
|
4728
4986
|
* field plus increase / decrease buttons. Plain Solid signals, no elements, no
|
|
@@ -4926,8 +5184,7 @@ const createSpinbutton = (options = {}) => {
|
|
|
4926
5184
|
}
|
|
4927
5185
|
};
|
|
4928
5186
|
};
|
|
4929
|
-
|
|
4930
|
-
//#region src/switch.ts
|
|
5187
|
+
// src/switch.ts
|
|
4931
5188
|
/**
|
|
4932
5189
|
* APG Switch (https://www.w3.org/WAI/ARIA/apg/patterns/switch/): a binary on/off
|
|
4933
5190
|
* input. Platform choice (packages/headless/docs/apg-platform-features.md): **native
|
|
@@ -5016,8 +5273,7 @@ const createSwitch = (options = {}) => {
|
|
|
5016
5273
|
}
|
|
5017
5274
|
};
|
|
5018
5275
|
};
|
|
5019
|
-
|
|
5020
|
-
//#region src/tabs.ts
|
|
5276
|
+
// src/tabs.ts
|
|
5021
5277
|
/**
|
|
5022
5278
|
* APG Tabs (https://www.w3.org/WAI/ARIA/apg/patterns/tabs/): state plus prop
|
|
5023
5279
|
* objects for a tablist, tabs and panels. Roving tabindex, wrapping arrows,
|
|
@@ -5154,8 +5410,7 @@ const createTabs = (options = {}) => {
|
|
|
5154
5410
|
})
|
|
5155
5411
|
};
|
|
5156
5412
|
};
|
|
5157
|
-
|
|
5158
|
-
//#region src/timeline.ts
|
|
5413
|
+
// src/timeline.ts
|
|
5159
5414
|
const LAST_NODE = 5;
|
|
5160
5415
|
const DOMAIN_MIN = 0;
|
|
5161
5416
|
const DOMAIN_MAX = 100;
|
|
@@ -5391,8 +5646,7 @@ const createTimeline = (options = {}) => {
|
|
|
5391
5646
|
}
|
|
5392
5647
|
};
|
|
5393
5648
|
};
|
|
5394
|
-
|
|
5395
|
-
//#region src/toolbar.ts
|
|
5649
|
+
// src/toolbar.ts
|
|
5396
5650
|
const AXIS = (o) => o === "horizontal" ? "inline" : "block";
|
|
5397
5651
|
const delta = (axis, key) => {
|
|
5398
5652
|
if (axis === "inline") {
|
|
@@ -5572,8 +5826,7 @@ const createToolbar = (options) => {
|
|
|
5572
5826
|
})
|
|
5573
5827
|
};
|
|
5574
5828
|
};
|
|
5575
|
-
|
|
5576
|
-
//#region src/tooltip.ts
|
|
5829
|
+
// src/tooltip.ts
|
|
5577
5830
|
const letters = ["a", "b"];
|
|
5578
5831
|
const letterOf = (index) => letters[index] ?? "a";
|
|
5579
5832
|
const shownOf = (vis) => [vis === 1, vis === 2];
|
|
@@ -5861,8 +6114,7 @@ const createTooltipGroup = (options) => {
|
|
|
5861
6114
|
})
|
|
5862
6115
|
};
|
|
5863
6116
|
};
|
|
5864
|
-
|
|
5865
|
-
//#region src/treegrid.ts
|
|
6117
|
+
// src/treegrid.ts
|
|
5866
6118
|
const PARENTS = [
|
|
5867
6119
|
-1,
|
|
5868
6120
|
0,
|
|
@@ -6241,8 +6493,7 @@ const createTreegrid = (options = {}) => {
|
|
|
6241
6493
|
};
|
|
6242
6494
|
/** The `data-part` target the treegrid roving tab stop should focus. */
|
|
6243
6495
|
const treegridFocusTargetPart = (grid) => grid.focusTargetPart();
|
|
6244
|
-
|
|
6245
|
-
//#region src/treeview.ts
|
|
6496
|
+
// src/treeview.ts
|
|
6246
6497
|
/**
|
|
6247
6498
|
* The fixed tree of `specs/apg/treeview.qnt` (ids are pre-order = document
|
|
6248
6499
|
* order): 1 Projects > {2 Reports > {3 Roadmap, 4 Summary}, 5 Notes}, 6 Photos
|
|
@@ -6578,8 +6829,7 @@ const createTreeview = (options = {}) => {
|
|
|
6578
6829
|
})
|
|
6579
6830
|
};
|
|
6580
6831
|
};
|
|
6581
|
-
|
|
6582
|
-
//#region src/windowsplitter.ts
|
|
6832
|
+
// src/windowsplitter.ts
|
|
6583
6833
|
const KEY_TAGS = /* @__PURE__ */ new Set([
|
|
6584
6834
|
"ArrowLeft",
|
|
6585
6835
|
"ArrowRight",
|
|
@@ -6740,8 +6990,7 @@ const createWindowSplitter = (options = {}) => {
|
|
|
6740
6990
|
secondaryProps: paneProps("secondary")
|
|
6741
6991
|
};
|
|
6742
6992
|
};
|
|
6743
|
-
|
|
6744
|
-
//#region src/listbox-rearrangeable.ts
|
|
6993
|
+
// src/listbox-rearrangeable.ts
|
|
6745
6994
|
const other = (list) => list === "a" ? "b" : "a";
|
|
6746
6995
|
const normalize = (indices, count) => [...new Set(indices)].filter((index) => index >= 0 && index < count).sort((x, y) => x - y);
|
|
6747
6996
|
const same = (a, b) => a.length === b.length && a.every((value, index) => value === b[index]);
|
|
@@ -6990,5 +7239,4 @@ const createRearrangeableListbox = (options) => {
|
|
|
6990
7239
|
})
|
|
6991
7240
|
};
|
|
6992
7241
|
};
|
|
6993
|
-
|
|
6994
|
-
export { DEFAULT_PREFS, DRAG_PX, GRID, NO_POS, SNAP_PX, TONE, TREEVIEW_NODES, TWEEN_TICKS, WORLD_BOUND, YES_POS, ZMAX, ZMIN, ZONE, cellPart, createAccordion, createAlert, createAlertDialog, createBreadcrumb, createButton, createCanvas, createCarousel, createCheckbox, createCheckboxGroup, createCombobox, createDialogModal, createDisclosure, createFeed, createGrid, createLink, createListbox, createMenu, createMenubar, createMeter, createPlayer, createRadioGroup, createRearrangeableListbox, createSlider, createSliderMultiThumb, createSpinbutton, createSwitch, createTabs, createTimeline, createToolbar, createTooltipGroup, createTreegrid, createTreeview, createWindowSplitter, gridCandidates, headerPart, packSelection, packSort, rowPart, treegridCellPart, treegridFocusTargetPart, treegridRowPart, withPrefs };
|
|
7242
|
+
export { DEFAULT_PREFS, DRAG_PX, GRID, NO_POS, SNAP_PX, TONE, TREEVIEW_NODES, TWEEN_TICKS, WORLD_BOUND, YES_POS, ZMAX, ZMIN, ZONE, cellPart, createAccordion, createAlert, createAlertDialog, createBreadcrumb, createButton, createCanvas, createCarousel, createCheckbox, createCheckboxGroup, createCombobox, createDialogModal, createDisclosure, createFeed, createGrid, createLink, createListbox, createMenu, createMenubar, createMeter, createPlayer, createRadioGroup, createRearrangeableListbox, createResizablePanels, createSlider, createSliderMultiThumb, createSpinbutton, createSwitch, createTabs, createTimeline, createToolbar, createTooltipGroup, createTreegrid, createTreeview, createWindowSplitter, gridCandidates, headerPart, packSelection, packSort, rowPart, treegridCellPart, treegridFocusTargetPart, treegridRowPart, withPrefs };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cssints/headless",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Headless APG widgets on Solid 2: state plus attribute objects, no elements, no styling, each conformance-checked against its Quint spec",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|