react-aria-components 1.9.0 → 1.10.1
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/Checkbox.main.js +4 -1
- package/dist/Checkbox.main.js.map +1 -1
- package/dist/Checkbox.mjs +5 -2
- package/dist/Checkbox.module.js +5 -2
- package/dist/Checkbox.module.js.map +1 -1
- package/dist/Collection.main.js +31 -7
- package/dist/Collection.main.js.map +1 -1
- package/dist/Collection.mjs +32 -9
- package/dist/Collection.module.js +32 -9
- package/dist/Collection.module.js.map +1 -1
- package/dist/ComboBox.main.js +10 -1
- package/dist/ComboBox.main.js.map +1 -1
- package/dist/ComboBox.mjs +10 -1
- package/dist/ComboBox.module.js +10 -1
- package/dist/ComboBox.module.js.map +1 -1
- package/dist/DatePicker.main.js +11 -2
- package/dist/DatePicker.main.js.map +1 -1
- package/dist/DatePicker.mjs +11 -2
- package/dist/DatePicker.module.js +11 -2
- package/dist/DatePicker.module.js.map +1 -1
- package/dist/DragAndDrop.main.js.map +1 -1
- package/dist/DragAndDrop.module.js.map +1 -1
- package/dist/Popover.main.js +12 -2
- package/dist/Popover.main.js.map +1 -1
- package/dist/Popover.mjs +13 -3
- package/dist/Popover.module.js +13 -3
- package/dist/Popover.module.js.map +1 -1
- package/dist/RadioGroup.main.js +4 -1
- package/dist/RadioGroup.main.js.map +1 -1
- package/dist/RadioGroup.mjs +5 -2
- package/dist/RadioGroup.module.js +5 -2
- package/dist/RadioGroup.module.js.map +1 -1
- package/dist/Select.main.js +10 -2
- package/dist/Select.main.js.map +1 -1
- package/dist/Select.mjs +10 -2
- package/dist/Select.module.js +10 -2
- package/dist/Select.module.js.map +1 -1
- package/dist/Tabs.main.js +2 -1
- package/dist/Tabs.main.js.map +1 -1
- package/dist/Tabs.mjs +2 -1
- package/dist/Tabs.module.js +2 -1
- package/dist/Tabs.module.js.map +1 -1
- package/dist/Tree.main.js +296 -18
- package/dist/Tree.main.js.map +1 -1
- package/dist/Tree.mjs +299 -21
- package/dist/Tree.module.js +299 -21
- package/dist/Tree.module.js.map +1 -1
- package/dist/TreeDropTargetDelegate.main.js +213 -0
- package/dist/TreeDropTargetDelegate.main.js.map +1 -0
- package/dist/TreeDropTargetDelegate.mjs +208 -0
- package/dist/TreeDropTargetDelegate.module.js +208 -0
- package/dist/TreeDropTargetDelegate.module.js.map +1 -0
- package/dist/Virtualizer.main.js +8 -9
- package/dist/Virtualizer.main.js.map +1 -1
- package/dist/Virtualizer.mjs +9 -10
- package/dist/Virtualizer.module.js +9 -10
- package/dist/Virtualizer.module.js.map +1 -1
- package/dist/main.js.map +1 -1
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +23 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/useDragAndDrop.main.js +2 -2
- package/dist/useDragAndDrop.main.js.map +1 -1
- package/dist/useDragAndDrop.mjs +2 -2
- package/dist/useDragAndDrop.module.js +2 -2
- package/dist/useDragAndDrop.module.js.map +1 -1
- package/package.json +32 -28
- package/src/Checkbox.tsx +2 -2
- package/src/Collection.tsx +39 -5
- package/src/ComboBox.tsx +5 -1
- package/src/DatePicker.tsx +7 -2
- package/src/DragAndDrop.tsx +1 -1
- package/src/Popover.tsx +21 -5
- package/src/RadioGroup.tsx +2 -2
- package/src/Select.tsx +6 -2
- package/src/Tabs.tsx +2 -1
- package/src/Tree.tsx +364 -38
- package/src/TreeDropTargetDelegate.ts +304 -0
- package/src/Virtualizer.tsx +7 -8
- package/src/index.ts +3 -2
- package/src/useDragAndDrop.tsx +2 -1
package/src/Collection.tsx
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import {CollectionBase, DropTargetDelegate, ItemDropTarget, Key, LayoutDelegate, RefObject} from '@react-types/shared';
|
|
13
13
|
import {createBranchComponent, useCachedChildren} from '@react-aria/collections';
|
|
14
14
|
import {Collection as ICollection, Node, SelectionBehavior, SelectionMode, SectionProps as SharedSectionProps} from 'react-stately';
|
|
15
|
-
import React, {createContext, ForwardedRef, HTMLAttributes, JSX, ReactElement, ReactNode, useContext, useMemo} from 'react';
|
|
15
|
+
import React, {cloneElement, createContext, ForwardedRef, HTMLAttributes, isValidElement, JSX, ReactElement, ReactNode, useContext, useMemo} from 'react';
|
|
16
16
|
import {StyleProps} from './utils';
|
|
17
17
|
|
|
18
18
|
export interface CollectionProps<T> extends Omit<CollectionBase<T>, 'children'> {
|
|
@@ -164,19 +164,53 @@ function useCollectionRender(
|
|
|
164
164
|
return rendered;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
let key = node.key;
|
|
168
|
-
let keyAfter = collection.getKeyAfter(key);
|
|
169
167
|
return (
|
|
170
168
|
<>
|
|
171
|
-
{renderDropIndicator({type: 'item', key, dropPosition: 'before'})}
|
|
169
|
+
{renderDropIndicator({type: 'item', key: node.key, dropPosition: 'before'})}
|
|
172
170
|
{rendered}
|
|
173
|
-
{(
|
|
171
|
+
{renderAfterDropIndicators(collection, node, renderDropIndicator)}
|
|
174
172
|
</>
|
|
175
173
|
);
|
|
176
174
|
}
|
|
177
175
|
});
|
|
178
176
|
}
|
|
179
177
|
|
|
178
|
+
export function renderAfterDropIndicators(collection: ICollection<Node<unknown>>, node: Node<unknown>, renderDropIndicator: (target: ItemDropTarget) => ReactNode): ReactNode {
|
|
179
|
+
let key = node.key;
|
|
180
|
+
let keyAfter = collection.getKeyAfter(key);
|
|
181
|
+
let nextItemInFlattenedCollection = keyAfter != null ? collection.getItem(keyAfter) : null;
|
|
182
|
+
while (nextItemInFlattenedCollection != null && nextItemInFlattenedCollection.type !== 'item') {
|
|
183
|
+
keyAfter = collection.getKeyAfter(nextItemInFlattenedCollection.key);
|
|
184
|
+
nextItemInFlattenedCollection = keyAfter != null ? collection.getItem(keyAfter) : null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
let nextItemInSameLevel = node.nextKey != null ? collection.getItem(node.nextKey) : null;
|
|
188
|
+
while (nextItemInSameLevel != null && nextItemInSameLevel.type !== 'item') {
|
|
189
|
+
nextItemInSameLevel = nextItemInSameLevel.nextKey != null ? collection.getItem(nextItemInSameLevel.nextKey) : null;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Render one or more "after" drop indicators when the next item in the flattened collection
|
|
193
|
+
// has a smaller level, is not an item, or there are no more items in the collection.
|
|
194
|
+
// Otherwise, the "after" position is equivalent to the next item's "before" position.
|
|
195
|
+
let afterIndicators: ReactNode[] = [];
|
|
196
|
+
if (nextItemInSameLevel == null) {
|
|
197
|
+
let current: Node<unknown> | null = node;
|
|
198
|
+
while (current && (!nextItemInFlattenedCollection || (current.parentKey !== nextItemInFlattenedCollection.parentKey && nextItemInFlattenedCollection.level < current.level))) {
|
|
199
|
+
let indicator = renderDropIndicator({
|
|
200
|
+
type: 'item',
|
|
201
|
+
key: current.key,
|
|
202
|
+
dropPosition: 'after'
|
|
203
|
+
});
|
|
204
|
+
if (isValidElement(indicator)) {
|
|
205
|
+
afterIndicators.push(cloneElement(indicator, {key: `${current.key}-after`}));
|
|
206
|
+
}
|
|
207
|
+
current = current.parentKey != null ? collection.getItem(current.parentKey) : null;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return afterIndicators;
|
|
212
|
+
}
|
|
213
|
+
|
|
180
214
|
export const CollectionRendererContext = createContext<CollectionRenderer>(DefaultCollectionRenderer);
|
|
181
215
|
|
|
182
216
|
type PersistedKeysReturnValue = Set<Key> | null;
|
package/src/ComboBox.tsx
CHANGED
|
@@ -93,6 +93,9 @@ export const ComboBox = /*#__PURE__*/ (forwardRef as forwardRefType)(function Co
|
|
|
93
93
|
);
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
+
// Contexts to clear inside the popover.
|
|
97
|
+
const CLEAR_CONTEXTS = [LabelContext, ButtonContext, InputContext, GroupContext, TextContext];
|
|
98
|
+
|
|
96
99
|
interface ComboBoxInnerProps<T extends object> {
|
|
97
100
|
props: ComboBoxProps<T>,
|
|
98
101
|
collection: Collection<Node<T>>,
|
|
@@ -197,7 +200,8 @@ function ComboBoxInner<T extends object>({props, collection, comboBoxRef: ref}:
|
|
|
197
200
|
placement: 'bottom start',
|
|
198
201
|
isNonModal: true,
|
|
199
202
|
trigger: 'ComboBox',
|
|
200
|
-
style: {'--trigger-width': menuWidth} as React.CSSProperties
|
|
203
|
+
style: {'--trigger-width': menuWidth} as React.CSSProperties,
|
|
204
|
+
clearContexts: CLEAR_CONTEXTS
|
|
201
205
|
}],
|
|
202
206
|
[ListBoxContext, {...listBoxProps, ref: listBoxRef}],
|
|
203
207
|
[ListStateContext, state],
|
package/src/DatePicker.tsx
CHANGED
|
@@ -72,6 +72,9 @@ export const DateRangePickerContext = createContext<ContextValue<DateRangePicker
|
|
|
72
72
|
export const DatePickerStateContext = createContext<DatePickerState | null>(null);
|
|
73
73
|
export const DateRangePickerStateContext = createContext<DateRangePickerState | null>(null);
|
|
74
74
|
|
|
75
|
+
// Contexts to clear inside the popover.
|
|
76
|
+
const CLEAR_CONTEXTS = [GroupContext, ButtonContext, LabelContext, TextContext];
|
|
77
|
+
|
|
75
78
|
/**
|
|
76
79
|
* A date picker combines a DateField and a Calendar popover to allow users to enter or select a date and time value.
|
|
77
80
|
*/
|
|
@@ -148,7 +151,8 @@ export const DatePicker = /*#__PURE__*/ (forwardRef as forwardRefType)(function
|
|
|
148
151
|
trigger: 'DatePicker',
|
|
149
152
|
triggerRef: groupRef,
|
|
150
153
|
placement: 'bottom start',
|
|
151
|
-
style: {'--trigger-width': groupWidth} as React.CSSProperties
|
|
154
|
+
style: {'--trigger-width': groupWidth} as React.CSSProperties,
|
|
155
|
+
clearContexts: CLEAR_CONTEXTS
|
|
152
156
|
}],
|
|
153
157
|
[DialogContext, dialogProps],
|
|
154
158
|
[TextContext, {
|
|
@@ -251,7 +255,8 @@ export const DateRangePicker = /*#__PURE__*/ (forwardRef as forwardRefType)(func
|
|
|
251
255
|
trigger: 'DateRangePicker',
|
|
252
256
|
triggerRef: groupRef,
|
|
253
257
|
placement: 'bottom start',
|
|
254
|
-
style: {'--trigger-width': groupWidth} as React.CSSProperties
|
|
258
|
+
style: {'--trigger-width': groupWidth} as React.CSSProperties,
|
|
259
|
+
clearContexts: CLEAR_CONTEXTS
|
|
255
260
|
}],
|
|
256
261
|
[DialogContext, dialogProps],
|
|
257
262
|
[DateFieldContext, {
|
package/src/DragAndDrop.tsx
CHANGED
|
@@ -32,7 +32,7 @@ export interface DropIndicatorRenderProps {
|
|
|
32
32
|
isDropTarget: boolean
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export interface DropIndicatorProps extends AriaDropIndicatorProps, RenderProps<DropIndicatorRenderProps> { }
|
|
35
|
+
export interface DropIndicatorProps extends Omit<AriaDropIndicatorProps, 'activateButtonRef'>, RenderProps<DropIndicatorRenderProps> { }
|
|
36
36
|
interface DropIndicatorContextValue {
|
|
37
37
|
render: (props: DropIndicatorProps, ref: ForwardedRef<HTMLElement>) => ReactNode
|
|
38
38
|
}
|
package/src/Popover.tsx
CHANGED
|
@@ -18,7 +18,7 @@ import {focusSafely} from '@react-aria/interactions';
|
|
|
18
18
|
import {OverlayArrowContext} from './OverlayArrow';
|
|
19
19
|
import {OverlayTriggerProps, OverlayTriggerState, useOverlayTriggerState} from 'react-stately';
|
|
20
20
|
import {OverlayTriggerStateContext} from './Dialog';
|
|
21
|
-
import React, {createContext, ForwardedRef, forwardRef, useContext, useEffect, useRef, useState} from 'react';
|
|
21
|
+
import React, {Context, createContext, ForwardedRef, forwardRef, useContext, useEffect, useMemo, useRef, useState} from 'react';
|
|
22
22
|
import {useIsHidden} from '@react-aria/collections';
|
|
23
23
|
|
|
24
24
|
export interface PopoverProps extends Omit<PositionProps, 'isOpen'>, Omit<AriaPopoverProps, 'popoverRef' | 'triggerRef' | 'groupRef' | 'offset' | 'arrowSize'>, OverlayTriggerProps, RenderProps<PopoverRenderProps>, SlotProps, AriaLabelingProps {
|
|
@@ -80,7 +80,12 @@ export interface PopoverRenderProps {
|
|
|
80
80
|
isExiting: boolean
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
interface PopoverContextValue extends PopoverProps {
|
|
84
|
+
/** Contexts to clear. */
|
|
85
|
+
clearContexts?: Context<any>[]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const PopoverContext = createContext<ContextValue<PopoverContextValue, HTMLElement>>(null);
|
|
84
89
|
|
|
85
90
|
// Stores a ref for the portal container for a group of popovers (e.g. submenus).
|
|
86
91
|
const PopoverGroupContext = createContext<RefObject<Element | null> | null>(null);
|
|
@@ -134,10 +139,11 @@ interface PopoverInnerProps extends AriaPopoverProps, RenderProps<PopoverRenderP
|
|
|
134
139
|
isExiting: boolean,
|
|
135
140
|
UNSTABLE_portalContainer?: Element,
|
|
136
141
|
trigger?: string,
|
|
137
|
-
dir?: 'ltr' | 'rtl'
|
|
142
|
+
dir?: 'ltr' | 'rtl',
|
|
143
|
+
clearContexts?: Context<any>[]
|
|
138
144
|
}
|
|
139
145
|
|
|
140
|
-
function PopoverInner({state, isExiting, UNSTABLE_portalContainer, ...props}: PopoverInnerProps) {
|
|
146
|
+
function PopoverInner({state, isExiting, UNSTABLE_portalContainer, clearContexts, ...props}: PopoverInnerProps) {
|
|
141
147
|
// Calculate the arrow size internally (and remove props.arrowSize from PopoverProps)
|
|
142
148
|
// Referenced from: packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx
|
|
143
149
|
let arrowRef = useRef<HTMLDivElement>(null);
|
|
@@ -190,6 +196,16 @@ function PopoverInner({state, isExiting, UNSTABLE_portalContainer, ...props}: Po
|
|
|
190
196
|
}
|
|
191
197
|
}, [isDialog, ref]);
|
|
192
198
|
|
|
199
|
+
let children = useMemo(() => {
|
|
200
|
+
let children = renderProps.children;
|
|
201
|
+
if (clearContexts) {
|
|
202
|
+
for (let Context of clearContexts) {
|
|
203
|
+
children = <Context.Provider value={null}>{children}</Context.Provider>;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return children;
|
|
207
|
+
}, [renderProps.children, clearContexts]);
|
|
208
|
+
|
|
193
209
|
let style = {...popoverProps.style, ...renderProps.style};
|
|
194
210
|
let overlay = (
|
|
195
211
|
<div
|
|
@@ -209,7 +225,7 @@ function PopoverInner({state, isExiting, UNSTABLE_portalContainer, ...props}: Po
|
|
|
209
225
|
data-exiting={isExiting || undefined}>
|
|
210
226
|
{!props.isNonModal && <DismissButton onDismiss={state.close} />}
|
|
211
227
|
<OverlayArrowContext.Provider value={{...arrowProps, placement, ref: arrowRef}}>
|
|
212
|
-
{
|
|
228
|
+
{children}
|
|
213
229
|
</OverlayArrowContext.Provider>
|
|
214
230
|
<DismissButton onDismiss={state.close} />
|
|
215
231
|
</div>
|
package/src/RadioGroup.tsx
CHANGED
|
@@ -18,7 +18,7 @@ import {FormContext} from './Form';
|
|
|
18
18
|
import {forwardRefType, RefObject} from '@react-types/shared';
|
|
19
19
|
import {LabelContext} from './Label';
|
|
20
20
|
import {RadioGroupState, useRadioGroupState} from 'react-stately';
|
|
21
|
-
import React, {createContext, ForwardedRef, forwardRef} from 'react';
|
|
21
|
+
import React, {createContext, ForwardedRef, forwardRef, useMemo} from 'react';
|
|
22
22
|
import {TextContext} from './Text';
|
|
23
23
|
|
|
24
24
|
export interface RadioGroupProps extends Omit<AriaRadioGroupProps, 'children' | 'label' | 'description' | 'errorMessage' | 'validationState' | 'validationBehavior'>, RACValidation, RenderProps<RadioGroupRenderProps>, SlotProps {}
|
|
@@ -186,7 +186,7 @@ export const Radio = /*#__PURE__*/ (forwardRef as forwardRefType)(function Radio
|
|
|
186
186
|
} = props;
|
|
187
187
|
[props, ref] = useContextProps(otherProps, ref, RadioContext);
|
|
188
188
|
let state = React.useContext(RadioGroupStateContext)!;
|
|
189
|
-
let inputRef = useObjectRef(mergeRefs(userProvidedInputRef, props.inputRef !== undefined ? props.inputRef : null));
|
|
189
|
+
let inputRef = useObjectRef(useMemo(() => mergeRefs(userProvidedInputRef, props.inputRef !== undefined ? props.inputRef : null), [userProvidedInputRef, props.inputRef]));
|
|
190
190
|
let {labelProps, inputProps, isSelected, isDisabled, isPressed} = useRadio({
|
|
191
191
|
...removeDataAttributes<RadioProps>(props),
|
|
192
192
|
// ReactNode type doesn't allow function children.
|
package/src/Select.tsx
CHANGED
|
@@ -100,6 +100,9 @@ export const Select = /*#__PURE__*/ (forwardRef as forwardRefType)(function Sele
|
|
|
100
100
|
);
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
+
// Contexts to clear inside the popover.
|
|
104
|
+
const CLEAR_CONTEXTS = [LabelContext, ButtonContext, TextContext];
|
|
105
|
+
|
|
103
106
|
interface SelectInnerProps<T extends object> {
|
|
104
107
|
props: SelectProps<T>,
|
|
105
108
|
selectRef: ForwardedRef<HTMLDivElement>,
|
|
@@ -178,7 +181,7 @@ function SelectInner<T extends object>({props, selectRef: ref, collection}: Sele
|
|
|
178
181
|
[SelectStateContext, state],
|
|
179
182
|
[SelectValueContext, valueProps],
|
|
180
183
|
[LabelContext, {...labelProps, ref: labelRef, elementType: 'span'}],
|
|
181
|
-
[ButtonContext, {...triggerProps, ref: buttonRef, isPressed: state.isOpen}],
|
|
184
|
+
[ButtonContext, {...triggerProps, ref: buttonRef, isPressed: state.isOpen, autoFocus: props.autoFocus}],
|
|
182
185
|
[OverlayTriggerStateContext, state],
|
|
183
186
|
[PopoverContext, {
|
|
184
187
|
trigger: 'Select',
|
|
@@ -186,7 +189,8 @@ function SelectInner<T extends object>({props, selectRef: ref, collection}: Sele
|
|
|
186
189
|
scrollRef,
|
|
187
190
|
placement: 'bottom start',
|
|
188
191
|
style: {'--trigger-width': buttonWidth} as React.CSSProperties,
|
|
189
|
-
'aria-labelledby': menuProps['aria-labelledby']
|
|
192
|
+
'aria-labelledby': menuProps['aria-labelledby'],
|
|
193
|
+
clearContexts: CLEAR_CONTEXTS
|
|
190
194
|
}],
|
|
191
195
|
[ListBoxContext, {...menuProps, ref: scrollRef}],
|
|
192
196
|
[ListStateContext, state],
|
package/src/Tabs.tsx
CHANGED
|
@@ -300,7 +300,8 @@ export const TabPanel = /*#__PURE__*/ createHideableComponent(function TabPanel(
|
|
|
300
300
|
values: {
|
|
301
301
|
isFocused,
|
|
302
302
|
isFocusVisible,
|
|
303
|
-
|
|
303
|
+
// @ts-ignore - compatibility with React < 19
|
|
304
|
+
isInert: inertValue(!isSelected),
|
|
304
305
|
state
|
|
305
306
|
}
|
|
306
307
|
});
|