@ariakit/components 0.1.0

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 (115) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/checkbox/checkbox-store.d.ts +47 -0
  3. package/dist/checkbox/checkbox-store.d.ts.map +1 -0
  4. package/dist/checkbox/checkbox-store.js +16 -0
  5. package/dist/checkbox/checkbox-store.js.map +1 -0
  6. package/dist/collection/collection-store.d.ts +2 -0
  7. package/dist/collection/collection-store.js +132 -0
  8. package/dist/collection/collection-store.js.map +1 -0
  9. package/dist/collection-store-yNe83BiS.d.ts +81 -0
  10. package/dist/collection-store-yNe83BiS.d.ts.map +1 -0
  11. package/dist/combobox/combobox-store.d.ts +150 -0
  12. package/dist/combobox/combobox-store.d.ts.map +1 -0
  13. package/dist/combobox/combobox-store.js +83 -0
  14. package/dist/combobox/combobox-store.js.map +1 -0
  15. package/dist/composite/composite-overflow-store.d.ts +16 -0
  16. package/dist/composite/composite-overflow-store.d.ts.map +1 -0
  17. package/dist/composite/composite-overflow-store.js +12 -0
  18. package/dist/composite/composite-overflow-store.js.map +1 -0
  19. package/dist/composite/composite-store.d.ts +2 -0
  20. package/dist/composite/composite-store.js +167 -0
  21. package/dist/composite/composite-store.js.map +1 -0
  22. package/dist/composite-store-B-iDEtZZ.d.ts +331 -0
  23. package/dist/composite-store-B-iDEtZZ.d.ts.map +1 -0
  24. package/dist/dialog/dialog-store.d.ts +2 -0
  25. package/dist/dialog/dialog-store.js +12 -0
  26. package/dist/dialog/dialog-store.js.map +1 -0
  27. package/dist/dialog-store-BOLvw2IX.d.ts +16 -0
  28. package/dist/dialog-store-BOLvw2IX.d.ts.map +1 -0
  29. package/dist/disclosure/disclosure-store.d.ts +2 -0
  30. package/dist/disclosure/disclosure-store.js +47 -0
  31. package/dist/disclosure/disclosure-store.js.map +1 -0
  32. package/dist/disclosure-store-xKlQffR0.d.ts +142 -0
  33. package/dist/disclosure-store-xKlQffR0.d.ts.map +1 -0
  34. package/dist/form/form-store.d.ts +247 -0
  35. package/dist/form/form-store.d.ts.map +1 -0
  36. package/dist/form/form-store.js +211 -0
  37. package/dist/form/form-store.js.map +1 -0
  38. package/dist/form/types.d.ts +37 -0
  39. package/dist/form/types.d.ts.map +1 -0
  40. package/dist/form/types.js +0 -0
  41. package/dist/hovercard/hovercard-store.d.ts +65 -0
  42. package/dist/hovercard/hovercard-store.d.ts.map +1 -0
  43. package/dist/hovercard/hovercard-store.js +31 -0
  44. package/dist/hovercard/hovercard-store.js.map +1 -0
  45. package/dist/index.d.ts +5 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +6 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/menu/menu-bar-store.d.ts +16 -0
  50. package/dist/menu/menu-bar-store.d.ts.map +1 -0
  51. package/dist/menu/menu-bar-store.js +12 -0
  52. package/dist/menu/menu-bar-store.js.map +1 -0
  53. package/dist/menu/menu-store.d.ts +100 -0
  54. package/dist/menu/menu-store.d.ts.map +1 -0
  55. package/dist/menu/menu-store.js +74 -0
  56. package/dist/menu/menu-store.js.map +1 -0
  57. package/dist/menubar/menubar-store.d.ts +2 -0
  58. package/dist/menubar/menubar-store.js +24 -0
  59. package/dist/menubar/menubar-store.js.map +1 -0
  60. package/dist/menubar-store-CD3YDYfW.d.ts +16 -0
  61. package/dist/menubar-store-CD3YDYfW.d.ts.map +1 -0
  62. package/dist/popover/popover-store.d.ts +2 -0
  63. package/dist/popover/popover-store.js +44 -0
  64. package/dist/popover/popover-store.js.map +1 -0
  65. package/dist/popover-store-DoCiTmUQ.d.ts +106 -0
  66. package/dist/popover-store-DoCiTmUQ.d.ts.map +1 -0
  67. package/dist/radio/radio-store.d.ts +42 -0
  68. package/dist/radio/radio-store.d.ts.map +1 -0
  69. package/dist/radio/radio-store.js +27 -0
  70. package/dist/radio/radio-store.js.map +1 -0
  71. package/dist/select/select-store.d.ts +116 -0
  72. package/dist/select/select-store.d.ts.map +1 -0
  73. package/dist/select/select-store.js +93 -0
  74. package/dist/select/select-store.js.map +1 -0
  75. package/dist/tab/tab-store.d.ts +127 -0
  76. package/dist/tab/tab-store.d.ts.map +1 -0
  77. package/dist/tab/tab-store.js +107 -0
  78. package/dist/tab/tab-store.js.map +1 -0
  79. package/dist/tag/tag-store.d.ts +2 -0
  80. package/dist/tag/tag-store.js +60 -0
  81. package/dist/tag/tag-store.js.map +1 -0
  82. package/dist/tag-store-D47X5_zA.d.ts +83 -0
  83. package/dist/tag-store-D47X5_zA.d.ts.map +1 -0
  84. package/dist/toolbar/toolbar-store.d.ts +21 -0
  85. package/dist/toolbar/toolbar-store.d.ts.map +1 -0
  86. package/dist/toolbar/toolbar-store.js +18 -0
  87. package/dist/toolbar/toolbar-store.js.map +1 -0
  88. package/dist/tooltip/tooltip-store.d.ts +35 -0
  89. package/dist/tooltip/tooltip-store.d.ts.map +1 -0
  90. package/dist/tooltip/tooltip-store.js +29 -0
  91. package/dist/tooltip/tooltip-store.js.map +1 -0
  92. package/license +21 -0
  93. package/package.json +121 -0
  94. package/readme.md +19 -0
  95. package/src/checkbox/checkbox-store.ts +93 -0
  96. package/src/collection/collection-store.ts +301 -0
  97. package/src/combobox/combobox-store.ts +382 -0
  98. package/src/composite/composite-overflow-store.ts +30 -0
  99. package/src/composite/composite-store.ts +711 -0
  100. package/src/dialog/dialog-store.ts +26 -0
  101. package/src/disclosure/disclosure-store.ts +226 -0
  102. package/src/form/form-store.ts +608 -0
  103. package/src/form/types.ts +44 -0
  104. package/src/hovercard/hovercard-store.ts +112 -0
  105. package/src/index.ts +1 -0
  106. package/src/menu/menu-bar-store.ts +28 -0
  107. package/src/menu/menu-store.ts +263 -0
  108. package/src/menubar/menubar-store.ts +51 -0
  109. package/src/popover/popover-store.ts +170 -0
  110. package/src/radio/radio-store.ts +80 -0
  111. package/src/select/select-store.ts +323 -0
  112. package/src/tab/tab-store.ts +330 -0
  113. package/src/tag/tag-store.ts +170 -0
  114. package/src/toolbar/toolbar-store.ts +47 -0
  115. package/src/tooltip/tooltip-store.ts +93 -0
package/package.json ADDED
@@ -0,0 +1,121 @@
1
+ {
2
+ "name": "@ariakit/components",
3
+ "version": "0.1.0",
4
+ "description": "Ariakit components",
5
+ "keywords": [
6
+ "ariakit",
7
+ "components"
8
+ ],
9
+ "homepage": "https://ariakit.com",
10
+ "license": "MIT",
11
+ "author": {
12
+ "name": "Diego Haz",
13
+ "email": "hazdiego@gmail.com",
14
+ "url": "https://github.com/diegohaz"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/ariakit/ariakit.git",
19
+ "directory": "packages/ariakit-components"
20
+ },
21
+ "type": "module",
22
+ "sideEffects": false,
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js"
27
+ },
28
+ "./checkbox/checkbox-store": {
29
+ "types": "./dist/checkbox/checkbox-store.d.ts",
30
+ "import": "./dist/checkbox/checkbox-store.js"
31
+ },
32
+ "./collection/collection-store": {
33
+ "types": "./dist/collection/collection-store.d.ts",
34
+ "import": "./dist/collection/collection-store.js"
35
+ },
36
+ "./combobox/combobox-store": {
37
+ "types": "./dist/combobox/combobox-store.d.ts",
38
+ "import": "./dist/combobox/combobox-store.js"
39
+ },
40
+ "./composite/composite-overflow-store": {
41
+ "types": "./dist/composite/composite-overflow-store.d.ts",
42
+ "import": "./dist/composite/composite-overflow-store.js"
43
+ },
44
+ "./composite/composite-store": {
45
+ "types": "./dist/composite/composite-store.d.ts",
46
+ "import": "./dist/composite/composite-store.js"
47
+ },
48
+ "./dialog/dialog-store": {
49
+ "types": "./dist/dialog/dialog-store.d.ts",
50
+ "import": "./dist/dialog/dialog-store.js"
51
+ },
52
+ "./disclosure/disclosure-store": {
53
+ "types": "./dist/disclosure/disclosure-store.d.ts",
54
+ "import": "./dist/disclosure/disclosure-store.js"
55
+ },
56
+ "./form/form-store": {
57
+ "types": "./dist/form/form-store.d.ts",
58
+ "import": "./dist/form/form-store.js"
59
+ },
60
+ "./form/types": {
61
+ "types": "./dist/form/types.d.ts",
62
+ "import": "./dist/form/types.js"
63
+ },
64
+ "./hovercard/hovercard-store": {
65
+ "types": "./dist/hovercard/hovercard-store.d.ts",
66
+ "import": "./dist/hovercard/hovercard-store.js"
67
+ },
68
+ "./menu/menu-bar-store": {
69
+ "types": "./dist/menu/menu-bar-store.d.ts",
70
+ "import": "./dist/menu/menu-bar-store.js"
71
+ },
72
+ "./menu/menu-store": {
73
+ "types": "./dist/menu/menu-store.d.ts",
74
+ "import": "./dist/menu/menu-store.js"
75
+ },
76
+ "./menubar/menubar-store": {
77
+ "types": "./dist/menubar/menubar-store.d.ts",
78
+ "import": "./dist/menubar/menubar-store.js"
79
+ },
80
+ "./popover/popover-store": {
81
+ "types": "./dist/popover/popover-store.d.ts",
82
+ "import": "./dist/popover/popover-store.js"
83
+ },
84
+ "./radio/radio-store": {
85
+ "types": "./dist/radio/radio-store.d.ts",
86
+ "import": "./dist/radio/radio-store.js"
87
+ },
88
+ "./select/select-store": {
89
+ "types": "./dist/select/select-store.d.ts",
90
+ "import": "./dist/select/select-store.js"
91
+ },
92
+ "./tab/tab-store": {
93
+ "types": "./dist/tab/tab-store.d.ts",
94
+ "import": "./dist/tab/tab-store.js"
95
+ },
96
+ "./tag/tag-store": {
97
+ "types": "./dist/tag/tag-store.d.ts",
98
+ "import": "./dist/tag/tag-store.js"
99
+ },
100
+ "./toolbar/toolbar-store": {
101
+ "types": "./dist/toolbar/toolbar-store.d.ts",
102
+ "import": "./dist/toolbar/toolbar-store.js"
103
+ },
104
+ "./tooltip/tooltip-store": {
105
+ "types": "./dist/tooltip/tooltip-store.d.ts",
106
+ "import": "./dist/tooltip/tooltip-store.js"
107
+ },
108
+ "./package.json": "./package.json"
109
+ },
110
+ "dependencies": {
111
+ "@ariakit/utils": "0.1.0",
112
+ "@ariakit/store": "0.1.0"
113
+ },
114
+ "devDependencies": {
115
+ "@ariakit/scripts": "0.0.0"
116
+ },
117
+ "scripts": {
118
+ "build": "ariakit build",
119
+ "clean": "ariakit clean"
120
+ }
121
+ }
package/readme.md ADDED
@@ -0,0 +1,19 @@
1
+ # Ariakit Components
2
+
3
+ **Important:** This package is an internal dependency of Ariakit and does not follow semantic versioning, meaning breaking changes may occur in patch and minor versions. You probably want to use [`@ariakit/react`](https://npmjs.org/package/@ariakit/react) instead.
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ npm i @ariakit/components
9
+ ```
10
+
11
+ ## Core Team
12
+
13
+ - [Diego Haz](https://bsky.app/profile/haz.dev)
14
+ - [Ben Rodri](https://bsky.app/profile/ben.ariakit.org)
15
+ - [Dani Guardiola](https://bsky.app/profile/dio.la)
16
+
17
+ ## Contributing
18
+
19
+ Follow the instructions on the [contributing guide](https://github.com/ariakit/ariakit/blob/main/contributing.md).
@@ -0,0 +1,93 @@
1
+ import { createStore, throwOnConflictingProps } from "@ariakit/store";
2
+ import type { Store, StoreOptions, StoreProps } from "@ariakit/store";
3
+ import { defaultValue } from "@ariakit/utils";
4
+ import type { PickRequired, SetState, ToPrimitive } from "@ariakit/utils";
5
+
6
+ /**
7
+ * Creates a checkbox store.
8
+ */
9
+ export function createCheckboxStore<
10
+ T extends CheckboxStoreValue = CheckboxStoreValue,
11
+ >(
12
+ props: PickRequired<CheckboxStoreProps<T>, "value" | "defaultValue">,
13
+ ): CheckboxStore<T>;
14
+
15
+ export function createCheckboxStore(props?: CheckboxStoreProps): CheckboxStore;
16
+
17
+ export function createCheckboxStore(
18
+ props: CheckboxStoreProps = {},
19
+ ): CheckboxStore {
20
+ throwOnConflictingProps(props, props.store);
21
+
22
+ const syncState = props.store?.getState();
23
+ const initialState: CheckboxStoreState = {
24
+ value: defaultValue(
25
+ props.value,
26
+ syncState?.value,
27
+ props.defaultValue,
28
+ false,
29
+ ),
30
+ };
31
+ const checkbox = createStore(initialState, props.store);
32
+ return {
33
+ ...checkbox,
34
+ setValue: (value) => checkbox.setState("value", value),
35
+ };
36
+ }
37
+
38
+ export type CheckboxStoreValue =
39
+ | boolean
40
+ | string
41
+ | number
42
+ | ReadonlyArray<string | number>;
43
+
44
+ export interface CheckboxStoreState<
45
+ T extends CheckboxStoreValue = CheckboxStoreValue,
46
+ > {
47
+ /**
48
+ * The checked state of the checkbox.
49
+ *
50
+ * Live examples:
51
+ * - [Custom Checkbox](https://ariakit.com/examples/checkbox-custom)
52
+ */
53
+ value: ToPrimitive<T>;
54
+ }
55
+
56
+ export interface CheckboxStoreFunctions<
57
+ T extends CheckboxStoreValue = CheckboxStoreValue,
58
+ > {
59
+ /**
60
+ * Sets the [`value`](https://ariakit.com/reference/checkbox-provider#value)
61
+ * state.
62
+ * @example
63
+ * store.setValue(true);
64
+ * store.setValue((value) => !value);
65
+ */
66
+ setValue: SetState<CheckboxStoreState<T>["value"]>;
67
+ }
68
+
69
+ export interface CheckboxStoreOptions<
70
+ T extends CheckboxStoreValue = CheckboxStoreValue,
71
+ > extends StoreOptions<CheckboxStoreState<T>, "value"> {
72
+ /**
73
+ * The default
74
+ * [`value`](https://ariakit.com/reference/checkbox-provider#value) state of
75
+ * the checkbox.
76
+ *
77
+ * Live examples:
78
+ * - [Custom Checkbox](https://ariakit.com/examples/checkbox-custom)
79
+ * - [Checkbox group](https://ariakit.com/examples/checkbox-group)
80
+ * @default false
81
+ */
82
+ defaultValue?: CheckboxStoreState<T>["value"];
83
+ }
84
+
85
+ export interface CheckboxStoreProps<
86
+ T extends CheckboxStoreValue = CheckboxStoreValue,
87
+ >
88
+ extends CheckboxStoreOptions<T>, StoreProps<CheckboxStoreState<T>> {}
89
+
90
+ export interface CheckboxStore<
91
+ T extends CheckboxStoreValue = CheckboxStoreValue,
92
+ >
93
+ extends CheckboxStoreFunctions<T>, Store<CheckboxStoreState<T>> {}
@@ -0,0 +1,301 @@
1
+ import {
2
+ batch,
3
+ createStore,
4
+ init,
5
+ setup,
6
+ throwOnConflictingProps,
7
+ } from "@ariakit/store";
8
+ import type { Store, StoreOptions, StoreProps } from "@ariakit/store";
9
+ import {
10
+ getDocument,
11
+ sortBasedOnDOMPosition,
12
+ chain,
13
+ defaultValue,
14
+ } from "@ariakit/utils";
15
+ import type { BivariantCallback } from "@ariakit/utils";
16
+
17
+ function getCommonParent(items: CollectionStoreItem[]) {
18
+ const firstItem = items.find((item) => !!item.element);
19
+ const lastElement = [...items]
20
+ .reverse()
21
+ .find((item) => !!item.element)?.element;
22
+ let parentElement = firstItem?.element?.parentElement;
23
+ if (!lastElement) {
24
+ return getDocument(parentElement).body;
25
+ }
26
+ while (parentElement) {
27
+ const parent = parentElement;
28
+ if (parent.contains(lastElement)) {
29
+ return parentElement;
30
+ }
31
+ parentElement = parentElement.parentElement;
32
+ }
33
+ return getDocument(parentElement).body;
34
+ }
35
+
36
+ function getPrivateStore<T extends CollectionStoreItem>(
37
+ store?: Store & {
38
+ __unstablePrivateStore?: Store<{
39
+ renderedItems: T[];
40
+ }>;
41
+ },
42
+ ) {
43
+ return store?.__unstablePrivateStore;
44
+ }
45
+
46
+ /**
47
+ * Creates a collection store.
48
+ */
49
+ export function createCollectionStore<
50
+ T extends CollectionStoreItem = CollectionStoreItem,
51
+ >(props: CollectionStoreProps<T> = {}): CollectionStore<T> {
52
+ throwOnConflictingProps(props, props.store);
53
+
54
+ const syncState = props.store?.getState();
55
+
56
+ const items = defaultValue(
57
+ props.items,
58
+ syncState?.items,
59
+ props.defaultItems,
60
+ [],
61
+ );
62
+
63
+ const itemsMap = new Map<string, T>(items.map((item) => [item.id, item]));
64
+
65
+ const initialState: CollectionStoreState<T> = {
66
+ items,
67
+ renderedItems: defaultValue(syncState?.renderedItems, []),
68
+ };
69
+
70
+ const syncPrivateStore = getPrivateStore<T>(props.store);
71
+
72
+ const privateStore = createStore(
73
+ { items, renderedItems: initialState.renderedItems },
74
+ syncPrivateStore,
75
+ );
76
+
77
+ const collection = createStore(initialState, props.store);
78
+
79
+ const sortItems = (renderedItems: T[]) => {
80
+ const sortedItems = sortBasedOnDOMPosition(renderedItems, (i) => i.element);
81
+ privateStore.setState("renderedItems", sortedItems);
82
+ collection.setState("renderedItems", sortedItems);
83
+ };
84
+
85
+ setup(collection, () => init(privateStore));
86
+
87
+ // Use the private store to register items and then batch the changes to the
88
+ // public store so we don't trigger multiple updates on the store when adding
89
+ // multiple items.
90
+ setup(privateStore, () => {
91
+ return batch(privateStore, ["items"], (state) => {
92
+ collection.setState("items", state.items);
93
+ });
94
+ });
95
+
96
+ setup(privateStore, () => {
97
+ return batch(privateStore, ["renderedItems"], (state) => {
98
+ let firstRun = true;
99
+
100
+ let raf = requestAnimationFrame(() => {
101
+ const { renderedItems } = collection.getState();
102
+ // Bail out if the rendered items haven't changed. This is important
103
+ // because the following lines can cause this function to be called
104
+ // again.
105
+ if (state.renderedItems === renderedItems) return;
106
+ sortItems(state.renderedItems);
107
+ });
108
+
109
+ if (typeof IntersectionObserver !== "function") {
110
+ return () => cancelAnimationFrame(raf);
111
+ }
112
+
113
+ const ioCallback: IntersectionObserverCallback = () => {
114
+ if (firstRun) {
115
+ // The IntersectionObserver callback is called synchronously the first
116
+ // time. We just ignore it.
117
+ firstRun = false;
118
+ return;
119
+ }
120
+ cancelAnimationFrame(raf);
121
+ raf = requestAnimationFrame(() => sortItems(state.renderedItems));
122
+ };
123
+
124
+ const root = getCommonParent(state.renderedItems);
125
+ const observer = new IntersectionObserver(ioCallback, { root });
126
+
127
+ for (const item of state.renderedItems) {
128
+ if (!item.element) continue;
129
+ observer.observe(item.element);
130
+ }
131
+
132
+ return () => {
133
+ cancelAnimationFrame(raf);
134
+ observer.disconnect();
135
+ };
136
+ });
137
+ });
138
+
139
+ const mergeItem = (
140
+ item: T,
141
+ setItems: (getItems: (items: T[]) => T[]) => void,
142
+ canDeleteFromMap = false,
143
+ ) => {
144
+ let prevItem: T | undefined;
145
+ setItems((items) => {
146
+ const index = items.findIndex(({ id }) => id === item.id);
147
+ const nextItems = items.slice();
148
+ if (index !== -1) {
149
+ prevItem = items[index];
150
+ const nextItem = { ...prevItem, ...item };
151
+ nextItems[index] = nextItem;
152
+ itemsMap.set(item.id, nextItem);
153
+ } else {
154
+ nextItems.push(item);
155
+ itemsMap.set(item.id, item);
156
+ }
157
+ return nextItems;
158
+ });
159
+ const unmergeItem = () => {
160
+ setItems((items) => {
161
+ if (!prevItem) {
162
+ if (canDeleteFromMap) {
163
+ itemsMap.delete(item.id);
164
+ }
165
+ return items.filter(({ id }) => id !== item.id);
166
+ }
167
+ const index = items.findIndex(({ id }) => id === item.id);
168
+ if (index === -1) return items;
169
+ const nextItems = items.slice();
170
+ nextItems[index] = prevItem;
171
+ itemsMap.set(item.id, prevItem);
172
+ return nextItems;
173
+ });
174
+ };
175
+ return unmergeItem;
176
+ };
177
+
178
+ const registerItem: CollectionStore<T>["registerItem"] = (item) =>
179
+ mergeItem(
180
+ item,
181
+ (getItems) => privateStore.setState("items", getItems),
182
+ true,
183
+ );
184
+
185
+ return {
186
+ ...collection,
187
+
188
+ registerItem,
189
+ renderItem: (item) =>
190
+ chain(
191
+ registerItem(item),
192
+ mergeItem(item, (getItems) =>
193
+ privateStore.setState("renderedItems", getItems),
194
+ ),
195
+ ),
196
+
197
+ item: (id) => {
198
+ if (!id) return null;
199
+ let item = itemsMap.get(id);
200
+ if (!item) {
201
+ const { items } = privateStore.getState();
202
+ item = items.find((item) => item.id === id);
203
+ if (item) {
204
+ itemsMap.set(id, item);
205
+ }
206
+ }
207
+ return item || null;
208
+ },
209
+
210
+ // @ts-expect-error Internal
211
+ __unstablePrivateStore: privateStore,
212
+ };
213
+ }
214
+
215
+ export interface CollectionStoreItem {
216
+ /**
217
+ * The id of the item.
218
+ */
219
+ id: string;
220
+ /**
221
+ * The item HTML element. This is automatically set when the item is rendered.
222
+ */
223
+ element?: HTMLElement | null;
224
+ }
225
+
226
+ export interface CollectionStoreState<
227
+ T extends CollectionStoreItem = CollectionStoreItem,
228
+ > {
229
+ /**
230
+ * Lists all items along with their metadata. This state is automatically
231
+ * updated when an item is registered or unregistered using the
232
+ * [`registerItem`](https://ariakit.com/reference/use-collection-store#registeritem)
233
+ * function.
234
+ *
235
+ * Live examples:
236
+ * - [Command Menu with
237
+ * Tabs](https://ariakit.com/examples/dialog-combobox-tab-command-menu)
238
+ */
239
+ items: T[];
240
+ /**
241
+ * Lists all items, along with their metadata, in the exact order they appear in
242
+ * the DOM. This state is automatically updated when an item is rendered or
243
+ * unmounted using the
244
+ * [`renderItem`](https://ariakit.com/reference/use-collection-store#renderitem)
245
+ * function.
246
+ */
247
+ renderedItems: T[];
248
+ }
249
+
250
+ export interface CollectionStoreFunctions<
251
+ T extends CollectionStoreItem = CollectionStoreItem,
252
+ > {
253
+ /**
254
+ * Registers an item in the collection. This function returns a cleanup
255
+ * function that unregisters the item.
256
+ * @example
257
+ * const unregisterItem = store.registerItem({ id: "item-1" });
258
+ * // on cleanup
259
+ * unregisterItem();
260
+ */
261
+ registerItem: BivariantCallback<(item: T) => () => void>;
262
+ /**
263
+ * Renders an item in the collection. This function returns a cleanup function
264
+ * that unmounts the item.
265
+ * @example
266
+ * const unrenderItem = store.renderItem({ id: "item-1" });
267
+ * // on cleanup
268
+ * unrenderItem();
269
+ */
270
+ renderItem: BivariantCallback<(item: T) => () => void>;
271
+ /**
272
+ * Gets an item by its id.
273
+ *
274
+ * Live examples:
275
+ * - [Animated TabPanel](https://ariakit.com/examples/tab-panel-animated)
276
+ * @example
277
+ * const item = store.item("item-1");
278
+ */
279
+ item: (id: string | null | undefined) => T | null;
280
+ }
281
+
282
+ export interface CollectionStoreOptions<
283
+ T extends CollectionStoreItem = CollectionStoreItem,
284
+ > extends StoreOptions<CollectionStoreState<T>, "items"> {
285
+ /**
286
+ * The defaut value for the
287
+ * [`items`](https://ariakit.com/reference/collection-provider#items) state.
288
+ * @default []
289
+ */
290
+ defaultItems?: CollectionStoreState<T>["items"];
291
+ }
292
+
293
+ export interface CollectionStoreProps<
294
+ T extends CollectionStoreItem = CollectionStoreItem,
295
+ >
296
+ extends CollectionStoreOptions<T>, StoreProps<CollectionStoreState<T>> {}
297
+
298
+ export interface CollectionStore<
299
+ T extends CollectionStoreItem = CollectionStoreItem,
300
+ >
301
+ extends CollectionStoreFunctions<T>, Store<CollectionStoreState<T>> {}