@octanejs/aria 0.0.4 → 0.0.5

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 (93) hide show
  1. package/package.json +7 -5
  2. package/src/autocomplete/useAutocomplete.ts +656 -0
  3. package/src/collections/BaseCollection.ts +374 -0
  4. package/src/collections/CollectionBuilder.ts +343 -0
  5. package/src/collections/Document.ts +451 -0
  6. package/src/collections/Hidden.ts +84 -0
  7. package/src/collections/useCachedChildren.ts +103 -0
  8. package/src/components/Autocomplete.ts +124 -0
  9. package/src/components/Breadcrumbs.ts +170 -0
  10. package/src/components/Button.ts +209 -0
  11. package/src/components/Checkbox.ts +593 -0
  12. package/src/components/Collection.ts +301 -0
  13. package/src/components/ComboBox.ts +477 -0
  14. package/src/components/Dialog.ts +195 -0
  15. package/src/components/Disclosure.ts +322 -0
  16. package/src/components/DragAndDrop.ts +177 -0
  17. package/src/components/FieldError.ts +79 -0
  18. package/src/components/Form.ts +65 -0
  19. package/src/components/GridList.ts +1099 -0
  20. package/src/components/Group.ts +146 -0
  21. package/src/components/Header.ts +32 -0
  22. package/src/components/Heading.ts +45 -0
  23. package/src/components/Input.ts +139 -0
  24. package/src/components/Keyboard.ts +23 -0
  25. package/src/components/Label.ts +30 -0
  26. package/src/components/Link.ts +137 -0
  27. package/src/components/ListBox.ts +886 -0
  28. package/src/components/Menu.ts +685 -0
  29. package/src/components/Meter.ts +100 -0
  30. package/src/components/Modal.ts +352 -0
  31. package/src/components/NumberField.ts +221 -0
  32. package/src/components/OverlayArrow.ts +117 -0
  33. package/src/components/Popover.ts +385 -0
  34. package/src/components/ProgressBar.ts +112 -0
  35. package/src/components/RadioGroup.ts +542 -0
  36. package/src/components/SearchField.ts +208 -0
  37. package/src/components/Select.ts +505 -0
  38. package/src/components/SelectionIndicator.ts +52 -0
  39. package/src/components/Separator.ts +97 -0
  40. package/src/components/SharedElementTransition.ts +209 -0
  41. package/src/components/Slider.ts +472 -0
  42. package/src/components/Switch.ts +449 -0
  43. package/src/components/Tabs.ts +675 -0
  44. package/src/components/TagGroup.ts +443 -0
  45. package/src/components/Text.ts +27 -0
  46. package/src/components/TextArea.ts +92 -0
  47. package/src/components/TextField.ts +200 -0
  48. package/src/components/ToggleButton.ts +147 -0
  49. package/src/components/ToggleButtonGroup.ts +106 -0
  50. package/src/components/Toolbar.ts +74 -0
  51. package/src/components/Tooltip.ts +249 -0
  52. package/src/components/index.ts +302 -0
  53. package/src/components/useDragAndDrop.ts +164 -0
  54. package/src/components/utils.ts +521 -0
  55. package/src/intl/autocomplete/ar-AE.json +3 -0
  56. package/src/intl/autocomplete/bg-BG.json +3 -0
  57. package/src/intl/autocomplete/cs-CZ.json +3 -0
  58. package/src/intl/autocomplete/da-DK.json +3 -0
  59. package/src/intl/autocomplete/de-DE.json +3 -0
  60. package/src/intl/autocomplete/el-GR.json +3 -0
  61. package/src/intl/autocomplete/en-US.json +3 -0
  62. package/src/intl/autocomplete/es-ES.json +3 -0
  63. package/src/intl/autocomplete/et-EE.json +3 -0
  64. package/src/intl/autocomplete/fi-FI.json +3 -0
  65. package/src/intl/autocomplete/fr-FR.json +3 -0
  66. package/src/intl/autocomplete/he-IL.json +3 -0
  67. package/src/intl/autocomplete/hr-HR.json +3 -0
  68. package/src/intl/autocomplete/hu-HU.json +3 -0
  69. package/src/intl/autocomplete/index.ts +75 -0
  70. package/src/intl/autocomplete/it-IT.json +3 -0
  71. package/src/intl/autocomplete/ja-JP.json +3 -0
  72. package/src/intl/autocomplete/ko-KR.json +3 -0
  73. package/src/intl/autocomplete/lt-LT.json +3 -0
  74. package/src/intl/autocomplete/lv-LV.json +3 -0
  75. package/src/intl/autocomplete/nb-NO.json +3 -0
  76. package/src/intl/autocomplete/nl-NL.json +3 -0
  77. package/src/intl/autocomplete/pl-PL.json +3 -0
  78. package/src/intl/autocomplete/pt-BR.json +3 -0
  79. package/src/intl/autocomplete/pt-PT.json +3 -0
  80. package/src/intl/autocomplete/ro-RO.json +3 -0
  81. package/src/intl/autocomplete/ru-RU.json +3 -0
  82. package/src/intl/autocomplete/sk-SK.json +3 -0
  83. package/src/intl/autocomplete/sl-SI.json +3 -0
  84. package/src/intl/autocomplete/sr-SP.json +3 -0
  85. package/src/intl/autocomplete/sv-SE.json +3 -0
  86. package/src/intl/autocomplete/tr-TR.json +3 -0
  87. package/src/intl/autocomplete/uk-UA.json +3 -0
  88. package/src/intl/autocomplete/zh-CN.json +3 -0
  89. package/src/intl/autocomplete/zh-TW.json +3 -0
  90. package/src/stately/autocomplete/useAutocompleteState.ts +85 -0
  91. package/src/utils/animation.ts +149 -0
  92. package/src/utils/useLoadMoreSentinel.ts +78 -0
  93. package/src/utils/useViewportSize.ts +123 -0
@@ -0,0 +1,449 @@
1
+ // Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Switch.tsx).
2
+ // octane adaptations: `.tsx` → `.ts`, JSX → `createElement`; NO forwardRef — the forwarded ref
3
+ // is `props.ref`, passed into `useContextProps` explicitly and re-applied as the merged object
4
+ // ref; the plain-`.ts` components use the S()/subSlot component-slot convention (`useContext`
5
+ // stays slotless — context-identity keyed); the ported useSwitch already carries octane's
6
+ // native change-event wiring for the hidden switch input — inputProps pass through untouched.
7
+ import type { HoverEvents, RefObject } from '@react-types/shared';
8
+ import { createContext, createElement, useContext } from 'octane';
9
+
10
+ import { useFocusRing } from '../focus/useFocusRing';
11
+ import { useHover } from '../interactions/useHover';
12
+ import { S, subSlot } from '../internal';
13
+ import { type ToggleState, useToggleState } from '../stately/toggle/useToggleState';
14
+ import { type AriaSwitchProps, type SwitchAria, useSwitch } from '../switch/useSwitch';
15
+ import { filterDOMProps } from '../utils/filterDOMProps';
16
+ import { mergeProps } from '../utils/mergeProps';
17
+ import { mergeRefs } from '../utils/mergeRefs';
18
+ import { useObjectRef } from '../utils/useObjectRef';
19
+ import { VisuallyHidden } from '../visually-hidden/VisuallyHidden';
20
+ import { FieldErrorContext } from './FieldError';
21
+ import { FormContext } from './Form';
22
+ import { TextContext } from './Text';
23
+ import {
24
+ type ClassNameOrFunction,
25
+ type ContextValue,
26
+ dom,
27
+ Provider,
28
+ type RACValidation,
29
+ removeDataAttributes,
30
+ type RenderProps,
31
+ type SlotProps,
32
+ useContextProps,
33
+ useRenderProps,
34
+ useSlottedContext,
35
+ } from './utils';
36
+
37
+ // octane adaptation: structural bag (upstream's `GlobalDOMAttributes` drags React handler types).
38
+ type GlobalDOMAttributes = Record<string, any>;
39
+
40
+ export interface SwitchProps
41
+ extends
42
+ Omit<
43
+ AriaSwitchProps,
44
+ | 'children'
45
+ | 'validationState'
46
+ | 'validationBehavior'
47
+ | 'isRequired'
48
+ | 'isInvalid'
49
+ | 'validate'
50
+ >,
51
+ HoverEvents,
52
+ RenderProps<SwitchRenderProps, 'label'>,
53
+ SlotProps,
54
+ Omit<GlobalDOMAttributes, 'onClick'> {
55
+ /**
56
+ * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
57
+ * element. A function may be provided to compute the class based on component state.
58
+ *
59
+ * @default 'react-aria-Switch'
60
+ */
61
+ className?: ClassNameOrFunction<SwitchRenderProps>;
62
+ /**
63
+ * A ref for the HTML input element.
64
+ */
65
+ inputRef?: RefObject<HTMLInputElement | null>;
66
+ }
67
+
68
+ export interface SwitchFieldProps
69
+ extends
70
+ Omit<AriaSwitchProps, 'children' | 'validationState' | 'validationBehavior'>,
71
+ RACValidation,
72
+ RenderProps<SwitchFieldRenderProps>,
73
+ SlotProps,
74
+ Omit<GlobalDOMAttributes, 'onClick'> {
75
+ /**
76
+ * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
77
+ * element. A function may be provided to compute the class based on component state.
78
+ *
79
+ * @default 'react-aria-SwitchField'
80
+ */
81
+ className?: ClassNameOrFunction<SwitchFieldRenderProps>;
82
+ /**
83
+ * A ref for the HTML input element.
84
+ */
85
+ inputRef?: RefObject<HTMLInputElement | null>;
86
+ }
87
+
88
+ export interface SwitchButtonProps
89
+ extends
90
+ HoverEvents,
91
+ RenderProps<SwitchButtonRenderProps, 'label'>,
92
+ SlotProps,
93
+ GlobalDOMAttributes {
94
+ /**
95
+ * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the
96
+ * element. A function may be provided to compute the class based on component state.
97
+ *
98
+ * @default 'react-aria-SwitchButton'
99
+ */
100
+ className?: ClassNameOrFunction<SwitchButtonRenderProps>;
101
+ }
102
+
103
+ export interface SwitchRenderProps {
104
+ /**
105
+ * Whether the switch is selected.
106
+ *
107
+ * @selector [data-selected]
108
+ */
109
+ isSelected: boolean;
110
+ /**
111
+ * Whether the switch is currently hovered with a mouse.
112
+ *
113
+ * @selector [data-hovered]
114
+ */
115
+ isHovered: boolean;
116
+ /**
117
+ * Whether the switch is currently in a pressed state.
118
+ *
119
+ * @selector [data-pressed]
120
+ */
121
+ isPressed: boolean;
122
+ /**
123
+ * Whether the switch is focused, either via a mouse or keyboard.
124
+ *
125
+ * @selector [data-focused]
126
+ */
127
+ isFocused: boolean;
128
+ /**
129
+ * Whether the switch is keyboard focused.
130
+ *
131
+ * @selector [data-focus-visible]
132
+ */
133
+ isFocusVisible: boolean;
134
+ /**
135
+ * Whether the switch is disabled.
136
+ *
137
+ * @selector [data-disabled]
138
+ */
139
+ isDisabled: boolean;
140
+ /**
141
+ * Whether the switch is read only.
142
+ *
143
+ * @selector [data-readonly]
144
+ */
145
+ isReadOnly: boolean;
146
+ /**
147
+ * State of the switch.
148
+ */
149
+ state: ToggleState;
150
+ }
151
+
152
+ export interface SwitchFieldRenderProps {
153
+ /**
154
+ * Whether the switch is selected.
155
+ *
156
+ * @selector [data-selected]
157
+ */
158
+ isSelected: boolean;
159
+ /**
160
+ * Whether the switch is disabled.
161
+ *
162
+ * @selector [data-disabled]
163
+ */
164
+ isDisabled: boolean;
165
+ /**
166
+ * Whether the switch is read only.
167
+ *
168
+ * @selector [data-readonly]
169
+ */
170
+ isReadOnly: boolean;
171
+ /**
172
+ * Whether the switch invalid.
173
+ *
174
+ * @selector [data-invalid]
175
+ */
176
+ isInvalid: boolean;
177
+ /**
178
+ * Whether the switch is required.
179
+ *
180
+ * @selector [data-required]
181
+ */
182
+ isRequired: boolean;
183
+ /**
184
+ * State of the switch.
185
+ */
186
+ state: ToggleState;
187
+ }
188
+
189
+ export interface SwitchButtonRenderProps extends SwitchRenderProps {
190
+ /**
191
+ * Whether the switch invalid.
192
+ *
193
+ * @selector [data-invalid]
194
+ */
195
+ isInvalid: boolean;
196
+ /**
197
+ * Whether the switch is required.
198
+ *
199
+ * @selector [data-required]
200
+ */
201
+ isRequired: boolean;
202
+ /**
203
+ * State of the switch.
204
+ */
205
+ state: ToggleState;
206
+ }
207
+
208
+ export const SwitchContext = createContext<ContextValue<SwitchProps, HTMLLabelElement>>(null);
209
+ export const SwitchFieldContext =
210
+ createContext<ContextValue<SwitchFieldProps, HTMLDivElement>>(null);
211
+ export const ToggleStateContext = createContext<ToggleState | null>(null);
212
+
213
+ /**
214
+ * A switch allows a user to turn a setting on or off.
215
+ *
216
+ * @deprecated Use SwitchField + SwitchButton instead.
217
+ */
218
+ export function Switch(props: SwitchProps): any {
219
+ const slot = S('Switch');
220
+ let { inputRef: userProvidedInputRef = null, ...otherProps } = props;
221
+ let ref: any;
222
+ [props, ref] = useContextProps(
223
+ otherProps as SwitchProps,
224
+ (otherProps as any).ref,
225
+ SwitchContext,
226
+ subSlot(slot, 'ctx'),
227
+ );
228
+ let inputRef = useObjectRef(
229
+ mergeRefs(userProvidedInputRef, props.inputRef !== undefined ? props.inputRef : null),
230
+ subSlot(slot, 'inputRef'),
231
+ );
232
+ let state = useToggleState(props, subSlot(slot, 'toggleState'));
233
+ let aria = useSwitch(
234
+ {
235
+ ...removeDataAttributes(props),
236
+ // ReactNode type doesn't allow function children.
237
+ children: typeof props.children === 'function' ? true : props.children,
238
+ },
239
+ state,
240
+ inputRef,
241
+ subSlot(slot, 'switch'),
242
+ );
243
+
244
+ return createElement(Provider, {
245
+ values: [
246
+ [ToggleStateContext, state],
247
+ [
248
+ InternalSwitchContext,
249
+ {
250
+ ...aria,
251
+ inputRef,
252
+ defaultClassName: 'react-aria-Switch',
253
+ },
254
+ ],
255
+ ] as any,
256
+ children: createElement(SwitchButton, { ...props, ref } as any),
257
+ });
258
+ }
259
+
260
+ interface InternalSwitchContextValue extends SwitchAria {
261
+ inputRef: RefObject<HTMLInputElement | null>;
262
+ defaultClassName: string;
263
+ isRequired?: boolean;
264
+ }
265
+
266
+ const InternalSwitchContext = createContext<InternalSwitchContextValue | null>(null);
267
+
268
+ /**
269
+ * A switch allows a user to turn a setting on or off, with support for validation and help text.
270
+ */
271
+ export function SwitchField(props: SwitchFieldProps): any {
272
+ const slot = S('SwitchField');
273
+ let { inputRef: userProvidedInputRef = null, ...otherProps } = props;
274
+ let ref: any;
275
+ [props, ref] = useContextProps(
276
+ otherProps as SwitchFieldProps,
277
+ (otherProps as any).ref,
278
+ SwitchFieldContext,
279
+ subSlot(slot, 'ctx'),
280
+ );
281
+ let { validationBehavior: formValidationBehavior } =
282
+ useSlottedContext(FormContext, undefined, subSlot(slot, 'form')) || {};
283
+ let validationBehavior = props.validationBehavior ?? formValidationBehavior ?? 'native';
284
+ let inputRef = useObjectRef(
285
+ mergeRefs(userProvidedInputRef, props.inputRef !== undefined ? props.inputRef : null),
286
+ subSlot(slot, 'inputRef'),
287
+ );
288
+ let state = useToggleState(props, subSlot(slot, 'toggleState'));
289
+ let aria = useSwitch(
290
+ {
291
+ ...removeDataAttributes(props),
292
+ // ReactNode type doesn't allow function children.
293
+ children: typeof props.children === 'function' ? true : props.children,
294
+ validationBehavior,
295
+ },
296
+ state,
297
+ inputRef,
298
+ subSlot(slot, 'switch'),
299
+ );
300
+ let {
301
+ descriptionProps,
302
+ errorMessageProps,
303
+ isSelected,
304
+ isDisabled,
305
+ isReadOnly,
306
+ isInvalid,
307
+ validationDetails,
308
+ validationErrors,
309
+ } = aria;
310
+
311
+ let renderProps = useRenderProps(
312
+ {
313
+ ...props,
314
+ defaultClassName: 'react-aria-SwitchField',
315
+ values: {
316
+ isSelected,
317
+ isDisabled,
318
+ isReadOnly,
319
+ isInvalid,
320
+ isRequired: props.isRequired || false,
321
+ state,
322
+ },
323
+ },
324
+ subSlot(slot, 'render'),
325
+ );
326
+
327
+ let DOMProps = filterDOMProps(props, { global: true });
328
+ delete DOMProps.id;
329
+ delete (DOMProps as any).onClick;
330
+
331
+ return createElement(dom.div, {
332
+ ...mergeProps(DOMProps, renderProps),
333
+ ref,
334
+ slot: props.slot || undefined,
335
+ 'data-selected': isSelected || undefined,
336
+ 'data-disabled': isDisabled || undefined,
337
+ 'data-readonly': isReadOnly || undefined,
338
+ 'data-invalid': isInvalid || undefined,
339
+ 'data-required': props.isRequired || undefined,
340
+ children: createElement(Provider, {
341
+ values: [
342
+ [ToggleStateContext, state],
343
+ [
344
+ InternalSwitchContext,
345
+ {
346
+ ...aria,
347
+ inputRef,
348
+ defaultClassName: 'react-aria-SwitchButton',
349
+ isRequired: props.isRequired,
350
+ },
351
+ ],
352
+ [
353
+ TextContext,
354
+ {
355
+ slots: {
356
+ description: descriptionProps,
357
+ errorMessage: errorMessageProps,
358
+ },
359
+ },
360
+ ],
361
+ [FieldErrorContext, { isInvalid, validationDetails, validationErrors }],
362
+ ] as any,
363
+ children: renderProps.children,
364
+ }),
365
+ });
366
+ }
367
+
368
+ /**
369
+ * A switch button is the clickable area of a switch, including the indicator and label.
370
+ */
371
+ export function SwitchButton(props: SwitchButtonProps): any {
372
+ const slot = S('SwitchButton');
373
+ let {
374
+ labelProps,
375
+ inputProps,
376
+ isSelected,
377
+ isDisabled,
378
+ isReadOnly,
379
+ isPressed,
380
+ isInvalid,
381
+ inputRef,
382
+ defaultClassName,
383
+ isRequired,
384
+ } = useContext(InternalSwitchContext)!;
385
+ let { isFocused, isFocusVisible, focusProps } = useFocusRing(
386
+ undefined,
387
+ subSlot(slot, 'focusRing'),
388
+ );
389
+ let isInteractionDisabled = isDisabled || isReadOnly;
390
+ let state = useContext(ToggleStateContext)!;
391
+
392
+ let { hoverProps, isHovered } = useHover(
393
+ {
394
+ ...props,
395
+ isDisabled: isInteractionDisabled,
396
+ },
397
+ subSlot(slot, 'hover'),
398
+ );
399
+
400
+ let renderProps = useRenderProps(
401
+ {
402
+ ...props,
403
+ defaultClassName,
404
+ values: {
405
+ isSelected,
406
+ isPressed,
407
+ isHovered,
408
+ isFocused,
409
+ isFocusVisible,
410
+ isDisabled,
411
+ isReadOnly,
412
+ isInvalid,
413
+ isRequired: isRequired || false,
414
+ state,
415
+ },
416
+ },
417
+ subSlot(slot, 'render'),
418
+ );
419
+
420
+ let DOMProps = filterDOMProps(props, { global: true });
421
+ delete DOMProps.id;
422
+ delete (DOMProps as any).onClick;
423
+
424
+ return createElement(
425
+ dom.label,
426
+ {
427
+ ...mergeProps(DOMProps, labelProps, hoverProps, renderProps),
428
+ ref: (props as any).ref,
429
+ slot: props.slot || undefined,
430
+ 'data-selected': isSelected || undefined,
431
+ 'data-pressed': isPressed || undefined,
432
+ 'data-hovered': isHovered || undefined,
433
+ 'data-focused': isFocused || undefined,
434
+ 'data-focus-visible': isFocusVisible || undefined,
435
+ 'data-disabled': isDisabled || undefined,
436
+ 'data-readonly': isReadOnly || undefined,
437
+ 'data-invalid': isInvalid || undefined,
438
+ 'data-required': isRequired || undefined,
439
+ },
440
+ createElement(VisuallyHidden, {
441
+ elementType: 'span',
442
+ children: createElement('input', {
443
+ ...mergeProps(inputProps, focusProps),
444
+ ref: inputRef,
445
+ }),
446
+ }),
447
+ renderProps.children,
448
+ );
449
+ }