react-aria-components 1.7.1 → 1.9.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/Autocomplete.main.js.map +1 -1
- package/dist/Autocomplete.module.js.map +1 -1
- package/dist/Calendar.main.js +5 -7
- package/dist/Calendar.main.js.map +1 -1
- package/dist/Calendar.mjs +6 -8
- package/dist/Calendar.module.js +6 -8
- package/dist/Calendar.module.js.map +1 -1
- package/dist/Collection.main.js +1 -1
- package/dist/Collection.main.js.map +1 -1
- package/dist/Collection.mjs +1 -1
- package/dist/Collection.module.js +1 -1
- package/dist/Collection.module.js.map +1 -1
- package/dist/ColorPicker.main.js.map +1 -1
- package/dist/ColorPicker.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/DateField.main.js +16 -9
- package/dist/DateField.main.js.map +1 -1
- package/dist/DateField.mjs +16 -9
- package/dist/DateField.module.js +16 -9
- package/dist/DateField.module.js.map +1 -1
- package/dist/Dialog.main.js +16 -2
- package/dist/Dialog.main.js.map +1 -1
- package/dist/Dialog.mjs +18 -4
- package/dist/Dialog.module.js +18 -4
- package/dist/Dialog.module.js.map +1 -1
- package/dist/DragAndDrop.main.js.map +1 -1
- package/dist/DragAndDrop.module.js.map +1 -1
- package/dist/GridList.main.js +61 -5
- package/dist/GridList.main.js.map +1 -1
- package/dist/GridList.mjs +62 -7
- package/dist/GridList.module.js +62 -7
- package/dist/GridList.module.js.map +1 -1
- package/dist/ListBox.main.js +63 -4
- package/dist/ListBox.main.js.map +1 -1
- package/dist/ListBox.mjs +64 -6
- package/dist/ListBox.module.js +64 -6
- package/dist/ListBox.module.js.map +1 -1
- package/dist/Menu.main.js.map +1 -1
- package/dist/Menu.module.js.map +1 -1
- package/dist/Modal.main.js.map +1 -1
- package/dist/Modal.module.js.map +1 -1
- package/dist/OverlayArrow.main.js +4 -1
- package/dist/OverlayArrow.main.js.map +1 -1
- package/dist/OverlayArrow.mjs +4 -1
- package/dist/OverlayArrow.module.js +4 -1
- package/dist/OverlayArrow.module.js.map +1 -1
- package/dist/Popover.main.js +1 -1
- package/dist/Popover.main.js.map +1 -1
- package/dist/Popover.mjs +1 -1
- package/dist/Popover.module.js +1 -1
- package/dist/Popover.module.js.map +1 -1
- package/dist/Select.main.js.map +1 -1
- package/dist/Select.module.js.map +1 -1
- package/dist/Separator.main.js +3 -2
- package/dist/Separator.main.js.map +1 -1
- package/dist/Separator.mjs +3 -2
- package/dist/Separator.module.js +3 -2
- package/dist/Separator.module.js.map +1 -1
- package/dist/Table.main.js +45 -12
- package/dist/Table.main.js.map +1 -1
- package/dist/Table.mjs +46 -13
- package/dist/Table.module.js +46 -13
- package/dist/Table.module.js.map +1 -1
- package/dist/TableLayout.main.js.map +1 -1
- package/dist/TableLayout.module.js.map +1 -1
- package/dist/TagGroup.main.js +2 -2
- package/dist/TagGroup.main.js.map +1 -1
- package/dist/TagGroup.mjs +2 -2
- package/dist/TagGroup.module.js +2 -2
- package/dist/TagGroup.module.js.map +1 -1
- package/dist/TextArea.main.js.map +1 -1
- package/dist/TextArea.module.js.map +1 -1
- package/dist/Toast.main.js +45 -16
- package/dist/Toast.main.js.map +1 -1
- package/dist/Toast.mjs +45 -18
- package/dist/Toast.module.js +45 -18
- package/dist/Toast.module.js.map +1 -1
- package/dist/Tooltip.main.js.map +1 -1
- package/dist/Tooltip.module.js.map +1 -1
- package/dist/Tree.main.js +2 -2
- package/dist/Tree.main.js.map +1 -1
- package/dist/Tree.mjs +2 -2
- package/dist/Tree.module.js +2 -2
- package/dist/Tree.module.js.map +1 -1
- package/dist/Virtualizer.main.js +0 -1
- package/dist/Virtualizer.main.js.map +1 -1
- package/dist/Virtualizer.mjs +0 -1
- package/dist/Virtualizer.module.js +0 -1
- package/dist/Virtualizer.module.js.map +1 -1
- package/dist/import.mjs +6 -6
- package/dist/main.js +6 -1
- package/dist/main.js.map +1 -1
- package/dist/module.js +6 -6
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +121 -45
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.main.js.map +1 -1
- package/dist/utils.module.js.map +1 -1
- package/i18n/es-ES.js +1 -1
- package/i18n/es-ES.mjs +1 -1
- package/i18n/index.js +1 -1
- package/i18n/index.mjs +1 -1
- package/package.json +27 -25
- package/src/Autocomplete.tsx +2 -2
- package/src/Calendar.tsx +23 -11
- package/src/Collection.tsx +5 -2
- package/src/ColorPicker.tsx +2 -2
- package/src/ColorWheel.tsx +3 -1
- package/src/DateField.tsx +13 -9
- package/src/Dialog.tsx +19 -5
- package/src/DragAndDrop.tsx +4 -2
- package/src/GridList.tsx +73 -8
- package/src/ListBox.tsx +74 -7
- package/src/Menu.tsx +2 -1
- package/src/Modal.tsx +1 -0
- package/src/OverlayArrow.tsx +6 -3
- package/src/Popover.tsx +2 -1
- package/src/Select.tsx +7 -1
- package/src/Separator.tsx +3 -2
- package/src/Table.tsx +52 -19
- package/src/TableLayout.ts +1 -1
- package/src/TagGroup.tsx +2 -2
- package/src/TextArea.tsx +1 -1
- package/src/Toast.tsx +51 -13
- package/src/Tooltip.tsx +3 -2
- package/src/Tree.tsx +2 -2
- package/src/Virtualizer.tsx +3 -7
- package/src/index.ts +8 -8
- package/src/utils.tsx +8 -1
package/i18n/index.mjs
CHANGED
|
@@ -83,7 +83,7 @@ function getLocalizationScript(locale, dict = dictionary) {
|
|
|
83
83
|
return getPackageLocalizationScript(locale, strings);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
let deps = {"@react-aria/autocomplete":["@react-aria/combobox","@react-aria/searchfield"],"@react-aria/color":["@react-aria/numberfield","@react-aria/spinbutton","@react-stately/color"],"@react-aria/combobox":["@react-aria/menu","@react-aria/overlays"],"@react-aria/datepicker":["@react-aria/spinbutton","@react-stately/datepicker"],"@react-aria/dnd":["@react-aria/overlays"],"@react-aria/gridlist":["@react-aria/grid"],"@react-aria/menu":["@react-aria/overlays"],"@react-aria/numberfield":["@react-aria/spinbutton"],"@react-aria/table":["@react-aria/grid"],"@react-aria/tag":["@react-aria/gridlist"],"@react-aria/tree":["@react-aria/gridlist"],"react-aria-components":["@react-aria/autocomplete","@react-aria/dnd"]};
|
|
86
|
+
let deps = {"@react-aria/autocomplete":["@react-aria/combobox","@react-aria/searchfield"],"@react-aria/color":["@react-aria/numberfield","@react-aria/spinbutton","@react-stately/color"],"@react-aria/combobox":["@react-aria/menu","@react-aria/overlays"],"@react-aria/datepicker":["@react-aria/spinbutton","@react-stately/datepicker"],"@react-aria/dnd":["@react-aria/overlays"],"@react-aria/gridlist":["@react-aria/grid"],"@react-aria/menu":["@react-aria/overlays"],"@react-aria/numberfield":["@react-aria/spinbutton"],"@react-aria/table":["@react-aria/grid"],"@react-aria/tag":["@react-aria/gridlist"],"@react-aria/tree":["@react-aria/gridlist"],"react-aria-components":["@react-aria/autocomplete","@react-aria/dnd","@react-aria/overlays"]};
|
|
87
87
|
|
|
88
88
|
function createLocalizedStringDictionary(packages) {
|
|
89
89
|
let strings = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-aria-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "A library of styleable components built using React Aria",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -37,31 +37,33 @@
|
|
|
37
37
|
"url": "https://github.com/adobe/react-spectrum"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@internationalized/date": "^3.
|
|
41
|
-
"@internationalized/string": "^3.2.
|
|
42
|
-
"@react-aria/autocomplete": "3.0.0-beta.
|
|
43
|
-
"@react-aria/collections": "3.0.0-
|
|
44
|
-
"@react-aria/dnd": "^3.9.
|
|
45
|
-
"@react-aria/focus": "^3.20.
|
|
46
|
-
"@react-aria/interactions": "^3.
|
|
47
|
-
"@react-aria/live-announcer": "^3.4.
|
|
48
|
-
"@react-aria/
|
|
49
|
-
"@react-aria/
|
|
50
|
-
"@react-aria/
|
|
51
|
-
"@react-
|
|
52
|
-
"@react-
|
|
53
|
-
"@react-stately/
|
|
54
|
-
"@react-stately/
|
|
55
|
-
"@react-stately/
|
|
56
|
-
"@react-stately/
|
|
57
|
-
"@react-
|
|
58
|
-
"@react-
|
|
59
|
-
"@react-types/
|
|
60
|
-
"@react-types/
|
|
40
|
+
"@internationalized/date": "^3.8.1",
|
|
41
|
+
"@internationalized/string": "^3.2.6",
|
|
42
|
+
"@react-aria/autocomplete": "3.0.0-beta.3",
|
|
43
|
+
"@react-aria/collections": "3.0.0-rc.1",
|
|
44
|
+
"@react-aria/dnd": "^3.9.3",
|
|
45
|
+
"@react-aria/focus": "^3.20.3",
|
|
46
|
+
"@react-aria/interactions": "^3.25.1",
|
|
47
|
+
"@react-aria/live-announcer": "^3.4.2",
|
|
48
|
+
"@react-aria/overlays": "^3.27.1",
|
|
49
|
+
"@react-aria/ssr": "^3.9.8",
|
|
50
|
+
"@react-aria/toolbar": "3.0.0-beta.16",
|
|
51
|
+
"@react-aria/utils": "^3.29.0",
|
|
52
|
+
"@react-aria/virtualizer": "^4.1.5",
|
|
53
|
+
"@react-stately/autocomplete": "3.0.0-beta.1",
|
|
54
|
+
"@react-stately/layout": "^4.3.0",
|
|
55
|
+
"@react-stately/selection": "^3.20.2",
|
|
56
|
+
"@react-stately/table": "^3.14.2",
|
|
57
|
+
"@react-stately/utils": "^3.10.6",
|
|
58
|
+
"@react-stately/virtualizer": "^4.4.0",
|
|
59
|
+
"@react-types/form": "^3.7.12",
|
|
60
|
+
"@react-types/grid": "^3.3.2",
|
|
61
|
+
"@react-types/shared": "^3.29.1",
|
|
62
|
+
"@react-types/table": "^3.13.0",
|
|
61
63
|
"@swc/helpers": "^0.5.0",
|
|
62
64
|
"client-only": "^0.0.1",
|
|
63
|
-
"react-aria": "^3.
|
|
64
|
-
"react-stately": "^3.
|
|
65
|
+
"react-aria": "^3.40.0",
|
|
66
|
+
"react-stately": "^3.38.0",
|
|
65
67
|
"use-sync-external-store": "^1.4.0"
|
|
66
68
|
},
|
|
67
69
|
"peerDependencies": {
|
|
@@ -74,5 +76,5 @@
|
|
|
74
76
|
"devDependencies": {
|
|
75
77
|
"@tailwindcss/postcss": "^4.0.0"
|
|
76
78
|
},
|
|
77
|
-
"gitHead": "
|
|
79
|
+
"gitHead": "9c77d4e8267ed39469c65f65da94ece7be509874"
|
|
78
80
|
}
|
package/src/Autocomplete.tsx
CHANGED
|
@@ -15,7 +15,7 @@ import {AutocompleteState, useAutocompleteState} from '@react-stately/autocomple
|
|
|
15
15
|
import {InputContext} from './Input';
|
|
16
16
|
import {mergeProps} from '@react-aria/utils';
|
|
17
17
|
import {Provider, removeDataAttributes, SlotProps, SlottedContextValue, useSlottedContext} from './utils';
|
|
18
|
-
import React, {createContext, RefObject, useRef} from 'react';
|
|
18
|
+
import React, {createContext, JSX, RefObject, useRef} from 'react';
|
|
19
19
|
import {SearchFieldContext} from './SearchField';
|
|
20
20
|
import {TextFieldContext} from './TextField';
|
|
21
21
|
|
|
@@ -36,7 +36,7 @@ export const UNSTABLE_InternalAutocompleteContext = createContext<InternalAutoco
|
|
|
36
36
|
/**
|
|
37
37
|
* An autocomplete combines a TextField or SearchField with a Menu or ListBox, allowing users to search or filter a list of suggestions.
|
|
38
38
|
*/
|
|
39
|
-
export function Autocomplete(props: AutocompleteProps) {
|
|
39
|
+
export function Autocomplete(props: AutocompleteProps): JSX.Element {
|
|
40
40
|
let ctx = useSlottedContext(AutocompleteContext, props.slot);
|
|
41
41
|
props = mergeProps(ctx, props);
|
|
42
42
|
let {filter, disableAutoFocusFirst} = props;
|
package/src/Calendar.tsx
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
VisuallyHidden
|
|
25
25
|
} from 'react-aria';
|
|
26
26
|
import {ButtonContext} from './Button';
|
|
27
|
-
import {CalendarDate, createCalendar, DateDuration, endOfMonth,
|
|
27
|
+
import {CalendarDate, CalendarIdentifier, createCalendar, DateDuration, endOfMonth, Calendar as ICalendar, isSameDay, isSameMonth} from '@internationalized/date';
|
|
28
28
|
import {CalendarState, RangeCalendarState, useCalendarState, useRangeCalendarState} from 'react-stately';
|
|
29
29
|
import {ContextValue, DOMProps, Provider, RenderProps, SlotProps, StyleProps, useContextProps, useRenderProps, useSlottedContext} from './utils';
|
|
30
30
|
import {DOMAttributes, FocusableElement, forwardRefType, HoverEvents} from '@react-types/shared';
|
|
@@ -62,7 +62,14 @@ export interface CalendarProps<T extends DateValue> extends Omit<AriaCalendarPro
|
|
|
62
62
|
* The amount of days that will be displayed at once. This affects how pagination works.
|
|
63
63
|
* @default {months: 1}
|
|
64
64
|
*/
|
|
65
|
-
visibleDuration?: DateDuration
|
|
65
|
+
visibleDuration?: DateDuration,
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A function to create a new [Calendar](https://react-spectrum.adobe.com/internationalized/date/Calendar.html)
|
|
69
|
+
* object for a given calendar identifier. If not provided, the `createCalendar` function
|
|
70
|
+
* from `@internationalized/date` will be used.
|
|
71
|
+
*/
|
|
72
|
+
createCalendar?: (identifier: CalendarIdentifier) => ICalendar
|
|
66
73
|
}
|
|
67
74
|
|
|
68
75
|
export interface RangeCalendarProps<T extends DateValue> extends Omit<AriaRangeCalendarProps<T>, 'errorMessage' | 'validationState'>, RenderProps<RangeCalendarRenderProps>, SlotProps {
|
|
@@ -70,7 +77,14 @@ export interface RangeCalendarProps<T extends DateValue> extends Omit<AriaRangeC
|
|
|
70
77
|
* The amount of days that will be displayed at once. This affects how pagination works.
|
|
71
78
|
* @default {months: 1}
|
|
72
79
|
*/
|
|
73
|
-
visibleDuration?: DateDuration
|
|
80
|
+
visibleDuration?: DateDuration,
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* A function to create a new [Calendar](https://react-spectrum.adobe.com/internationalized/date/Calendar.html)
|
|
84
|
+
* object for a given calendar identifier. If not provided, the `createCalendar` function
|
|
85
|
+
* from `@internationalized/date` will be used.
|
|
86
|
+
*/
|
|
87
|
+
createCalendar?: (identifier: CalendarIdentifier) => ICalendar
|
|
74
88
|
}
|
|
75
89
|
|
|
76
90
|
export const CalendarContext = createContext<ContextValue<CalendarProps<any>, HTMLDivElement>>(null);
|
|
@@ -87,7 +101,7 @@ export const Calendar = /*#__PURE__*/ (forwardRef as forwardRefType)(function Ca
|
|
|
87
101
|
let state = useCalendarState({
|
|
88
102
|
...props,
|
|
89
103
|
locale,
|
|
90
|
-
createCalendar
|
|
104
|
+
createCalendar: props.createCalendar || createCalendar
|
|
91
105
|
});
|
|
92
106
|
|
|
93
107
|
let {calendarProps, prevButtonProps, nextButtonProps, errorMessageProps, title} = useCalendar(props, state);
|
|
@@ -160,7 +174,7 @@ export const RangeCalendar = /*#__PURE__*/ (forwardRef as forwardRefType)(functi
|
|
|
160
174
|
let state = useRangeCalendarState({
|
|
161
175
|
...props,
|
|
162
176
|
locale,
|
|
163
|
-
createCalendar
|
|
177
|
+
createCalendar: props.createCalendar || createCalendar
|
|
164
178
|
});
|
|
165
179
|
|
|
166
180
|
let {calendarProps, prevButtonProps, nextButtonProps, errorMessageProps, title} = useRangeCalendar(
|
|
@@ -329,7 +343,7 @@ interface InternalCalendarGridContextValue {
|
|
|
329
343
|
headerProps: DOMAttributes<FocusableElement>,
|
|
330
344
|
weekDays: string[],
|
|
331
345
|
startDate: CalendarDate,
|
|
332
|
-
|
|
346
|
+
weeksInMonth: number
|
|
333
347
|
}
|
|
334
348
|
|
|
335
349
|
const InternalCalendarGridContext = createContext<InternalCalendarGridContextValue | null>(null);
|
|
@@ -351,7 +365,7 @@ export const CalendarGrid = /*#__PURE__*/ (forwardRef as forwardRefType)(functio
|
|
|
351
365
|
|
|
352
366
|
let firstDayOfWeek = calenderProps?.firstDayOfWeek ?? rangeCalenderProps?.firstDayOfWeek;
|
|
353
367
|
|
|
354
|
-
let {gridProps, headerProps, weekDays} = useCalendarGrid({
|
|
368
|
+
let {gridProps, headerProps, weekDays, weeksInMonth} = useCalendarGrid({
|
|
355
369
|
startDate,
|
|
356
370
|
endDate: endOfMonth(startDate),
|
|
357
371
|
weekdayStyle: props.weekdayStyle,
|
|
@@ -359,7 +373,7 @@ export const CalendarGrid = /*#__PURE__*/ (forwardRef as forwardRefType)(functio
|
|
|
359
373
|
}, state);
|
|
360
374
|
|
|
361
375
|
return (
|
|
362
|
-
<InternalCalendarGridContext.Provider value={{headerProps, weekDays, startDate,
|
|
376
|
+
<InternalCalendarGridContext.Provider value={{headerProps, weekDays, startDate, weeksInMonth}}>
|
|
363
377
|
<table
|
|
364
378
|
{...filterDOMProps(props as any)}
|
|
365
379
|
{...gridProps}
|
|
@@ -442,9 +456,7 @@ function CalendarGridBody(props: CalendarGridBodyProps, ref: ForwardedRef<HTMLTa
|
|
|
442
456
|
let calendarState = useContext(CalendarStateContext);
|
|
443
457
|
let rangeCalendarState = useContext(RangeCalendarStateContext);
|
|
444
458
|
let state = calendarState ?? rangeCalendarState!;
|
|
445
|
-
let {startDate,
|
|
446
|
-
let {locale} = useLocale();
|
|
447
|
-
let weeksInMonth = getWeeksInMonth(startDate, locale, firstDayOfWeek);
|
|
459
|
+
let {startDate, weeksInMonth} = useContext(InternalCalendarGridContext)!;
|
|
448
460
|
|
|
449
461
|
return (
|
|
450
462
|
<tbody
|
package/src/Collection.tsx
CHANGED
|
@@ -102,7 +102,9 @@ export const SectionContext = createContext<SectionContextValue | null>(null);
|
|
|
102
102
|
/** @deprecated */
|
|
103
103
|
export const Section = /*#__PURE__*/ createBranchComponent('section', <T extends object>(props: SectionProps<T>, ref: ForwardedRef<HTMLElement>, section: Node<T>): JSX.Element => {
|
|
104
104
|
let {name, render} = useContext(SectionContext)!;
|
|
105
|
-
|
|
105
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
106
|
+
console.warn(`<Section> is deprecated. Please use <${name}> instead.`);
|
|
107
|
+
}
|
|
106
108
|
return render(props, ref, section, 'react-aria-Section');
|
|
107
109
|
});
|
|
108
110
|
|
|
@@ -177,6 +179,7 @@ function useCollectionRender(
|
|
|
177
179
|
|
|
178
180
|
export const CollectionRendererContext = createContext<CollectionRenderer>(DefaultCollectionRenderer);
|
|
179
181
|
|
|
180
|
-
|
|
182
|
+
type PersistedKeysReturnValue = Set<Key> | null;
|
|
183
|
+
export function usePersistedKeys(focusedKey: Key | null): PersistedKeysReturnValue {
|
|
181
184
|
return useMemo(() => focusedKey != null ? new Set([focusedKey]) : null, [focusedKey]);
|
|
182
185
|
}
|
package/src/ColorPicker.tsx
CHANGED
|
@@ -16,7 +16,7 @@ import {ColorSwatchContext} from './ColorSwatch';
|
|
|
16
16
|
import {ColorSwatchPickerContext} from './ColorSwatchPicker';
|
|
17
17
|
import {mergeProps} from 'react-aria';
|
|
18
18
|
import {Provider, RenderProps, SlotProps, SlottedContextValue, useRenderProps, useSlottedContext} from './utils';
|
|
19
|
-
import React, {createContext} from 'react';
|
|
19
|
+
import React, {createContext, JSX} from 'react';
|
|
20
20
|
|
|
21
21
|
export interface ColorPickerRenderProps {
|
|
22
22
|
/** The currently selected color. */
|
|
@@ -32,7 +32,7 @@ export const ColorPickerStateContext = createContext<ColorPickerState | null>(nu
|
|
|
32
32
|
* A ColorPicker synchronizes a color value between multiple React Aria color components.
|
|
33
33
|
* It simplifies building color pickers with customizable layouts via composition.
|
|
34
34
|
*/
|
|
35
|
-
export function ColorPicker(props: ColorPickerProps) {
|
|
35
|
+
export function ColorPicker(props: ColorPickerProps): JSX.Element {
|
|
36
36
|
let ctx = useSlottedContext(ColorPickerContext, props.slot);
|
|
37
37
|
props = mergeProps(ctx, props);
|
|
38
38
|
let state = useColorPickerState(props);
|
package/src/ColorWheel.tsx
CHANGED
|
@@ -77,6 +77,8 @@ export const ColorWheelTrackContext = createContext<ContextValue<ColorWheelTrack
|
|
|
77
77
|
export const ColorWheelTrack = forwardRef(function ColorWheelTrack(props: ColorWheelTrackProps, ref: ForwardedRef<HTMLDivElement>) {
|
|
78
78
|
[props, ref] = useContextProps(props, ref, ColorWheelTrackContext);
|
|
79
79
|
let state = useContext(ColorWheelStateContext)!;
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
81
|
+
let {className, style, ...rest} = props;
|
|
80
82
|
|
|
81
83
|
let renderProps = useRenderProps({
|
|
82
84
|
...props,
|
|
@@ -89,7 +91,7 @@ export const ColorWheelTrack = forwardRef(function ColorWheelTrack(props: ColorW
|
|
|
89
91
|
|
|
90
92
|
return (
|
|
91
93
|
<div
|
|
92
|
-
{...
|
|
94
|
+
{...rest}
|
|
93
95
|
{...renderProps}
|
|
94
96
|
ref={ref}
|
|
95
97
|
data-disabled={state.isDisabled || undefined} />
|
package/src/DateField.tsx
CHANGED
|
@@ -92,7 +92,7 @@ export const DateField = /*#__PURE__*/ (forwardRef as forwardRefType)(function D
|
|
|
92
92
|
<Provider
|
|
93
93
|
values={[
|
|
94
94
|
[DateFieldStateContext, state],
|
|
95
|
-
[GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid}],
|
|
95
|
+
[GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid, isDisabled: state.isDisabled}],
|
|
96
96
|
[InputContext, {...inputProps, ref: inputRef}],
|
|
97
97
|
[LabelContext, {...labelProps, ref: labelRef, elementType: 'span'}],
|
|
98
98
|
[TextContext, {
|
|
@@ -108,7 +108,8 @@ export const DateField = /*#__PURE__*/ (forwardRef as forwardRefType)(function D
|
|
|
108
108
|
{...renderProps}
|
|
109
109
|
ref={ref}
|
|
110
110
|
slot={props.slot || undefined}
|
|
111
|
-
data-invalid={state.isInvalid || undefined}
|
|
111
|
+
data-invalid={state.isInvalid || undefined}
|
|
112
|
+
data-disabled={state.isDisabled || undefined} />
|
|
112
113
|
</Provider>
|
|
113
114
|
);
|
|
114
115
|
});
|
|
@@ -157,7 +158,7 @@ export const TimeField = /*#__PURE__*/ (forwardRef as forwardRefType)(function T
|
|
|
157
158
|
<Provider
|
|
158
159
|
values={[
|
|
159
160
|
[TimeFieldStateContext, state],
|
|
160
|
-
[GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid}],
|
|
161
|
+
[GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid, isDisabled: state.isDisabled}],
|
|
161
162
|
[InputContext, {...inputProps, ref: inputRef}],
|
|
162
163
|
[LabelContext, {...labelProps, ref: labelRef, elementType: 'span'}],
|
|
163
164
|
[TextContext, {
|
|
@@ -173,7 +174,8 @@ export const TimeField = /*#__PURE__*/ (forwardRef as forwardRefType)(function T
|
|
|
173
174
|
{...renderProps}
|
|
174
175
|
ref={ref}
|
|
175
176
|
slot={props.slot || undefined}
|
|
176
|
-
data-invalid={state.isInvalid || undefined}
|
|
177
|
+
data-invalid={state.isInvalid || undefined}
|
|
178
|
+
data-disabled={state.isDisabled || undefined} />
|
|
177
179
|
</Provider>
|
|
178
180
|
);
|
|
179
181
|
});
|
|
@@ -241,7 +243,7 @@ const DateInputStandalone = forwardRef((props: DateInputProps, ref: ForwardedRef
|
|
|
241
243
|
values={[
|
|
242
244
|
[DateFieldStateContext, state],
|
|
243
245
|
[InputContext, {...inputProps, ref: inputRef}],
|
|
244
|
-
[GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid}]
|
|
246
|
+
[GroupContext, {...fieldProps, ref: fieldRef, isInvalid: state.isInvalid, isDisabled: state.isDisabled}]
|
|
245
247
|
]}>
|
|
246
248
|
<DateInputInner {...props} />
|
|
247
249
|
</Provider>
|
|
@@ -261,7 +263,8 @@ const DateInputInner = forwardRef((props: DateInputProps, ref: ForwardedRef<HTML
|
|
|
261
263
|
ref={ref}
|
|
262
264
|
slot={props.slot || undefined}
|
|
263
265
|
className={className ?? 'react-aria-DateInput'}
|
|
264
|
-
isInvalid={state.isInvalid}
|
|
266
|
+
isInvalid={state.isInvalid}
|
|
267
|
+
isDisabled={state.isDisabled}>
|
|
265
268
|
{state.segments.map((segment, i) => cloneElement(children(segment), {key: i}))}
|
|
266
269
|
</Group>
|
|
267
270
|
<Input />
|
|
@@ -328,11 +331,12 @@ export const DateSegment = /*#__PURE__*/ (forwardRef as forwardRefType)(function
|
|
|
328
331
|
let {segmentProps} = useDateSegment(segment, state, domRef);
|
|
329
332
|
let {focusProps, isFocused, isFocusVisible} = useFocusRing();
|
|
330
333
|
let {hoverProps, isHovered} = useHover({...otherProps, isDisabled: state.isDisabled || segment.type === 'literal'});
|
|
334
|
+
let {isEditable, ...segmentRest} = segment;
|
|
331
335
|
let renderProps = useRenderProps({
|
|
332
336
|
...otherProps,
|
|
333
337
|
values: {
|
|
334
|
-
...
|
|
335
|
-
isReadOnly: !
|
|
338
|
+
...segmentRest,
|
|
339
|
+
isReadOnly: !isEditable,
|
|
336
340
|
isInvalid: state.isInvalid,
|
|
337
341
|
isDisabled: state.isDisabled,
|
|
338
342
|
isHovered,
|
|
@@ -352,7 +356,7 @@ export const DateSegment = /*#__PURE__*/ (forwardRef as forwardRefType)(function
|
|
|
352
356
|
ref={domRef}
|
|
353
357
|
data-placeholder={segment.isPlaceholder || undefined}
|
|
354
358
|
data-invalid={state.isInvalid || undefined}
|
|
355
|
-
data-readonly={!
|
|
359
|
+
data-readonly={!isEditable || undefined}
|
|
356
360
|
data-disabled={state.isDisabled || undefined}
|
|
357
361
|
data-type={segment.type}
|
|
358
362
|
data-hovered={isHovered || undefined}
|
package/src/Dialog.tsx
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
import {AriaDialogProps, useDialog, useId, useOverlayTrigger} from 'react-aria';
|
|
13
13
|
import {ButtonContext} from './Button';
|
|
14
14
|
import {ContextValue, DEFAULT_SLOT, Provider, SlotProps, StyleProps, useContextProps, useRenderProps} from './utils';
|
|
15
|
-
import {filterDOMProps} from '@react-aria/utils';
|
|
15
|
+
import {filterDOMProps, useResizeObserver} from '@react-aria/utils';
|
|
16
16
|
import {forwardRefType} from '@react-types/shared';
|
|
17
17
|
import {HeadingContext} from './RSPContexts';
|
|
18
18
|
import {OverlayTriggerProps, OverlayTriggerState, useMenuTriggerState} from 'react-stately';
|
|
19
19
|
import {PopoverContext} from './Popover';
|
|
20
20
|
import {PressResponder} from '@react-aria/interactions';
|
|
21
|
-
import React, {createContext, ForwardedRef, forwardRef, ReactNode, useContext, useRef} from 'react';
|
|
21
|
+
import React, {createContext, ForwardedRef, forwardRef, JSX, ReactNode, useCallback, useContext, useRef, useState} from 'react';
|
|
22
22
|
import {RootMenuTriggerStateContext} from './Menu';
|
|
23
23
|
|
|
24
24
|
export interface DialogTriggerProps extends OverlayTriggerProps {
|
|
@@ -40,7 +40,7 @@ export const OverlayTriggerStateContext = createContext<OverlayTriggerState | nu
|
|
|
40
40
|
/**
|
|
41
41
|
* A DialogTrigger opens a dialog when a trigger element is pressed.
|
|
42
42
|
*/
|
|
43
|
-
export function DialogTrigger(props: DialogTriggerProps) {
|
|
43
|
+
export function DialogTrigger(props: DialogTriggerProps): JSX.Element {
|
|
44
44
|
// Use useMenuTriggerState instead of useOverlayTriggerState in case a menu is embedded in the dialog.
|
|
45
45
|
// This is needed to handle submenus.
|
|
46
46
|
let state = useMenuTriggerState(props);
|
|
@@ -48,6 +48,19 @@ export function DialogTrigger(props: DialogTriggerProps) {
|
|
|
48
48
|
let buttonRef = useRef<HTMLButtonElement>(null);
|
|
49
49
|
let {triggerProps, overlayProps} = useOverlayTrigger({type: 'dialog'}, state, buttonRef);
|
|
50
50
|
|
|
51
|
+
// Allows popover width to match trigger element
|
|
52
|
+
let [buttonWidth, setButtonWidth] = useState<string | null>(null);
|
|
53
|
+
let onResize = useCallback(() => {
|
|
54
|
+
if (buttonRef.current) {
|
|
55
|
+
setButtonWidth(buttonRef.current.offsetWidth + 'px');
|
|
56
|
+
}
|
|
57
|
+
}, [buttonRef]);
|
|
58
|
+
|
|
59
|
+
useResizeObserver({
|
|
60
|
+
ref: buttonRef,
|
|
61
|
+
onResize: onResize
|
|
62
|
+
});
|
|
63
|
+
|
|
51
64
|
// Label dialog by the trigger as a fallback if there is no title slot.
|
|
52
65
|
// This is done in RAC instead of hooks because otherwise we cannot distinguish
|
|
53
66
|
// between context and props. Normally aria-labelledby overrides the title
|
|
@@ -64,7 +77,8 @@ export function DialogTrigger(props: DialogTriggerProps) {
|
|
|
64
77
|
[PopoverContext, {
|
|
65
78
|
trigger: 'DialogTrigger',
|
|
66
79
|
triggerRef: buttonRef,
|
|
67
|
-
'aria-labelledby': overlayProps['aria-labelledby']
|
|
80
|
+
'aria-labelledby': overlayProps['aria-labelledby'],
|
|
81
|
+
style: {'--trigger-width': buttonWidth} as React.CSSProperties
|
|
68
82
|
}]
|
|
69
83
|
]}>
|
|
70
84
|
<PressResponder {...triggerProps} ref={buttonRef} isPressed={state.isOpen}>
|
|
@@ -93,7 +107,7 @@ export const Dialog = /*#__PURE__*/ (forwardRef as forwardRefType)(function Dial
|
|
|
93
107
|
// Use that as a fallback in case there is no title slot.
|
|
94
108
|
if (props['aria-labelledby']) {
|
|
95
109
|
dialogProps['aria-labelledby'] = props['aria-labelledby'];
|
|
96
|
-
} else {
|
|
110
|
+
} else if (process.env.NODE_ENV !== 'production') {
|
|
97
111
|
console.warn('If a Dialog does not contain a <Heading slot="title">, it must have an aria-label or aria-labelledby attribute for accessibility.');
|
|
98
112
|
}
|
|
99
113
|
}
|
package/src/DragAndDrop.tsx
CHANGED
|
@@ -45,7 +45,9 @@ export const DropIndicator = forwardRef(function DropIndicator(props: DropIndica
|
|
|
45
45
|
return <>{render(props, ref)}</>;
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
type RenderDropIndicatorRetValue = ((target: ItemDropTarget) => ReactNode | undefined) | undefined
|
|
49
|
+
|
|
50
|
+
export function useRenderDropIndicator(dragAndDropHooks?: DragAndDropHooks, dropState?: DroppableCollectionState): RenderDropIndicatorRetValue {
|
|
49
51
|
let renderDropIndicator = dragAndDropHooks?.renderDropIndicator;
|
|
50
52
|
let isVirtualDragging = dragAndDropHooks?.isVirtualDragging?.();
|
|
51
53
|
let fn = useCallback((target: ItemDropTarget) => {
|
|
@@ -59,7 +61,7 @@ export function useRenderDropIndicator(dragAndDropHooks?: DragAndDropHooks, drop
|
|
|
59
61
|
return dragAndDropHooks?.useDropIndicator ? fn : undefined;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
export function useDndPersistedKeys(selectionManager: MultipleSelectionManager, dragAndDropHooks?: DragAndDropHooks, dropState?: DroppableCollectionState) {
|
|
64
|
+
export function useDndPersistedKeys(selectionManager: MultipleSelectionManager, dragAndDropHooks?: DragAndDropHooks, dropState?: DroppableCollectionState): Set<Key> {
|
|
63
65
|
// Persist the focused key and the drop target key.
|
|
64
66
|
let focusedKey = selectionManager.focusedKey;
|
|
65
67
|
let dropTargetKey: Key | null | undefined = null;
|
package/src/GridList.tsx
CHANGED
|
@@ -14,11 +14,11 @@ 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, ScrollableProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
|
|
17
|
+
import {ContextValue, DEFAULT_SLOT, Provider, RenderProps, ScrollableProps, 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, useObjectRef} from '@react-aria/utils';
|
|
21
|
+
import {filterDOMProps, inertValue, LoadMoreSentinelProps, UNSTABLE_useLoadMoreSentinel, useObjectRef} from '@react-aria/utils';
|
|
22
22
|
import {forwardRefType, HoverEvents, Key, LinkDOMProps, 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';
|
|
@@ -130,7 +130,8 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
|
|
|
130
130
|
keyboardDelegate,
|
|
131
131
|
// Only tab navigation is supported in grid layout.
|
|
132
132
|
keyboardNavigationBehavior: layout === 'grid' ? 'tab' : keyboardNavigationBehavior,
|
|
133
|
-
isVirtualized
|
|
133
|
+
isVirtualized,
|
|
134
|
+
shouldSelectOnPressUp: props.shouldSelectOnPressUp
|
|
134
135
|
}, state, ref);
|
|
135
136
|
|
|
136
137
|
let selectionManager = state.selectionManager;
|
|
@@ -139,6 +140,9 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
|
|
|
139
140
|
let dragHooksProvided = useRef(isListDraggable);
|
|
140
141
|
let dropHooksProvided = useRef(isListDroppable);
|
|
141
142
|
useEffect(() => {
|
|
143
|
+
if (process.env.NODE_ENV === 'production') {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
142
146
|
if (dragHooksProvided.current !== isListDraggable) {
|
|
143
147
|
console.warn('Drag hooks were provided during one render, but not another. This should be avoided as it may produce unexpected behavior.');
|
|
144
148
|
}
|
|
@@ -190,9 +194,11 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
|
|
|
190
194
|
}
|
|
191
195
|
|
|
192
196
|
let {focusProps, isFocused, isFocusVisible} = useFocusRing();
|
|
197
|
+
// TODO: What do we think about this check? Ideally we could just query the collection and see if ALL node are loaders and thus have it return that it is empty
|
|
198
|
+
let isEmpty = state.collection.size === 0 || (state.collection.size === 1 && state.collection.getItem(state.collection.getFirstKey()!)?.type === 'loader');
|
|
193
199
|
let renderValues = {
|
|
194
200
|
isDropTarget: isRootDropTarget,
|
|
195
|
-
isEmpty
|
|
201
|
+
isEmpty,
|
|
196
202
|
isFocused,
|
|
197
203
|
isFocusVisible,
|
|
198
204
|
layout,
|
|
@@ -207,10 +213,11 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
|
|
|
207
213
|
|
|
208
214
|
let emptyState: ReactNode = null;
|
|
209
215
|
let emptyStatePropOverrides: HTMLAttributes<HTMLElement> | null = null;
|
|
210
|
-
|
|
216
|
+
|
|
217
|
+
if (isEmpty && props.renderEmptyState) {
|
|
211
218
|
let content = props.renderEmptyState(renderValues);
|
|
212
219
|
emptyState = (
|
|
213
|
-
<div role="row" style={{display: 'contents'}}>
|
|
220
|
+
<div role="row" aria-rowindex={1} style={{display: 'contents'}}>
|
|
214
221
|
<div role="gridcell" style={{display: 'contents'}}>
|
|
215
222
|
{content}
|
|
216
223
|
</div>
|
|
@@ -228,7 +235,7 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
|
|
|
228
235
|
slot={props.slot || undefined}
|
|
229
236
|
onScroll={props.onScroll}
|
|
230
237
|
data-drop-target={isRootDropTarget || undefined}
|
|
231
|
-
data-empty={
|
|
238
|
+
data-empty={isEmpty || undefined}
|
|
232
239
|
data-focused={isFocused || undefined}
|
|
233
240
|
data-focus-visible={isFocusVisible || undefined}
|
|
234
241
|
data-layout={layout}>
|
|
@@ -344,7 +351,7 @@ export const GridListItem = /*#__PURE__*/ createLeafComponent('item', function G
|
|
|
344
351
|
}, []);
|
|
345
352
|
|
|
346
353
|
useEffect(() => {
|
|
347
|
-
if (!item.textValue) {
|
|
354
|
+
if (!item.textValue && process.env.NODE_ENV !== 'production') {
|
|
348
355
|
console.warn('A `textValue` prop is required for <GridListItem> elements with non-plain text children in order to support accessibility features such as type to select.');
|
|
349
356
|
}
|
|
350
357
|
}, [item.textValue]);
|
|
@@ -489,3 +496,61 @@ function RootDropIndicator() {
|
|
|
489
496
|
</div>
|
|
490
497
|
);
|
|
491
498
|
}
|
|
499
|
+
|
|
500
|
+
export interface GridListLoadingSentinelProps extends Omit<LoadMoreSentinelProps, 'collection'>, StyleProps {
|
|
501
|
+
/**
|
|
502
|
+
* The load more spinner to render when loading additional items.
|
|
503
|
+
*/
|
|
504
|
+
children?: ReactNode,
|
|
505
|
+
/**
|
|
506
|
+
* Whether or not the loading spinner should be rendered or not.
|
|
507
|
+
*/
|
|
508
|
+
isLoading?: boolean
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
export const UNSTABLE_GridListLoadingSentinel = createLeafComponent('loader', function GridListLoadingIndicator<T extends object>(props: GridListLoadingSentinelProps, ref: ForwardedRef<HTMLDivElement>, item: Node<T>) {
|
|
512
|
+
let state = useContext(ListStateContext)!;
|
|
513
|
+
let {isVirtualized} = useContext(CollectionRendererContext);
|
|
514
|
+
let {isLoading, onLoadMore, scrollOffset, ...otherProps} = props;
|
|
515
|
+
|
|
516
|
+
let sentinelRef = useRef(null);
|
|
517
|
+
let memoedLoadMoreProps = useMemo(() => ({
|
|
518
|
+
onLoadMore,
|
|
519
|
+
collection: state?.collection,
|
|
520
|
+
sentinelRef,
|
|
521
|
+
scrollOffset
|
|
522
|
+
}), [onLoadMore, scrollOffset, state?.collection]);
|
|
523
|
+
UNSTABLE_useLoadMoreSentinel(memoedLoadMoreProps, sentinelRef);
|
|
524
|
+
|
|
525
|
+
let renderProps = useRenderProps({
|
|
526
|
+
...otherProps,
|
|
527
|
+
id: undefined,
|
|
528
|
+
children: item.rendered,
|
|
529
|
+
defaultClassName: 'react-aria-GridListLoadingIndicator',
|
|
530
|
+
values: null
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
return (
|
|
534
|
+
<>
|
|
535
|
+
{/* 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) */}
|
|
536
|
+
{/* @ts-ignore - compatibility with React < 19 */}
|
|
537
|
+
<div style={{position: 'relative', width: 0, height: 0}} inert={inertValue(true)} >
|
|
538
|
+
<div data-testid="loadMoreSentinel" ref={sentinelRef} style={{position: 'absolute', height: 1, width: 1}} />
|
|
539
|
+
</div>
|
|
540
|
+
{isLoading && renderProps.children && (
|
|
541
|
+
<div
|
|
542
|
+
{...renderProps}
|
|
543
|
+
{...mergeProps(filterDOMProps(props as any))}
|
|
544
|
+
role="row"
|
|
545
|
+
aria-rowindex={isVirtualized ? item.index + 1 : undefined}
|
|
546
|
+
ref={ref}>
|
|
547
|
+
<div
|
|
548
|
+
aria-colindex={isVirtualized ? 1 : undefined}
|
|
549
|
+
role="gridcell">
|
|
550
|
+
{renderProps.children}
|
|
551
|
+
</div>
|
|
552
|
+
</div>
|
|
553
|
+
)}
|
|
554
|
+
</>
|
|
555
|
+
);
|
|
556
|
+
});
|