@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
@@ -0,0 +1,382 @@
1
+ import {
2
+ batch,
3
+ createStore,
4
+ mergeStore,
5
+ pick,
6
+ setup,
7
+ sync,
8
+ throwOnConflictingProps,
9
+ } from "@ariakit/store";
10
+ import type { Store, StoreOptions, StoreProps } from "@ariakit/store";
11
+ import { chain, defaultValue, isSafari, isTouchDevice } from "@ariakit/utils";
12
+ import type { PickRequired, SetState } from "@ariakit/utils";
13
+ import type {
14
+ CompositeStoreFunctions,
15
+ CompositeStoreItem,
16
+ CompositeStoreOptions,
17
+ CompositeStoreState,
18
+ } from "../composite/composite-store.ts";
19
+ import { createCompositeStore } from "../composite/composite-store.ts";
20
+ import type {
21
+ PopoverStoreFunctions,
22
+ PopoverStoreOptions,
23
+ PopoverStoreState,
24
+ } from "../popover/popover-store.ts";
25
+ import { createPopoverStore } from "../popover/popover-store.ts";
26
+ import type { TagStore } from "../tag/tag-store.ts";
27
+
28
+ type MutableValue<
29
+ T extends ComboboxStoreSelectedValue = ComboboxStoreSelectedValue,
30
+ > = T extends string ? string : T;
31
+
32
+ const isTouchSafari = isSafari() && isTouchDevice();
33
+
34
+ /**
35
+ * Creates a combobox store.
36
+ */
37
+ export function createComboboxStore<
38
+ T extends ComboboxStoreSelectedValue = ComboboxStoreSelectedValue,
39
+ >(
40
+ props: PickRequired<
41
+ ComboboxStoreProps<T>,
42
+ "selectedValue" | "defaultSelectedValue"
43
+ >,
44
+ ): ComboboxStore<T>;
45
+
46
+ export function createComboboxStore(props?: ComboboxStoreProps): ComboboxStore;
47
+
48
+ export function createComboboxStore({
49
+ tag,
50
+ ...props
51
+ }: ComboboxStoreProps = {}): ComboboxStore {
52
+ const store = mergeStore(props.store, pick(tag, ["value", "rtl"]));
53
+
54
+ throwOnConflictingProps(props, store);
55
+
56
+ const tagState = tag?.getState();
57
+ const syncState = store?.getState();
58
+
59
+ const activeId = defaultValue(
60
+ props.activeId,
61
+ syncState?.activeId,
62
+ props.defaultActiveId,
63
+ null,
64
+ );
65
+
66
+ const composite = createCompositeStore({
67
+ ...props,
68
+ activeId,
69
+ includesBaseElement: defaultValue(
70
+ props.includesBaseElement,
71
+ syncState?.includesBaseElement,
72
+ true,
73
+ ),
74
+ orientation: defaultValue(
75
+ props.orientation,
76
+ syncState?.orientation,
77
+ "vertical" as const,
78
+ ),
79
+ focusLoop: defaultValue(props.focusLoop, syncState?.focusLoop, true),
80
+ focusWrap: defaultValue(props.focusWrap, syncState?.focusWrap, true),
81
+ virtualFocus: defaultValue(
82
+ props.virtualFocus,
83
+ syncState?.virtualFocus,
84
+ true,
85
+ ),
86
+ });
87
+
88
+ const popover = createPopoverStore({
89
+ ...props,
90
+ placement: defaultValue(
91
+ props.placement,
92
+ syncState?.placement,
93
+ "bottom-start" as const,
94
+ ),
95
+ });
96
+
97
+ const value = defaultValue(
98
+ props.value,
99
+ syncState?.value,
100
+ props.defaultValue,
101
+ "",
102
+ );
103
+
104
+ const selectedValue = defaultValue(
105
+ props.selectedValue,
106
+ syncState?.selectedValue,
107
+ tagState?.values,
108
+ props.defaultSelectedValue,
109
+ "",
110
+ );
111
+
112
+ const multiSelectable = Array.isArray(selectedValue);
113
+
114
+ const initialState: ComboboxStoreState = {
115
+ ...composite.getState(),
116
+ ...popover.getState(),
117
+ value,
118
+ selectedValue,
119
+ resetValueOnSelect: defaultValue(
120
+ props.resetValueOnSelect,
121
+ syncState?.resetValueOnSelect,
122
+ multiSelectable,
123
+ ),
124
+ resetValueOnHide: defaultValue(
125
+ props.resetValueOnHide,
126
+ syncState?.resetValueOnHide,
127
+ multiSelectable && !tag,
128
+ ),
129
+ activeValue: syncState?.activeValue,
130
+ };
131
+
132
+ const combobox = createStore(initialState, composite, popover, store);
133
+
134
+ // Safari doesn't support aria-activedescendant on combobox elements. This is
135
+ // particularly problematic when using touch devices as moving the VoiceOver
136
+ // virtual cursor through the combobox items will always move the focus to the
137
+ // input element. To work around this, we disable virtual focus on touch
138
+ // devices when using Safari.
139
+ if (isTouchSafari) {
140
+ setup(combobox, () =>
141
+ sync(combobox, ["virtualFocus"], () => {
142
+ combobox.setState("virtualFocus", false);
143
+ }),
144
+ );
145
+ }
146
+
147
+ // Sync tag values with the combobox selectedValue state.
148
+ setup(combobox, () => {
149
+ if (!tag) return;
150
+ return chain(
151
+ sync(combobox, ["selectedValue"], (state) => {
152
+ if (!Array.isArray(state.selectedValue)) return;
153
+ tag.setValues(state.selectedValue);
154
+ }),
155
+ sync(tag, ["values"], (state) => {
156
+ combobox.setState("selectedValue", state.values);
157
+ }),
158
+ );
159
+ });
160
+
161
+ setup(combobox, () =>
162
+ sync(combobox, ["resetValueOnHide", "mounted"], (state) => {
163
+ if (!state.resetValueOnHide) return;
164
+ if (state.mounted) return;
165
+ combobox.setState("value", value);
166
+ }),
167
+ );
168
+
169
+ // Resets the state when the combobox popover is hidden.
170
+ setup(combobox, () =>
171
+ sync(combobox, ["open"], (state) => {
172
+ if (state.open) return;
173
+ combobox.setState("activeId", activeId);
174
+ combobox.setState("moves", 0);
175
+ }),
176
+ );
177
+
178
+ // When the activeId changes, but the moves count doesn't, we reset the
179
+ // activeValue state. This is useful when the activeId changes because of
180
+ // a mouse move interaction.
181
+ setup(combobox, () =>
182
+ sync(combobox, ["moves", "activeId"], (state, prevState) => {
183
+ if (state.moves === prevState.moves) {
184
+ combobox.setState("activeValue", undefined);
185
+ }
186
+ }),
187
+ );
188
+
189
+ // Otherwise, if the moves count changes, we update the activeValue state.
190
+ setup(combobox, () =>
191
+ batch(combobox, ["moves", "renderedItems"], (state, prev) => {
192
+ if (state.moves === prev.moves) return;
193
+ const { activeId } = combobox.getState();
194
+ const activeItem = composite.item(activeId);
195
+ combobox.setState("activeValue", activeItem?.value);
196
+ }),
197
+ );
198
+
199
+ return {
200
+ ...popover,
201
+ ...composite,
202
+ ...combobox,
203
+ tag,
204
+ setValue: (value) => combobox.setState("value", value),
205
+ resetValue: () => combobox.setState("value", initialState.value),
206
+ setSelectedValue: (selectedValue) =>
207
+ combobox.setState("selectedValue", selectedValue),
208
+ };
209
+ }
210
+
211
+ export type ComboboxStoreSelectedValue = string | readonly string[];
212
+
213
+ export interface ComboboxStoreItem extends CompositeStoreItem {
214
+ value?: string;
215
+ }
216
+
217
+ export interface ComboboxStoreState<
218
+ T extends ComboboxStoreSelectedValue = ComboboxStoreSelectedValue,
219
+ >
220
+ extends CompositeStoreState<ComboboxStoreItem>, PopoverStoreState {
221
+ /** @default true */
222
+ includesBaseElement: CompositeStoreState<ComboboxStoreItem>["includesBaseElement"];
223
+ /** @default true */
224
+ focusLoop: CompositeStoreState<ComboboxStoreItem>["focusLoop"];
225
+ /** @default true */
226
+ focusWrap: CompositeStoreState<ComboboxStoreItem>["focusWrap"];
227
+ /** @default "vertical" */
228
+ orientation: CompositeStoreState<ComboboxStoreItem>["orientation"];
229
+ /** @default true */
230
+ virtualFocus: CompositeStoreState<ComboboxStoreItem>["virtualFocus"];
231
+ /**
232
+ * The combobox input value.
233
+ *
234
+ * Live examples:
235
+ * - [Combobox with integrated
236
+ * filter](https://ariakit.com/examples/combobox-filtering-integrated)
237
+ * - [Combobox with links](https://ariakit.com/examples/combobox-links)
238
+ * - [Combobox filtering](https://ariakit.com/examples/combobox-filtering)
239
+ * - [Multi-selectable
240
+ * Combobox](https://ariakit.com/examples/combobox-multiple)
241
+ * - [Textarea with inline
242
+ * Combobox](https://ariakit.com/examples/combobox-textarea)
243
+ * - [Command Menu with
244
+ * Tabs](https://ariakit.com/examples/dialog-combobox-tab-command-menu)
245
+ */
246
+ value: string;
247
+ /**
248
+ * The value of the currently active item. This state automatically updates as
249
+ * the user navigates the combobox items either by keyboard or mouse click.
250
+ * Note that it doesn't update when the user simply hovers over the items.
251
+ */
252
+ activeValue: string | undefined;
253
+ /**
254
+ * The value(s) of the currently selected item(s). This can be a string or an
255
+ * array of strings. If it's an array, the combobox is considered
256
+ * [multi-selectable](https://ariakit.com/examples/combobox-multiple).
257
+ *
258
+ * Live examples:
259
+ * - [Multi-selectable
260
+ * Combobox](https://ariakit.com/examples/combobox-multiple)
261
+ */
262
+ selectedValue: MutableValue<T>;
263
+ /**
264
+ * Whether to reset the value when the combobox popover closes. This prop is
265
+ * automatically set to `true` by default if the combobox supports multiple
266
+ * selections. In other words, if the
267
+ * [`selectedValue`](https://ariakit.com/reference/combobox-provider#selectedvalue)
268
+ * or
269
+ * [`defaultSelectedValue`](https://ariakit.com/reference/combobox-provider#defaultselectedvalue)
270
+ * props are arrays.
271
+ *
272
+ * Live examples:
273
+ * - [Multi-selectable
274
+ * Combobox](https://ariakit.com/examples/combobox-multiple)
275
+ * - [Menu with Combobox](https://ariakit.com/examples/menu-combobox)
276
+ * - [Select with Combobox](https://ariakit.com/examples/select-combobox)
277
+ * - [Submenu with
278
+ * Combobox](https://ariakit.com/examples/menu-nested-combobox)
279
+ * - [Command Menu with
280
+ * Tabs](https://ariakit.com/examples/dialog-combobox-tab-command-menu)
281
+ * - [Select with Combobox and
282
+ * Tabs](https://ariakit.com/examples/select-combobox-tab)
283
+ */
284
+ resetValueOnHide: boolean;
285
+ /**
286
+ * Whether to reset the value when an item is selected. This prop is
287
+ * automatically set to `true` by default if the combobox supports multiple
288
+ * selections. In other words, if the
289
+ * [`selectedValue`](https://ariakit.com/reference/combobox-provider#selectedvalue)
290
+ * or
291
+ * [`defaultSelectedValue`](https://ariakit.com/reference/combobox-provider#defaultselectedvalue)
292
+ * props are arrays.
293
+ * @deprecated Use the
294
+ * [`resetValueOnSelect`](https://ariakit.com/reference/combobox-item#resetvalueonselect)
295
+ * prop on [`ComboboxItem`](https://ariakit.com/reference/combobox-item)
296
+ * instead.
297
+ */
298
+ resetValueOnSelect: boolean;
299
+ }
300
+
301
+ export interface ComboboxStoreFunctions<
302
+ T extends ComboboxStoreSelectedValue = ComboboxStoreSelectedValue,
303
+ >
304
+ extends
305
+ Pick<ComboboxStoreOptions<T>, "tag">,
306
+ CompositeStoreFunctions<ComboboxStoreItem>,
307
+ PopoverStoreFunctions {
308
+ /**
309
+ * Sets the [`value`](https://ariakit.com/reference/combobox-provider#value)
310
+ * state.
311
+ *
312
+ * Live examples:
313
+ * - [Textarea with inline
314
+ * Combobox](https://ariakit.com/examples/combobox-textarea)
315
+ * @example
316
+ * store.setValue("Hello world");
317
+ * store.setValue((value) => value + "!");
318
+ */
319
+ setValue: SetState<ComboboxStoreState<T>["value"]>;
320
+ /**
321
+ * Resets the [`value`](https://ariakit.com/reference/combobox-provider#value)
322
+ * state to its initial value.
323
+ */
324
+ resetValue: () => void;
325
+ /**
326
+ * Sets the
327
+ * [`selectedValue`](https://ariakit.com/reference/combobox-provider#selectedvalue)
328
+ * state.
329
+ */
330
+ setSelectedValue: SetState<ComboboxStoreState<T>["selectedValue"]>;
331
+ }
332
+
333
+ export interface ComboboxStoreOptions<
334
+ T extends ComboboxStoreSelectedValue = ComboboxStoreSelectedValue,
335
+ >
336
+ extends
337
+ StoreOptions<
338
+ ComboboxStoreState<T>,
339
+ | "includesBaseElement"
340
+ | "focusLoop"
341
+ | "focusWrap"
342
+ | "orientation"
343
+ | "virtualFocus"
344
+ | "value"
345
+ | "selectedValue"
346
+ | "resetValueOnHide"
347
+ | "resetValueOnSelect"
348
+ >,
349
+ CompositeStoreOptions<ComboboxStoreItem>,
350
+ PopoverStoreOptions {
351
+ /** @default null */
352
+ defaultActiveId?: CompositeStoreOptions<ComboboxStoreItem>["activeId"];
353
+ /**
354
+ * The initial value of the combobox input.
355
+ * @default ""
356
+ */
357
+ defaultValue?: ComboboxStoreState<T>["value"];
358
+ /**
359
+ * The initial value of the
360
+ * [`selectedValue`](https://ariakit.com/reference/combobox-provider#selectedvalue)
361
+ * state. This can be a string or an array of strings. If it's an array, the
362
+ * combobox is considered
363
+ * [multi-selectable](https://ariakit.com/examples/combobox-multiple).
364
+ * @default ""
365
+ */
366
+ defaultSelectedValue?: ComboboxStoreState<T>["selectedValue"];
367
+ /**
368
+ * A reference to a tag store. This is used when rendering a combobox within a
369
+ * tag list. The stores will share the same state.
370
+ */
371
+ tag?: TagStore | null;
372
+ }
373
+
374
+ export interface ComboboxStoreProps<
375
+ T extends ComboboxStoreSelectedValue = ComboboxStoreSelectedValue,
376
+ >
377
+ extends ComboboxStoreOptions<T>, StoreProps<ComboboxStoreState<T>> {}
378
+
379
+ export interface ComboboxStore<
380
+ T extends ComboboxStoreSelectedValue = ComboboxStoreSelectedValue,
381
+ >
382
+ extends ComboboxStoreFunctions<T>, Store<ComboboxStoreState<T>> {}
@@ -0,0 +1,30 @@
1
+ import type { Store, StoreProps } from "@ariakit/store";
2
+ import type {
3
+ PopoverStoreFunctions,
4
+ PopoverStoreOptions,
5
+ PopoverStoreState,
6
+ } from "../popover/popover-store.ts";
7
+ import { createPopoverStore } from "../popover/popover-store.ts";
8
+
9
+ /**
10
+ * Creates a compositeOverflow store.
11
+ */
12
+ export function createCompositeOverflowStore(
13
+ props: CompositeOverflowStoreProps = {},
14
+ ): CompositeOverflowStore {
15
+ return createPopoverStore(props);
16
+ }
17
+
18
+ export interface CompositeOverflowStoreState extends PopoverStoreState {}
19
+
20
+ export interface CompositeOverflowStoreFunctions extends PopoverStoreFunctions {}
21
+
22
+ export interface CompositeOverflowStoreOptions extends PopoverStoreOptions {}
23
+
24
+ export interface CompositeOverflowStoreProps
25
+ extends
26
+ CompositeOverflowStoreOptions,
27
+ StoreProps<CompositeOverflowStoreState> {}
28
+
29
+ export interface CompositeOverflowStore
30
+ extends CompositeOverflowStoreFunctions, Store<CompositeOverflowStoreState> {}