diff --git a/packages/@react-aria/disclosure/src/useDisclosure.ts b/packages/@react-aria/disclosure/src/useDisclosure.ts index ab55538a91f..34b254afce6 100644 --- a/packages/@react-aria/disclosure/src/useDisclosure.ts +++ b/packages/@react-aria/disclosure/src/useDisclosure.ts @@ -73,7 +73,7 @@ export function useDisclosure(props: AriaDisclosureProps, state: DisclosureState if (raf.current) { cancelAnimationFrame(raf.current); } - if (ref.current && !isDisabled && !isSSR) { + if (ref.current && !isSSR) { let panel = ref.current; if (isExpandedRef.current == null || typeof panel.getAnimations !== 'function') { @@ -155,7 +155,7 @@ export function useDisclosure(props: AriaDisclosureProps, state: DisclosureState role: 'group', 'aria-labelledby': triggerId, 'aria-hidden': !state.isExpanded, - hidden: !state.isExpanded || undefined + hidden: isSSR ? !state.isExpanded : undefined } }; } diff --git a/packages/@react-aria/disclosure/test/useDisclosure.test.ts b/packages/@react-aria/disclosure/test/useDisclosure.test.ts index b3bcf38ffe5..9f2932acc93 100644 --- a/packages/@react-aria/disclosure/test/useDisclosure.test.ts +++ b/packages/@react-aria/disclosure/test/useDisclosure.test.ts @@ -91,7 +91,7 @@ describe('useDisclosure', () => { }); it('should keep panel hidden when toggling disabled state', () => { - let {result, rerender} = renderHook(({isDisabled}: {isDisabled: boolean}) => { + let {rerender} = renderHook(({isDisabled}: {isDisabled: boolean}) => { let state = useDisclosureState({}); return useDisclosure({isDisabled}, state, ref); }, {initialProps: {isDisabled: false}}); @@ -100,13 +100,13 @@ describe('useDisclosure', () => { rerender({isDisabled: true}); }); - expect(result.current.panelProps.hidden).toBe(true); + expect(ref.current.hidden).toBe(true); act(() => { rerender({isDisabled: false}); }); - expect(result.current.panelProps.hidden).toBe(true); + expect(ref.current.hidden).toBe(true); }); it('should set correct IDs for accessibility', () => { diff --git a/packages/@react-aria/table/src/useTableColumnHeader.ts b/packages/@react-aria/table/src/useTableColumnHeader.ts index b352ff98c22..e6ac331c1cd 100644 --- a/packages/@react-aria/table/src/useTableColumnHeader.ts +++ b/packages/@react-aria/table/src/useTableColumnHeader.ts @@ -31,7 +31,9 @@ export interface AriaTableColumnHeaderProps { export interface TableColumnHeaderAria { /** Props for the [column header](https://www.w3.org/TR/wai-aria-1.1/#columnheader) element. */ - columnHeaderProps: DOMAttributes + columnHeaderProps: DOMAttributes, + /** Whether the column is currently in a pressed state. */ + isPressed: boolean } /** @@ -48,7 +50,7 @@ export function useTableColumnHeader(props: AriaTableColumnHeaderProps, st let isSelectionCellDisabled = node.props.isSelectionCell && state.selectionManager.selectionMode === 'single'; - let {pressProps} = usePress({ + let {pressProps, isPressed} = usePress({ isDisabled: !allowsSorting || isSelectionCellDisabled, onPress() { state.sort(node.key); @@ -100,6 +102,7 @@ export function useTableColumnHeader(props: AriaTableColumnHeaderProps, st id: getColumnHeaderId(state, node.key), 'aria-colspan': node.colSpan && node.colSpan > 1 ? node.colSpan : undefined, 'aria-sort': ariaSort - } + }, + isPressed }; } diff --git a/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx b/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx index eb2b75a46c0..f835f94e8e1 100644 --- a/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx +++ b/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx @@ -15,13 +15,13 @@ import {Button} from 'tailwind-starter/Button'; import {Cell, Column, Row, TableHeader} from 'tailwind-starter/Table'; import {Checkbox} from 'tailwind-starter/Checkbox'; import {CloudSun, Dessert, Droplet, Droplets, FilterIcon, Mail, MoreHorizontal, PencilIcon, PlusIcon, RefreshCw, ShareIcon, SlidersIcon, StarIcon, Sun, SunDim, TrashIcon, Twitter} from 'lucide-react'; -import {ColumnProps, Dialog, DialogTrigger, DropZone, Form, Heading, isFileDropItem, Key, MenuTrigger, ModalOverlay, ModalOverlayProps, Modal as RACModal, ResizableTableContainer, Selection, SortDescriptor, SubmenuTrigger, Table, TableBody, Text, ToggleButton, ToggleButtonProps, TooltipTrigger} from 'react-aria-components'; +import {ColumnProps, Dialog, DialogTrigger, DropZone, Form, Heading, isFileDropItem, Key, ModalOverlay, ModalOverlayProps, Modal as RACModal, ResizableTableContainer, Selection, SortDescriptor, Table, TableBody, Text, ToggleButton, ToggleButtonProps, TooltipTrigger} from 'react-aria-components'; import {ComboBox, ComboBoxItem} from 'tailwind-starter/ComboBox'; import {DatePicker} from 'tailwind-starter/DatePicker'; import {focusRing} from 'tailwind-starter/utils'; import {getLocalTimeZone, today} from '@internationalized/date'; import {GridList, GridListItem} from 'tailwind-starter/GridList'; -import {Menu, MenuItem} from 'tailwind-starter/Menu'; +import {Menu, MenuItem, MenuTrigger, SubmenuTrigger} from 'tailwind-starter/Menu'; import {Modal} from 'tailwind-starter/Modal'; import plants, {Plant} from './plants'; import {Popover} from 'tailwind-starter/Popover'; @@ -41,7 +41,7 @@ const allColumns: ColumnProps[] = [ {id: 'cycle', children: 'Cycle', defaultWidth: 120, allowsSorting: true}, {id: 'sunlight', children: 'Sunlight', defaultWidth: 120, allowsSorting: true}, {id: 'watering', children: 'Watering', defaultWidth: 120, allowsSorting: true}, - {id: 'actions', children: Actions, width: 44, minWidth: 44} + {id: 'actions', children: Actions, width: 64, minWidth: 64} ]; let hideOnScroll = document.getElementById('hideOnScroll'); @@ -237,9 +237,9 @@ export function ExampleApp(): React.ReactNode { {item.common_name} {item.scientific_name} - - - onAction(item, action)}> + + + onAction(item, action)}> {item.isFavorite ? 'Unfavorite' : 'Favorite'} Edit… Delete… @@ -296,7 +296,7 @@ export function ExampleApp(): React.ReactNode { return ( - onAction(item, action)}> diff --git a/packages/dev/s2-docs/pages/react-aria/Button.mdx b/packages/dev/s2-docs/pages/react-aria/Button.mdx index e9d2f02b200..452dd693ed5 100644 --- a/packages/dev/s2-docs/pages/react-aria/Button.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Button.mdx @@ -6,6 +6,7 @@ import docs from 'docs:react-aria-components'; import {Button as VanillaButton} from 'vanilla-starter/Button'; import {Button as TailwindButton} from 'tailwind-starter/Button'; /* import {Button as MacroButton} from './ButtonExample'; */ +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'; @@ -19,9 +20,9 @@ export const tags = ['btn']; @@ -114,7 +115,7 @@ The `Button` component always represents a button semantically. To create a link "use client"; import {Link} from 'react-aria-components'; - + Adobe ``` diff --git a/packages/dev/s2-docs/pages/react-aria/Calendar.mdx b/packages/dev/s2-docs/pages/react-aria/Calendar.mdx index 560fed91a6b..4325cdc604c 100644 --- a/packages/dev/s2-docs/pages/react-aria/Calendar.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Calendar.mdx @@ -183,8 +183,11 @@ Set the `visibleDuration` prop and render multiple `CalendarGrid` elements to di ```tsx render docs={docs.exports.Calendar} links={docs.links} props={['visibleDuration', 'pageBehavior', 'firstDayOfWeek']} initialProps={{visibleDuration: {months: 2}}} wide "use client"; -import {Calendar, Heading, Button, CalendarGrid, CalendarCell} from 'react-aria-components'; +import {Calendar, Heading} from 'react-aria-components'; +import {CalendarGrid, CalendarCell} from 'vanilla-starter/Calendar'; +import {Button} from 'vanilla-starter/Button'; import {useDateFormatter} from 'react-aria'; +import {ChevronLeft, ChevronRight} from 'lucide-react'; // TODO: move this into the starter example. function Example(props) { @@ -201,18 +204,22 @@ function Example(props) { ///- begin highlight -/// /* PROPS */ ///- end highlight -/// - style={{display: 'flex', gap: 30, overflow: 'auto'}} + style={{display: 'flex', gap: 12, overflow: 'auto'}} > {({state}) => ( [...Array(props.visibleDuration.months).keys()].map(i => (
-
+
{i === 0 && - + } -

{monthFormatter.format(state.visibleRange.start.add({months: i}).toDate('UTC'))}

+ {monthFormatter.format(state.visibleRange.start.add({months: i}).toDate(state.timeZone))} {i === props.visibleDuration.months - 1 && - + }
@@ -265,19 +272,25 @@ You can also control the focused date via `CalendarStateContext`. This example s ```tsx render files={['packages/dev/s2-docs/pages/react-aria/MonthDropdown.tsx', 'packages/dev/s2-docs/pages/react-aria/YearDropdown.tsx']} "use client"; -import {Calendar, CalendarGrid, CalendarCell} from 'react-aria-components'; +import {Calendar} from 'react-aria-components'; +import {CalendarGrid, CalendarCell} from 'vanilla-starter/Calendar'; import {MonthDropdown} from './MonthDropdown'; import {YearDropdown} from './YearDropdown'; import {Button} from 'vanilla-starter/Button'; +import {ChevronLeft, ChevronRight} from 'lucide-react';
- + {/*- begin highlight -*/} {/*- end highlight -*/} - +
{(date) => } diff --git a/packages/dev/s2-docs/pages/react-aria/Checkbox.mdx b/packages/dev/s2-docs/pages/react-aria/Checkbox.mdx index 19ba646d98d..42195a062d2 100644 --- a/packages/dev/s2-docs/pages/react-aria/Checkbox.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Checkbox.mdx @@ -70,7 +70,7 @@ Use the `name` and `value` props to submit the checkbox to the server. Set the ` "use client"; import {Checkbox} from 'vanilla-starter/Checkbox'; import {Button} from 'vanilla-starter/Button'; -import {Form} from 'react-aria-components'; +import {Form} from 'vanilla-starter/Form';;
diff --git a/packages/dev/s2-docs/pages/react-aria/ColorField.mdx b/packages/dev/s2-docs/pages/react-aria/ColorField.mdx index 3db74874820..c4ac7c62928 100644 --- a/packages/dev/s2-docs/pages/react-aria/ColorField.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ColorField.mdx @@ -20,7 +20,7 @@ export const tags = ['input']; docs={vanillaDocs.exports.ColorField} links={vanillaDocs.links} props={['label', 'colorSpace', 'channel', 'description', 'isDisabled']} - initialProps={{label: 'Color', defaultValue: '#ff0000'}} + initialProps={{label: 'Color', defaultValue: '#ff0000', placeholder: 'Enter a color'}} type="vanilla" files={["starters/docs/src/ColorField.tsx", "starters/docs/src/ColorField.css"]} /> @@ -50,9 +50,10 @@ function Example() {
-
Current value: {value.toString('hex')}
+
Current value: {value?.toString('hex')}
); } @@ -75,6 +76,7 @@ function Example() {
diff --git a/packages/dev/s2-docs/pages/react-aria/ComboBox.mdx b/packages/dev/s2-docs/pages/react-aria/ComboBox.mdx index c6091720d43..0efd57fda82 100644 --- a/packages/dev/s2-docs/pages/react-aria/ComboBox.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ComboBox.mdx @@ -14,7 +14,7 @@ export const tags = ['autocomplete', 'search', 'typeahead', 'input']; {docs.exports.ComboBox.description} - ```tsx render docs={vanillaDocs.exports.ComboBox} links={vanillaDocs.links} props={['label', 'isDisabled']} initialProps={{label: 'Favorite Animal'}} type="vanilla" files={["starters/docs/src/ComboBox.tsx", "starters/docs/src/ComboBox.css"]} + ```tsx render docs={vanillaDocs.exports.ComboBox} links={vanillaDocs.links} props={['label', 'isDisabled']} initialProps={{label: 'Favorite Animal', placeholder: 'Select a flavor'}} type="vanilla" files={["starters/docs/src/ComboBox.tsx", "starters/docs/src/ComboBox.css"]} "use client"; import {ComboBox, ComboBoxItem} from 'vanilla-starter/ComboBox'; @@ -28,7 +28,7 @@ export const tags = ['autocomplete', 'search', 'typeahead', 'input']; ``` - ```tsx render docs={vanillaDocs.exports.ComboBox} links={vanillaDocs.links} props={['label', 'isDisabled']} initialProps={{label: 'Favorite Animal'}} type="tailwind" files={["starters/tailwind/src/ComboBox.tsx"]} + ```tsx render docs={vanillaDocs.exports.ComboBox} links={vanillaDocs.links} props={['label', 'isDisabled']} initialProps={{label: 'Favorite Animal', placeholder: 'Select a flavor'}} type="tailwind" files={["starters/tailwind/src/ComboBox.tsx"]} "use client"; import {ComboBox, ComboBoxItem} from 'tailwind-starter/ComboBox'; @@ -52,8 +52,8 @@ The following example shows a dynamic collection of items, grouped into sections ```tsx render "use client"; -import {ComboBox} from 'vanilla-starter/ComboBox'; -import {ListBoxSection, ListBoxItem, Collection, Header} from 'react-aria-components'; +import {ComboBox, ComboBoxItem} from 'vanilla-starter/ComboBox'; +import {ListBoxSection, Collection, Header} from 'react-aria-components'; function Example() { /*- begin collapse -*/ @@ -82,16 +82,21 @@ function Example() { /*- end collapse -*/ return ( - + /*- begin highlight -*/ + {section => (
{section.name}
- {item => {item.name}} + {item => {item.name}}
)}
+ /*- end highlight -*/ ); } ``` @@ -112,7 +117,8 @@ function Example() { return (
@@ -148,6 +154,7 @@ function Example(props) { @@ -278,11 +287,12 @@ Use the `name` prop to submit the `id` of the selected item to the server. Set t "use client"; import {ComboBox, ComboBoxItem} from 'vanilla-starter/ComboBox'; import {Button} from 'vanilla-starter/Button'; -import {Form} from 'react-aria-components'; +import {Form} from 'vanilla-starter/Form';; -
+
{/*- begin highlight -*/} Files - + {/*- end highlight -*/}
Files content diff --git a/packages/dev/s2-docs/pages/react-aria/Form.mdx b/packages/dev/s2-docs/pages/react-aria/Form.mdx index 88a106efb32..c0b65dfd57b 100644 --- a/packages/dev/s2-docs/pages/react-aria/Form.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Form.mdx @@ -18,11 +18,11 @@ export const tags = ['input', 'field']; import {Button} from 'vanilla-starter/Button'; - - + +
- +
``` @@ -34,11 +34,11 @@ export const tags = ['input', 'field']; import {Button} from 'tailwind-starter/Button';
- - + +
- +
``` @@ -64,7 +64,7 @@ import {Button} from 'vanilla-starter/Button'; alert(`Hello, ${name}!`); }}> {/*- end highlight -*/} - + ``` @@ -90,7 +90,7 @@ import {Button} from 'vanilla-starter/Button'; event.target.reset(); }}> {/*- end highlight -*/} - + ``` @@ -110,6 +110,7 @@ import {Button} from 'vanilla-starter/Button';
value === 'admin' ? 'Nice try.' : null} name="username" @@ -136,6 +137,7 @@ import {TextField} from 'vanilla-starter/TextField'; ``` @@ -176,14 +178,16 @@ function Example() { + label="First Name" + placeholder="Enter your first name" /> + label="Last Name" + placeholder="Enter your last name" />
- +
); diff --git a/packages/dev/s2-docs/pages/react-aria/GridList.mdx b/packages/dev/s2-docs/pages/react-aria/GridList.mdx index d03c53afdd6..1f068c35ac3 100644 --- a/packages/dev/s2-docs/pages/react-aria/GridList.mdx +++ b/packages/dev/s2-docs/pages/react-aria/GridList.mdx @@ -14,27 +14,62 @@ export const tags = ['list view']; {docs.exports.GridList.description} - ```tsx render docs={docs.exports.GridList} links={docs.links} props={['selectionMode']} initialProps={{'aria-label': 'Favorite pokemon', selectionMode: 'multiple'}} type="vanilla" files={["starters/docs/src/GridList.tsx", "starters/docs/src/GridList.css"]} + ```tsx render docs={docs.exports.GridList} links={docs.links} props={['layout', 'selectionMode']} initialProps={{'aria-label': 'Favorite pokemon', selectionMode: 'multiple', layout: 'grid'}} type="vanilla" files={["starters/docs/src/GridList.tsx", "starters/docs/src/GridList.css"]} "use client"; + import {Text} from 'react-aria-components'; import {GridList, GridListItem} from 'vanilla-starter/GridList'; import {Button} from 'vanilla-starter/Button'; - - Charizard - + + + Desert Sunset + PNG • 2/3/2024 - - Blastoise - + + + Hiking Trail + JPEG • 1/10/2022 - - Venusaur - + + + Lion + JPEG • 8/28/2021 - - Pikachu - + + + Mountain Sunrise + PNG • 3/15/2015 + + + + Giraffe tongue + PNG • 11/27/2019 + + + + Golden Hour + WEBP • 7/24/2024 + + + + Architecture + PNG • 12/24/2016 + + + + Peeking leopard + JPEG • 3/2/2016 + + + + Roofs + JPEG • 4/24/2025 + + + + Half Dome Deer + DNG • 8/28/2018 ``` @@ -62,26 +97,262 @@ export const tags = ['list view']; ```tsx render "use client"; import {GridList, GridListItem} from 'vanilla-starter/GridList'; +import {Text} from 'react-aria-components'; + +///- begin collapse -/// +let images = [ + { + id: "8SXaMMWCTGc", + title: "A Ficus Lyrata Leaf", + user: "Clay Banks", + image: "https://images.unsplash.com/photo-1580133318324-f2f76d987dd8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "pYjCqqDEOFo", + title: "Italian beach", + user: "Alan Bajura", + image: "https://images.unsplash.com/photo-1737100522891-e8946ac97fd1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "CF-2tl6MQj0", + title: "Forest road", + user: "Artem Stoliar", + image: "https://images.unsplash.com/photo-1738249034651-1896f689be58?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 300 + }, + { + id: "OW97sLU0cOw", + title: "Snowy Aurora", + user: "Janosch Diggelmann", + image: "https://images.unsplash.com/photo-1738189669835-61808a9d5981?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "WfeLZ02IhkM", + title: "A blue and white firework is seen from above", + user: "Janosch Diggelmann", + image: "https://images.unsplash.com/photo-1738168601630-1c1f3ef5a95a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 300 + }, + { + id: "w1GpST72Bg8", + title: "Snowy Mountain", + user: "Daniil Silantev", + image: "https://images.unsplash.com/photo-1738165170747-ecc6e3a4d97c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 267 + }, + { + id: "0iN0KIt6lYI", + title: "Pastel Sunset", + user: "Marek Piwnicki", + image: "https://images.unsplash.com/photo-1737917818689-f3b3708de5d7?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 640 + }, + { + id: "-mFKPfXXUG0", + title: "Snowy Birches", + user: "Simon Berger", + image: "https://images.unsplash.com/photo-1737972970322-cc2e255021bd?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 400 + }, + { + id: "y36Nj_edtRE", + title: "Snowy Lake Reflections", + user: "Daniel Seßler", + image: "https://images.unsplash.com/photo-1736018545810-3de4c7ec25fa?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "NvBV-YwlgBw", + title: "Rocky night sky", + user: "Dennis Haug", + image: "https://images.unsplash.com/photo-1735528655501-cf671a3323c3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 400 + }, + { + id: "UthQdrPFxt0", + title: "A pine tree covered in snow in a forest", + user: "Anita Austvika", + image: "https://images.unsplash.com/photo-1737312905026-5dfdff1097bc?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "2k74xaf8dfc", + title: "The sun shines through the trees in the forest", + user: "Joyce G", + image: "https://images.unsplash.com/photo-1736185597807-371cae1c7e4e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "Yje5kgfvCm0", + title: "A blurry photo of a field of flowers", + user: "Eugene Golovesov", + image: "https://images.unsplash.com/photo-1736483065204-e55e62092780?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "G2bsj2LVttI", + title: "A foggy road lined with trees and grass", + user: "Ingmar H", + image: "https://images.unsplash.com/photo-1737903071772-4d20348b4d81?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 533 + }, + { + id: "ppyNBOkfiuY", + title: "A close up of a green palm tree", + user: "Junel Mujar", + image: "https://images.unsplash.com/photo-1736849544918-6ddb5cfc2c42?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 533 + }, + { + id: "UcWUMqIsld8", + title: "A green leaf floating on top of a body of water", + user: "Allec Gomes", + image: "https://images.unsplash.com/photo-1737559217439-a5703e9b65cb?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "xHqOVq9w8OI", + title: "Leafy plants", + user: "Joshua Michaels", + image: "https://images.unsplash.com/photo-1563364664-399838d1394c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 266 + }, + { + id: "uWx3_XEc-Jw", + title: "A view of a mountain covered in fog", + user: "iuliu illes", + image: "https://images.unsplash.com/photo-1737403428945-c584529b7b17?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 298 + }, + { + id: "2_3lhGt8i-Y", + title: "A field with tall grass and fog in the background", + user: "Ingmar H", + image: "https://images.unsplash.com/photo-1737439987404-a3ee9fb95351?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "FV-__IOxb08", + title: "A close up of a wave on a sandy beach", + user: "Jonathan Borba", + image: "https://images.unsplash.com/photo-1726502102472-2108ef2a5cae?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "_BS-vK3boOU", + title: "Desert textures", + user: "Braden Jarvis", + image: "https://images.unsplash.com/photo-1722359546494-8e3a00f88e95?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 561 + }, + { + id: "LjAcS9lJdBg", + title: "Tew Falls, waterfall, in Hamilton, Canada.", + user: "Andre Portolesi", + image: "https://images.unsplash.com/photo-1705021246536-aecfad654893?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 500 + }, + { + id: "hlj6xJG30FE", + title: "Cave light rays", + user: "Intricate Explorer", + image: "https://images.unsplash.com/photo-1631641551473-fbe46919289d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 267 + }, + { + id: "vMoZvKeZOhw", + title: "Salt Marshes, Isle of Harris, Scotland", + user: "Nils Leonhardt", + image: "https://images.unsplash.com/photo-1585951301678-8fd6f3b32c7e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "wCLCK9LDDjI", + title: "An aerial view of a snow covered forest", + user: "Lukas Hädrich", + image: "https://images.unsplash.com/photo-1737405555489-78b3755eaa81?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 267 + }, + { + id: "OdDx3_NB-Wk", + title: "Tall grass", + user: "Ingmar H", + image: "https://images.unsplash.com/photo-1737301519296-062cd324dbfa?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "Gn-FOw1geFc", + title: "Larches on Maple Pass, Washington", + user: "Noelle", + image: "https://images.unsplash.com/photo-1737496538329-a59d10148a08?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "VhKJHOz2tJ8", + title: "Heart Nebula", + user: "Arnaud Girault", + image: "https://images.unsplash.com/photo-1737478598284-b9bc11cb1e9b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 266 + }, + { + id: "w5QmH_uqB0U", + title: "A pile of shells sitting on top of a sandy beach", + user: "Toa Heftiba", + image: "https://images.unsplash.com/photo-1725366351350-a64a1be919ef?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + } +]; +///- end collapse -/// function Example() { - let options = [ - { id: 1, name: 'Aardvark' }, - { id: 2, name: 'Cat' }, - { id: 3, name: 'Dog' }, - { id: 4, name: 'Kangaroo' }, - { id: 5, name: 'Koala' }, - { id: 6, name: 'Penguin' }, - { id: 7, name: 'Snake' }, - { id: 8, name: 'Turtle' }, - { id: 9, name: 'Wombat' } - ]; - return ( - /*- begin highlight -*/ - - {(item) => {item.name}} + + {/*- end highlight -*/} + {(image) => ( + + + {image.title} + By {image.user} + + )} - /*- end highlight -*/ ); } ``` @@ -92,51 +363,48 @@ Use [renderEmptyState](#empty-state) to display a spinner during initial load. T ```tsx render "use client"; -import {Collection, GridListLoadMoreItem} from 'react-aria-components'; -import {GridList, GridListItem} from 'vanilla-starter/GridList'; +import {GridList, GridListItem, GridListLoadMoreItem} from 'vanilla-starter/GridList'; +import {Collection, Text} from 'react-aria-components'; import {ProgressCircle} from 'vanilla-starter/ProgressCircle'; import {useAsyncList} from '@react-stately/data'; -interface Character { - name: string -} - function AsyncLoadingExample() { - let list = useAsyncList({ - async load({ signal, cursor }) { - if (cursor) { - cursor = cursor.replace(/^http:\/\//i, 'https://'); - } - + let list = useAsyncList({ + async load({signal, cursor, items}) { + let page = cursor || 1; let res = await fetch( - cursor || `https://swapi.py4e.com/api/people/?search=`, - { signal } + `https://api.unsplash.com/topics/nature/photos?page=${page}&per_page=30&client_id=AJuU-FPh11hn7RuumUllp4ppT8kgiLS7LtOHp_sp4nc`, + {signal} ); - let json = await res.json(); - - return { - items: json.results, - cursor: json.next - }; + let nextItems = await res.json(); + // Filter duplicates which might be returned by the API. + let existingKeys = new Set(items.map(i => i.id)); + nextItems = nextItems.filter(i => !existingKeys.has(i.id) && (i.description || i.alt_description)); + return {items: nextItems, cursor: nextItems.length ? page + 1 : null}; } }); return ( ( )}> - {(item) => {item.name}} + {(item) => ( + + + {item.description || item.alt_description} + By {item.user.name} + + )} {/*- begin highlight -*/} - - + isLoading={list.loadingState === 'loadingMore'} /> {/*- end highlight -*/} ); @@ -150,14 +418,89 @@ Use the `href` prop on a `` to create a link. See the **client sid ```tsx render docs={docs.exports.GridList} links={docs.links} props={['selectionBehavior']} initialProps={{'aria-label': 'Links', selectionMode: 'multiple'}} wide "use client"; import {GridList, GridListItem} from 'vanilla-starter/GridList'; - - - {/*- begin highlight -*/} - Adobe - {/*- end highlight -*/} - Apple - Google - Microsoft +import {Text} from 'react-aria-components'; + +///- begin collapse -/// +let images = [ + { + id: "dxylfBs2Xzc", + title: "Tropical island", + image: "https://images.unsplash.com/photo-1757258632083-e9b8a5345047?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTc2MDYyMjY4NHw&ixlib=rb-4.1.0&q=80&w=1080", + width: 5464, + height: 3640, + href: "https://unsplash.com/photos/aerial-view-of-a-tropical-island-coastline-with-clear-blue-water-dxylfBs2Xzc" + }, + { + id: "xloDEfz0X7g", + title: "Bryce Canyon", + image: "https://images.unsplash.com/photo-1759872409669-05565abbb575?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTc2MDYyMjY4NHw&ixlib=rb-4.1.0&q=80&w=1080", + width: 4032, + height: 3024, + href: "https://unsplash.com/photos/orange-rock-formations-with-green-trees-and-blue-sky-xloDEfz0X7g" + }, + { + id: "oTBY78rZcEU", + title: "Snowy river", + image: "https://images.unsplash.com/photo-1735577561802-380c3afb0146?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTc2MDYyMjY4NHw&ixlib=rb-4.1.0&q=80&w=1080", + width: 3264, + height: 4896, + href: "https://unsplash.com/photos/a-river-surrounded-by-snow-covered-trees-and-mountains-oTBY78rZcEU" + }, + { + id: "Go811IU9a2g", + title: "Ocean waves", + image: "https://images.unsplash.com/photo-1759997604062-c31f20012ac1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTc2MDYyMjY4NHw&ixlib=rb-4.1.0&q=80&w=1080", + width: 5250, + height: 3500, + href: "https://unsplash.com/photos/a-large-wave-crashes-on-a-sandy-beach-Go811IU9a2g" + }, + { + id: "B0mydNIV-sI", + title: "Mount Kazbek at Dawn", + image: "https://images.unsplash.com/photo-1760464864365-2188cd2afcde?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTc2MDYyMjY4NHw&ixlib=rb-4.1.0&q=80&w=1080", + width: 3947, + height: 5920, + href: "https://unsplash.com/photos/snow-capped-mountain-peak-illuminated-by-sunrise-B0mydNIV-sI" + }, + { + id: "IHfbPJYsnsI", + title: "Snowy mountain sunrise", + image: "https://images.unsplash.com/photo-1759675795062-a657fcb278b1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTc2MDYyMjY4NHw&ixlib=rb-4.1.0&q=80&w=1080", + width: 5794, + height: 3360, + href: "https://unsplash.com/photos/snowy-mountains-rise-from-the-ocean-at-sunrise-IHfbPJYsnsI" + }, + { + id: "mmcSaJrRuCM", + title: "Mount Blum", + image: "https://images.unsplash.com/photo-1760301269447-fbc82b5a8d14?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTc2MDYyMjY4NHw&ixlib=rb-4.1.0&q=80&w=1080", + width: 5862, + height: 4000, + href: "https://unsplash.com/photos/majestic-mountain-peak-illuminated-by-sunrise-light-mmcSaJrRuCM" + }, + { + id: "SSpEIUBRG9s", + title: "Sunset", + image: "https://images.unsplash.com/photo-1760199025509-2ecc68d39acd?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTc2MDYyMjY4NHw&ixlib=rb-4.1.0&q=80&w=1080", + width: 6000, + height: 4000, + href: "https://unsplash.com/photos/silhouette-of-trees-and-plants-against-a-sunset-sky-SSpEIUBRG9s" + } +]; +///- end collapse -/// + + + {image => ( + + + {image.title} + + )} ``` @@ -180,7 +523,7 @@ Use the `selectionMode` prop to enable single or multiple selection. The selecte ```tsx render docs={docs.exports.GridList} links={docs.links} props={['selectionMode', 'selectionBehavior', 'disabledBehavior', 'disallowEmptySelection']} initialProps={{selectionMode: 'multiple'}} wide "use client"; -import type {Selection} from 'react-aria-components'; +import {type Selection, Text} from 'react-aria-components'; import {GridList, GridListItem} from 'vanilla-starter/GridList'; import {useState} from 'react'; @@ -188,10 +531,11 @@ function Example(props) { let [selected, setSelected] = useState(new Set()); return ( -
+ <> alert(`Clicked ${key}`)} ///- end highlight -/// > - Lettuce - Tomato - Cheese - Tuna Salad - Egg Salad - Ham + + + Desert Sunset + PNG • 2/3/2024 + + + + Hiking Trail + JPEG • 1/10/2022 + + + + Lion + JPEG • 8/28/2021 + + + + Mountain Sunrise + PNG • 3/15/2015 + + + + Giraffe tongue + PNG • 11/27/2019 + + + + Golden Hour + WEBP • 7/24/2024 + + + + Architecture + PNG • 12/24/2016 + + + + Peeking leopard + JPEG • 3/2/2016 + + + + Roofs + JPEG • 4/24/2025 + + + + Half Dome Deer + DNG • 8/28/2018 +

Current selection: {selected === 'all' ? 'all' : [...selected].join(', ')}

-
+ ); } ``` @@ -220,22 +608,261 @@ GridList supports drag and drop interactions when the `dragAndDropHooks` prop is "use client"; import {useListData} from 'react-stately'; import {GridList, GridListItem} from 'vanilla-starter/GridList'; -import {useDragAndDrop} from 'react-aria-components'; +import {useDragAndDrop, Text} from 'react-aria-components'; + +///- begin collapse -/// +let images = [ + { + id: "8SXaMMWCTGc", + title: "A Ficus Lyrata Leaf in the sunlight (2/2) (IG: @clay.banks)", + user: "Clay Banks", + image: "https://images.unsplash.com/photo-1580133318324-f2f76d987dd8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "pYjCqqDEOFo", + title: "beach of Italy", + user: "alan bajura", + image: "https://images.unsplash.com/photo-1737100522891-e8946ac97fd1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "CF-2tl6MQj0", + title: "A winding road in the middle of a forest", + user: "Artem Stoliar", + image: "https://images.unsplash.com/photo-1738249034651-1896f689be58?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 300 + }, + { + id: "OW97sLU0cOw", + title: "A green and purple aurora over a snow covered forest", + user: "Janosch Diggelmann", + image: "https://images.unsplash.com/photo-1738189669835-61808a9d5981?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "WfeLZ02IhkM", + title: "A blue and white firework is seen from above", + user: "Janosch Diggelmann", + image: "https://images.unsplash.com/photo-1738168601630-1c1f3ef5a95a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 300 + }, + { + id: "w1GpST72Bg8", + title: "A snow covered mountain with a sky background", + user: "Daniil Silantev", + image: "https://images.unsplash.com/photo-1738165170747-ecc6e3a4d97c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 267 + }, + { + id: "0iN0KIt6lYI", + title: "\"Pastel Sunset\"", + user: "Marek Piwnicki", + image: "https://images.unsplash.com/photo-1737917818689-f3b3708de5d7?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 640 + }, + { + id: "-mFKPfXXUG0", + title: "Leave the weight behind! You must make yourself light to strive upwards — to reach the light. (A serene winter landscape featuring a dense collection of bare, white trees.)", + user: "Simon Berger", + image: "https://images.unsplash.com/photo-1737972970322-cc2e255021bd?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 400 + }, + { + id: "MOk6URQ28R4", + title: "A snow covered tree with a sky background", + user: "Daniil Silantev", + image: "https://images.unsplash.com/photo-1738081359113-a7a33c509cf9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "y36Nj_edtRE", + title: "A lake surrounded by trees covered in snow", + user: "Daniel Seßler", + image: "https://images.unsplash.com/photo-1736018545810-3de4c7ec25fa?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "NvBV-YwlgBw", + title: "The night sky with stars above a rock formation", + user: "Dennis Haug", + image: "https://images.unsplash.com/photo-1735528655501-cf671a3323c3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 400 + }, + { + id: "UthQdrPFxt0", + title: "A pine tree covered in snow in a forest", + user: "Anita Austvika", + image: "https://images.unsplash.com/photo-1737312905026-5dfdff1097bc?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "2k74xaf8dfc", + title: "The sun shines through the trees in the forest", + user: "Joyce G", + image: "https://images.unsplash.com/photo-1736185597807-371cae1c7e4e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "Yje5kgfvCm0", + title: "A blurry photo of a field of flowers", + user: "Eugene Golovesov", + image: "https://images.unsplash.com/photo-1736483065204-e55e62092780?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "G2bsj2LVttI", + title: "A foggy road lined with trees and grass", + user: "Ingmar H", + image: "https://images.unsplash.com/photo-1737903071772-4d20348b4d81?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 533 + }, + { + id: "ppyNBOkfiuY", + title: "A close up of a green palm tree", + user: "Junel Mujar", + image: "https://images.unsplash.com/photo-1736849544918-6ddb5cfc2c42?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 533 + }, + { + id: "UcWUMqIsld8", + title: "A green leaf floating on top of a body of water", + user: "Allec Gomes", + image: "https://images.unsplash.com/photo-1737559217439-a5703e9b65cb?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "xHqOVq9w8OI", + title: "green-leafed plant", + user: "Joshua Michaels", + image: "https://images.unsplash.com/photo-1563364664-399838d1394c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 266 + }, + { + id: "uWx3_XEc-Jw", + title: "A view of a mountain covered in fog", + user: "iuliu illes", + image: "https://images.unsplash.com/photo-1737403428945-c584529b7b17?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 298 + }, + { + id: "2_3lhGt8i-Y", + title: "A field with tall grass and fog in the background", + user: "Ingmar H", + image: "https://images.unsplash.com/photo-1737439987404-a3ee9fb95351?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "FV-__IOxb08", + title: "A close up of a wave on a sandy beach", + user: "Jonathan Borba", + image: "https://images.unsplash.com/photo-1726502102472-2108ef2a5cae?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "_BS-vK3boOU", + title: "Desert textures", + user: "Braden Jarvis", + image: "https://images.unsplash.com/photo-1722359546494-8e3a00f88e95?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 561 + }, + { + id: "LjAcS9lJdBg", + title: "Tew Falls, waterfall, in Hamilton, Canada.", + user: "Andre Portolesi", + image: "https://images.unsplash.com/photo-1705021246536-aecfad654893?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 500 + }, + { + id: "hlj6xJG30FE", + title: "Find me on Instagram! @intricateexplorer", + user: "Intricate Explorer", + image: "https://images.unsplash.com/photo-1631641551473-fbe46919289d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 267 + }, + { + id: "vMoZvKeZOhw", + title: "Salt Marshes, Isle of Harris, Scotland by Nils Leonhardt. Visit my website: https://nilsleonhardt.com/storytelling-harris/ Instagram: @am.basteir", + user: "Nils Leonhardt", + image: "https://images.unsplash.com/photo-1585951301678-8fd6f3b32c7e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "wCLCK9LDDjI", + title: "An aerial view of a snow covered forest", + user: "Lukas Hädrich", + image: "https://images.unsplash.com/photo-1737405555489-78b3755eaa81?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 267 + }, + { + id: "OdDx3_NB-Wk", + title: "A close up of a tall grass with a sky in the background", + user: "Ingmar H", + image: "https://images.unsplash.com/photo-1737301519296-062cd324dbfa?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "Gn-FOw1geFc", + title: "Larches on Maple Pass, Washington", + user: "noelle", + image: "https://images.unsplash.com/photo-1737496538329-a59d10148a08?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + }, + { + id: "VhKJHOz2tJ8", + title: "IC 1805 La nébuleuse du coeur", + user: "arnaud girault", + image: "https://images.unsplash.com/photo-1737478598284-b9bc11cb1e9b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 266 + }, + { + id: "w5QmH_uqB0U", + title: "A pile of shells sitting on top of a sandy beach", + user: "Toa Heftiba", + image: "https://images.unsplash.com/photo-1725366351350-a64a1be919ef?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzNDA4NDh8MHwxfHRvcGljfHw2c01WalRMU2tlUXx8fHx8Mnx8MTczODM2NzE4M3w&ixlib=rb-4.0.3&q=80&w=400", + width: 400, + height: 600 + } +]; +///- end collapse -/// function Example() { let list = useListData({ - initialItems: [ - {id: 1, name: 'Adobe Photoshop'}, - {id: 2, name: 'Adobe XD'}, - {id: 3, name: 'Adobe Dreamweaver'}, - {id: 4, name: 'Adobe InDesign'}, - {id: 5, name: 'Adobe Connect'} - ] + initialItems: images }); ///- begin highlight -/// let {dragAndDropHooks} = useDragAndDrop({ - getItems: (keys) => [...keys].map(key => ({'text/plain': list.getItem(key).name})), + getItems: (keys) => [...keys].map(key => ({'text/plain': list.getItem(key).title})), onReorder(e) { if (e.target.dropPosition === 'before') { list.moveBefore(e.target.key, e.keys); @@ -249,13 +876,20 @@ function Example() { return ( - {item => {item.name}} + {image => ( + + + {image.title} + {image.user} + + )} ); } diff --git a/packages/dev/s2-docs/pages/react-aria/ListBox.mdx b/packages/dev/s2-docs/pages/react-aria/ListBox.mdx index 3e1c7218b4e..b39702a53a1 100644 --- a/packages/dev/s2-docs/pages/react-aria/ListBox.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ListBox.mdx @@ -15,7 +15,7 @@ export const tags = ['options']; {docs.exports.ListBox.description} - ```tsx render docs={docs.exports.ListBox} links={docs.links} props={['selectionMode']} type="vanilla" files={["starters/docs/src/ListBox.tsx", "starters/docs/src/ListBox.css"]} + ```tsx render docs={docs.exports.ListBox} links={docs.links} props={['selectionMode']} initialProps={{selectionMode: 'multiple'}} type="vanilla" files={["starters/docs/src/ListBox.tsx", "starters/docs/src/ListBox.css"]} "use client"; import {ListBox, ListBoxItem} from 'vanilla-starter/ListBox'; @@ -29,7 +29,7 @@ export const tags = ['options']; ``` - ```tsx render docs={docs.exports.ListBox} links={docs.links} props={['selectionMode']} type="tailwind" files={["starters/tailwind/src/ListBox.tsx"]} + ```tsx render docs={docs.exports.ListBox} links={docs.links} props={['selectionMode']} initialProps={{selectionMode: 'multiple'}} type="tailwind" files={["starters/tailwind/src/ListBox.tsx"]} "use client"; import {ListBox, ListBoxItem} from 'tailwind-starter/ListBox'; @@ -145,9 +145,9 @@ Use [renderEmptyState](#empty-state) to display a spinner during initial load. T ```tsx render "use client"; -import {Collection, ListBoxLoadMoreItem} from 'react-aria-components'; -import {ListBox, ListBoxItem} from 'vanilla-starter/ListBox'; +import {ListBox, ListBoxItem, ListBoxLoadMoreItem} from 'vanilla-starter/ListBox'; import {ProgressCircle} from 'vanilla-starter/ProgressCircle'; +import {Collection} from 'react-aria-components'; import {useAsyncList} from 'react-stately'; interface Character { @@ -183,9 +183,7 @@ function AsyncLoadingExample() { {/*- begin highlight -*/} - - + isLoading={list.loadingState === 'loadingMore'} /> {/*- end highlight -*/} ); @@ -271,52 +269,61 @@ Use the `layout` and `orientation` props to create horizontal and vertical stack import {ListBox, ListBoxItem, Text} from 'react-aria-components'; ///- begin collapse -/// -let albums = [ +let planets = [ { id: 1, - image: 'https://images.unsplash.com/photo-1593958812614-2db6a598c71c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Nnx8ZGlzY298ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=900&q=60', - title: 'Euphoric Echoes', - artist: 'Luna Solstice' + title: 'Mercury', + description: 'A year lasts 88 days' }, { id: 2, - image: 'https://images.unsplash.com/photo-1601042879364-f3947d3f9c16?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8bmVvbnxlbnwwfHwwfHx8MA%3D%3D&auto=format&fit=crop&w=900&q=60', - title: 'Neon Dreamscape', - artist: 'Electra Skyline' + title: 'Venus', + description: 'Spins backwards!' }, { id: 3, - image: 'https://images.unsplash.com/photo-1528722828814-77b9b83aafb2?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTF8fHNwYWNlfGVufDB8fDB8fHww&auto=format&fit=crop&w=900&q=60', - title: 'Cosmic Serenade', - artist: 'Orion\'s Symphony' + title: 'Earth', + description: 'Only planet with life' }, { id: 4, - image: 'https://images.unsplash.com/photo-1511379938547-c1f69419868d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8bXVzaWN8ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=900&q=60', - title: 'Melancholy Melodies', - artist: 'Violet Mistral' + title: 'Mars', + description: 'Has the tallest volcano' }, { id: 5, - image: 'https://images.unsplash.com/photo-1608433319511-dfe8ea4cbd3c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTF8fGJlYXR8ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=900&q=60', - title: 'Rhythmic Illusions', - artist: 'Mirage Beats' + title: 'Jupiter', + description: 'Can fit 1,300 Earths' + }, + { + id: 6, + title: 'Saturn', + description: 'Rings made of ice' + }, + { + id: 7, + title: 'Uranus', + description: 'Rolls on its side' + }, + { + id: 8, + title: 'Neptune', + description: 'Fastest winds in space' } ]; ///- end collapse -/// {item => ( - {item.title} - {item.artist} + {item.description} )} diff --git a/packages/dev/s2-docs/pages/react-aria/Menu.mdx b/packages/dev/s2-docs/pages/react-aria/Menu.mdx index bbfcde42091..e58ab58f55a 100644 --- a/packages/dev/s2-docs/pages/react-aria/Menu.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Menu.mdx @@ -15,29 +15,61 @@ export const tags = ['dropdown']; ```tsx render type="vanilla" files={["starters/docs/src/Menu.tsx", "starters/docs/src/Menu.css"]} "use client"; - import {MenuTrigger, Menu, Popover, SubmenuTrigger, MenuSection, Separator} from 'react-aria-components'; + import {MenuTrigger, SubmenuTrigger, Menu, MenuItem, MenuSection} from 'vanilla-starter/Menu'; + import {Separator, Text, Keyboard} from 'react-aria-components'; + import {Popover} from 'vanilla-starter/Popover'; import {Button} from 'vanilla-starter/Button'; - import {MenuItem} from 'vanilla-starter/Menu'; + import {Button} from 'vanilla-starter/Button'; + import {Ellipsis, FolderOpen, Pencil, Copy, Trash, Share, Mail, Smartphone, Instagram} from 'lucide-react'; - + - alert('open')}>Open - alert('rename')}>Rename… - alert('duplicate')}>Duplicate - alert('share')}>Share… - - Share - + + alert('open')}> + + Open + ⌘O + + alert('rename')}> + + Rename… + ⌘R + + alert('duplicate')}> + + Duplicate + ⌘D + + alert('delete')}> + + Delete… + ⌘⌫ + + + + + Share + - Email - SMS - Instagram + + + Email + + + + SMS + + + + Instagram + - - - alert('delete')}>Delete… + + Show files @@ -50,20 +82,19 @@ export const tags = ['dropdown']; ```tsx render type="tailwind" files={["starters/tailwind/src/Menu.tsx"]} "use client"; - import {MenuTrigger, SubmenuTrigger} from 'react-aria-components'; - import {Menu, MenuItem, MenuSection, MenuSeparator} from 'tailwind-starter/Menu'; + import {MenuTrigger, SubmenuTrigger, Menu, MenuItem, MenuSection, MenuSeparator} from 'tailwind-starter/Menu'; import {Button} from 'tailwind-starter/Button'; import {MoreHorizontal} from 'lucide-react'; - alert('open')}>Open alert('rename')}>Rename… alert('duplicate')}>Duplicate - alert('share')}>Share… + alert('delete')}>Delete… Share @@ -72,7 +103,6 @@ export const tags = ['dropdown']; Instagram - alert('delete')}>Delete… Show files @@ -90,7 +120,9 @@ export const tags = ['dropdown']; ```tsx render hideImports "use client"; -import {MenuTrigger, Menu, MenuItem, Button, Popover} from 'react-aria-components'; +import {MenuTrigger, Menu, MenuItem} from 'vanilla-starter/Menu'; +import {Popover} from 'vanilla-starter/Popover'; +import {Button} from 'vanilla-starter/Button'; function Example() { let items = [ @@ -126,7 +158,10 @@ Use the `"label"` and `"description"` slots to separate primary and secondary co ```tsx render hideImports "use client"; -import {MenuTrigger, Menu, MenuItem, Text, Keyboard, Button, Popover} from 'react-aria-components'; +import {MenuTrigger, Menu, MenuItem} from 'vanilla-starter/Menu'; +import {Text, Keyboard} from 'react-aria-components'; +import {Popover} from 'vanilla-starter/Popover'; +import {Button} from 'vanilla-starter/Button'; @@ -165,7 +200,10 @@ Use the `` component to group options. A `
` element may als ```tsx render hideImports "use client"; -import {MenuTrigger, Menu, MenuItem, MenuSection, Header, Button, Popover} from 'react-aria-components'; +import {Header} from 'react-aria-components'; +import {MenuTrigger, Menu, MenuItem, MenuSection} from 'vanilla-starter/Menu'; +import {Popover} from 'vanilla-starter/Popover'; +import {Button} from 'vanilla-starter/Button'; @@ -196,8 +234,9 @@ Wrap a `` and a `` with a `` to create a subm ```tsx render hideImports "use client"; -import {MenuTrigger, Menu, Popover, SubmenuTrigger, Button, Popover} from 'react-aria-components'; -import {MenuItem} from 'vanilla-starter/Menu'; +import {MenuTrigger, SubmenuTrigger, Menu, MenuItem, MenuSection} from 'vanilla-starter/Menu'; +import {Popover} from 'vanilla-starter/Popover'; +import {Button} from 'vanilla-starter/Button'; @@ -215,12 +254,10 @@ import {MenuItem} from 'vanilla-starter/Menu'; Instagram Email - - - Work - Personal - - + + Work + Personal +
@@ -235,7 +272,10 @@ Separators may be added between menu items or sections in order to create non-la ```tsx render hideImports "use client"; -import {MenuTrigger, Menu, MenuItem, Separator, Button, Popover} from 'react-aria-components'; +import {MenuTrigger, Menu, MenuItem, MenuSection} from 'vanilla-starter/Menu'; +import {Separator} from 'react-aria-components'; +import {Popover} from 'vanilla-starter/Popover'; +import {Button} from 'vanilla-starter/Button'; @@ -263,7 +303,9 @@ Use the `href` prop on a `` to create a link. See the **client side ro ```tsx render hideImports "use client"; -import {MenuTrigger, Menu, MenuItem, Button, Popover} from 'react-aria-components'; +import {MenuTrigger, Menu, MenuItem, MenuSection} from 'vanilla-starter/Menu'; +import {Popover} from 'vanilla-starter/Popover'; +import {Button} from 'vanilla-starter/Button'; @@ -298,11 +340,11 @@ function Example() { return ( - + {/*- begin highlight -*/} - - + + {/*- end highlight -*/} News Travel @@ -328,7 +370,9 @@ Use the `selectionMode` prop to enable single or multiple selection. The selecte ```tsx render docs={docs.exports.Menu} links={docs.links} props={['selectionMode', 'disallowEmptySelection']} initialProps={{selectionMode: 'multiple'}} wide align="start" "use client"; import type {Selection} from 'react-aria-components'; -import {MenuTrigger, Menu, MenuItem, Button, Popover} 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 {useState} from 'react'; function Example(props) { @@ -368,7 +412,10 @@ Each section in a menu may have independent selection states by passing `selecti ```tsx render hideImports "use client"; import type {Selection} from 'react-aria-components'; -import {MenuTrigger, Menu, MenuItem, MenuSection, Header, Button, Popover} from 'react-aria-components'; +import {Header} from 'react-aria-components'; +import {MenuTrigger, Menu, MenuItem, MenuSection} from 'vanilla-starter/Menu'; +import {Button} from 'vanilla-starter/Button'; +import {Popover} from 'vanilla-starter/Popover'; import {useState} from 'react'; function Example() { @@ -417,7 +464,10 @@ function Example() { ```tsx render hideImports "use client"; -import {MenuTrigger, Menu, MenuItem, Button, Popover, Pressable} from 'react-aria-components'; +import {Pressable} from 'react-aria-components'; +import {MenuTrigger, Menu, MenuItem} from 'vanilla-starter/Menu'; +import {Button} from 'vanilla-starter/Button'; +import {Popover} from 'vanilla-starter/Popover'; {/*- begin highlight -*/} @@ -453,10 +503,16 @@ Use `trigger="longPress"` to open the menu on long press instead of on click/tap ```tsx render hideImports "use client"; -import {MenuTrigger, Menu, MenuItem, Button, Popover} 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 {ChevronDown} from 'lucide-react'; - + Rotate diff --git a/packages/dev/s2-docs/pages/react-aria/Modal.mdx b/packages/dev/s2-docs/pages/react-aria/Modal.mdx index e2f5b0ca18b..9b317e3048f 100644 --- a/packages/dev/s2-docs/pages/react-aria/Modal.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Modal.mdx @@ -19,8 +19,9 @@ export const tags = ['dialog', 'popup', 'overlay']; import {DialogTrigger, Heading} from 'react-aria-components'; import {Modal} from 'vanilla-starter/Modal'; import {Dialog} from 'vanilla-starter/Dialog'; - import {Button} from 'vanilla-starter/Button'; + import {Form} from 'vanilla-starter/Form'; import {TextField} from 'vanilla-starter/TextField'; + import {Button} from 'vanilla-starter/Button'; function Example(props) { return ( @@ -28,12 +29,16 @@ export const tags = ['dialog', 'popup', 'overlay']; -
- Sign up - - - - + Subscribe to our newsletter +

Enter your information to subscribe to our newsletter and receive updates about new features and announcements.

+
+ + +
+ + +
+
@@ -46,8 +51,9 @@ export const tags = ['dialog', 'popup', 'overlay']; import {DialogTrigger, Heading} from 'react-aria-components'; import {Modal} from 'tailwind-starter/Modal'; import {Dialog} from 'tailwind-starter/Dialog'; - import {Button} from 'tailwind-starter/Button'; + import {Form} from 'tailwind-starter/Form'; import {TextField} from 'tailwind-starter/TextField'; + import {Button} from 'tailwind-starter/Button'; function Example(props) { return ( @@ -55,12 +61,12 @@ export const tags = ['dialog', 'popup', 'overlay']; -
+ Sign up - - + +
diff --git a/packages/dev/s2-docs/pages/react-aria/MonthDropdown.tsx b/packages/dev/s2-docs/pages/react-aria/MonthDropdown.tsx index 68b6279cc9f..84c57a9e83b 100644 --- a/packages/dev/s2-docs/pages/react-aria/MonthDropdown.tsx +++ b/packages/dev/s2-docs/pages/react-aria/MonthDropdown.tsx @@ -37,7 +37,7 @@ export function MonthDropdown(): ReactElement { return ( {/*- begin highlight -*/} diff --git a/packages/dev/s2-docs/pages/react-aria/Table.mdx b/packages/dev/s2-docs/pages/react-aria/Table.mdx index d1edbdb9d86..74556365ad2 100644 --- a/packages/dev/s2-docs/pages/react-aria/Table.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Table.mdx @@ -16,8 +16,7 @@ export const tags = ['data', 'grid']; ```tsx render docs={docs.exports.Table} links={docs.links} props={['selectionMode']} initialProps={{'aria-label': 'Files', selectionMode: 'multiple'}} type="vanilla" files={["starters/docs/src/Table.tsx", "starters/docs/src/Table.css"]} "use client"; - import {Table, TableHeader, Column, Row} from 'vanilla-starter/Table'; - import {TableBody, Cell} from 'react-aria-components'; + import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table'; @@ -95,8 +94,7 @@ In this example, both the columns and the rows are provided to the table via a r ```tsx render "use client"; -import {Table, TableHeader, Column, Row} from 'vanilla-starter/Table'; -import {TableBody, Cell} from 'react-aria-components'; +import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table'; import {CheckboxGroup} from 'vanilla-starter/CheckboxGroup'; import {Checkbox} from 'vanilla-starter/Checkbox'; import {Button} from 'vanilla-starter/Button'; @@ -134,7 +132,7 @@ function FileTable() { return (
- + Type Date Modified @@ -174,8 +172,8 @@ Use [renderEmptyState](#empty-state) to display a spinner during initial load. T ```tsx render "use client"; -import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table'; -import {Collection, TableLoadMoreItem} from 'react-aria-components'; +import {Table, TableHeader, Column, Row, TableBody, Cell, TableLoadMoreItem} from 'vanilla-starter/Table'; +import {Collection} from 'react-aria-components'; import {ProgressCircle} from 'vanilla-starter/ProgressCircle'; import {useAsyncList} from 'react-stately'; @@ -211,8 +209,8 @@ function AsyncSortTable() { style={{ height: 150, overflow: 'auto', - border: '1px solid var(--border-color)', - borderRadius: 6 + border: '0.5px solid var(--border-color)', + borderRadius: 'var(--radius)' }}>
- Name - Height - Mass - Birth Year + Name + Height + Mass + Birth Year ( @@ -246,9 +244,7 @@ function AsyncSortTable() { {/*- begin highlight -*/} - - + isLoading={list.loadingState === 'loadingMore'} /> {/*- end highlight -*/}
@@ -263,8 +259,7 @@ Use the `href` prop on a `` to create a link. See the **client side routing ```tsx render docs={docs.exports.ListBox} links={docs.links} props={['selectionBehavior']} initialProps={{'aria-label': 'Bookmarks', selectionMode: 'multiple'}} wide "use client"; -import {Table, TableHeader, Column, Row} from 'vanilla-starter/Table'; -import {TableBody, Cell} from 'react-aria-components'; +import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table'; @@ -298,8 +293,7 @@ import {TableBody, Cell} from 'react-aria-components'; ```tsx render hideImports "use client"; -import {Table, TableHeader, Column, Row} from 'vanilla-starter/Table'; -import {TableBody, Cell} from 'react-aria-components'; +import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table';
@@ -322,15 +316,14 @@ Use the `selectionMode` prop to enable single or multiple selection. The selecte ```tsx render docs={docs.exports.Table} links={docs.links} props={['selectionMode', 'selectionBehavior', 'disabledBehavior', 'disallowEmptySelection']} initialProps={{selectionMode: 'multiple'}} wide "use client"; import type {Selection} from 'react-aria-components'; -import {Table, TableHeader, Column, Row} from 'vanilla-starter/Table'; -import {TableBody, Cell} from 'react-aria-components'; +import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table'; import {useState} from 'react'; function Example(props) { let [selected, setSelected] = useState(new Set()); return ( -
+ <>

Current selection: {selected === 'all' ? 'all' : [...selected].join(', ')}

-
+ ); } ``` @@ -381,8 +374,8 @@ Set the `allowsSorting` prop on a `` to make it sortable. When the colum ```tsx render "use client"; -import {Table, TableHeader, Column, Row} from 'vanilla-starter/Table'; -import {TableBody, Cell, type SortDescriptor} from 'react-aria-components'; +import {type SortDescriptor} from 'react-aria-components'; +import {Table, TableHeader, Column, TableBody, Row, Cell} from 'vanilla-starter/Table'; import {useState} from 'react'; ///- begin collapse -/// @@ -395,7 +388,11 @@ const rows = [ ///- end collapse -/// function SortableTable() { - let [sortDescriptor, setSortDescriptor] = useState(null); + let [sortDescriptor, setSortDescriptor] = useState({ + column: 'name', + direction: 'ascending' + }); + let sortedRows = rows; if (sortDescriptor) { sortedRows = rows.toSorted((a, b) => { @@ -442,8 +439,8 @@ Wrap the `` with a ``, and add a ` {/*- begin highlight -*/} - -
- File Name - -
-
- Size - -
- Date Modified - -
-
+ File Name + Size + Date Modified {/*- end highlight -*/}
@@ -492,8 +479,8 @@ The ResizableTableContainer's `onResize` event is called when a column resizer i ```tsx render "use client"; -import {Table, TableHeader, Column, Row} from 'vanilla-starter/Table'; -import {ResizableTableContainer, ColumnResizer, TableBody, Cell} from 'react-aria-components'; +import {Table, TableHeader, Column, Row, TableBody, Cell} from 'vanilla-starter/Table'; +import {ResizableTableContainer} from 'react-aria-components'; import {useSyncExternalStore} from 'react'; ///- begin collapse -/// @@ -533,14 +520,12 @@ export default function ResizableTable() { {column => ( -
- {column.name} - -
+ {column.name}
)} diff --git a/packages/dev/s2-docs/pages/react-aria/TextField.mdx b/packages/dev/s2-docs/pages/react-aria/TextField.mdx index 55deb3f373b..ab9d9c0702e 100644 --- a/packages/dev/s2-docs/pages/react-aria/TextField.mdx +++ b/packages/dev/s2-docs/pages/react-aria/TextField.mdx @@ -20,7 +20,7 @@ export const tags = ['input']; docs={vanillaDocs.exports.TextField} links={vanillaDocs.links} props={['label', 'description', 'isReadOnly', 'isDisabled']} - initialProps={{label: 'Name'}} + initialProps={{label: 'Name', placeholder: 'Enter your full name'}} type="vanilla" files={["starters/docs/src/TextField.tsx", "starters/docs/src/TextField.css"]} /> @@ -49,6 +49,7 @@ function Example() { <> @@ -67,7 +68,7 @@ Use the `name` prop to submit the text value to the server. Set the `isRequired` "use client"; import {TextField} from 'vanilla-starter/TextField'; import {Button} from 'vanilla-starter/Button'; -import {Form} from 'react-aria-components'; +import {Form} from 'vanilla-starter/Form';; function Example(props) { return ( @@ -75,6 +76,7 @@ function Example(props) { -