@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,301 @@
1
+ // Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/Collection.tsx).
2
+ // octane adaptations: the collection engine lives at `../collections/*` (the
3
+ // detached-real-DOM host — see src/collections/Document.ts); `.tsx` → `.ts`
4
+ // (JSX → createElement), no forwardRef (octane refs are props), React element
5
+ // types → `any`, S()/subSlot slot conventions. The public `Collection`
6
+ // component + its `CollectionProps` live in the engine (upstream: exported
7
+ // from `react-aria/Collection`); they are re-exported here for the package
8
+ // index, matching the upstream RAC index wiring. Note upstream's RAC-local
9
+ // `CollectionProps` interface (a different type, used internally by collection
10
+ // components) is NOT exported from the RAC index — it stays module-local here
11
+ // as `ItemCollectionProps` consumers import from this module directly.
12
+ import type {
13
+ Collection as ICollection,
14
+ CollectionBase,
15
+ DropTargetDelegate,
16
+ GlobalDOMAttributes,
17
+ ItemDropTarget,
18
+ Key,
19
+ LayoutDelegate,
20
+ Node,
21
+ RefObject,
22
+ SelectionBehavior,
23
+ SelectionMode,
24
+ SectionProps as SharedSectionProps,
25
+ } from '@react-types/shared';
26
+ import {
27
+ Fragment,
28
+ cloneElement,
29
+ createContext,
30
+ createElement,
31
+ isValidElement,
32
+ useContext,
33
+ useMemo,
34
+ } from 'octane';
35
+ import { createBranchComponent } from '../collections/CollectionBuilder';
36
+ import { useCachedChildren } from '../collections/useCachedChildren';
37
+
38
+ import type { StyleProps } from './utils';
39
+
40
+ import { S, splitSlot, subSlot } from '../internal';
41
+
42
+ // Re-export the engine's public Collection component + props, as the upstream
43
+ // RAC index does (`export {Collection} from 'react-aria/Collection'`).
44
+ export { Collection } from '../collections/CollectionBuilder';
45
+ export type { CollectionProps } from '../collections/CollectionBuilder';
46
+
47
+ /**
48
+ * The RAC-local collection props shape (upstream `CollectionProps` in
49
+ * react-aria-components/src/Collection.tsx — renamed to avoid clashing with
50
+ * the engine's exported `CollectionProps`).
51
+ */
52
+ export interface ItemCollectionProps<T> extends Omit<CollectionBase<T>, 'children'> {
53
+ /** The contents of the collection. */
54
+ children?: any | ((item: T) => any);
55
+ /** Values that should invalidate the item cache when using dynamic collections. */
56
+ dependencies?: ReadonlyArray<any>;
57
+ }
58
+
59
+ export interface ItemRenderProps {
60
+ /**
61
+ * Whether the item is currently hovered with a mouse.
62
+ * @selector [data-hovered]
63
+ */
64
+ isHovered: boolean;
65
+ /**
66
+ * Whether the item is currently in a pressed state.
67
+ * @selector [data-pressed]
68
+ */
69
+ isPressed: boolean;
70
+ /**
71
+ * Whether the item is currently selected.
72
+ * @selector [data-selected]
73
+ */
74
+ isSelected: boolean;
75
+ /**
76
+ * Whether the item is currently focused.
77
+ * @selector [data-focused]
78
+ */
79
+ isFocused: boolean;
80
+ /**
81
+ * Whether the item is currently keyboard focused.
82
+ * @selector [data-focus-visible]
83
+ */
84
+ isFocusVisible: boolean;
85
+ /**
86
+ * Whether the item is non-interactive, i.e. both selection and actions are disabled and the item
87
+ * may not be focused. Dependent on `disabledKeys` and `disabledBehavior`.
88
+ * @selector [data-disabled]
89
+ */
90
+ isDisabled: boolean;
91
+ /**
92
+ * The type of selection that is allowed in the collection.
93
+ * @selector [data-selection-mode="single | multiple"]
94
+ */
95
+ selectionMode: SelectionMode;
96
+ /** The selection behavior for the collection. */
97
+ selectionBehavior: SelectionBehavior;
98
+ /**
99
+ * Whether the item allows dragging.
100
+ * @note This property is only available in collection components that support drag and drop.
101
+ * @selector [data-allows-dragging]
102
+ */
103
+ allowsDragging?: boolean;
104
+ /**
105
+ * Whether the item is currently being dragged.
106
+ * @note This property is only available in collection components that support drag and drop.
107
+ * @selector [data-dragging]
108
+ */
109
+ isDragging?: boolean;
110
+ /**
111
+ * Whether the item is currently an active drop target.
112
+ * @note This property is only available in collection components that support drag and drop.
113
+ * @selector [data-drop-target]
114
+ */
115
+ isDropTarget?: boolean;
116
+ }
117
+
118
+ export interface SectionProps<T>
119
+ extends
120
+ Omit<SharedSectionProps<T>, 'children' | 'title'>,
121
+ StyleProps,
122
+ GlobalDOMAttributes<HTMLElement> {
123
+ /** The unique id of the section. */
124
+ id?: Key;
125
+ /**
126
+ * The object value that this section represents. When using dynamic collections, this is set
127
+ * automatically.
128
+ */
129
+ value?: T;
130
+ /** Static child items or a function to render children. */
131
+ children?: any | ((item: T) => any);
132
+ /** Values that should invalidate the item cache when using dynamic collections. */
133
+ dependencies?: ReadonlyArray<any>;
134
+ }
135
+
136
+ interface SectionContextValue {
137
+ name: string;
138
+ render: (props: SectionProps<any>, ref: any, section: Node<any>, className?: string) => any;
139
+ }
140
+
141
+ export const SectionContext = createContext<SectionContextValue | null>(null);
142
+
143
+ /** @deprecated */
144
+ export const Section = /*#__PURE__*/ createBranchComponent(
145
+ 'section',
146
+ <T>(props: SectionProps<T>, ref: any, section: Node<T>): any => {
147
+ let { name, render } = useContext(SectionContext)!;
148
+ if (process.env.NODE_ENV !== 'production') {
149
+ console.warn(`<Section> is deprecated. Please use <${name}> instead.`);
150
+ }
151
+ return render(props, ref, section, 'react-aria-Section');
152
+ },
153
+ );
154
+
155
+ export interface CollectionBranchProps {
156
+ /** The collection of items to render. */
157
+ collection: ICollection<Node<unknown>>;
158
+ /** The parent node of the items to render. */
159
+ parent: Node<unknown>;
160
+ /** A function that renders a drop indicator between items. */
161
+ renderDropIndicator?: (target: ItemDropTarget) => any;
162
+ }
163
+
164
+ export interface CollectionRootProps {
165
+ /** The collection of items to render. */
166
+ collection: ICollection<Node<unknown>>;
167
+ /** A set of keys for items that should always be persisted in the DOM. */
168
+ persistedKeys?: Set<Key> | null;
169
+ /** A ref to the scroll container for the collection. */
170
+ scrollRef?: RefObject<HTMLElement | null>;
171
+ /** A function that renders a drop indicator between items. */
172
+ renderDropIndicator?: (target: ItemDropTarget) => any;
173
+ [key: string]: any;
174
+ }
175
+
176
+ export interface CollectionRenderer {
177
+ /** Whether this is a virtualized collection. */
178
+ isVirtualized?: boolean;
179
+ /** A delegate object that provides layout information for items in the collection. */
180
+ layoutDelegate?: LayoutDelegate;
181
+ /** A delegate object that provides drop targets for pointer coordinates within the collection. */
182
+ dropTargetDelegate?: DropTargetDelegate;
183
+ /** A component that renders the root collection items. */
184
+ CollectionRoot: (props: CollectionRootProps) => any;
185
+ /** A component that renders the child collection items. */
186
+ CollectionBranch: (props: CollectionBranchProps) => any;
187
+ }
188
+
189
+ export const DefaultCollectionRenderer: CollectionRenderer = {
190
+ CollectionRoot({ collection, renderDropIndicator }) {
191
+ const slot = S('DefaultCollectionRoot');
192
+ return useCollectionRender(collection, null, renderDropIndicator, subSlot(slot, 'render'));
193
+ },
194
+ CollectionBranch({ collection, parent, renderDropIndicator }) {
195
+ const slot = S('DefaultCollectionBranch');
196
+ return useCollectionRender(collection, parent, renderDropIndicator, subSlot(slot, 'render'));
197
+ },
198
+ };
199
+
200
+ function useCollectionRender(
201
+ collection: ICollection<Node<unknown>>,
202
+ parent: Node<unknown> | null,
203
+ renderDropIndicator: ((target: ItemDropTarget) => any) | undefined,
204
+ slot: symbol | undefined,
205
+ ): any {
206
+ return useCachedChildren(
207
+ {
208
+ items: parent ? collection.getChildren!(parent.key) : collection,
209
+ dependencies: [renderDropIndicator],
210
+ children(node: Node<unknown>) {
211
+ // Return an empty fragment since we don't want to render the content twice.
212
+ // If we don't skip the content node here, we end up rendering it twice in a
213
+ // Tree since we also render the content node in TreeItem.
214
+ if (node.type === 'content') {
215
+ return createElement(Fragment, null);
216
+ }
217
+
218
+ let rendered = node.render!(node);
219
+ if (!renderDropIndicator || node.type !== 'item') {
220
+ return rendered;
221
+ }
222
+
223
+ return createElement(
224
+ Fragment,
225
+ null,
226
+ renderDropIndicator({ type: 'item', key: node.key, dropPosition: 'before' }),
227
+ rendered,
228
+ renderAfterDropIndicators(collection, node, renderDropIndicator),
229
+ );
230
+ },
231
+ },
232
+ slot,
233
+ );
234
+ }
235
+
236
+ export function renderAfterDropIndicators(
237
+ collection: ICollection<Node<unknown>>,
238
+ node: Node<unknown>,
239
+ renderDropIndicator: (target: ItemDropTarget) => any,
240
+ ): any {
241
+ let key = node.key;
242
+ let keyAfter = collection.getKeyAfter(key);
243
+ let nextItemInFlattenedCollection = keyAfter != null ? collection.getItem(keyAfter) : null;
244
+ while (nextItemInFlattenedCollection != null && nextItemInFlattenedCollection.type !== 'item') {
245
+ keyAfter = collection.getKeyAfter(nextItemInFlattenedCollection.key);
246
+ nextItemInFlattenedCollection = keyAfter != null ? collection.getItem(keyAfter) : null;
247
+ }
248
+
249
+ let nextItemInSameLevel = node.nextKey != null ? collection.getItem(node.nextKey) : null;
250
+ while (nextItemInSameLevel != null && nextItemInSameLevel.type !== 'item') {
251
+ nextItemInSameLevel =
252
+ nextItemInSameLevel.nextKey != null ? collection.getItem(nextItemInSameLevel.nextKey) : null;
253
+ }
254
+
255
+ // Render one or more "after" drop indicators when the next item in the flattened collection
256
+ // has a smaller level, is not an item, or there are no more items in the collection.
257
+ // Otherwise, the "after" position is equivalent to the next item's "before" position.
258
+ let afterIndicators: any[] = [];
259
+ if (nextItemInSameLevel == null) {
260
+ let current: Node<unknown> | null = node;
261
+ while (
262
+ current?.type === 'item' &&
263
+ (!nextItemInFlattenedCollection ||
264
+ (current.parentKey !== nextItemInFlattenedCollection.parentKey &&
265
+ nextItemInFlattenedCollection.level < current.level))
266
+ ) {
267
+ let indicator = renderDropIndicator({
268
+ type: 'item',
269
+ key: current.key,
270
+ dropPosition: 'after',
271
+ });
272
+ if (isValidElement(indicator)) {
273
+ afterIndicators.push(cloneElement(indicator, { key: `${current.key}-after` }));
274
+ }
275
+ current = current.parentKey != null ? collection.getItem(current.parentKey) : null;
276
+ }
277
+ }
278
+
279
+ return afterIndicators;
280
+ }
281
+
282
+ export const CollectionRendererContext =
283
+ createContext<CollectionRenderer>(DefaultCollectionRenderer);
284
+
285
+ type PersistedKeysReturnValue = Set<Key> | null;
286
+ export function usePersistedKeys(focusedKey: Key | null): PersistedKeysReturnValue;
287
+ // Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
288
+ export function usePersistedKeys(
289
+ focusedKey: Key | null,
290
+ slot: symbol | undefined,
291
+ ): PersistedKeysReturnValue;
292
+ export function usePersistedKeys(...args: any[]): PersistedKeysReturnValue {
293
+ const [user, slotArg] = splitSlot(args);
294
+ const slot = slotArg ?? S('usePersistedKeys');
295
+ const focusedKey = user[0] as Key | null;
296
+ return useMemo(
297
+ () => (focusedKey != null ? new Set([focusedKey]) : null),
298
+ [focusedKey],
299
+ subSlot(slot, 'keys'),
300
+ );
301
+ }