react-aria-components 1.10.1 → 1.11.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.
- package/dist/Breadcrumbs.main.js +9 -2
- package/dist/Breadcrumbs.main.js.map +1 -1
- package/dist/Breadcrumbs.mjs +10 -3
- package/dist/Breadcrumbs.module.js +10 -3
- package/dist/Breadcrumbs.module.js.map +1 -1
- package/dist/Button.main.js +7 -17
- package/dist/Button.main.js.map +1 -1
- package/dist/Button.mjs +7 -17
- package/dist/Button.module.js +7 -17
- package/dist/Button.module.js.map +1 -1
- package/dist/Calendar.main.js +36 -14
- package/dist/Calendar.main.js.map +1 -1
- package/dist/Calendar.mjs +38 -16
- package/dist/Calendar.module.js +38 -16
- package/dist/Calendar.module.js.map +1 -1
- package/dist/Checkbox.main.js +8 -3
- package/dist/Checkbox.main.js.map +1 -1
- package/dist/Checkbox.mjs +10 -5
- package/dist/Checkbox.module.js +10 -5
- package/dist/Checkbox.module.js.map +1 -1
- package/dist/Collection.main.js.map +1 -1
- package/dist/Collection.module.js.map +1 -1
- package/dist/ColorArea.main.js +4 -4
- package/dist/ColorArea.main.js.map +1 -1
- package/dist/ColorArea.mjs +5 -5
- package/dist/ColorArea.module.js +5 -5
- package/dist/ColorArea.module.js.map +1 -1
- package/dist/ColorField.main.js +14 -1
- package/dist/ColorField.main.js.map +1 -1
- package/dist/ColorField.mjs +14 -1
- package/dist/ColorField.module.js +14 -1
- package/dist/ColorField.module.js.map +1 -1
- package/dist/ColorSlider.main.js +3 -1
- package/dist/ColorSlider.main.js.map +1 -1
- package/dist/ColorSlider.mjs +3 -1
- package/dist/ColorSlider.module.js +3 -1
- package/dist/ColorSlider.module.js.map +1 -1
- package/dist/ColorSwatch.main.js +6 -2
- package/dist/ColorSwatch.main.js.map +1 -1
- package/dist/ColorSwatch.mjs +6 -2
- package/dist/ColorSwatch.module.js +6 -2
- package/dist/ColorSwatch.module.js.map +1 -1
- package/dist/ColorSwatchPicker.main.js.map +1 -1
- package/dist/ColorSwatchPicker.module.js.map +1 -1
- package/dist/ColorThumb.main.js +3 -1
- package/dist/ColorThumb.main.js.map +1 -1
- package/dist/ColorThumb.mjs +3 -1
- package/dist/ColorThumb.module.js +3 -1
- package/dist/ColorThumb.module.js.map +1 -1
- package/dist/ColorWheel.main.js +3 -1
- package/dist/ColorWheel.main.js.map +1 -1
- package/dist/ColorWheel.mjs +3 -1
- package/dist/ColorWheel.module.js +3 -1
- package/dist/ColorWheel.module.js.map +1 -1
- package/dist/ComboBox.main.js +4 -1
- package/dist/ComboBox.main.js.map +1 -1
- package/dist/ComboBox.mjs +4 -1
- package/dist/ComboBox.module.js +4 -1
- package/dist/ComboBox.module.js.map +1 -1
- package/dist/DateField.main.js +16 -3
- package/dist/DateField.main.js.map +1 -1
- package/dist/DateField.mjs +16 -3
- package/dist/DateField.module.js +16 -3
- package/dist/DateField.module.js.map +1 -1
- package/dist/DatePicker.main.js +15 -8
- package/dist/DatePicker.main.js.map +1 -1
- package/dist/DatePicker.mjs +16 -9
- package/dist/DatePicker.module.js +16 -9
- package/dist/DatePicker.module.js.map +1 -1
- package/dist/Dialog.main.js +4 -3
- package/dist/Dialog.main.js.map +1 -1
- package/dist/Dialog.mjs +5 -4
- package/dist/Dialog.module.js +5 -4
- package/dist/Dialog.module.js.map +1 -1
- package/dist/Disclosure.main.js +12 -10
- package/dist/Disclosure.main.js.map +1 -1
- package/dist/Disclosure.mjs +13 -11
- package/dist/Disclosure.module.js +13 -11
- package/dist/Disclosure.module.js.map +1 -1
- package/dist/DragAndDrop.main.js +31 -3
- package/dist/DragAndDrop.main.js.map +1 -1
- package/dist/DragAndDrop.mjs +31 -3
- package/dist/DragAndDrop.module.js +31 -3
- package/dist/DragAndDrop.module.js.map +1 -1
- package/dist/DropZone.main.js +4 -3
- package/dist/DropZone.main.js.map +1 -1
- package/dist/DropZone.mjs +4 -3
- package/dist/DropZone.module.js +4 -3
- package/dist/DropZone.module.js.map +1 -1
- package/dist/FieldError.main.js +3 -1
- package/dist/FieldError.main.js.map +1 -1
- package/dist/FieldError.mjs +3 -1
- package/dist/FieldError.module.js +3 -1
- package/dist/FieldError.module.js.map +1 -1
- package/dist/FileTrigger.main.js +3 -1
- package/dist/FileTrigger.main.js.map +1 -1
- package/dist/FileTrigger.mjs +3 -1
- package/dist/FileTrigger.module.js +3 -1
- package/dist/FileTrigger.module.js.map +1 -1
- package/dist/Form.main.js.map +1 -1
- package/dist/Form.module.js.map +1 -1
- package/dist/GridList.main.js +20 -13
- package/dist/GridList.main.js.map +1 -1
- package/dist/GridList.mjs +21 -14
- package/dist/GridList.module.js +21 -14
- package/dist/GridList.module.js.map +1 -1
- package/dist/HiddenDateInput.main.js +118 -0
- package/dist/HiddenDateInput.main.js.map +1 -0
- package/dist/HiddenDateInput.mjs +109 -0
- package/dist/HiddenDateInput.module.js +109 -0
- package/dist/HiddenDateInput.module.js.map +1 -0
- package/dist/Link.main.js +7 -1
- package/dist/Link.main.js.map +1 -1
- package/dist/Link.mjs +7 -1
- package/dist/Link.module.js +7 -1
- package/dist/Link.module.js.map +1 -1
- package/dist/ListBox.main.js +22 -19
- package/dist/ListBox.main.js.map +1 -1
- package/dist/ListBox.mjs +23 -20
- package/dist/ListBox.module.js +23 -20
- package/dist/ListBox.module.js.map +1 -1
- package/dist/Menu.main.js +15 -8
- package/dist/Menu.main.js.map +1 -1
- package/dist/Menu.mjs +16 -9
- package/dist/Menu.module.js +16 -9
- package/dist/Menu.module.js.map +1 -1
- package/dist/Meter.main.js +6 -2
- package/dist/Meter.main.js.map +1 -1
- package/dist/Meter.mjs +6 -2
- package/dist/Meter.module.js +6 -2
- package/dist/Meter.module.js.map +1 -1
- package/dist/Modal.main.js +31 -6
- package/dist/Modal.main.js.map +1 -1
- package/dist/Modal.mjs +31 -6
- package/dist/Modal.module.js +31 -6
- package/dist/Modal.module.js.map +1 -1
- package/dist/NumberField.main.js +4 -1
- package/dist/NumberField.main.js.map +1 -1
- package/dist/NumberField.mjs +4 -1
- package/dist/NumberField.module.js +4 -1
- package/dist/NumberField.module.js.map +1 -1
- package/dist/Popover.main.js +3 -1
- package/dist/Popover.main.js.map +1 -1
- package/dist/Popover.mjs +3 -1
- package/dist/Popover.module.js +3 -1
- package/dist/Popover.module.js.map +1 -1
- package/dist/ProgressBar.main.js +6 -2
- package/dist/ProgressBar.main.js.map +1 -1
- package/dist/ProgressBar.mjs +6 -2
- package/dist/ProgressBar.module.js +6 -2
- package/dist/ProgressBar.module.js.map +1 -1
- package/dist/RadioGroup.main.js +8 -3
- package/dist/RadioGroup.main.js.map +1 -1
- package/dist/RadioGroup.mjs +9 -4
- package/dist/RadioGroup.module.js +9 -4
- package/dist/RadioGroup.module.js.map +1 -1
- package/dist/SearchField.main.js +3 -1
- package/dist/SearchField.main.js.map +1 -1
- package/dist/SearchField.mjs +3 -1
- package/dist/SearchField.module.js +3 -1
- package/dist/SearchField.module.js.map +1 -1
- package/dist/Select.main.js +12 -14
- package/dist/Select.main.js.map +1 -1
- package/dist/Select.mjs +13 -15
- package/dist/Select.module.js +13 -15
- package/dist/Select.module.js.map +1 -1
- package/dist/Separator.main.js +4 -2
- package/dist/Separator.main.js.map +1 -1
- package/dist/Separator.mjs +5 -3
- package/dist/Separator.module.js +5 -3
- package/dist/Separator.module.js.map +1 -1
- package/dist/Slider.main.js +7 -5
- package/dist/Slider.main.js.map +1 -1
- package/dist/Slider.mjs +8 -6
- package/dist/Slider.module.js +8 -6
- package/dist/Slider.module.js.map +1 -1
- package/dist/Switch.main.js +4 -1
- package/dist/Switch.main.js.map +1 -1
- package/dist/Switch.mjs +4 -1
- package/dist/Switch.module.js +4 -1
- package/dist/Switch.module.js.map +1 -1
- package/dist/Table.main.js +47 -26
- package/dist/Table.main.js.map +1 -1
- package/dist/Table.mjs +48 -27
- package/dist/Table.module.js +48 -27
- package/dist/Table.module.js.map +1 -1
- package/dist/Tabs.main.js +20 -10
- package/dist/Tabs.main.js.map +1 -1
- package/dist/Tabs.mjs +21 -11
- package/dist/Tabs.module.js +21 -11
- package/dist/Tabs.module.js.map +1 -1
- package/dist/TagGroup.main.js +14 -8
- package/dist/TagGroup.main.js.map +1 -1
- package/dist/TagGroup.mjs +14 -8
- package/dist/TagGroup.module.js +14 -8
- package/dist/TagGroup.module.js.map +1 -1
- package/dist/TextField.main.js +13 -1
- package/dist/TextField.main.js.map +1 -1
- package/dist/TextField.mjs +13 -1
- package/dist/TextField.module.js +13 -1
- package/dist/TextField.module.js.map +1 -1
- package/dist/Toast.main.js +9 -5
- package/dist/Toast.main.js.map +1 -1
- package/dist/Toast.mjs +9 -5
- package/dist/Toast.module.js +9 -5
- package/dist/Toast.module.js.map +1 -1
- package/dist/ToggleButton.main.js +8 -2
- package/dist/ToggleButton.main.js.map +1 -1
- package/dist/ToggleButton.mjs +8 -2
- package/dist/ToggleButton.module.js +8 -2
- package/dist/ToggleButton.module.js.map +1 -1
- package/dist/ToggleButtonGroup.main.js +6 -2
- package/dist/ToggleButtonGroup.main.js.map +1 -1
- package/dist/ToggleButtonGroup.mjs +6 -2
- package/dist/ToggleButtonGroup.module.js +6 -2
- package/dist/ToggleButtonGroup.module.js.map +1 -1
- package/dist/Toolbar.main.js +4 -3
- package/dist/Toolbar.main.js.map +1 -1
- package/dist/Toolbar.mjs +4 -3
- package/dist/Toolbar.module.js +4 -3
- package/dist/Toolbar.module.js.map +1 -1
- package/dist/Tooltip.main.js +5 -3
- package/dist/Tooltip.main.js.map +1 -1
- package/dist/Tooltip.mjs +5 -3
- package/dist/Tooltip.module.js +5 -3
- package/dist/Tooltip.module.js.map +1 -1
- package/dist/Tree.main.js +73 -26
- package/dist/Tree.main.js.map +1 -1
- package/dist/Tree.mjs +74 -27
- package/dist/Tree.module.js +74 -27
- package/dist/Tree.module.js.map +1 -1
- package/dist/TreeDropTargetDelegate.main.js +8 -5
- package/dist/TreeDropTargetDelegate.main.js.map +1 -1
- package/dist/TreeDropTargetDelegate.mjs +8 -5
- package/dist/TreeDropTargetDelegate.module.js +8 -5
- package/dist/TreeDropTargetDelegate.module.js.map +1 -1
- package/dist/import.mjs +5 -5
- package/dist/main.js +4 -4
- package/dist/main.js.map +1 -1
- package/dist/module.js +5 -5
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +212 -203
- package/dist/types.d.ts.map +1 -1
- package/dist/useDragAndDrop.main.js.map +1 -1
- package/dist/useDragAndDrop.module.js.map +1 -1
- package/dist/utils.main.js.map +1 -1
- package/dist/utils.module.js.map +1 -1
- package/i18n/de-DE.js +1 -1
- package/i18n/de-DE.mjs +1 -1
- package/package.json +25 -25
- package/src/Breadcrumbs.tsx +10 -6
- package/src/Button.tsx +8 -30
- package/src/Calendar.tsx +41 -24
- package/src/Checkbox.tsx +8 -6
- package/src/Collection.tsx +2 -2
- package/src/ColorArea.tsx +5 -6
- package/src/ColorField.tsx +6 -4
- package/src/ColorSlider.tsx +3 -2
- package/src/ColorSwatch.tsx +6 -3
- package/src/ColorSwatchPicker.tsx +3 -3
- package/src/ColorThumb.tsx +3 -3
- package/src/ColorWheel.tsx +6 -5
- package/src/ComboBox.tsx +4 -4
- package/src/DateField.tsx +15 -10
- package/src/DatePicker.tsx +14 -12
- package/src/Dialog.tsx +6 -6
- package/src/Disclosure.tsx +10 -14
- package/src/DragAndDrop.tsx +31 -1
- package/src/DropZone.tsx +4 -5
- package/src/FieldError.tsx +3 -3
- package/src/FileTrigger.tsx +4 -3
- package/src/Form.tsx +2 -1
- package/src/GridList.tsx +25 -18
- package/src/HiddenDateInput.tsx +142 -0
- package/src/Link.tsx +7 -3
- package/src/ListBox.tsx +30 -26
- package/src/Menu.tsx +15 -12
- package/src/Meter.tsx +6 -3
- package/src/Modal.tsx +16 -5
- package/src/NumberField.tsx +4 -4
- package/src/Popover.tsx +3 -3
- package/src/ProgressBar.tsx +6 -2
- package/src/RadioGroup.tsx +8 -6
- package/src/SearchField.tsx +3 -2
- package/src/Select.tsx +13 -16
- package/src/Separator.tsx +6 -4
- package/src/Slider.tsx +9 -11
- package/src/Switch.tsx +4 -3
- package/src/Table.tsx +58 -56
- package/src/Tabs.tsx +18 -15
- package/src/TagGroup.tsx +13 -12
- package/src/TextField.tsx +5 -2
- package/src/Toast.tsx +10 -8
- package/src/ToggleButton.tsx +8 -4
- package/src/ToggleButtonGroup.tsx +6 -4
- package/src/Toolbar.tsx +4 -5
- package/src/Tooltip.tsx +6 -5
- package/src/Tree.tsx +90 -42
- package/src/TreeDropTargetDelegate.ts +5 -1
- package/src/index.ts +8 -8
- package/src/useDragAndDrop.tsx +2 -2
- package/src/utils.tsx +9 -9
package/src/GridList.tsx
CHANGED
|
@@ -14,12 +14,12 @@ import {ButtonContext} from './Button';
|
|
|
14
14
|
import {CheckboxContext} from './RSPContexts';
|
|
15
15
|
import {Collection, CollectionBuilder, createLeafComponent} from '@react-aria/collections';
|
|
16
16
|
import {CollectionProps, CollectionRendererContext, DefaultCollectionRenderer, ItemRenderProps} from './Collection';
|
|
17
|
-
import {ContextValue, DEFAULT_SLOT, Provider, RenderProps,
|
|
17
|
+
import {ContextValue, DEFAULT_SLOT, Provider, RenderProps, SlotProps, StyleProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
|
|
18
18
|
import {DragAndDropContext, DropIndicatorContext, DropIndicatorProps, useDndPersistedKeys, useRenderDropIndicator} from './DragAndDrop';
|
|
19
19
|
import {DragAndDropHooks} from './useDragAndDrop';
|
|
20
20
|
import {DraggableCollectionState, DroppableCollectionState, Collection as ICollection, ListState, Node, SelectionBehavior, useListState} from 'react-stately';
|
|
21
|
-
import {filterDOMProps, inertValue, LoadMoreSentinelProps,
|
|
22
|
-
import {forwardRefType, HoverEvents, Key, LinkDOMProps, RefObject} from '@react-types/shared';
|
|
21
|
+
import {filterDOMProps, inertValue, LoadMoreSentinelProps, useLoadMoreSentinel, useObjectRef} from '@react-aria/utils';
|
|
22
|
+
import {forwardRefType, GlobalDOMAttributes, HoverEvents, Key, LinkDOMProps, PressEvents, RefObject} from '@react-types/shared';
|
|
23
23
|
import {ListStateContext} from './ListBox';
|
|
24
24
|
import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes, JSX, ReactNode, useContext, useEffect, useMemo, useRef} from 'react';
|
|
25
25
|
import {TextContext} from './Text';
|
|
@@ -56,13 +56,16 @@ export interface GridListRenderProps {
|
|
|
56
56
|
state: ListState<unknown>
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export interface GridListProps<T> extends Omit<AriaGridListProps<T>, 'children'>, CollectionProps<T>, StyleRenderProps<GridListRenderProps>, SlotProps,
|
|
59
|
+
export interface GridListProps<T> extends Omit<AriaGridListProps<T>, 'children'>, CollectionProps<T>, StyleRenderProps<GridListRenderProps>, SlotProps, GlobalDOMAttributes<HTMLDivElement> {
|
|
60
60
|
/**
|
|
61
61
|
* Whether typeahead navigation is disabled.
|
|
62
62
|
* @default false
|
|
63
63
|
*/
|
|
64
64
|
disallowTypeAhead?: boolean,
|
|
65
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* How multiple selection should behave in the collection.
|
|
67
|
+
* @default "toggle"
|
|
68
|
+
*/
|
|
66
69
|
selectionBehavior?: SelectionBehavior,
|
|
67
70
|
/** The drag and drop hooks returned by `useDragAndDrop` used to enable drag and drop behavior for the GridList. */
|
|
68
71
|
dragAndDropHooks?: DragAndDropHooks,
|
|
@@ -194,8 +197,7 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
|
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
let {focusProps, isFocused, isFocusVisible} = useFocusRing();
|
|
197
|
-
|
|
198
|
-
let isEmpty = state.collection.size === 0 || (state.collection.size === 1 && state.collection.getItem(state.collection.getFirstKey()!)?.type === 'loader');
|
|
200
|
+
let isEmpty = state.collection.size === 0;
|
|
199
201
|
let renderValues = {
|
|
200
202
|
isDropTarget: isRootDropTarget,
|
|
201
203
|
isEmpty,
|
|
@@ -225,12 +227,12 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
|
|
|
225
227
|
);
|
|
226
228
|
}
|
|
227
229
|
|
|
230
|
+
let DOMProps = filterDOMProps(props, {global: true});
|
|
231
|
+
|
|
228
232
|
return (
|
|
229
233
|
<FocusScope>
|
|
230
234
|
<div
|
|
231
|
-
{...
|
|
232
|
-
{...renderProps}
|
|
233
|
-
{...mergeProps(gridProps, focusProps, droppableCollection?.collectionProps, emptyStatePropOverrides)}
|
|
235
|
+
{...mergeProps(DOMProps, renderProps, gridProps, focusProps, droppableCollection?.collectionProps, emptyStatePropOverrides)}
|
|
234
236
|
ref={ref}
|
|
235
237
|
slot={props.slot || undefined}
|
|
236
238
|
onScroll={props.onScroll}
|
|
@@ -261,7 +263,7 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
|
|
|
261
263
|
|
|
262
264
|
export interface GridListItemRenderProps extends ItemRenderProps {}
|
|
263
265
|
|
|
264
|
-
export interface GridListItemProps<T = object> extends RenderProps<GridListItemRenderProps>, LinkDOMProps, HoverEvents {
|
|
266
|
+
export interface GridListItemProps<T = object> extends RenderProps<GridListItemRenderProps>, LinkDOMProps, HoverEvents, PressEvents, Omit<GlobalDOMAttributes<HTMLDivElement>, 'onClick'> {
|
|
265
267
|
/** The unique id of the item. */
|
|
266
268
|
id?: Key,
|
|
267
269
|
/** The object value that this item represents. When using dynamic collections, this is set automatically. */
|
|
@@ -356,6 +358,10 @@ export const GridListItem = /*#__PURE__*/ createLeafComponent('item', function G
|
|
|
356
358
|
}
|
|
357
359
|
}, [item.textValue]);
|
|
358
360
|
|
|
361
|
+
let DOMProps = filterDOMProps(props as any, {global: true});
|
|
362
|
+
delete DOMProps.id;
|
|
363
|
+
delete DOMProps.onClick;
|
|
364
|
+
|
|
359
365
|
return (
|
|
360
366
|
<>
|
|
361
367
|
{dropIndicator && !dropIndicator.isHidden &&
|
|
@@ -366,8 +372,7 @@ export const GridListItem = /*#__PURE__*/ createLeafComponent('item', function G
|
|
|
366
372
|
</div>
|
|
367
373
|
}
|
|
368
374
|
<div
|
|
369
|
-
{...mergeProps(
|
|
370
|
-
{...renderProps}
|
|
375
|
+
{...mergeProps(DOMProps, renderProps, rowProps, focusProps, hoverProps, draggableItem?.dragProps)}
|
|
371
376
|
ref={ref}
|
|
372
377
|
data-selected={states.isSelected || undefined}
|
|
373
378
|
data-disabled={states.isDisabled || undefined}
|
|
@@ -497,7 +502,7 @@ function RootDropIndicator() {
|
|
|
497
502
|
);
|
|
498
503
|
}
|
|
499
504
|
|
|
500
|
-
export interface
|
|
505
|
+
export interface GridListLoadMoreItemProps extends Omit<LoadMoreSentinelProps, 'collection'>, StyleProps, GlobalDOMAttributes<HTMLDivElement> {
|
|
501
506
|
/**
|
|
502
507
|
* The load more spinner to render when loading additional items.
|
|
503
508
|
*/
|
|
@@ -508,7 +513,7 @@ export interface GridListLoadingSentinelProps extends Omit<LoadMoreSentinelProps
|
|
|
508
513
|
isLoading?: boolean
|
|
509
514
|
}
|
|
510
515
|
|
|
511
|
-
export const
|
|
516
|
+
export const GridListLoadMoreItem = createLeafComponent('loader', function GridListLoadingIndicator(props: GridListLoadMoreItemProps, ref: ForwardedRef<HTMLDivElement>, item: Node<object>) {
|
|
512
517
|
let state = useContext(ListStateContext)!;
|
|
513
518
|
let {isVirtualized} = useContext(CollectionRendererContext);
|
|
514
519
|
let {isLoading, onLoadMore, scrollOffset, ...otherProps} = props;
|
|
@@ -520,7 +525,7 @@ export const UNSTABLE_GridListLoadingSentinel = createLeafComponent('loader', fu
|
|
|
520
525
|
sentinelRef,
|
|
521
526
|
scrollOffset
|
|
522
527
|
}), [onLoadMore, scrollOffset, state?.collection]);
|
|
523
|
-
|
|
528
|
+
useLoadMoreSentinel(memoedLoadMoreProps, sentinelRef);
|
|
524
529
|
|
|
525
530
|
let renderProps = useRenderProps({
|
|
526
531
|
...otherProps,
|
|
@@ -529,6 +534,9 @@ export const UNSTABLE_GridListLoadingSentinel = createLeafComponent('loader', fu
|
|
|
529
534
|
defaultClassName: 'react-aria-GridListLoadingIndicator',
|
|
530
535
|
values: null
|
|
531
536
|
});
|
|
537
|
+
// For now don't include aria-posinset and aria-setsize on loader since they aren't keyboard focusable
|
|
538
|
+
// Arguably shouldn't include them ever since it might be confusing to the user to include the loaders as part of the
|
|
539
|
+
// item count
|
|
532
540
|
|
|
533
541
|
return (
|
|
534
542
|
<>
|
|
@@ -540,9 +548,8 @@ export const UNSTABLE_GridListLoadingSentinel = createLeafComponent('loader', fu
|
|
|
540
548
|
{isLoading && renderProps.children && (
|
|
541
549
|
<div
|
|
542
550
|
{...renderProps}
|
|
543
|
-
{...
|
|
551
|
+
{...filterDOMProps(props, {global: true})}
|
|
544
552
|
role="row"
|
|
545
|
-
aria-rowindex={isVirtualized ? item.index + 1 : undefined}
|
|
546
553
|
ref={ref}>
|
|
547
554
|
<div
|
|
548
555
|
aria-colindex={isVirtualized ? 1 : undefined}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 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
|
+
|
|
14
|
+
import {CalendarDate, CalendarDateTime, parseDate, parseDateTime} from '@internationalized/date';
|
|
15
|
+
import {DateFieldState, DatePickerState, DateSegmentType} from 'react-stately';
|
|
16
|
+
import React, {ReactNode} from 'react';
|
|
17
|
+
import {useVisuallyHidden} from 'react-aria';
|
|
18
|
+
|
|
19
|
+
interface AriaHiddenDateInputProps {
|
|
20
|
+
/**
|
|
21
|
+
* Describes the type of autocomplete functionality the input should provide if any. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautocomplete).
|
|
22
|
+
*/
|
|
23
|
+
autoComplete?: string,
|
|
24
|
+
/** HTML form input name. */
|
|
25
|
+
name?: string,
|
|
26
|
+
/** Sets the disabled state of the input. */
|
|
27
|
+
isDisabled?: boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface HiddenDateInputProps extends AriaHiddenDateInputProps {
|
|
31
|
+
/**
|
|
32
|
+
* State for the input.
|
|
33
|
+
*/
|
|
34
|
+
state: DateFieldState | DatePickerState
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface HiddenDateAria {
|
|
38
|
+
/** Props for the container element. */
|
|
39
|
+
containerProps: React.HTMLAttributes<HTMLDivElement>,
|
|
40
|
+
/** Props for the hidden input element. */
|
|
41
|
+
inputProps: React.InputHTMLAttributes<HTMLInputElement>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const dateSegments = ['day', 'month', 'year'];
|
|
45
|
+
const granularityMap = {'hour': 1, 'minute': 2, 'second': 3};
|
|
46
|
+
|
|
47
|
+
export function useHiddenDateInput(props: HiddenDateInputProps, state: DateFieldState | DatePickerState) : HiddenDateAria {
|
|
48
|
+
let {
|
|
49
|
+
autoComplete,
|
|
50
|
+
isDisabled,
|
|
51
|
+
name
|
|
52
|
+
} = props;
|
|
53
|
+
let {visuallyHiddenProps} = useVisuallyHidden({
|
|
54
|
+
style: {
|
|
55
|
+
// Prevent page scrolling.
|
|
56
|
+
position: 'fixed',
|
|
57
|
+
top: 0,
|
|
58
|
+
left: 0
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
let inputStep = 60;
|
|
63
|
+
if (state.granularity === 'second') {
|
|
64
|
+
inputStep = 1;
|
|
65
|
+
} else if (state.granularity === 'hour') {
|
|
66
|
+
inputStep = 3600;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let dateValue = state.value == null ? '' : state.value.toString();
|
|
70
|
+
|
|
71
|
+
let inputType = state.granularity === 'day' ? 'date' : 'datetime-local';
|
|
72
|
+
|
|
73
|
+
let timeSegments = ['hour', 'minute', 'second'];
|
|
74
|
+
// Depending on the granularity, we only want to validate certain time segments
|
|
75
|
+
let end = 0;
|
|
76
|
+
if (timeSegments.includes(state.granularity)) {
|
|
77
|
+
end = granularityMap[state.granularity];
|
|
78
|
+
timeSegments = timeSegments.slice(0, end);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
containerProps: {
|
|
83
|
+
...visuallyHiddenProps,
|
|
84
|
+
'aria-hidden': true,
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
['data-react-aria-prevent-focus']: true,
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
['data-a11y-ignore']: 'aria-hidden-focus'
|
|
89
|
+
},
|
|
90
|
+
inputProps: {
|
|
91
|
+
tabIndex: -1,
|
|
92
|
+
autoComplete,
|
|
93
|
+
disabled: isDisabled,
|
|
94
|
+
type: inputType,
|
|
95
|
+
// We set the form prop to an empty string to prevent the hidden date input's value from being submitted
|
|
96
|
+
form: '',
|
|
97
|
+
name,
|
|
98
|
+
step: inputStep,
|
|
99
|
+
value: dateValue,
|
|
100
|
+
onChange: (e) => {
|
|
101
|
+
let targetString = e.target.value.toString();
|
|
102
|
+
if (targetString) {
|
|
103
|
+
try {
|
|
104
|
+
let targetValue: CalendarDateTime | CalendarDate = parseDateTime(targetString);
|
|
105
|
+
if (state.granularity === 'day') {
|
|
106
|
+
targetValue = parseDate(targetString);
|
|
107
|
+
}
|
|
108
|
+
// We check to to see if setSegment exists in the state since it only exists in DateFieldState and not DatePickerState.
|
|
109
|
+
// The setValue method has different behavior depending on if it's coming from DateFieldState or DatePickerState.
|
|
110
|
+
// In DateFieldState, setValue firsts checks to make sure that each segment is filled before committing the newValue
|
|
111
|
+
// which is why in the code below we first set each segment to validate it before committing the new value.
|
|
112
|
+
// However, in DatePickerState, since we have to be able to commit values from the Calendar popover, we are also able to
|
|
113
|
+
// set a new value when the field itself is empty.
|
|
114
|
+
if ('setSegment' in state) {
|
|
115
|
+
for (let type in targetValue) {
|
|
116
|
+
if (dateSegments.includes(type)) {
|
|
117
|
+
state.setSegment(type as DateSegmentType, targetValue[type]);
|
|
118
|
+
}
|
|
119
|
+
if (timeSegments.includes(type)) {
|
|
120
|
+
state.setSegment(type as DateSegmentType, targetValue[type]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
state.setValue(targetValue);
|
|
125
|
+
} catch {
|
|
126
|
+
// ignore
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function HiddenDateInput(props: HiddenDateInputProps): ReactNode | null {
|
|
135
|
+
let {state} = props;
|
|
136
|
+
let {containerProps, inputProps} = useHiddenDateInput({...props}, state);
|
|
137
|
+
return (
|
|
138
|
+
<div {...containerProps} data-testid="hidden-dateinput-container">
|
|
139
|
+
<input {...inputProps} />
|
|
140
|
+
</div>
|
|
141
|
+
);
|
|
142
|
+
}
|
package/src/Link.tsx
CHANGED
|
@@ -12,10 +12,11 @@
|
|
|
12
12
|
|
|
13
13
|
import {AriaLinkOptions, HoverEvents, mergeProps, useFocusRing, useHover, useLink} from 'react-aria';
|
|
14
14
|
import {ContextValue, RenderProps, SlotProps, useContextProps, useRenderProps} from './utils';
|
|
15
|
-
import {
|
|
15
|
+
import {filterDOMProps} from '@react-aria/utils';
|
|
16
|
+
import {forwardRefType, GlobalDOMAttributes} from '@react-types/shared';
|
|
16
17
|
import React, {createContext, ElementType, ForwardedRef, forwardRef} from 'react';
|
|
17
18
|
|
|
18
|
-
export interface LinkProps extends Omit<AriaLinkOptions, 'elementType'>, HoverEvents, RenderProps<LinkRenderProps>, SlotProps {}
|
|
19
|
+
export interface LinkProps extends Omit<AriaLinkOptions, 'elementType'>, HoverEvents, RenderProps<LinkRenderProps>, SlotProps, Omit<GlobalDOMAttributes<HTMLDivElement>, 'onClick'> {}
|
|
19
20
|
|
|
20
21
|
export interface LinkRenderProps {
|
|
21
22
|
/**
|
|
@@ -78,11 +79,14 @@ export const Link = /*#__PURE__*/ (forwardRef as forwardRefType)(function Link(p
|
|
|
78
79
|
}
|
|
79
80
|
});
|
|
80
81
|
|
|
82
|
+
let DOMProps = filterDOMProps(props, {global: true});
|
|
83
|
+
delete DOMProps.onClick;
|
|
84
|
+
|
|
81
85
|
return (
|
|
82
86
|
<ElementType
|
|
83
87
|
ref={ref}
|
|
84
88
|
slot={props.slot || undefined}
|
|
85
|
-
{...mergeProps(renderProps, linkProps, hoverProps, focusProps)}
|
|
89
|
+
{...mergeProps(DOMProps, renderProps, linkProps, hoverProps, focusProps)}
|
|
86
90
|
data-focused={isFocused || undefined}
|
|
87
91
|
data-hovered={isHovered || undefined}
|
|
88
92
|
data-pressed={isPressed || undefined}
|
package/src/ListBox.tsx
CHANGED
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
import {AriaListBoxOptions, AriaListBoxProps, DraggableItemResult, DragPreviewRenderer, DroppableCollectionResult, DroppableItemResult, FocusScope, ListKeyboardDelegate, mergeProps, useCollator, useFocusRing, useHover, useListBox, useListBoxSection, useLocale, useOption} from 'react-aria';
|
|
14
14
|
import {Collection, CollectionBuilder, createBranchComponent, createLeafComponent} from '@react-aria/collections';
|
|
15
15
|
import {CollectionProps, CollectionRendererContext, ItemRenderProps, SectionContext, SectionProps} from './Collection';
|
|
16
|
-
import {ContextValue, DEFAULT_SLOT, Provider, RenderProps,
|
|
16
|
+
import {ContextValue, DEFAULT_SLOT, Provider, RenderProps, SlotProps, StyleProps, StyleRenderProps, useContextProps, useRenderProps, useSlot} from './utils';
|
|
17
17
|
import {DragAndDropContext, DropIndicatorContext, DropIndicatorProps, useDndPersistedKeys, useRenderDropIndicator} from './DragAndDrop';
|
|
18
18
|
import {DragAndDropHooks} from './useDragAndDrop';
|
|
19
19
|
import {DraggableCollectionState, DroppableCollectionState, ListState, Node, Orientation, SelectionBehavior, UNSTABLE_useFilteredListState, useListState} from 'react-stately';
|
|
20
|
-
import {filterDOMProps, inertValue, LoadMoreSentinelProps, mergeRefs,
|
|
21
|
-
import {forwardRefType, HoverEvents, Key, LinkDOMProps, RefObject} from '@react-types/shared';
|
|
20
|
+
import {filterDOMProps, inertValue, LoadMoreSentinelProps, mergeRefs, useLoadMoreSentinel, useObjectRef} from '@react-aria/utils';
|
|
21
|
+
import {forwardRefType, GlobalDOMAttributes, HoverEvents, Key, LinkDOMProps, PressEvents, RefObject} from '@react-types/shared';
|
|
22
22
|
import {HeaderContext} from './Header';
|
|
23
23
|
import React, {createContext, ForwardedRef, forwardRef, JSX, ReactNode, useContext, useEffect, useMemo, useRef} from 'react';
|
|
24
24
|
import {SeparatorContext} from './Separator';
|
|
@@ -57,8 +57,11 @@ export interface ListBoxRenderProps {
|
|
|
57
57
|
state: ListState<unknown>
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export interface ListBoxProps<T> extends Omit<AriaListBoxProps<T>, 'children' | 'label'>, CollectionProps<T>, StyleRenderProps<ListBoxRenderProps>, SlotProps,
|
|
61
|
-
/**
|
|
60
|
+
export interface ListBoxProps<T> extends Omit<AriaListBoxProps<T>, 'children' | 'label'>, CollectionProps<T>, StyleRenderProps<ListBoxRenderProps>, SlotProps, GlobalDOMAttributes<HTMLDivElement> {
|
|
61
|
+
/**
|
|
62
|
+
* How multiple selection should behave in the collection.
|
|
63
|
+
* @default "toggle"
|
|
64
|
+
*/
|
|
62
65
|
selectionBehavior?: SelectionBehavior,
|
|
63
66
|
/** The drag and drop hooks returned by `useDragAndDrop` used to enable drag and drop behavior for the ListBox. */
|
|
64
67
|
dragAndDropHooks?: DragAndDropHooks,
|
|
@@ -202,7 +205,7 @@ function ListBoxInner<T extends object>({state: inputState, props, listBoxRef}:
|
|
|
202
205
|
}
|
|
203
206
|
|
|
204
207
|
let {focusProps, isFocused, isFocusVisible} = useFocusRing();
|
|
205
|
-
let isEmpty = state.collection.size === 0
|
|
208
|
+
let isEmpty = state.collection.size === 0;
|
|
206
209
|
let renderValues = {
|
|
207
210
|
isDropTarget: isRootDropTarget,
|
|
208
211
|
isEmpty,
|
|
@@ -230,12 +233,12 @@ function ListBoxInner<T extends object>({state: inputState, props, listBoxRef}:
|
|
|
230
233
|
);
|
|
231
234
|
}
|
|
232
235
|
|
|
236
|
+
let DOMProps = filterDOMProps(props, {global: true});
|
|
237
|
+
|
|
233
238
|
return (
|
|
234
239
|
<FocusScope>
|
|
235
240
|
<div
|
|
236
|
-
{...
|
|
237
|
-
{...mergeProps(listBoxProps, focusProps, droppableCollection?.collectionProps)}
|
|
238
|
-
{...renderProps}
|
|
241
|
+
{...mergeProps(DOMProps, renderProps, listBoxProps, focusProps, droppableCollection?.collectionProps)}
|
|
239
242
|
ref={listBoxRef}
|
|
240
243
|
slot={props.slot || undefined}
|
|
241
244
|
onScroll={props.onScroll}
|
|
@@ -285,11 +288,12 @@ function ListBoxSectionInner<T extends object>(props: ListBoxSectionProps<T>, re
|
|
|
285
288
|
values: {}
|
|
286
289
|
});
|
|
287
290
|
|
|
291
|
+
let DOMProps = filterDOMProps(props as any, {global: true});
|
|
292
|
+
delete DOMProps.id;
|
|
293
|
+
|
|
288
294
|
return (
|
|
289
295
|
<section
|
|
290
|
-
{...
|
|
291
|
-
{...groupProps}
|
|
292
|
-
{...renderProps}
|
|
296
|
+
{...mergeProps(DOMProps, renderProps, groupProps)}
|
|
293
297
|
ref={ref}>
|
|
294
298
|
<HeaderContext.Provider value={{...headingProps, ref: headingRef}}>
|
|
295
299
|
<CollectionBranch
|
|
@@ -308,7 +312,7 @@ export const ListBoxSection = /*#__PURE__*/ createBranchComponent('section', Lis
|
|
|
308
312
|
|
|
309
313
|
export interface ListBoxItemRenderProps extends ItemRenderProps {}
|
|
310
314
|
|
|
311
|
-
export interface ListBoxItemProps<T = object> extends RenderProps<ListBoxItemRenderProps>, LinkDOMProps, HoverEvents {
|
|
315
|
+
export interface ListBoxItemProps<T = object> extends RenderProps<ListBoxItemRenderProps>, LinkDOMProps, HoverEvents, PressEvents, Omit<GlobalDOMAttributes<HTMLDivElement>, 'onClick'> {
|
|
312
316
|
/** The unique id of the item. */
|
|
313
317
|
id?: Key,
|
|
314
318
|
/** The object value that this item represents. When using dynamic collections, this is set automatically. */
|
|
@@ -383,10 +387,13 @@ export const ListBoxItem = /*#__PURE__*/ createLeafComponent('item', function Li
|
|
|
383
387
|
|
|
384
388
|
let ElementType: React.ElementType = props.href ? 'a' : 'div';
|
|
385
389
|
|
|
390
|
+
let DOMProps = filterDOMProps(props as any, {global: true});
|
|
391
|
+
delete DOMProps.id;
|
|
392
|
+
delete DOMProps.onClick;
|
|
393
|
+
|
|
386
394
|
return (
|
|
387
395
|
<ElementType
|
|
388
|
-
{...mergeProps(optionProps, hoverProps, draggableItem?.dragProps, droppableItem?.dropProps)}
|
|
389
|
-
{...renderProps}
|
|
396
|
+
{...mergeProps(DOMProps, renderProps, optionProps, hoverProps, draggableItem?.dragProps, droppableItem?.dropProps)}
|
|
390
397
|
ref={ref}
|
|
391
398
|
data-allows-dragging={!!dragState || undefined}
|
|
392
399
|
data-selected={states.isSelected || undefined}
|
|
@@ -465,7 +472,7 @@ function ListBoxDropIndicator(props: ListBoxDropIndicatorProps, ref: ForwardedRe
|
|
|
465
472
|
|
|
466
473
|
const ListBoxDropIndicatorForwardRef = forwardRef(ListBoxDropIndicator);
|
|
467
474
|
|
|
468
|
-
export interface
|
|
475
|
+
export interface ListBoxLoadMoreItemProps extends Omit<LoadMoreSentinelProps, 'collection'>, StyleProps, GlobalDOMAttributes<HTMLDivElement> {
|
|
469
476
|
/**
|
|
470
477
|
* The load more spinner to render when loading additional items.
|
|
471
478
|
*/
|
|
@@ -476,9 +483,8 @@ export interface ListBoxLoadingSentinelProps extends Omit<LoadMoreSentinelProps,
|
|
|
476
483
|
isLoading?: boolean
|
|
477
484
|
}
|
|
478
485
|
|
|
479
|
-
export const
|
|
486
|
+
export const ListBoxLoadMoreItem = createLeafComponent('loader', function ListBoxLoadingIndicator(props: ListBoxLoadMoreItemProps, ref: ForwardedRef<HTMLDivElement>, item: Node<object>) {
|
|
480
487
|
let state = useContext(ListStateContext)!;
|
|
481
|
-
let {isVirtualized} = useContext(CollectionRendererContext);
|
|
482
488
|
let {isLoading, onLoadMore, scrollOffset, ...otherProps} = props;
|
|
483
489
|
|
|
484
490
|
let sentinelRef = useRef<HTMLDivElement>(null);
|
|
@@ -488,7 +494,7 @@ export const UNSTABLE_ListBoxLoadingSentinel = createLeafComponent('loader', fun
|
|
|
488
494
|
sentinelRef,
|
|
489
495
|
scrollOffset
|
|
490
496
|
}), [onLoadMore, scrollOffset, state?.collection]);
|
|
491
|
-
|
|
497
|
+
useLoadMoreSentinel(memoedLoadMoreProps, sentinelRef);
|
|
492
498
|
let renderProps = useRenderProps({
|
|
493
499
|
...otherProps,
|
|
494
500
|
id: undefined,
|
|
@@ -500,13 +506,11 @@ export const UNSTABLE_ListBoxLoadingSentinel = createLeafComponent('loader', fun
|
|
|
500
506
|
let optionProps = {
|
|
501
507
|
// For Android talkback
|
|
502
508
|
tabIndex: -1
|
|
509
|
+
// For now don't include aria-posinset and aria-setsize on loader since they aren't keyboard focusable
|
|
510
|
+
// Arguably shouldn't include them ever since it might be confusing to the user to include the loaders as part of the
|
|
511
|
+
// item count
|
|
503
512
|
};
|
|
504
513
|
|
|
505
|
-
if (isVirtualized) {
|
|
506
|
-
optionProps['aria-posinset'] = item.index + 1;
|
|
507
|
-
optionProps['aria-setsize'] = state.collection.size;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
514
|
return (
|
|
511
515
|
<>
|
|
512
516
|
{/* Alway render the sentinel. For now onus is on the user for styling when using flex + gap (this would introduce a gap even though it doesn't take room) */}
|
|
@@ -516,12 +520,12 @@ export const UNSTABLE_ListBoxLoadingSentinel = createLeafComponent('loader', fun
|
|
|
516
520
|
</div>
|
|
517
521
|
{isLoading && renderProps.children && (
|
|
518
522
|
<div
|
|
519
|
-
{...mergeProps(filterDOMProps(props
|
|
523
|
+
{...mergeProps(filterDOMProps(props, {global: true}), optionProps)}
|
|
520
524
|
{...renderProps}
|
|
521
525
|
// aria-selected isn't needed here since this option is not selectable.
|
|
522
526
|
// eslint-disable-next-line jsx-a11y/role-has-required-aria-props
|
|
523
527
|
role="option"
|
|
524
|
-
ref={ref}>
|
|
528
|
+
ref={ref as ForwardedRef<HTMLDivElement>}>
|
|
525
529
|
{renderProps.children}
|
|
526
530
|
</div>
|
|
527
531
|
)}
|
package/src/Menu.tsx
CHANGED
|
@@ -14,9 +14,9 @@ import {AriaMenuProps, FocusScope, mergeProps, useHover, useMenu, useMenuItem, u
|
|
|
14
14
|
import {BaseCollection, Collection, CollectionBuilder, createBranchComponent, createLeafComponent} from '@react-aria/collections';
|
|
15
15
|
import {MenuTriggerProps as BaseMenuTriggerProps, Collection as ICollection, Node, RootMenuTriggerState, TreeState, useMenuTriggerState, useSubmenuTriggerState, useTreeState} from 'react-stately';
|
|
16
16
|
import {CollectionProps, CollectionRendererContext, ItemRenderProps, SectionContext, SectionProps, usePersistedKeys} from './Collection';
|
|
17
|
-
import {ContextValue, DEFAULT_SLOT, Provider, RenderProps,
|
|
17
|
+
import {ContextValue, DEFAULT_SLOT, Provider, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps, useSlot, useSlottedContext} from './utils';
|
|
18
18
|
import {filterDOMProps, mergeRefs, useObjectRef, useResizeObserver} from '@react-aria/utils';
|
|
19
|
-
import {FocusStrategy, forwardRefType, HoverEvents, Key, LinkDOMProps, MultipleSelection} from '@react-types/shared';
|
|
19
|
+
import {FocusStrategy, forwardRefType, GlobalDOMAttributes, HoverEvents, Key, LinkDOMProps, MultipleSelection, PressEvents} from '@react-types/shared';
|
|
20
20
|
import {HeaderContext} from './Header';
|
|
21
21
|
import {KeyboardContext} from './Keyboard';
|
|
22
22
|
import {MultipleSelectionState, SelectionManager, useMultipleSelectionState} from '@react-stately/selection';
|
|
@@ -156,7 +156,7 @@ export interface MenuRenderProps {
|
|
|
156
156
|
isEmpty: boolean
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
export interface MenuProps<T> extends Omit<AriaMenuProps<T>, 'children'>, CollectionProps<T>, StyleRenderProps<MenuRenderProps>, SlotProps,
|
|
159
|
+
export interface MenuProps<T> extends Omit<AriaMenuProps<T>, 'children'>, CollectionProps<T>, StyleRenderProps<MenuRenderProps>, SlotProps, GlobalDOMAttributes<HTMLDivElement> {
|
|
160
160
|
/** Provides content to display when there are no items in the list. */
|
|
161
161
|
renderEmptyState?: () => ReactNode
|
|
162
162
|
}
|
|
@@ -214,12 +214,12 @@ function MenuInner<T extends object>({props, collection, menuRef: ref}: MenuInne
|
|
|
214
214
|
);
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
let DOMProps = filterDOMProps(props, {global: true});
|
|
218
|
+
|
|
217
219
|
return (
|
|
218
220
|
<FocusScope>
|
|
219
221
|
<div
|
|
220
|
-
{...
|
|
221
|
-
{...menuProps}
|
|
222
|
-
{...renderProps}
|
|
222
|
+
{...mergeProps(DOMProps, renderProps, menuProps)}
|
|
223
223
|
ref={ref}
|
|
224
224
|
slot={props.slot || undefined}
|
|
225
225
|
data-empty={state.collection.size === 0 || undefined}
|
|
@@ -301,11 +301,12 @@ function MenuSectionInner<T extends object>(props: MenuSectionProps<T>, ref: For
|
|
|
301
301
|
let selectionState = useMultipleSelectionState(props);
|
|
302
302
|
let manager = props.selectionMode != null ? new GroupSelectionManager(parent, selectionState) : parent;
|
|
303
303
|
|
|
304
|
+
let DOMProps = filterDOMProps(props as any, {global: true});
|
|
305
|
+
delete DOMProps.id;
|
|
306
|
+
|
|
304
307
|
return (
|
|
305
308
|
<section
|
|
306
|
-
{...
|
|
307
|
-
{...groupProps}
|
|
308
|
-
{...renderProps}
|
|
309
|
+
{...mergeProps(DOMProps, renderProps, groupProps)}
|
|
309
310
|
ref={ref}>
|
|
310
311
|
<Provider
|
|
311
312
|
values={[
|
|
@@ -338,7 +339,7 @@ export interface MenuItemRenderProps extends ItemRenderProps {
|
|
|
338
339
|
isOpen: boolean
|
|
339
340
|
}
|
|
340
341
|
|
|
341
|
-
export interface MenuItemProps<T = object> extends RenderProps<MenuItemRenderProps>, LinkDOMProps, HoverEvents {
|
|
342
|
+
export interface MenuItemProps<T = object> extends RenderProps<MenuItemRenderProps>, LinkDOMProps, HoverEvents, PressEvents, Omit<GlobalDOMAttributes<HTMLDivElement>, 'onClick'> {
|
|
342
343
|
/** The unique id of the item. */
|
|
343
344
|
id?: Key,
|
|
344
345
|
/** The object value that this item represents. When using dynamic collections, this is set automatically. */
|
|
@@ -392,11 +393,13 @@ export const MenuItem = /*#__PURE__*/ createLeafComponent('item', function MenuI
|
|
|
392
393
|
});
|
|
393
394
|
|
|
394
395
|
let ElementType: React.ElementType = props.href ? 'a' : 'div';
|
|
396
|
+
let DOMProps = filterDOMProps(props as any, {global: true});
|
|
397
|
+
delete DOMProps.id;
|
|
398
|
+
delete DOMProps.onClick;
|
|
395
399
|
|
|
396
400
|
return (
|
|
397
401
|
<ElementType
|
|
398
|
-
{...mergeProps(menuItemProps, hoverProps)}
|
|
399
|
-
{...renderProps}
|
|
402
|
+
{...mergeProps(DOMProps, renderProps, menuItemProps, hoverProps)}
|
|
400
403
|
ref={ref}
|
|
401
404
|
data-disabled={states.isDisabled || undefined}
|
|
402
405
|
data-hovered={isHovered || undefined}
|
package/src/Meter.tsx
CHANGED
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
import {AriaMeterProps, useMeter} from 'react-aria';
|
|
14
14
|
import {clamp} from '@react-stately/utils';
|
|
15
15
|
import {ContextValue, RenderProps, SlotProps, useContextProps, useRenderProps, useSlot} from './utils';
|
|
16
|
-
import {
|
|
16
|
+
import {filterDOMProps, mergeProps} from '@react-aria/utils';
|
|
17
|
+
import {forwardRefType, GlobalDOMAttributes} from '@react-types/shared';
|
|
17
18
|
import {LabelContext} from './Label';
|
|
18
19
|
import React, {createContext, ForwardedRef, forwardRef} from 'react';
|
|
19
20
|
|
|
20
|
-
export interface MeterProps extends Omit<AriaMeterProps, 'label'>, RenderProps<MeterRenderProps>, SlotProps {}
|
|
21
|
+
export interface MeterProps extends Omit<AriaMeterProps, 'label'>, RenderProps<MeterRenderProps>, SlotProps, GlobalDOMAttributes<HTMLDivElement> {}
|
|
21
22
|
|
|
22
23
|
export interface MeterRenderProps {
|
|
23
24
|
/**
|
|
@@ -65,8 +66,10 @@ export const Meter = /*#__PURE__*/ (forwardRef as forwardRefType)(function Meter
|
|
|
65
66
|
}
|
|
66
67
|
});
|
|
67
68
|
|
|
69
|
+
let DOMProps = filterDOMProps(props, {global: true});
|
|
70
|
+
|
|
68
71
|
return (
|
|
69
|
-
<div {...
|
|
72
|
+
<div {...mergeProps(DOMProps, renderProps, meterProps)} ref={ref} slot={props.slot || undefined}>
|
|
70
73
|
<LabelContext.Provider value={{...labelProps, ref: labelRef, elementType: 'span'}}>
|
|
71
74
|
{renderProps.children}
|
|
72
75
|
</LabelContext.Provider>
|
package/src/Modal.tsx
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
import {AriaModalOverlayProps, DismissButton, Overlay, useIsSSR, useModalOverlay} from 'react-aria';
|
|
14
14
|
import {ContextValue, Provider, RenderProps, SlotProps, useContextProps, useRenderProps} from './utils';
|
|
15
|
-
import {DOMAttributes, forwardRefType, RefObject} from '@react-types/shared';
|
|
15
|
+
import {DOMAttributes, forwardRefType, GlobalDOMAttributes, RefObject} from '@react-types/shared';
|
|
16
16
|
import {filterDOMProps, mergeProps, mergeRefs, useEnterAnimation, useExitAnimation, useObjectRef, useViewportSize} from '@react-aria/utils';
|
|
17
17
|
import {OverlayTriggerProps, OverlayTriggerState, useOverlayTriggerState} from 'react-stately';
|
|
18
18
|
import {OverlayTriggerStateContext} from './Dialog';
|
|
19
19
|
import React, {createContext, ForwardedRef, forwardRef, useContext, useMemo, useRef} from 'react';
|
|
20
20
|
|
|
21
|
-
export interface ModalOverlayProps extends AriaModalOverlayProps, OverlayTriggerProps, RenderProps<ModalRenderProps>, SlotProps {
|
|
21
|
+
export interface ModalOverlayProps extends AriaModalOverlayProps, OverlayTriggerProps, RenderProps<ModalRenderProps>, SlotProps, GlobalDOMAttributes<HTMLDivElement> {
|
|
22
22
|
/**
|
|
23
23
|
* Whether the modal is currently performing an entry animation.
|
|
24
24
|
*/
|
|
@@ -69,6 +69,12 @@ export const Modal = /*#__PURE__*/ (forwardRef as forwardRefType)(function Modal
|
|
|
69
69
|
let ctx = useContext(InternalModalContext);
|
|
70
70
|
|
|
71
71
|
if (ctx) {
|
|
72
|
+
if (process.env.NODE_ENV !== 'production' && (props.onOpenChange || props.defaultOpen !== undefined || props.isOpen !== undefined)) {
|
|
73
|
+
// create a list of props that are passed in but not allowed when using an external ModalOverlay
|
|
74
|
+
const invalidSet = new Set(['isDismissable', 'isKeyboardDismissDisabled', 'isOpen', 'defaultOpen', 'onOpenChange', 'isEntering', 'isExiting', 'UNSTABLE_portalContainer', 'shouldCloseOnInteractOutside']);
|
|
75
|
+
const invalidProps = Object.keys(props).filter(key => invalidSet.has(key));
|
|
76
|
+
console.warn(`This modal is already wrapped in a ModalOverlay, props [${invalidProps.join(', ')}] should be placed on the ModalOverlay instead.`);
|
|
77
|
+
}
|
|
72
78
|
return <ModalContent {...props} modalRef={ref}>{props.children}</ModalContent>;
|
|
73
79
|
}
|
|
74
80
|
|
|
@@ -116,6 +122,11 @@ function ModalOverlayWithForwardRef(props: ModalOverlayProps, ref: ForwardedRef<
|
|
|
116
122
|
let contextState = useContext(OverlayTriggerStateContext);
|
|
117
123
|
let localState = useOverlayTriggerState(props);
|
|
118
124
|
let state = props.isOpen != null || props.defaultOpen != null || !contextState ? localState : contextState;
|
|
125
|
+
if (state === contextState) {
|
|
126
|
+
if (process.env.NODE_ENV !== 'production' && (props.onOpenChange || props.defaultOpen !== undefined || props.isOpen !== undefined)) {
|
|
127
|
+
console.warn('This modals state is controlled by a trigger, place onOpenChange on the trigger instead.');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
119
130
|
|
|
120
131
|
let objectRef = useObjectRef(ref);
|
|
121
132
|
let modalRef = useRef<HTMLDivElement>(null);
|
|
@@ -168,7 +179,7 @@ function ModalOverlayInner({UNSTABLE_portalContainer, ...props}: ModalOverlayInn
|
|
|
168
179
|
return (
|
|
169
180
|
<Overlay isExiting={props.isExiting} portalContainer={UNSTABLE_portalContainer}>
|
|
170
181
|
<div
|
|
171
|
-
{...mergeProps(filterDOMProps(props
|
|
182
|
+
{...mergeProps(filterDOMProps(props, {global: true}), underlayProps)}
|
|
172
183
|
{...renderProps}
|
|
173
184
|
style={style}
|
|
174
185
|
ref={props.overlayRef}
|
|
@@ -186,7 +197,7 @@ function ModalOverlayInner({UNSTABLE_portalContainer, ...props}: ModalOverlayInn
|
|
|
186
197
|
);
|
|
187
198
|
}
|
|
188
199
|
|
|
189
|
-
interface ModalContentProps extends RenderProps<ModalRenderProps> {
|
|
200
|
+
interface ModalContentProps extends RenderProps<ModalRenderProps>, GlobalDOMAttributes<HTMLDivElement> {
|
|
190
201
|
modalRef: ForwardedRef<HTMLDivElement>
|
|
191
202
|
}
|
|
192
203
|
|
|
@@ -209,7 +220,7 @@ function ModalContent(props: ModalContentProps) {
|
|
|
209
220
|
|
|
210
221
|
return (
|
|
211
222
|
<div
|
|
212
|
-
{...mergeProps(filterDOMProps(props
|
|
223
|
+
{...mergeProps(filterDOMProps(props, {global: true}), modalProps)}
|
|
213
224
|
{...renderProps}
|
|
214
225
|
ref={ref}
|
|
215
226
|
data-entering={entering || undefined}
|