Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
4dbaab7
Fix escape key and restoring focus
devongovett Dec 2, 2025
407e31d
Virtual focus listbox items should not be tabbable
devongovett Dec 2, 2025
058d416
Improve view transition on android
devongovett Dec 2, 2025
6bdc573
Fix autocomplete focusing input on autofocus
devongovett Dec 2, 2025
e725b6e
Fix Autocomplete example
devongovett Dec 2, 2025
9b74440
Show two columns of items in GridList on mobile
devongovett Dec 2, 2025
fbd7555
Fix Vanilla Checkbox disabled checkmark color
devongovett Dec 2, 2025
f46521a
RAC ColorPicker fixes
devongovett Dec 2, 2025
a2e04f9
Fix DatePicker button and scrolling
devongovett Dec 2, 2025
e0fb892
Fix Autocomplete example overflowing
devongovett Dec 2, 2025
168b036
Fix DateField scrolling
devongovett Dec 2, 2025
dd1969c
Fix tailwind font sizes
devongovett Dec 2, 2025
ec68cad
Fix CommandPalette scrolling
devongovett Dec 2, 2025
b07d263
Fix RadioGroup scaling and disabled state
devongovett Dec 2, 2025
bae40b8
Fix vanilla SearchField close button scaling
devongovett Dec 2, 2025
6d42690
Add press state to tailwind dropdown items for touch
devongovett Dec 2, 2025
f42c35a
Less layout shifting on Select example
devongovett Dec 2, 2025
abdb347
Fix slider clipping, shorten vertical height
devongovett Dec 2, 2025
006f032
Fix Tabs disabled state inheriting into Checkboxes
devongovett Dec 2, 2025
6f0a5de
Make add/remove tab buttons narrower, and fix client router example
devongovett Dec 2, 2025
44e3d9a
Tailwind Toolbar flex wrap
devongovett Dec 2, 2025
1fa9dd0
Fix vanilla TreeItem height
devongovett Dec 2, 2025
7722120
Only render VisualExample controls if there are props provided
devongovett Dec 2, 2025
d527fab
Fix some API types in hook docs
devongovett Dec 2, 2025
a8fbf88
Disable native long press on images in GridList
devongovett Dec 2, 2025
0d8b047
Don't scroll library out of view on mobile if there is no toc
devongovett Dec 2, 2025
02fe874
Fix toc picking up unrelated headings
devongovett Dec 2, 2025
86515fd
Fix selection indicator scaling
devongovett Dec 2, 2025
b15a510
Update hook docs
devongovett Dec 2, 2025
dabf735
omit homepage from nav
devongovett Dec 2, 2025
96c9005
Fix dotted underline links in Safari
devongovett Dec 2, 2025
19d818c
Fix width of color editor blog example
devongovett Dec 2, 2025
16c49a3
Fix cross-library links
devongovett Dec 2, 2025
c2b9f7b
Add horizontal scrolling for non-expandable code blocks
devongovett Dec 2, 2025
b2a16a1
Add tap highlight color to tailwind elements
devongovett Dec 2, 2025
b568ac6
Fix react warning in Tabs
devongovett Dec 2, 2025
7a7758f
Fix table async loading spinner positioning
devongovett Dec 2, 2025
f072886
Update TableView examples
devongovett Dec 2, 2025
ce88f27
Fix links in breadcrumbs examples
devongovett Dec 2, 2025
84f11cb
Update testing page description to match others
devongovett Dec 2, 2025
ed28457
illustrations page should have lower case url to match icons
devongovett Dec 2, 2025
b87a7b0
Fix illustration page overflow
devongovett Dec 2, 2025
2b934d1
Link to client side routing guide from Provider
devongovett Dec 2, 2025
8e66f29
Re-export useListData, useTreeData, and useAsyncList from RAC and S2
devongovett Dec 3, 2025
97bf924
Fix bug with code folding
devongovett Dec 3, 2025
4a46eb1
Fix table rounding
devongovett Dec 3, 2025
f45aed5
Re-export useLocale
devongovett Dec 3, 2025
e34b28f
Update migration wording
devongovett Dec 3, 2025
e533cfb
Merge branch 'main' of github.com:adobe/react-spectrum into fixes2
devongovett Dec 3, 2025
10c1439
Fix markdown docs
devongovett Dec 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 2 additions & 16 deletions packages/@react-aria/autocomplete/src/useAutocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {AriaTextFieldProps} from '@react-aria/textfield';
import {AutocompleteProps, AutocompleteState} from '@react-stately/autocomplete';
import {CLEAR_FOCUS_EVENT, FOCUS_EVENT, getActiveElement, getOwnerDocument, isAndroid, isCtrlKeyPressed, isIOS, mergeProps, mergeRefs, useEffectEvent, useEvent, useId, useLabels, useLayoutEffect, useObjectRef} from '@react-aria/utils';
import {dispatchVirtualBlur, dispatchVirtualFocus, getVirtuallyFocusedElement, moveVirtualFocus} from '@react-aria/focus';
import {getInteractionModality} from '@react-aria/interactions';
import {getInteractionModality, getPointerType} from '@react-aria/interactions';
// @ts-ignore
import intlMessages from '../intl/*.json';
import {FocusEvent as ReactFocusEvent, KeyboardEvent as ReactKeyboardEvent, useCallback, useEffect, useMemo, useRef, useState} from 'react';
Expand Down Expand Up @@ -92,7 +92,6 @@ export function useAutocomplete<T>(props: AriaAutocompleteOptions<T>, state: Aut
let timeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
let delayNextActiveDescendant = useRef(false);
let queuedActiveDescendant = useRef<string | null>(null);
let lastPointerType = useRef<string | null>(null);

// For mobile screen readers, we don't want virtual focus, instead opting to disable FocusScope's restoreFocus and manually
// moving focus back to the subtriggers
Expand All @@ -106,23 +105,10 @@ export function useAutocomplete<T>(props: AriaAutocompleteOptions<T>, state: Aut
return () => clearTimeout(timeout.current);
}, []);

useEffect(() => {
let handlePointerDown = (e: PointerEvent) => {
lastPointerType.current = e.pointerType;
};

if (typeof PointerEvent !== 'undefined') {
document.addEventListener('pointerdown', handlePointerDown, true);
return () => {
document.removeEventListener('pointerdown', handlePointerDown, true);
};
}
}, []);

let updateActiveDescendantEvent = useEffectEvent((e: Event) => {
// Ensure input is focused if the user clicks on the collection directly.
// don't trigger on touch so that mobile keyboard doesnt appear when tapping on options
if (!e.isTrusted && shouldUseVirtualFocus && inputRef.current && getActiveElement(getOwnerDocument(inputRef.current)) !== inputRef.current && lastPointerType.current !== 'touch') {
if (!e.isTrusted && shouldUseVirtualFocus && inputRef.current && getActiveElement(getOwnerDocument(inputRef.current)) !== inputRef.current && getPointerType() !== 'touch') {
inputRef.current.focus();
}

Expand Down
1 change: 1 addition & 0 deletions packages/@react-aria/interactions/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export {
isFocusVisible,
getInteractionModality,
setInteractionModality,
getPointerType,
addWindowFocusTracking,
useInteractionModality,
useFocusVisible,
Expand Down
12 changes: 12 additions & 0 deletions packages/@react-aria/interactions/src/useFocusVisible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import {getOwnerDocument, getOwnerWindow, isMac, isVirtualClick, openLink} from '@react-aria/utils';
import {ignoreFocusEvent} from './utils';
import {PointerType} from '@react-types/shared';
import {useEffect, useState} from 'react';
import {useIsSSR} from '@react-aria/ssr';

Expand All @@ -37,6 +38,7 @@ export interface FocusVisibleResult {
}

let currentModality: null | Modality = null;
let currentPointerType: PointerType = 'keyboard';
let changeHandlers = new Set<Handler>();
interface GlobalListenerData {
focus: () => void
Expand Down Expand Up @@ -70,12 +72,14 @@ function handleKeyboardEvent(e: KeyboardEvent) {
hasEventBeforeFocus = true;
if (!(openLink as any).isOpening && isValidKey(e)) {
currentModality = 'keyboard';
currentPointerType = 'keyboard';
triggerChangeHandlers('keyboard', e);
}
}

function handlePointerEvent(e: PointerEvent | MouseEvent) {
currentModality = 'pointer';
currentPointerType = 'pointerType' in e ? e.pointerType as PointerType : 'mouse';
if (e.type === 'mousedown' || e.type === 'pointerdown') {
hasEventBeforeFocus = true;
triggerChangeHandlers('pointer', e);
Expand All @@ -86,6 +90,7 @@ function handleClickEvent(e: MouseEvent) {
if (!(openLink as any).isOpening && isVirtualClick(e)) {
hasEventBeforeFocus = true;
currentModality = 'virtual';
currentPointerType = 'virtual';
}
}

Expand All @@ -101,6 +106,7 @@ function handleFocusEvent(e: FocusEvent) {
// This occurs, for example, when navigating a form with the next/previous buttons on iOS.
if (!hasEventBeforeFocus && !hasBlurredWindowRecently) {
currentModality = 'virtual';
currentPointerType = 'virtual';
triggerChangeHandlers('virtual', e);
}

Expand Down Expand Up @@ -249,9 +255,15 @@ export function getInteractionModality(): Modality | null {

export function setInteractionModality(modality: Modality): void {
currentModality = modality;
currentPointerType = modality === 'pointer' ? 'mouse' : modality;
triggerChangeHandlers(modality, null);
}

/** @private */
export function getPointerType(): PointerType {
return currentPointerType;
}

/**
* Keeps state of the current modality.
*/
Expand Down
58 changes: 30 additions & 28 deletions packages/@react-aria/test-utils/src/testSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,35 +35,37 @@ export function installMouseEvent(): void {
});
}

export function definePointerEvent(): void {
// @ts-ignore
global.PointerEvent = class FakePointerEvent extends MouseEvent {
_init: {pageX: number, pageY: number, pointerType: string, pointerId: number, width: number, height: number};
constructor(name, init) {
super(name, init);
this._init = init;
}
get pointerType() {
return this._init.pointerType ?? 'mouse';
}
get pointerId() {
return this._init.pointerId;
}
get pageX() {
return this._init.pageX;
}
get pageY() {
return this._init.pageY;
}
get width() {
return this._init.width;
}
get height() {
return this._init.height;
}
};
}

export function installPointerEvent(): void {
beforeAll(() => {
// @ts-ignore
global.PointerEvent = class FakePointerEvent extends MouseEvent {
_init: {pageX: number, pageY: number, pointerType: string, pointerId: number, width: number, height: number};
constructor(name, init) {
super(name, init);
this._init = init;
}
get pointerType() {
return this._init.pointerType ?? 'mouse';
}
get pointerId() {
return this._init.pointerId;
}
get pageX() {
return this._init.pageX;
}
get pageY() {
return this._init.pageY;
}
get width() {
return this._init.width;
}
get height() {
return this._init.height;
}
};
});
beforeAll(definePointerEvent);
afterAll(() => {
// @ts-ignore
delete global.PointerEvent;
Expand Down
3 changes: 1 addition & 2 deletions packages/@react-aria/utils/src/mergeProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (

/**
* Merges multiple props objects together. Event handlers are chained,
* classNames are combined, and ids are deduplicated - different ids
* will trigger a side-effect and re-render components hooked up with `useId`.
* classNames are combined, and ids are deduplicated.
* For all other props, the last prop object overrides all previous ones.
* @param args - Multiple sets of props to merge together.
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-spectrum/s2/src/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ export function TabPanel(props: TabPanelProps): ReactNode | null {

function CollapsedTabPanel(props: TabPanelProps) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
let {UNSAFE_style, UNSAFE_className = '', id, ...otherProps} = props;
let {UNSAFE_style, UNSAFE_className = '', id, shouldForceMount, ...otherProps} = props;
let {menuId, valueId} = useContext(CollapseContext);
let ref = useRef(null);
let tabIndex = useHasTabbableChild(ref) ? undefined : 0;
Expand Down
7 changes: 3 additions & 4 deletions packages/@react-spectrum/s2/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,8 @@ export {TreeView, TreeViewItem, TreeViewItemContent, TreeViewLoadMoreItem} from

export {pressScale} from './pressScale';

export {Autocomplete} from 'react-aria-components';
export {Collection} from 'react-aria-components';
export {FileTrigger} from 'react-aria-components';
export {parseColor} from 'react-aria-components';
export {Autocomplete, Collection, FileTrigger, parseColor, useLocale} from 'react-aria-components';
export {useListData, useTreeData, useAsyncList} from 'react-stately';

export type {AccordionProps, AccordionItemProps, AccordionItemHeaderProps, AccordionItemTitleProps, AccordionItemPanelProps} from './Accordion';
export type {ActionBarProps} from './ActionBar';
Expand Down Expand Up @@ -169,3 +167,4 @@ export type {ToggleButtonGroupProps} from './ToggleButtonGroup';
export type {TooltipProps} from './Tooltip';
export type {TreeViewProps, TreeViewItemProps, TreeViewItemContentProps, TreeViewLoadMoreItemProps} from './TreeView';
export type {AutocompleteProps, FileTriggerProps, TooltipTriggerComponentProps as TooltipTriggerProps, SortDescriptor, Color, Key, Selection} from 'react-aria-components';
export type {ListData, TreeData, AsyncListData} from 'react-stately';
8 changes: 3 additions & 5 deletions packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ Autocomplete filters a collection component using a [TextField](TextField) or [S
import {Autocomplete, useFilter} from 'react-aria-components';
import {MenuTrigger, Menu, MenuItem} from 'vanilla-starter/Menu';
import {Button} from 'vanilla-starter/Button';
import {Popover} from 'vanilla-starter/Popover';
import {SearchField} from 'vanilla-starter/SearchField';

function Example(props) {
Expand All @@ -131,7 +130,7 @@ function Example(props) {
return (
<MenuTrigger>
<Button>Add tag...</Button>
<Popover style={{display: 'flex', flexDirection: 'column'}}>
<div style={{display: 'flex', flexDirection: 'column', maxHeight: 'inherit'}}>
{/*- begin highlight -*/}
<Autocomplete {...props}/* PROPS */ filter={contains}>
<SearchField
Expand All @@ -152,7 +151,7 @@ function Example(props) {
<MenuItem>Science</MenuItem>
</Menu>
</Autocomplete>
</Popover>
</div>
</MenuTrigger>
);
}
Expand Down Expand Up @@ -1059,10 +1058,9 @@ When the `filter` prop is not set, the items are controlled. This example uses a

```tsx render
"use client";
import {Autocomplete} from 'react-aria-components';
import {Autocomplete, useAsyncList} from 'react-aria-components';
import {SearchField} from 'vanilla-starter/SearchField';
import {ListBox, ListBoxItem} from 'vanilla-starter/ListBox';
import {useAsyncList} from 'react-stately';

function AsyncLoadingExample() {
let list = useAsyncList<{name: string}>({
Expand Down
8 changes: 4 additions & 4 deletions packages/dev/s2-docs/pages/react-aria/Breadcrumbs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export const description = 'Displays a hierarchy of links to the current page or
import {Breadcrumbs, Breadcrumb} from 'vanilla-starter/Breadcrumbs';

<Breadcrumbs/* PROPS */>
<Breadcrumb href="/">Home</Breadcrumb>
<Breadcrumb href="/react-aria/">React Aria</Breadcrumb>
<Breadcrumb href="https://adobe.com/" target="_blank">Adobe</Breadcrumb>
<Breadcrumb href="/">React Aria</Breadcrumb>
<Breadcrumb>Breadcrumbs</Breadcrumb>
</Breadcrumbs>
```
Expand All @@ -31,8 +31,8 @@ export const description = 'Displays a hierarchy of links to the current page or
import {Breadcrumbs, Breadcrumb} from 'tailwind-starter/Breadcrumbs';

<Breadcrumbs/* PROPS */>
<Breadcrumb href="/">Home</Breadcrumb>
<Breadcrumb href="/react-aria/">React Aria</Breadcrumb>
<Breadcrumb href="https://adobe.com/" target="_blank">Adobe</Breadcrumb>
<Breadcrumb href="/">React Aria</Breadcrumb>
<Breadcrumb>Breadcrumbs</Breadcrumb>
</Breadcrumbs>
```
Expand Down
3 changes: 1 addition & 2 deletions packages/dev/s2-docs/pages/react-aria/Button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import vanillaDocs from 'docs:vanilla-starter/Button';
import tailwindDocs from 'docs:tailwind-starter/Button';
import '../../tailwind/tailwind.css';
import typesDocs from 'docs:@react-types/shared/src/events.d.ts';
import {getBaseUrl} from '../../src/pageUtils';

export const tags = ['btn'];
export const relatedPages = [{'title': 'useButton', 'url': 'https://react-spectrum.adobe.com/react-aria/useButton.html'}];
Expand Down Expand Up @@ -50,7 +49,7 @@ export const description = 'Allows a user to perform an action, with mouse, touc

Use the `onPress` prop to handle interactions via mouse, keyboard, and touch. This is similar to `onClick`, but normalized for consistency across browsers, devices, and interaction methods. Read our [blog post](blog/building-a-button-part-1) to learn more.

The `onPressStart`, `onPressEnd`, and `onPressChange` events are also emitted as the user interacts with the button. Each of these handlers receives a <TypeLink links={typesDocs.links} type={typesDocs.exports.PressEvent} />, which provides information about the target and interaction method. See <Link href={`${getBaseUrl('react-aria')}/usePress`}>usePress</Link> for more details.
The `onPressStart`, `onPressEnd`, and `onPressChange` events are also emitted as the user interacts with the button. Each of these handlers receives a <TypeLink links={typesDocs.links} type={typesDocs.exports.PressEvent} />, which provides information about the target and interaction method. See [usePress](usePress) for more details.

```tsx render
"use client";
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/s2-docs/pages/react-aria/Calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Use the `minValue` and `maxValue` props to set the valid date range. The `isDate
```tsx render docs={vanillaDocs.exports.Calendar} links={docs.links} props={['isInvalid', 'errorMessage']} wide
"use client";
import {isWeekend, today, getLocalTimeZone} from '@internationalized/date';
import {useLocale} from 'react-aria';
import {useLocale} from 'react-aria-components';
import {Calendar} from 'vanilla-starter/Calendar';

function Example(props) {
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/s2-docs/pages/react-aria/DatePicker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Use the `name` prop to submit the selected date to the server as an [ISO 8601](h
```tsx render
"use client";
import {isWeekend, today, getLocalTimeZone} from '@internationalized/date';
import {useLocale} from 'react-aria';
import {useLocale} from 'react-aria-components';
import {DatePicker} from 'vanilla-starter/DatePicker';
import {Button} from 'vanilla-starter/Button';
import {Form} from 'vanilla-starter/Form';;
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/s2-docs/pages/react-aria/DateRangePicker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Use the `name` prop to submit the selected date to the server as an [ISO 8601](h
```tsx render docs={vanillaDocs.exports.DateRangePicker} links={docs.links} props={['allowsNonContiguousRanges']} wide
"use client";
import {isWeekend, today, getLocalTimeZone} from '@internationalized/date';
import {useLocale} from 'react-aria';
import {useLocale} from 'react-aria-components';
import {DateRangePicker} from 'vanilla-starter/DateRangePicker';
import {Button} from 'vanilla-starter/Button';
import {Form} from 'vanilla-starter/Form';;
Expand Down
3 changes: 1 addition & 2 deletions packages/dev/s2-docs/pages/react-aria/FileTrigger.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export default Layout;
import docs from 'docs:react-aria-components';
import '../../tailwind/tailwind.css';
import {InlineAlert, Heading, Content} from '@react-spectrum/s2'
import {getBaseUrl} from '../../src/pageUtils';

export const tags = ['upload', 'input'];
export const description = 'Allows a user to access the file system with any pressable React Aria or React Spectrum component.';
Expand Down Expand Up @@ -44,7 +43,7 @@ function Example(props) {

## Custom trigger

`FileTrigger` works with any pressable React Aria component (e.g. [Button](Button), [Link](Link), etc.). Use the `<Pressable>` component or <Link href={`${getBaseUrl('react-aria')}/usePress`}>usePress</Link> hook to wrap a custom trigger element such as a third party component or DOM element.
`FileTrigger` works with any pressable React Aria component (e.g. [Button](Button), [Link](Link), etc.). Use the `<Pressable>` component or [usePress](usePress) hook to wrap a custom trigger element such as a third party component or DOM element.

```tsx render
"use client"
Expand Down
26 changes: 11 additions & 15 deletions packages/dev/s2-docs/pages/react-aria/FocusRing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@ export const description = 'A utility component that applies a visual focus indi

<PageDescription>{docs.exports.FocusRing.description}</PageDescription>

## Introduction

`FocusRing` is a utility component that can be used to apply a CSS class when an element has keyboard focus.
This helps keyboard users determine which element on a page or in an application has keyboard focus as they
navigate around. Focus rings are only visible when interacting with a keyboard so as not to distract mouse
and touch screen users. When we are unable to detect if the user is using a mouse or touch screen, such as
switching in from a different tab, we show the focus ring.

If CSS classes are not being used for styling, see [useFocusRing](useFocusRing) for a hooks version.

## Example

This example shows how to use `<FocusRing>` to apply a CSS class when keyboard focus is on a button.

```tsx render files={["packages/dev/s2-docs/pages/react-aria/FocusRingExample.css"]}
'use client';
import {FocusRing} from '@react-aria/focus';
Expand All @@ -44,8 +30,18 @@ import './FocusRingExample.css';
</FocusRing>
```

## Features

`FocusRing` is a utility component that can be used to apply a CSS class when an element has keyboard focus.
This helps keyboard users determine which element on a page or in an application has keyboard focus as they
navigate around. Focus rings are only visible when interacting with a keyboard so as not to distract mouse
and touch screen users. When we are unable to detect if the user is using a mouse or touch screen, such as
switching in from a different tab, we show the focus ring.

If CSS classes are not being used for styling, see [useFocusRing](useFocusRing) for a hooks version.

## API

### FocusRing

<PropTable links={docs.links} component={docs.exports.FocusRing} />
<PropTable links={docs.links} component={docs.exports.FocusRing} />
3 changes: 2 additions & 1 deletion packages/dev/s2-docs/pages/react-aria/FocusRingExample.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
border: none;
color: white;
font-size: 14px;
padding: 4px 8px;
padding: 8px 12px;
border-radius: 8px;
}

.button.focus-ring {
Expand Down
3 changes: 1 addition & 2 deletions packages/dev/s2-docs/pages/react-aria/GridList.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -611,9 +611,8 @@ GridList supports drag and drop interactions when the `dragAndDropHooks` prop is

```tsx render
"use client";
import {useListData} from 'react-stately';
import {GridList, GridListItem} from 'vanilla-starter/GridList';
import {useDragAndDrop, Text} from 'react-aria-components';
import {useDragAndDrop, Text, useListData} from 'react-aria-components';

///- begin collapse -///
let images = [
Expand Down
Loading