react-aria-components 0.0.4 → 1.0.0-alpha.2

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 (91) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +12 -29
  3. package/dist/import.mjs +5223 -0
  4. package/dist/main.js +5345 -0
  5. package/dist/main.js.map +1 -0
  6. package/dist/module.js +5223 -0
  7. package/dist/module.js.map +1 -0
  8. package/dist/types.d.ts +1481 -0
  9. package/dist/types.d.ts.map +1 -0
  10. package/package.json +36 -44
  11. package/src/Breadcrumbs.tsx +90 -0
  12. package/src/Button.tsx +79 -0
  13. package/src/Calendar.tsx +471 -0
  14. package/src/Checkbox.tsx +240 -0
  15. package/src/Collection.tsx +787 -0
  16. package/src/ComboBox.tsx +129 -0
  17. package/src/DateField.tsx +244 -0
  18. package/src/DatePicker.tsx +178 -0
  19. package/src/Dialog.tsx +95 -0
  20. package/src/GridList.tsx +411 -0
  21. package/src/Group.tsx +69 -0
  22. package/src/Header.tsx +34 -0
  23. package/src/Heading.tsx +35 -0
  24. package/src/Input.tsx +73 -0
  25. package/src/Keyboard.tsx +24 -0
  26. package/src/Label.tsx +30 -0
  27. package/src/Link.tsx +98 -0
  28. package/src/ListBox.tsx +406 -0
  29. package/src/Menu.tsx +227 -0
  30. package/src/Meter.tsx +73 -0
  31. package/src/Modal.tsx +192 -0
  32. package/src/NumberField.tsx +79 -0
  33. package/src/OverlayArrow.tsx +70 -0
  34. package/src/Popover.tsx +125 -0
  35. package/src/ProgressBar.tsx +81 -0
  36. package/src/RadioGroup.tsx +219 -0
  37. package/src/SearchField.tsx +78 -0
  38. package/src/Select.tsx +180 -0
  39. package/src/Separator.tsx +53 -0
  40. package/src/Slider.tsx +217 -0
  41. package/src/Switch.tsx +127 -0
  42. package/src/Table.tsx +917 -0
  43. package/src/Tabs.tsx +282 -0
  44. package/src/Text.tsx +30 -0
  45. package/src/TextField.tsx +62 -0
  46. package/src/ToggleButton.tsx +59 -0
  47. package/src/Tooltip.tsx +135 -0
  48. package/src/index.ts +94 -0
  49. package/src/useDragAndDrop.tsx +172 -0
  50. package/src/utils.tsx +235 -0
  51. package/.babelrc +0 -17
  52. package/.eslintrc +0 -12
  53. package/src/accordion/accordion.css +0 -4
  54. package/src/accordion/accordion.js +0 -20
  55. package/src/accordion/index.js +0 -2
  56. package/src/accordion/section.css +0 -21
  57. package/src/accordion/section.js +0 -85
  58. package/src/examples/accordion-example.js +0 -73
  59. package/src/examples/example.js +0 -21
  60. package/src/examples/grid-cells/fancy-input-grid-cell.js +0 -206
  61. package/src/examples/grid-cells/input-grid-cell.js +0 -44
  62. package/src/examples/grid-example.css +0 -23
  63. package/src/examples/grid-example.js +0 -231
  64. package/src/examples/index.html +0 -10
  65. package/src/examples/index.js +0 -53
  66. package/src/examples/tabs-example.js +0 -52
  67. package/src/grid/column-header.css +0 -4
  68. package/src/grid/column-header.js +0 -29
  69. package/src/grid/grid-cell.css +0 -16
  70. package/src/grid/grid-cell.js +0 -104
  71. package/src/grid/grid-context.js +0 -3
  72. package/src/grid/grid.css +0 -4
  73. package/src/grid/grid.js +0 -110
  74. package/src/grid/index.js +0 -6
  75. package/src/grid/interactive-grid-cell.js +0 -96
  76. package/src/grid/row-headers.css +0 -6
  77. package/src/grid/row-headers.js +0 -22
  78. package/src/grid/row.css +0 -5
  79. package/src/grid/row.js +0 -21
  80. package/src/prop-types/ref.js +0 -3
  81. package/src/tabs/index.js +0 -4
  82. package/src/tabs/tab-list.css +0 -6
  83. package/src/tabs/tab-list.js +0 -103
  84. package/src/tabs/tab-panels.js +0 -35
  85. package/src/tabs/tab.css +0 -10
  86. package/src/tabs/tab.js +0 -45
  87. package/src/tabs/tabs.js +0 -52
  88. package/src/utils/debounce.js +0 -12
  89. package/src/utils/event-handlers-factory.js +0 -42
  90. package/src/utils/unique-id.js +0 -6
  91. package/webpack.config.js +0 -43
@@ -0,0 +1,411 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ import {AriaGridListProps, DraggableItemResult, DragPreviewRenderer, DropIndicatorAria, DroppableCollectionResult, FocusScope, ListKeyboardDelegate, mergeProps, useFocusRing, useGridList, useGridListItem, useGridListSelectionCheckbox, useHover, useVisuallyHidden, VisuallyHidden} from 'react-aria';
13
+ import {ButtonContext} from './Button';
14
+ import {CheckboxContext} from './Checkbox';
15
+ import {CollectionProps, ItemProps, useCachedChildren, useCollection} from './Collection';
16
+ import {ContextValue, defaultSlot, forwardRefType, Provider, SlotProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
17
+ import {DragAndDropHooks, DropIndicator, DropIndicatorContext, DropIndicatorProps} from './useDragAndDrop';
18
+ import {DraggableCollectionState, DroppableCollectionState, ListState, Node, SelectionBehavior, useListState} from 'react-stately';
19
+ import {filterDOMProps, isIOS, isWebKit, useObjectRef} from '@react-aria/utils';
20
+ import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes, ReactNode, RefObject, useContext, useEffect, useRef} from 'react';
21
+ import {TextContext} from './Text';
22
+
23
+ export interface GridListRenderProps {
24
+ /**
25
+ * Whether the list has no items and should display its empty state.
26
+ * @selector [data-empty]
27
+ */
28
+ isEmpty: boolean,
29
+ /**
30
+ * Whether the grid list is currently focused.
31
+ * @selector [data-focused]
32
+ */
33
+ isFocused: boolean,
34
+ /**
35
+ * Whether the grid list is currently keyboard focused.
36
+ * @selector [data-focus-visible]
37
+ */
38
+ isFocusVisible: boolean,
39
+ /**
40
+ * Whether the grid list is currently the active drop target.
41
+ * @selector [data-drop-target]
42
+ */
43
+ isDropTarget: boolean
44
+ }
45
+
46
+ export interface GridListProps<T> extends Omit<AriaGridListProps<T>, 'children'>, CollectionProps<T>, StyleRenderProps<GridListRenderProps>, SlotProps {
47
+ /** How multiple selection should behave in the collection. */
48
+ selectionBehavior?: SelectionBehavior,
49
+ /** The drag and drop hooks returned by `useDragAndDrop` used to enable drag and drop behavior for the GridList. */
50
+ dragAndDropHooks?: DragAndDropHooks,
51
+ /** Provides content to display when there are no items in the list. */
52
+ renderEmptyState?: () => ReactNode
53
+ }
54
+
55
+ interface InternalGridListContextValue {
56
+ state: ListState<unknown>,
57
+ dragAndDropHooks?: DragAndDropHooks,
58
+ dragState?: DraggableCollectionState,
59
+ dropState?: DroppableCollectionState
60
+ }
61
+
62
+ export const GridListContext = createContext<ContextValue<GridListProps<any>, HTMLDivElement>>(null);
63
+ const InternalGridListContext = createContext<InternalGridListContextValue | null>(null);
64
+
65
+ function GridList<T extends object>(props: GridListProps<T>, ref: ForwardedRef<HTMLDivElement>) {
66
+ [props, ref] = useContextProps(props, ref, GridListContext);
67
+ let {dragAndDropHooks} = props;
68
+ let {portal, collection} = useCollection(props);
69
+ let state = useListState({
70
+ ...props,
71
+ collection,
72
+ children: undefined
73
+ });
74
+
75
+ let {gridProps} = useGridList(props, state, ref);
76
+
77
+ let children = useCachedChildren({
78
+ items: collection,
79
+ children: (item: Node<T>) => {
80
+ switch (item.type) {
81
+ case 'item':
82
+ return <GridListItem item={item} />;
83
+ default:
84
+ throw new Error('Unsupported node type in GridList: ' + item.type);
85
+ }
86
+ }
87
+ });
88
+
89
+ let selectionManager = state.selectionManager;
90
+ let isListDraggable = !!dragAndDropHooks?.useDraggableCollectionState;
91
+ let isListDroppable = !!dragAndDropHooks?.useDroppableCollectionState;
92
+ let dragHooksProvided = useRef(isListDraggable);
93
+ let dropHooksProvided = useRef(isListDroppable);
94
+ if (dragHooksProvided.current !== isListDraggable) {
95
+ console.warn('Drag hooks were provided during one render, but not another. This should be avoided as it may produce unexpected behavior.');
96
+ }
97
+ if (dropHooksProvided.current !== isListDroppable) {
98
+ console.warn('Drop hooks were provided during one render, but not another. This should be avoided as it may produce unexpected behavior.');
99
+ }
100
+
101
+ let dragState: DraggableCollectionState | undefined = undefined;
102
+ let dropState: DroppableCollectionState | undefined = undefined;
103
+ let droppableCollection: DroppableCollectionResult | undefined = undefined;
104
+ let isRootDropTarget = false;
105
+ let dragPreview: JSX.Element | null = null;
106
+ let preview = useRef<DragPreviewRenderer>(null);
107
+
108
+ if (isListDraggable && dragAndDropHooks) {
109
+ dragState = dragAndDropHooks.useDraggableCollectionState!({
110
+ collection,
111
+ selectionManager,
112
+ preview: dragAndDropHooks.renderDragPreview ? preview : undefined
113
+ });
114
+ dragAndDropHooks.useDraggableCollection!({}, dragState, ref);
115
+
116
+ let DragPreview = dragAndDropHooks.DragPreview!;
117
+ dragPreview = dragAndDropHooks.renderDragPreview
118
+ ? <DragPreview ref={preview}>{dragAndDropHooks.renderDragPreview}</DragPreview>
119
+ : null;
120
+ }
121
+
122
+ if (isListDroppable && dragAndDropHooks) {
123
+ dropState = dragAndDropHooks.useDroppableCollectionState!({
124
+ collection,
125
+ selectionManager
126
+ });
127
+
128
+ let keyboardDelegate = new ListKeyboardDelegate(
129
+ collection,
130
+ selectionManager.disabledBehavior === 'selection' ? new Set() : selectionManager.disabledKeys,
131
+ ref
132
+ );
133
+ let dropTargetDelegate = dragAndDropHooks.dropTargetDelegate || new dragAndDropHooks.ListDropTargetDelegate(collection, ref);
134
+ droppableCollection = dragAndDropHooks.useDroppableCollection!({
135
+ keyboardDelegate,
136
+ dropTargetDelegate
137
+ }, dropState, ref);
138
+
139
+ isRootDropTarget = dropState.isDropTarget({type: 'root'});
140
+ }
141
+
142
+ let {focusProps, isFocused, isFocusVisible} = useFocusRing();
143
+ let renderProps = useRenderProps({
144
+ className: props.className,
145
+ style: props.style,
146
+ defaultClassName: 'react-aria-GridList',
147
+ values: {
148
+ isDropTarget: isRootDropTarget,
149
+ isEmpty: state.collection.size === 0,
150
+ isFocused,
151
+ isFocusVisible
152
+ }
153
+ });
154
+
155
+ let emptyState: ReactNode = null;
156
+ let emptyStatePropOverrides: HTMLAttributes<HTMLElement> | null = null;
157
+ if (state.collection.size === 0 && props.renderEmptyState) {
158
+ // Ideally we'd use `display: contents` on the row and cell elements so that
159
+ // they don't affect the layout of the children. However, WebKit currently has
160
+ // a bug that makes grid elements with display: contents hidden to screen readers.
161
+ // https://bugs.webkit.org/show_bug.cgi?id=239479
162
+ let content = props.renderEmptyState();
163
+ if (isWebKit()) {
164
+ // For now, when in an empty state, swap the role to group in webkit.
165
+ emptyStatePropOverrides = {
166
+ role: 'group',
167
+ 'aria-multiselectable': undefined
168
+ };
169
+
170
+ if (isIOS()) {
171
+ // iOS VoiceOver also doesn't announce the aria-label of group elements
172
+ // so try to add a visually hidden label element as well.
173
+ emptyState = (
174
+ <>
175
+ <VisuallyHidden>{gridProps['aria-label']}</VisuallyHidden>
176
+ {content}
177
+ </>
178
+ );
179
+ } else {
180
+ emptyState = content;
181
+ }
182
+ } else {
183
+ emptyState = (
184
+ <div role="row" style={{display: 'contents'}}>
185
+ <div role="gridcell" style={{display: 'contents'}}>
186
+ {content}
187
+ </div>
188
+ </div>
189
+ );
190
+ }
191
+ }
192
+
193
+ return (
194
+ <FocusScope>
195
+ <div
196
+ {...filterDOMProps(props)}
197
+ {...renderProps}
198
+ {...mergeProps(gridProps, focusProps, droppableCollection?.collectionProps, emptyStatePropOverrides)}
199
+ ref={ref}
200
+ slot={props.slot}
201
+ data-drop-target={isRootDropTarget || undefined}
202
+ data-empty={state.collection.size === 0 || undefined}
203
+ data-focused={isFocused || undefined}
204
+ data-focus-visible={isFocusVisible || undefined}>
205
+ <Provider
206
+ values={[
207
+ [InternalGridListContext, {state, dragAndDropHooks, dragState, dropState}],
208
+ [DropIndicatorContext, {render: GridListDropIndicator}]
209
+ ]}>
210
+ {isListDroppable && <RootDropIndicator />}
211
+ {children}
212
+ </Provider>
213
+ {emptyState}
214
+ {dragPreview}
215
+ {portal}
216
+ </div>
217
+ </FocusScope>
218
+ );
219
+ }
220
+
221
+ /**
222
+ * A grid list displays a list of interactive items, with support for keyboard navigation,
223
+ * single or multiple selection, and row actions.
224
+ */
225
+ const _GridList = (forwardRef as forwardRefType)(GridList);
226
+ export {_GridList as GridList};
227
+
228
+ function GridListItem({item}) {
229
+ let {state, dragAndDropHooks, dragState, dropState} = useContext(InternalGridListContext)!;
230
+ let ref = React.useRef<HTMLDivElement>(null);
231
+ let {rowProps, gridCellProps, descriptionProps, ...states} = useGridListItem(
232
+ {
233
+ node: item,
234
+ shouldSelectOnPressUp: !!dragState
235
+ },
236
+ state,
237
+ ref
238
+ );
239
+
240
+ let {hoverProps, isHovered} = useHover({
241
+ isDisabled: !states.allowsSelection && !states.hasAction
242
+ });
243
+
244
+ let {isFocusVisible, focusProps} = useFocusRing();
245
+ let {checkboxProps} = useGridListSelectionCheckbox(
246
+ {key: item.key},
247
+ state
248
+ );
249
+
250
+ let draggableItem: DraggableItemResult | null = null;
251
+ if (dragState && dragAndDropHooks) {
252
+ draggableItem = dragAndDropHooks.useDraggableItem!({key: item.key, hasDragButton: true}, dragState);
253
+ }
254
+
255
+ let dropIndicator: DropIndicatorAria | null = null;
256
+ let dropIndicatorRef = useRef<HTMLDivElement>(null);
257
+ let {visuallyHiddenProps} = useVisuallyHidden();
258
+ if (dropState && dragAndDropHooks) {
259
+ dropIndicator = dragAndDropHooks.useDropIndicator!({
260
+ target: {type: 'item', key: item.key, dropPosition: 'on'}
261
+ }, dropState, dropIndicatorRef);
262
+ }
263
+
264
+ let props: ItemProps<unknown> = item.props;
265
+ let isDragging = dragState && dragState.isDragging(item.key);
266
+ let renderProps = useRenderProps({
267
+ ...props,
268
+ id: undefined,
269
+ children: item.rendered,
270
+ defaultClassName: 'react-aria-Item',
271
+ values: {
272
+ ...states,
273
+ isHovered,
274
+ isFocusVisible,
275
+ selectionMode: state.selectionManager.selectionMode,
276
+ selectionBehavior: state.selectionManager.selectionBehavior,
277
+ allowsDragging: !!dragState,
278
+ isDragging,
279
+ isDropTarget: dropIndicator?.isDropTarget
280
+ }
281
+ });
282
+
283
+ let renderDropIndicator = dragAndDropHooks?.renderDropIndicator || (target => <DropIndicator target={target} />);
284
+ let dragButtonRef = useRef<HTMLButtonElement>(null);
285
+ useEffect(() => {
286
+ if (dragState && !dragButtonRef.current) {
287
+ console.warn('Draggable items in a GridList must contain a <Button slot="drag"> element so that keyboard and screen reader users can drag them.');
288
+ }
289
+ // eslint-disable-next-line
290
+ }, []);
291
+
292
+ useEffect(() => {
293
+ if (!item.textValue) {
294
+ console.warn('A `textValue` prop is required for <Item> elements with non-plain text children in order to support accessibility features such as type to select.');
295
+ }
296
+ }, [item.textValue]);
297
+
298
+ return (
299
+ <>
300
+ {dragAndDropHooks?.useDropIndicator &&
301
+ renderDropIndicator({type: 'item', key: item.key, dropPosition: 'before'})
302
+ }
303
+ {dropIndicator && !dropIndicator.isHidden &&
304
+ <div role="row" style={{position: 'absolute'}}>
305
+ <div role="gridcell">
306
+ <div role="button" {...visuallyHiddenProps} {...dropIndicator?.dropIndicatorProps} ref={dropIndicatorRef} />
307
+ </div>
308
+ </div>
309
+ }
310
+ <div
311
+ {...mergeProps(rowProps, focusProps, hoverProps, draggableItem?.dragProps)}
312
+ {...renderProps}
313
+ ref={ref}
314
+ data-hovered={isHovered || undefined}
315
+ data-focused={states.isFocused || undefined}
316
+ data-focus-visible={isFocusVisible || undefined}
317
+ data-pressed={states.isPressed || undefined}
318
+ data-dragging={isDragging || undefined}
319
+ data-drop-target={dropIndicator?.isDropTarget || undefined}>
320
+ <div {...gridCellProps}>
321
+ <Provider
322
+ values={[
323
+ [CheckboxContext, checkboxProps],
324
+ [ButtonContext, {
325
+ slots: {
326
+ [defaultSlot]: {},
327
+ drag: {
328
+ ...draggableItem?.dragButtonProps,
329
+ ref: dragButtonRef,
330
+ style: {
331
+ pointerEvents: 'none'
332
+ }
333
+ }
334
+ }
335
+ }],
336
+ [TextContext, {
337
+ slots: {
338
+ description: descriptionProps
339
+ }
340
+ }]
341
+ ]}>
342
+ {renderProps.children}
343
+ </Provider>
344
+ </div>
345
+ </div>
346
+ {dragAndDropHooks?.useDropIndicator && state.collection.getKeyAfter(item.key) == null &&
347
+ renderDropIndicator({type: 'item', key: item.key, dropPosition: 'after'})
348
+ }
349
+ </>
350
+ );
351
+ }
352
+
353
+ function GridListDropIndicator(props: DropIndicatorProps, ref: ForwardedRef<HTMLElement>) {
354
+ ref = useObjectRef(ref);
355
+ let {dragAndDropHooks, dropState} = useContext(InternalGridListContext)!;
356
+ let buttonRef = useRef<HTMLDivElement>(null);
357
+ let {dropIndicatorProps, isHidden, isDropTarget} = dragAndDropHooks!.useDropIndicator!(
358
+ props,
359
+ dropState!,
360
+ buttonRef
361
+ );
362
+
363
+ let {visuallyHiddenProps} = useVisuallyHidden();
364
+
365
+ if (isHidden) {
366
+ return null;
367
+ }
368
+
369
+ // eslint-disable-next-line react-hooks/rules-of-hooks
370
+ let renderProps = useRenderProps({
371
+ ...props,
372
+ defaultClassName: 'react-aria-DropIndicator',
373
+ values: {
374
+ isDropTarget
375
+ }
376
+ });
377
+
378
+ return (
379
+ <div
380
+ {...renderProps}
381
+ role="row"
382
+ ref={ref as RefObject<HTMLDivElement>}
383
+ data-drop-target={isDropTarget || undefined}>
384
+ <div role="gridcell">
385
+ <div {...visuallyHiddenProps} role="button" {...dropIndicatorProps} ref={buttonRef} />
386
+ </div>
387
+ </div>
388
+ );
389
+ }
390
+
391
+ function RootDropIndicator() {
392
+ let {dragAndDropHooks, dropState} = useContext(InternalGridListContext)!;
393
+ let ref = useRef<HTMLDivElement>(null);
394
+ let {dropIndicatorProps} = dragAndDropHooks!.useDropIndicator!({
395
+ target: {type: 'root'}
396
+ }, dropState!, ref);
397
+ let isDropTarget = dropState!.isDropTarget({type: 'root'});
398
+ let {visuallyHiddenProps} = useVisuallyHidden();
399
+
400
+ if (!isDropTarget && dropIndicatorProps['aria-hidden']) {
401
+ return null;
402
+ }
403
+
404
+ return (
405
+ <div role="row" aria-hidden={dropIndicatorProps['aria-hidden']} style={{position: 'absolute'}}>
406
+ <div role="gridcell">
407
+ <div role="button" {...visuallyHiddenProps} {...dropIndicatorProps} ref={ref} />
408
+ </div>
409
+ </div>
410
+ );
411
+ }
package/src/Group.tsx ADDED
@@ -0,0 +1,69 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {ContextValue, StyleRenderProps, useContextProps, useRenderProps} from './utils';
14
+ import {mergeProps, useFocusRing, useHover} from 'react-aria';
15
+ import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes} from 'react';
16
+
17
+ export interface GroupRenderProps {
18
+ /**
19
+ * Whether the group is currently hovered with a mouse.
20
+ * @selector [data-hovered]
21
+ */
22
+ isHovered: boolean,
23
+ /**
24
+ * Whether an element within the group is focused, either via a mouse or keyboard.
25
+ * @selector :focus-within
26
+ */
27
+ isFocusWithin: boolean,
28
+ /**
29
+ * Whether an element within the group is keyboard focused.
30
+ * @selector [data-focus-visible]
31
+ */
32
+ isFocusVisible: boolean
33
+ }
34
+
35
+ export interface GroupProps extends Omit<HTMLAttributes<HTMLElement>, 'className' | 'style'>, StyleRenderProps<GroupRenderProps> {}
36
+
37
+ export const GroupContext = createContext<ContextValue<GroupProps, HTMLDivElement>>({});
38
+
39
+ function Group(props: GroupProps, ref: ForwardedRef<HTMLDivElement>) {
40
+ [props, ref] = useContextProps(props, ref, GroupContext);
41
+
42
+ let {hoverProps, isHovered} = useHover({});
43
+ let {isFocused, isFocusVisible, focusProps} = useFocusRing({
44
+ within: true
45
+ });
46
+
47
+ let renderProps = useRenderProps({
48
+ ...props,
49
+ values: {isHovered, isFocusWithin: isFocused, isFocusVisible},
50
+ defaultClassName: 'react-aria-Group'
51
+ });
52
+
53
+ return (
54
+ <div
55
+ {...mergeProps(props, focusProps, hoverProps)}
56
+ {...renderProps}
57
+ ref={ref}
58
+ data-hovered={isHovered || undefined}
59
+ data-focus-visible={isFocusVisible || undefined}>
60
+ {props.children}
61
+ </div>
62
+ );
63
+ }
64
+
65
+ /**
66
+ * An group represents a set of related UI controls.
67
+ */
68
+ const _Group = forwardRef(Group);
69
+ export {_Group as Group};
package/src/Header.tsx ADDED
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {ContextValue, useContextProps} from './utils';
14
+ import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes} from 'react';
15
+ import {useShallowRender} from './Collection';
16
+
17
+ export const HeaderContext = createContext<ContextValue<HTMLAttributes<HTMLElement>, HTMLElement>>({});
18
+
19
+ function Header(props: HTMLAttributes<HTMLElement>, ref: ForwardedRef<HTMLElement>) {
20
+ [props, ref] = useContextProps(props, ref, HeaderContext);
21
+ let shallow = useShallowRender('header', props, ref);
22
+ if (shallow) {
23
+ return shallow;
24
+ }
25
+
26
+ return (
27
+ <header className="react-aria-Header" {...props} ref={ref}>
28
+ {props.children}
29
+ </header>
30
+ );
31
+ }
32
+
33
+ const _Header = forwardRef(Header);
34
+ export {_Header as Header};
@@ -0,0 +1,35 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {ContextValue, useContextProps} from './utils';
14
+ import React, {createContext, ElementType, ForwardedRef, forwardRef, HTMLAttributes} from 'react';
15
+
16
+ export interface HeadingProps extends HTMLAttributes<HTMLElement> {
17
+ level?: number
18
+ }
19
+
20
+ export const HeadingContext = createContext<ContextValue<HeadingProps, HTMLHeadingElement>>({});
21
+
22
+ function Heading(props: HeadingProps, ref: ForwardedRef<HTMLHeadingElement>) {
23
+ [props, ref] = useContextProps(props, ref, HeadingContext);
24
+ let {children, level = 3, className, ...domProps} = props;
25
+ let Element = `h${level}` as ElementType;
26
+
27
+ return (
28
+ <Element {...domProps} className={className ?? 'react-aria-Heading'}>
29
+ {children}
30
+ </Element>
31
+ );
32
+ }
33
+
34
+ const _Heading = forwardRef(Heading);
35
+ export {_Heading as Heading};
package/src/Input.tsx ADDED
@@ -0,0 +1,73 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {ContextValue, StyleRenderProps, useContextProps, useRenderProps} from './utils';
14
+ import {mergeProps, useFocusRing, useHover} from 'react-aria';
15
+ import React, {createContext, ForwardedRef, forwardRef, InputHTMLAttributes} from 'react';
16
+
17
+ export interface InputRenderProps {
18
+ /**
19
+ * Whether the input is currently hovered with a mouse.
20
+ * @selector [data-hovered]
21
+ */
22
+ isHovered: boolean,
23
+ /**
24
+ * Whether the input is focused, either via a mouse or keyboard.
25
+ * @selector :focus
26
+ */
27
+ isFocused: boolean,
28
+ /**
29
+ * Whether the input is keyboard focused.
30
+ * @selector [data-focus-visible]
31
+ */
32
+ isFocusVisible: boolean,
33
+ /**
34
+ * Whether the input is disabled.
35
+ * @selector :disabled
36
+ */
37
+ isDisabled: boolean
38
+ }
39
+
40
+ export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'className' | 'style'>, StyleRenderProps<InputRenderProps> {}
41
+
42
+ export const InputContext = createContext<ContextValue<InputProps, HTMLInputElement>>({});
43
+
44
+ function Input(props: InputProps, ref: ForwardedRef<HTMLInputElement>) {
45
+ [props, ref] = useContextProps(props, ref, InputContext);
46
+
47
+ let {hoverProps, isHovered} = useHover({});
48
+ let {isFocused, isFocusVisible, focusProps} = useFocusRing({
49
+ isTextInput: true,
50
+ autoFocus: props.autoFocus
51
+ });
52
+
53
+ let renderProps = useRenderProps({
54
+ ...props,
55
+ values: {isHovered, isFocused, isFocusVisible, isDisabled: props.disabled || false},
56
+ defaultClassName: 'react-aria-Input'
57
+ });
58
+
59
+ return (
60
+ <input
61
+ {...mergeProps(props, focusProps, hoverProps)}
62
+ {...renderProps}
63
+ ref={ref}
64
+ data-hovered={isHovered || undefined}
65
+ data-focus-visible={isFocusVisible || undefined} />
66
+ );
67
+ }
68
+
69
+ /**
70
+ * An input allows a user to input text.
71
+ */
72
+ const _Input = forwardRef(Input);
73
+ export {_Input as Input};
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {ContextValue, useContextProps} from './utils';
14
+ import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes} from 'react';
15
+
16
+ export const KeyboardContext = createContext<ContextValue<HTMLAttributes<HTMLElement>, HTMLElement>>({});
17
+
18
+ function Keyboard(props: HTMLAttributes<HTMLElement>, ref: ForwardedRef<HTMLElement>) {
19
+ [props, ref] = useContextProps(props, ref, KeyboardContext);
20
+ return <kbd dir="ltr" {...props} ref={ref} />;
21
+ }
22
+
23
+ const _Keyboard = forwardRef(Keyboard);
24
+ export {_Keyboard as Keyboard};
package/src/Label.tsx ADDED
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {ContextValue, useContextProps} from './utils';
14
+ import React, {createContext, ForwardedRef, forwardRef, LabelHTMLAttributes} from 'react';
15
+
16
+ export interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
17
+ elementType?: string
18
+ }
19
+
20
+ export const LabelContext = createContext<ContextValue<LabelProps, HTMLLabelElement>>({});
21
+
22
+ function Label(props: LabelProps, ref: ForwardedRef<HTMLLabelElement>) {
23
+ [props, ref] = useContextProps(props, ref, LabelContext);
24
+ let {elementType: ElementType = 'label', ...labelProps} = props;
25
+ // @ts-ignore
26
+ return <ElementType className="react-aria-Label" {...labelProps} ref={ref} />;
27
+ }
28
+
29
+ const _Label = forwardRef(Label);
30
+ export {_Label as Label};