@ariakit/core 0.0.1 → 0.1.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.
Files changed (163) hide show
  1. package/.eslintignore +6 -0
  2. package/CHANGELOG.md +24 -0
  3. package/checkbox/checkbox-store/package.json +7 -0
  4. package/cjs/__chunks/2YFRPUZP.cjs +30 -0
  5. package/cjs/__chunks/3BBA3Z5G.cjs +143 -0
  6. package/cjs/__chunks/3KP2MDG6.cjs +1491 -0
  7. package/cjs/__chunks/5D5Y5EI4.cjs +146 -0
  8. package/cjs/__chunks/7ZXWQTAY.cjs +71 -0
  9. package/cjs/__chunks/AZVDLKO3.cjs +286 -0
  10. package/cjs/__chunks/EFEGT32M.cjs +12 -0
  11. package/cjs/__chunks/EIDN2CWH.cjs +57 -0
  12. package/cjs/__chunks/GDZQUFNP.cjs +30 -0
  13. package/cjs/__chunks/NX5OHIMM.cjs +169 -0
  14. package/cjs/__chunks/OFNGELMA.cjs +182 -0
  15. package/cjs/checkbox/checkbox-store.cjs +27 -0
  16. package/cjs/checkbox/checkbox-store.d.ts +34 -0
  17. package/cjs/collection/collection-store.cjs +9 -0
  18. package/cjs/collection/collection-store.d.ts +65 -0
  19. package/cjs/combobox/combobox-store.cjs +163 -0
  20. package/cjs/combobox/combobox-store.d.ts +67 -0
  21. package/cjs/composite/composite-overflow-store.cjs +15 -0
  22. package/cjs/composite/composite-overflow-store.d.ts +10 -0
  23. package/cjs/composite/composite-store.cjs +11 -0
  24. package/cjs/composite/composite-store.d.ts +202 -0
  25. package/cjs/dialog/dialog-store.cjs +9 -0
  26. package/cjs/dialog/dialog-store.d.ts +10 -0
  27. package/cjs/disclosure/disclosure-store.cjs +8 -0
  28. package/cjs/disclosure/disclosure-store.d.ts +87 -0
  29. package/cjs/form/form-store.cjs +241 -0
  30. package/cjs/form/form-store.d.ts +236 -0
  31. package/cjs/form/types.cjs +1 -0
  32. package/cjs/form/types.d.ts +38 -0
  33. package/cjs/hovercard/hovercard-store.cjs +11 -0
  34. package/cjs/hovercard/hovercard-store.d.ts +45 -0
  35. package/cjs/index.cjs +5 -0
  36. package/cjs/index.d.ts +2 -0
  37. package/cjs/menu/menu-bar-store.cjs +27 -0
  38. package/cjs/menu/menu-bar-store.d.ts +10 -0
  39. package/cjs/menu/menu-store.cjs +108 -0
  40. package/cjs/menu/menu-store.d.ts +70 -0
  41. package/cjs/popover/popover-store.cjs +10 -0
  42. package/cjs/popover/popover-store.d.ts +150 -0
  43. package/cjs/radio/radio-store.cjs +41 -0
  44. package/cjs/radio/radio-store.d.ts +36 -0
  45. package/cjs/select/select-store.cjs +164 -0
  46. package/cjs/select/select-store.d.ts +87 -0
  47. package/cjs/tab/tab-store.cjs +126 -0
  48. package/cjs/tab/tab-store.d.ts +78 -0
  49. package/cjs/toolbar/toolbar-store.cjs +27 -0
  50. package/cjs/toolbar/toolbar-store.d.ts +21 -0
  51. package/cjs/tooltip/tooltip-store.cjs +98 -0
  52. package/cjs/tooltip/tooltip-store.d.ts +28 -0
  53. package/cjs/tsconfig.build.tsbuildinfo +1 -0
  54. package/cjs/utils/array.cjs +12 -0
  55. package/cjs/utils/array.d.ts +29 -0
  56. package/cjs/utils/dom.cjs +38 -0
  57. package/cjs/utils/dom.d.ts +105 -0
  58. package/cjs/utils/events.cjs +132 -0
  59. package/cjs/utils/events.d.ts +73 -0
  60. package/cjs/utils/focus.cjs +222 -0
  61. package/cjs/utils/focus.d.ts +117 -0
  62. package/cjs/utils/misc.cjs +40 -0
  63. package/cjs/utils/misc.d.ts +111 -0
  64. package/cjs/utils/platform.cjs +15 -0
  65. package/cjs/utils/platform.d.ts +20 -0
  66. package/cjs/utils/store.cjs +9 -0
  67. package/cjs/utils/store.d.ts +99 -0
  68. package/cjs/utils/types.cjs +1 -0
  69. package/cjs/utils/types.d.ts +72 -0
  70. package/collection/collection-store/package.json +7 -0
  71. package/combobox/combobox-store/package.json +7 -0
  72. package/composite/composite-overflow-store/package.json +7 -0
  73. package/composite/composite-store/package.json +7 -0
  74. package/dialog/dialog-store/package.json +7 -0
  75. package/disclosure/disclosure-store/package.json +7 -0
  76. package/esm/__chunks/5XEKIOCW.js +30 -0
  77. package/esm/__chunks/6U25WEDX.js +286 -0
  78. package/esm/__chunks/6UPCMUXT.js +1491 -0
  79. package/esm/__chunks/ADRUFBEO.js +12 -0
  80. package/esm/__chunks/DXA3K2FY.js +30 -0
  81. package/esm/__chunks/HCKYJLMC.js +71 -0
  82. package/esm/__chunks/KLKI3AIB.js +146 -0
  83. package/esm/__chunks/L7KN5AYP.js +169 -0
  84. package/esm/__chunks/RX3ZUQ6U.js +57 -0
  85. package/esm/__chunks/UOJSZ35L.js +143 -0
  86. package/esm/__chunks/UVCATTRC.js +182 -0
  87. package/esm/checkbox/checkbox-store.d.ts +34 -0
  88. package/esm/checkbox/checkbox-store.js +27 -0
  89. package/esm/collection/collection-store.d.ts +65 -0
  90. package/esm/collection/collection-store.js +9 -0
  91. package/esm/combobox/combobox-store.d.ts +67 -0
  92. package/esm/combobox/combobox-store.js +163 -0
  93. package/esm/composite/composite-overflow-store.d.ts +10 -0
  94. package/esm/composite/composite-overflow-store.js +15 -0
  95. package/esm/composite/composite-store.d.ts +202 -0
  96. package/esm/composite/composite-store.js +11 -0
  97. package/esm/dialog/dialog-store.d.ts +10 -0
  98. package/esm/dialog/dialog-store.js +9 -0
  99. package/esm/disclosure/disclosure-store.d.ts +87 -0
  100. package/esm/disclosure/disclosure-store.js +8 -0
  101. package/esm/form/form-store.d.ts +236 -0
  102. package/esm/form/form-store.js +241 -0
  103. package/esm/form/types.d.ts +38 -0
  104. package/esm/form/types.js +0 -0
  105. package/esm/hovercard/hovercard-store.d.ts +45 -0
  106. package/esm/hovercard/hovercard-store.js +11 -0
  107. package/esm/index.d.ts +2 -0
  108. package/esm/index.js +5 -0
  109. package/esm/menu/menu-bar-store.d.ts +10 -0
  110. package/esm/menu/menu-bar-store.js +27 -0
  111. package/esm/menu/menu-store.d.ts +70 -0
  112. package/esm/menu/menu-store.js +108 -0
  113. package/esm/popover/popover-store.d.ts +150 -0
  114. package/esm/popover/popover-store.js +10 -0
  115. package/esm/radio/radio-store.d.ts +36 -0
  116. package/esm/radio/radio-store.js +41 -0
  117. package/esm/select/select-store.d.ts +87 -0
  118. package/esm/select/select-store.js +164 -0
  119. package/esm/tab/tab-store.d.ts +78 -0
  120. package/esm/tab/tab-store.js +126 -0
  121. package/esm/toolbar/toolbar-store.d.ts +21 -0
  122. package/esm/toolbar/toolbar-store.js +27 -0
  123. package/esm/tooltip/tooltip-store.d.ts +28 -0
  124. package/esm/tooltip/tooltip-store.js +98 -0
  125. package/esm/tsconfig.build.tsbuildinfo +1 -0
  126. package/esm/utils/array.d.ts +29 -0
  127. package/esm/utils/array.js +12 -0
  128. package/esm/utils/dom.d.ts +105 -0
  129. package/esm/utils/dom.js +38 -0
  130. package/esm/utils/events.d.ts +73 -0
  131. package/esm/utils/events.js +132 -0
  132. package/esm/utils/focus.d.ts +117 -0
  133. package/esm/utils/focus.js +222 -0
  134. package/esm/utils/misc.d.ts +111 -0
  135. package/esm/utils/misc.js +40 -0
  136. package/esm/utils/platform.d.ts +20 -0
  137. package/esm/utils/platform.js +15 -0
  138. package/esm/utils/store.d.ts +99 -0
  139. package/esm/utils/store.js +9 -0
  140. package/esm/utils/types.d.ts +72 -0
  141. package/esm/utils/types.js +0 -0
  142. package/form/form-store/package.json +7 -0
  143. package/form/types/package.json +7 -0
  144. package/hovercard/hovercard-store/package.json +7 -0
  145. package/license +21 -0
  146. package/menu/menu-bar-store/package.json +7 -0
  147. package/menu/menu-store/package.json +7 -0
  148. package/package.json +137 -6
  149. package/popover/popover-store/package.json +7 -0
  150. package/radio/radio-store/package.json +7 -0
  151. package/select/select-store/package.json +7 -0
  152. package/tab/tab-store/package.json +7 -0
  153. package/toolbar/toolbar-store/package.json +7 -0
  154. package/tooltip/tooltip-store/package.json +7 -0
  155. package/tsconfig.build.json +4 -0
  156. package/utils/array/package.json +7 -0
  157. package/utils/dom/package.json +7 -0
  158. package/utils/events/package.json +7 -0
  159. package/utils/focus/package.json +7 -0
  160. package/utils/misc/package.json +7 -0
  161. package/utils/platform/package.json +7 -0
  162. package/utils/store/package.json +7 -0
  163. package/utils/types/package.json +7 -0
@@ -0,0 +1,99 @@
1
+ import type { AnyObject, SetStateAction } from "./types.js";
2
+ /**
3
+ * Creates a store.
4
+ * @param initialState Initial state.
5
+ * @param stores Stores to extend.
6
+ */
7
+ export declare function createStore<S extends State>(initialState: S, ...stores: Array<Partial<Store<Partial<S>>> | undefined>): Store<S>;
8
+ /**
9
+ * Merges multiple stores into a single store.
10
+ */
11
+ export declare function mergeStore<S extends State>(...stores: Array<Partial<Store<S>> | undefined>): Store<S>;
12
+ /**
13
+ * Store state type.
14
+ */
15
+ export type State = AnyObject;
16
+ /**
17
+ * Initial state that can be passed to a store creator function.
18
+ * @template S State type.
19
+ * @template K Key type.
20
+ */
21
+ export type StoreOptions<S extends State, K extends keyof S> = Partial<Pick<S, K>>;
22
+ /**
23
+ * Props that can be passed to a store creator function.
24
+ * @template S State type.
25
+ */
26
+ export type StoreProps<S extends State = State> = {
27
+ store?: Store<Partial<S>>;
28
+ };
29
+ /**
30
+ * Extracts the state type from a store type.
31
+ * @template T Store type.
32
+ */
33
+ export type StoreState<T> = T extends {
34
+ getState(): infer S;
35
+ } ? S : never;
36
+ /**
37
+ * Store listener type.
38
+ * @template S State type.
39
+ */
40
+ export type Listener<S> = (state: S, prevState: S) => void | (() => void);
41
+ /**
42
+ * Subscriber function type used by `sync`, `subscribe` and `effect`.
43
+ * @template S State type.
44
+ */
45
+ export type Sync<S = State> = {
46
+ /**
47
+ * @param listener The listener function. It's called with the current state
48
+ * and the previous state as arguments and may return a cleanup function.
49
+ * @param keys Optional array of state keys to listen to.
50
+ */
51
+ <K extends keyof S = keyof S>(listener: Listener<Pick<S, K>>, keys?: K[]): () => void;
52
+ };
53
+ /**
54
+ * Store.
55
+ * @template S State type.
56
+ */
57
+ export interface Store<S = State> {
58
+ /**
59
+ * Returns the current store state.
60
+ */
61
+ getState(): S;
62
+ /**
63
+ * Sets a state value.
64
+ */
65
+ setState<K extends keyof S>(key: K, value: SetStateAction<S[K]>): void;
66
+ /**
67
+ * Register a callback function that's called when the store is initialized.
68
+ */
69
+ setup: (callback: () => void | (() => void)) => () => void;
70
+ /**
71
+ * Function that should be called when the store is initialized.
72
+ */
73
+ init: () => () => void;
74
+ /**
75
+ * Registers a listener function that's called immediately and synchronously
76
+ * whenever the store state changes.
77
+ */
78
+ sync: Sync<S>;
79
+ /**
80
+ * Registers a listener function that's called after state changes in the
81
+ * store.
82
+ */
83
+ subscribe: Sync<S>;
84
+ /**
85
+ * Registers a listener function that's called immediately and after a batch
86
+ * of state changes in the store.
87
+ */
88
+ syncBatch: Sync<S>;
89
+ /**
90
+ * Creates a new store with a subset of the current store state and keeps them
91
+ * in sync.
92
+ */
93
+ pick<K extends Array<keyof S>>(...keys: K): Store<Pick<S, K[number]>>;
94
+ /**
95
+ * Creates a new store with a subset of the current store state and keeps them
96
+ * in sync.
97
+ */
98
+ omit<K extends Array<keyof S>>(...keys: K): Store<Omit<S, K[number]>>;
99
+ }
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Any object.
3
+ */
4
+ export type AnyObject = Record<string, any>;
5
+ /**
6
+ * Any function.
7
+ */
8
+ export type AnyFunction = (...args: any) => any;
9
+ /**
10
+ * Workaround for variance issues.
11
+ * @template T The type of the callback.
12
+ */
13
+ export type BivariantCallback<T extends AnyFunction> = {
14
+ bivarianceHack(...args: Parameters<T>): ReturnType<T>;
15
+ }["bivarianceHack"];
16
+ /**
17
+ * @template T The state type.
18
+ */
19
+ export type SetStateAction<T> = T | BivariantCallback<(prevState: T) => T>;
20
+ /**
21
+ * The type of the `setState` function in `[state, setState] = useState()`.
22
+ * @template T The type of the state.
23
+ */
24
+ export type SetState<T> = BivariantCallback<(value: SetStateAction<T>) => void>;
25
+ /**
26
+ * A boolean value or a callback that returns a boolean value.
27
+ * @template T The type of the callback parameter.
28
+ */
29
+ export type BooleanOrCallback<T> = boolean | BivariantCallback<(arg: T) => boolean>;
30
+ /**
31
+ * A string that will provide autocomplete for specific strings.
32
+ * @template T The specific strings.
33
+ */
34
+ export type StringWithValue<T extends string> = T | (string & {
35
+ [key in symbol]: never;
36
+ });
37
+ /**
38
+ * Transforms a type into a primitive type.
39
+ * @template T The type to transform.
40
+ * @example
41
+ * // string
42
+ * ToPrimitive<"a">;
43
+ * // number
44
+ * ToPrimitive<1>;
45
+ */
46
+ export type ToPrimitive<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends AnyFunction ? (...args: Parameters<T>) => ReturnType<T> : T;
47
+ /**
48
+ * Picks only the properties from a type that have a specific value.
49
+ * @template T The type to pick from.
50
+ * @template Value The value to pick.
51
+ */
52
+ export type PickByValue<T, Value> = {
53
+ [K in keyof T as [Value] extends [T[K]] ? T[K] extends Value | undefined ? K : never : never]: T[K];
54
+ };
55
+ /**
56
+ * Picks only the required properties from a type.
57
+ * @template T The type to pick from.
58
+ * @template P The properties to pick.
59
+ */
60
+ export type PickRequired<T, P extends keyof T> = T & {
61
+ [K in keyof T]: Pick<Required<T>, K>;
62
+ }[P];
63
+ /**
64
+ * Indicates the availability and type of interactive popup element, such as
65
+ * menu or dialog, that can be triggered by an element.
66
+ */
67
+ export type AriaHasPopup = boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined;
68
+ /**
69
+ * All the WAI-ARIA 1.1 role attribute values from
70
+ * https://www.w3.org/TR/wai-aria-1.1/#role_definitions
71
+ */
72
+ export type AriaRole = "alert" | "alertdialog" | "application" | "article" | "banner" | "button" | "cell" | "checkbox" | "columnheader" | "combobox" | "complementary" | "contentinfo" | "definition" | "dialog" | "directory" | "document" | "feed" | "figure" | "form" | "grid" | "gridcell" | "group" | "heading" | "img" | "link" | "list" | "listbox" | "listitem" | "log" | "main" | "marquee" | "math" | "menu" | "menubar" | "menuitem" | "menuitemcheckbox" | "menuitemradio" | "navigation" | "none" | "note" | "option" | "presentation" | "progressbar" | "radio" | "radiogroup" | "region" | "row" | "rowgroup" | "rowheader" | "scrollbar" | "search" | "searchbox" | "separator" | "slider" | "spinbutton" | "status" | "switch" | "tab" | "table" | "tablist" | "tabpanel" | "term" | "textbox" | "timer" | "toolbar" | "tooltip" | "tree" | "treegrid" | "treeitem" | (string & {});
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@ariakit/core/collection/collection-store",
3
+ "private": true,
4
+ "sideEffects": false,
5
+ "main": "../../cjs/collection/collection-store",
6
+ "module": "../../esm/collection/collection-store"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@ariakit/core/combobox/combobox-store",
3
+ "private": true,
4
+ "sideEffects": false,
5
+ "main": "../../cjs/combobox/combobox-store",
6
+ "module": "../../esm/combobox/combobox-store"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@ariakit/core/composite/composite-overflow-store",
3
+ "private": true,
4
+ "sideEffects": false,
5
+ "main": "../../cjs/composite/composite-overflow-store",
6
+ "module": "../../esm/composite/composite-overflow-store"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@ariakit/core/composite/composite-store",
3
+ "private": true,
4
+ "sideEffects": false,
5
+ "main": "../../cjs/composite/composite-store",
6
+ "module": "../../esm/composite/composite-store"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@ariakit/core/dialog/dialog-store",
3
+ "private": true,
4
+ "sideEffects": false,
5
+ "main": "../../cjs/dialog/dialog-store",
6
+ "module": "../../esm/dialog/dialog-store"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@ariakit/core/disclosure/disclosure-store",
3
+ "private": true,
4
+ "sideEffects": false,
5
+ "main": "../../cjs/disclosure/disclosure-store",
6
+ "module": "../../esm/disclosure/disclosure-store"
7
+ }
@@ -0,0 +1,30 @@
1
+ // src/utils/array.ts
2
+ function toArray(arg) {
3
+ if (Array.isArray(arg)) {
4
+ return arg;
5
+ }
6
+ return typeof arg !== "undefined" ? [arg] : [];
7
+ }
8
+ function addItemToArray(array, item, index = -1) {
9
+ if (!(index in array)) {
10
+ return [...array, item];
11
+ }
12
+ return [...array.slice(0, index), item, ...array.slice(index)];
13
+ }
14
+ function flatten2DArray(array) {
15
+ const flattened = [];
16
+ for (const row of array) {
17
+ flattened.push(...row);
18
+ }
19
+ return flattened;
20
+ }
21
+ function reverseArray(array) {
22
+ return array.slice().reverse();
23
+ }
24
+
25
+ export {
26
+ toArray,
27
+ addItemToArray,
28
+ flatten2DArray,
29
+ reverseArray
30
+ };
@@ -0,0 +1,286 @@
1
+ import {
2
+ createCollectionStore
3
+ } from "./L7KN5AYP.js";
4
+ import {
5
+ createStore
6
+ } from "./UOJSZ35L.js";
7
+ import {
8
+ defaultValue
9
+ } from "./KLKI3AIB.js";
10
+ import {
11
+ flatten2DArray,
12
+ reverseArray
13
+ } from "./5XEKIOCW.js";
14
+
15
+ // src/composite/composite-store.ts
16
+ var NULL_ITEM = { id: null };
17
+ function findFirstEnabledItem(items, excludeId) {
18
+ return items.find((item) => {
19
+ if (excludeId) {
20
+ return !item.disabled && item.id !== excludeId;
21
+ }
22
+ return !item.disabled;
23
+ });
24
+ }
25
+ function getEnabledItems(items, excludeId) {
26
+ return items.filter((item) => {
27
+ if (excludeId) {
28
+ return !item.disabled && item.id !== excludeId;
29
+ }
30
+ return !item.disabled;
31
+ });
32
+ }
33
+ function getOppositeOrientation(orientation) {
34
+ if (orientation === "vertical")
35
+ return "horizontal";
36
+ if (orientation === "horizontal")
37
+ return "vertical";
38
+ return;
39
+ }
40
+ function getItemsInRow(items, rowId) {
41
+ return items.filter((item) => item.rowId === rowId);
42
+ }
43
+ function flipItems(items, activeId, shouldInsertNullItem = false) {
44
+ const index = items.findIndex((item) => item.id === activeId);
45
+ return [
46
+ ...items.slice(index + 1),
47
+ ...shouldInsertNullItem ? [NULL_ITEM] : [],
48
+ ...items.slice(0, index)
49
+ ];
50
+ }
51
+ function groupItemsByRows(items) {
52
+ const rows = [];
53
+ for (const item of items) {
54
+ const row = rows.find((currentRow) => currentRow[0]?.rowId === item.rowId);
55
+ if (row) {
56
+ row.push(item);
57
+ } else {
58
+ rows.push([item]);
59
+ }
60
+ }
61
+ return rows;
62
+ }
63
+ function getMaxRowLength(array) {
64
+ let maxLength = 0;
65
+ for (const { length } of array) {
66
+ if (length > maxLength) {
67
+ maxLength = length;
68
+ }
69
+ }
70
+ return maxLength;
71
+ }
72
+ function createEmptyItem(rowId) {
73
+ return {
74
+ id: "__EMPTY_ITEM__",
75
+ disabled: true,
76
+ rowId
77
+ };
78
+ }
79
+ function normalizeRows(rows, activeId, focusShift) {
80
+ const maxLength = getMaxRowLength(rows);
81
+ for (const row of rows) {
82
+ for (let i = 0; i < maxLength; i += 1) {
83
+ const item = row[i];
84
+ if (!item || focusShift && item.disabled) {
85
+ const isFirst = i === 0;
86
+ const previousItem = isFirst && focusShift ? findFirstEnabledItem(row) : row[i - 1];
87
+ row[i] = previousItem && activeId !== previousItem.id && focusShift ? previousItem : createEmptyItem(previousItem?.rowId);
88
+ }
89
+ }
90
+ }
91
+ return rows;
92
+ }
93
+ function verticalizeItems(items) {
94
+ const rows = groupItemsByRows(items);
95
+ const maxLength = getMaxRowLength(rows);
96
+ const verticalized = [];
97
+ for (let i = 0; i < maxLength; i += 1) {
98
+ for (const row of rows) {
99
+ const item = row[i];
100
+ if (item) {
101
+ verticalized.push({
102
+ ...item,
103
+ // If there's no rowId, it means that it's not a grid composite, but
104
+ // a single row instead. So, instead of verticalizing it, that is,
105
+ // assigning a different rowId based on the column index, we keep it
106
+ // undefined so they will be part of the same row. This is useful
107
+ // when using up/down on one-dimensional composites.
108
+ rowId: item.rowId ? `${i}` : void 0
109
+ });
110
+ }
111
+ }
112
+ }
113
+ return verticalized;
114
+ }
115
+ function createCompositeStore(props = {}) {
116
+ const syncState = props.store?.getState();
117
+ const collection = createCollectionStore(props);
118
+ const activeId = defaultValue(
119
+ props.activeId,
120
+ syncState?.activeId,
121
+ props.defaultActiveId
122
+ );
123
+ const initialState = {
124
+ ...collection.getState(),
125
+ activeId,
126
+ baseElement: defaultValue(syncState?.baseElement, null),
127
+ includesBaseElement: defaultValue(
128
+ props.includesBaseElement,
129
+ syncState?.includesBaseElement,
130
+ activeId === null
131
+ ),
132
+ moves: defaultValue(syncState?.moves, 0),
133
+ orientation: defaultValue(
134
+ props.orientation,
135
+ syncState?.orientation,
136
+ "both"
137
+ ),
138
+ rtl: defaultValue(props.rtl, syncState?.rtl, false),
139
+ virtualFocus: defaultValue(
140
+ props.virtualFocus,
141
+ syncState?.virtualFocus,
142
+ false
143
+ ),
144
+ focusLoop: defaultValue(props.focusLoop, syncState?.focusLoop, false),
145
+ focusWrap: defaultValue(props.focusWrap, syncState?.focusWrap, false),
146
+ focusShift: defaultValue(props.focusShift, syncState?.focusShift, false)
147
+ };
148
+ const composite = createStore(initialState, collection, props.store);
149
+ composite.setup(
150
+ () => composite.sync(
151
+ (state) => {
152
+ composite.setState("activeId", (activeId2) => {
153
+ if (activeId2 !== void 0)
154
+ return activeId2;
155
+ return findFirstEnabledItem(state.renderedItems)?.id;
156
+ });
157
+ },
158
+ ["renderedItems", "activeId"]
159
+ )
160
+ );
161
+ const getNextId = (items, orientation, hasNullItem, skip) => {
162
+ const { activeId: activeId2, rtl, focusLoop, focusWrap, includesBaseElement } = composite.getState();
163
+ const isHorizontal = orientation !== "vertical";
164
+ const isRTL = rtl && isHorizontal;
165
+ const allItems = isRTL ? reverseArray(items) : items;
166
+ if (activeId2 == null) {
167
+ return findFirstEnabledItem(allItems)?.id;
168
+ }
169
+ const activeItem = allItems.find((item) => item.id === activeId2);
170
+ if (!activeItem) {
171
+ return findFirstEnabledItem(allItems)?.id;
172
+ }
173
+ const isGrid = !!activeItem.rowId;
174
+ const activeIndex = allItems.indexOf(activeItem);
175
+ const nextItems = allItems.slice(activeIndex + 1);
176
+ const nextItemsInRow = getItemsInRow(nextItems, activeItem.rowId);
177
+ if (skip !== void 0) {
178
+ const nextEnabledItemsInRow = getEnabledItems(nextItemsInRow, activeId2);
179
+ const nextItem2 = nextEnabledItemsInRow.slice(skip)[0] || // If we can't find an item, just return the last one.
180
+ nextEnabledItemsInRow[nextEnabledItemsInRow.length - 1];
181
+ return nextItem2?.id;
182
+ }
183
+ const oppositeOrientation = getOppositeOrientation(
184
+ // If it's a grid and orientation is not set, it's a next/previous call,
185
+ // which is inherently horizontal. up/down will call next with orientation
186
+ // set to vertical by default (see below on up/down methods).
187
+ isGrid ? orientation || "horizontal" : orientation
188
+ );
189
+ const canLoop = focusLoop && focusLoop !== oppositeOrientation;
190
+ const canWrap = isGrid && focusWrap && focusWrap !== oppositeOrientation;
191
+ hasNullItem = hasNullItem || !isGrid && canLoop && includesBaseElement;
192
+ if (canLoop) {
193
+ const loopItems = canWrap && !hasNullItem ? allItems : getItemsInRow(allItems, activeItem.rowId);
194
+ const sortedItems = flipItems(loopItems, activeId2, hasNullItem);
195
+ const nextItem2 = findFirstEnabledItem(sortedItems, activeId2);
196
+ return nextItem2?.id;
197
+ }
198
+ if (canWrap) {
199
+ const nextItem2 = findFirstEnabledItem(
200
+ // We can use nextItems, which contains all the next items, including
201
+ // items from other rows, to wrap between rows. However, if there is a
202
+ // null item (the composite container), we'll only use the next items in
203
+ // the row. So moving next from the last item will focus on the
204
+ // composite container. On grid composites, horizontal navigation never
205
+ // focuses on the composite container, only vertical.
206
+ hasNullItem ? nextItemsInRow : nextItems,
207
+ activeId2
208
+ );
209
+ const nextId = hasNullItem ? nextItem2?.id || null : nextItem2?.id;
210
+ return nextId;
211
+ }
212
+ const nextItem = findFirstEnabledItem(nextItemsInRow, activeId2);
213
+ if (!nextItem && hasNullItem) {
214
+ return null;
215
+ }
216
+ return nextItem?.id;
217
+ };
218
+ return {
219
+ ...collection,
220
+ ...composite,
221
+ setBaseElement: (element) => composite.setState("baseElement", element),
222
+ setActiveId: (id) => composite.setState("activeId", id),
223
+ move: (id) => {
224
+ if (id === void 0)
225
+ return;
226
+ composite.setState("activeId", id);
227
+ composite.setState("moves", (moves) => moves + 1);
228
+ },
229
+ first: () => findFirstEnabledItem(composite.getState().renderedItems)?.id,
230
+ last: () => findFirstEnabledItem(reverseArray(composite.getState().renderedItems))?.id,
231
+ next: (skip) => {
232
+ const { renderedItems, orientation } = composite.getState();
233
+ return getNextId(renderedItems, orientation, false, skip);
234
+ },
235
+ previous: (skip) => {
236
+ const { renderedItems, orientation, includesBaseElement } = composite.getState();
237
+ const isGrid = !!findFirstEnabledItem(renderedItems)?.rowId;
238
+ const hasNullItem = !isGrid && includesBaseElement;
239
+ return getNextId(
240
+ reverseArray(renderedItems),
241
+ orientation,
242
+ hasNullItem,
243
+ skip
244
+ );
245
+ },
246
+ down: (skip) => {
247
+ const {
248
+ activeId: activeId2,
249
+ renderedItems,
250
+ focusShift,
251
+ focusLoop,
252
+ includesBaseElement
253
+ } = composite.getState();
254
+ const shouldShift = focusShift && !skip;
255
+ const verticalItems = verticalizeItems(
256
+ flatten2DArray(
257
+ normalizeRows(groupItemsByRows(renderedItems), activeId2, shouldShift)
258
+ )
259
+ );
260
+ const canLoop = focusLoop && focusLoop !== "horizontal";
261
+ const hasNullItem = canLoop && includesBaseElement;
262
+ return getNextId(verticalItems, "vertical", hasNullItem, skip);
263
+ },
264
+ up: (skip) => {
265
+ const { activeId: activeId2, renderedItems, focusShift, includesBaseElement } = composite.getState();
266
+ const shouldShift = focusShift && !skip;
267
+ const verticalItems = verticalizeItems(
268
+ reverseArray(
269
+ flatten2DArray(
270
+ normalizeRows(
271
+ groupItemsByRows(renderedItems),
272
+ activeId2,
273
+ shouldShift
274
+ )
275
+ )
276
+ )
277
+ );
278
+ const hasNullItem = includesBaseElement;
279
+ return getNextId(verticalItems, "vertical", hasNullItem, skip);
280
+ }
281
+ };
282
+ }
283
+
284
+ export {
285
+ createCompositeStore
286
+ };