From 3f4f58d54ecfac140e7c4fe5b27ffdb2cb60c876 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Thu, 16 Oct 2025 14:44:45 -0700 Subject: [PATCH 1/8] Add isPressed to table column header render props --- .../@react-aria/table/src/useTableColumnHeader.ts | 9 ++++++--- packages/react-aria-components/src/Table.tsx | 15 +++++++++++---- 2 files changed, 17 insertions(+), 7 deletions(-) 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/react-aria-components/src/Table.tsx b/packages/react-aria-components/src/Table.tsx index 03bbb3395a0..8b26e7565c0 100644 --- a/packages/react-aria-components/src/Table.tsx +++ b/packages/react-aria-components/src/Table.tsx @@ -663,17 +663,22 @@ function TableHeaderRow({item}: {item: GridNode}) { export interface ColumnRenderProps { /** - * Whether the item is currently hovered with a mouse. + * Whether the column is currently hovered with a mouse. * @selector [data-hovered] */ isHovered: boolean, /** - * Whether the item is currently focused. + * Whether the column is currently in a pressed state. + * @selector [data-pressed] + */ + isPressed: boolean, + /** + * Whether the column is currently focused. * @selector [data-focused] */ isFocused: boolean, /** - * Whether the item is currently keyboard focused. + * Whether the column is currently keyboard focused. * @selector [data-focus-visible] */ isFocusVisible: boolean, @@ -737,7 +742,7 @@ export const Column = /*#__PURE__*/ createLeafComponent(TableColumnNode, (props: let ref = useObjectRef(forwardedRef); let state = useContext(TableStateContext)!; let {isVirtualized} = useContext(CollectionRendererContext); - let {columnHeaderProps} = useTableColumnHeader( + let {columnHeaderProps, isPressed} = useTableColumnHeader( {node: column, isVirtualized}, state, ref @@ -764,6 +769,7 @@ export const Column = /*#__PURE__*/ createLeafComponent(TableColumnNode, (props: defaultClassName: 'react-aria-Column', values: { isHovered, + isPressed, isFocused, isFocusVisible, allowsSorting: column.props.allowsSorting, @@ -801,6 +807,7 @@ export const Column = /*#__PURE__*/ createLeafComponent(TableColumnNode, (props: style={style} ref={ref as any} data-hovered={isHovered || undefined} + data-pressed={isPressed || undefined} data-focused={isFocused || undefined} data-focus-visible={isFocusVisible || undefined} data-resizing={isResizing || undefined} From 9f419ea947b0df42633e54005f93f9bf72c08f1a Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Thu, 16 Oct 2025 15:21:42 -0700 Subject: [PATCH 2/8] docs: Update React Aria example styling --- .../docs/pages/react-aria/home/ExampleApp.tsx | 10 +- .../dev/s2-docs/pages/react-aria/Button.mdx | 9 +- .../dev/s2-docs/pages/react-aria/Calendar.mdx | 31 +- .../dev/s2-docs/pages/react-aria/Checkbox.mdx | 2 +- .../pages/react-aria/CheckboxGroup.mdx | 2 +- .../s2-docs/pages/react-aria/ColorField.mdx | 9 +- .../dev/s2-docs/pages/react-aria/ComboBox.mdx | 24 +- .../s2-docs/pages/react-aria/DateField.mdx | 2 +- .../s2-docs/pages/react-aria/DatePicker.mdx | 2 +- .../pages/react-aria/DateRangePicker.mdx | 2 +- .../s2-docs/pages/react-aria/Disclosure.mdx | 4 +- .../dev/s2-docs/pages/react-aria/Form.mdx | 24 +- .../dev/s2-docs/pages/react-aria/GridList.mdx | 792 ++++++++++++++++-- .../dev/s2-docs/pages/react-aria/ListBox.mdx | 53 +- .../dev/s2-docs/pages/react-aria/Menu.mdx | 130 ++- .../dev/s2-docs/pages/react-aria/Modal.mdx | 28 +- .../pages/react-aria/MonthDropdown.tsx | 2 +- .../s2-docs/pages/react-aria/NumberField.mdx | 2 +- .../pages/react-aria/PokemonGridList.tsx | 10 +- .../dev/s2-docs/pages/react-aria/Popover.mdx | 23 +- .../s2-docs/pages/react-aria/RadioGroup.mdx | 2 +- .../pages/react-aria/RangeCalendar.mdx | 31 +- .../s2-docs/pages/react-aria/SearchField.mdx | 8 +- .../dev/s2-docs/pages/react-aria/Select.mdx | 39 +- .../pages/react-aria/SelectionIndicator.css | 4 +- .../dev/s2-docs/pages/react-aria/Switch.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Table.mdx | 73 +- .../s2-docs/pages/react-aria/TextField.mdx | 12 +- .../s2-docs/pages/react-aria/TimeField.mdx | 2 +- .../pages/react-aria/ToggleButtonGroup.mdx | 11 +- .../dev/s2-docs/pages/react-aria/Toolbar.mdx | 2 +- .../dev/s2-docs/pages/react-aria/Tooltip.mdx | 2 +- .../s2-docs/pages/react-aria/Virtualizer.mdx | 36 +- .../s2-docs/pages/react-aria/YearDropdown.tsx | 2 +- packages/dev/s2-docs/pages/react-aria/dnd.mdx | 48 +- .../s2-docs/pages/react-aria/selection.mdx | 190 +++-- packages/dev/s2-docs/pages/s2/ColorField.mdx | 2 +- packages/dev/s2-docs/src/ExampleOutput.tsx | 5 +- packages/dev/s2-docs/src/ExampleSwitcher.tsx | 75 +- starters/docs/src/Autocomplete.css | 29 +- starters/docs/src/Breadcrumbs.css | 18 +- starters/docs/src/Breadcrumbs.tsx | 2 +- starters/docs/src/Button.css | 44 +- starters/docs/src/Button.tsx | 12 +- starters/docs/src/Calendar.css | 51 +- starters/docs/src/Calendar.tsx | 13 +- starters/docs/src/Checkbox.css | 71 +- starters/docs/src/Checkbox.tsx | 8 +- starters/docs/src/CheckboxGroup.css | 16 +- starters/docs/src/CheckboxGroup.tsx | 20 +- starters/docs/src/ColorArea.css | 2 +- starters/docs/src/ColorField.css | 37 +- starters/docs/src/ColorField.tsx | 6 +- starters/docs/src/ColorPicker.css | 15 +- starters/docs/src/ColorPicker.tsx | 2 +- starters/docs/src/ColorSlider.css | 11 +- starters/docs/src/ColorSwatch.css | 8 +- starters/docs/src/ColorSwatchPicker.css | 3 +- starters/docs/src/ColorThumb.css | 8 +- starters/docs/src/ComboBox.css | 86 +- starters/docs/src/ComboBox.tsx | 39 +- starters/docs/src/DateField.css | 40 +- starters/docs/src/DateField.tsx | 24 +- starters/docs/src/DatePicker.css | 26 +- starters/docs/src/DatePicker.tsx | 36 +- starters/docs/src/DateRangePicker.css | 47 +- starters/docs/src/DateRangePicker.tsx | 44 +- starters/docs/src/Dialog.css | 4 +- starters/docs/src/Disclosure.css | 40 +- starters/docs/src/Disclosure.tsx | 6 +- starters/docs/src/DisclosureGroup.css | 2 +- starters/docs/src/DropZone.css | 2 +- starters/docs/src/Form.css | 63 +- starters/docs/src/Form.tsx | 8 +- starters/docs/src/GridList.css | 286 ++++--- starters/docs/src/GridList.tsx | 4 +- starters/docs/src/InputGroup.css | 20 +- starters/docs/src/InputGroup.tsx | 5 +- starters/docs/src/Link.css | 13 +- starters/docs/src/ListBox.css | 372 +++++--- starters/docs/src/ListBox.tsx | 24 +- starters/docs/src/Menu.css | 192 +++-- starters/docs/src/Menu.tsx | 16 +- starters/docs/src/Meter.css | 29 +- starters/docs/src/Meter.tsx | 9 +- starters/docs/src/Modal.css | 13 +- starters/docs/src/NumberField.css | 79 +- starters/docs/src/NumberField.tsx | 13 +- starters/docs/src/Popover.css | 28 +- starters/docs/src/Popover.tsx | 18 +- starters/docs/src/ProgressBar.css | 77 +- starters/docs/src/ProgressBar.tsx | 4 +- starters/docs/src/ProgressCircle.tsx | 2 +- starters/docs/src/RadioGroup.css | 89 +- starters/docs/src/RadioGroup.tsx | 36 +- starters/docs/src/RangeCalendar.css | 94 ++- starters/docs/src/RangeCalendar.tsx | 31 +- starters/docs/src/SearchField.css | 89 +- starters/docs/src/SearchField.tsx | 12 +- .../docs/src}/SegmentedControl.css | 27 +- starters/docs/src/SegmentedControl.tsx | 18 + starters/docs/src/Select.css | 99 +-- starters/docs/src/Select.tsx | 16 +- starters/docs/src/Sheet.css | 2 +- starters/docs/src/Slider.css | 94 ++- starters/docs/src/Slider.tsx | 16 +- starters/docs/src/Switch.css | 72 +- starters/docs/src/Switch.tsx | 12 +- starters/docs/src/Table.css | 363 ++++---- starters/docs/src/Table.tsx | 46 +- starters/docs/src/Tabs.css | 45 +- starters/docs/src/TagGroup.css | 107 +-- starters/docs/src/TagGroup.tsx | 8 +- starters/docs/src/TextField.css | 61 +- starters/docs/src/TextField.tsx | 18 +- starters/docs/src/TimeField.css | 10 - starters/docs/src/TimeField.tsx | 22 +- starters/docs/src/ToggleButton.css | 49 +- starters/docs/src/ToggleButton.tsx | 18 +- starters/docs/src/ToggleButtonGroup.css | 29 +- starters/docs/src/Toolbar.css | 8 +- starters/docs/src/Tooltip.css | 17 +- starters/docs/src/Tree.css | 237 +++--- starters/docs/src/Tree.tsx | 54 +- starters/docs/src/theme.css | 244 ++++-- starters/docs/src/utilities.css | 277 ++++++ starters/docs/stories/Breadcrumbs.stories.tsx | 12 +- starters/docs/stories/TextField.stories.tsx | 5 +- starters/tailwind/src/Button.tsx | 9 +- starters/tailwind/src/Calendar.tsx | 16 +- starters/tailwind/src/Checkbox.tsx | 10 +- starters/tailwind/src/ColorField.tsx | 4 +- starters/tailwind/src/ColorPicker.tsx | 2 +- starters/tailwind/src/ColorSlider.tsx | 2 +- starters/tailwind/src/ColorSwatch.tsx | 2 +- starters/tailwind/src/ColorSwatchPicker.tsx | 2 +- starters/tailwind/src/ComboBox.tsx | 8 +- starters/tailwind/src/DateField.tsx | 2 +- starters/tailwind/src/DatePicker.tsx | 8 +- starters/tailwind/src/DateRangePicker.tsx | 8 +- starters/tailwind/src/Disclosure.tsx | 4 +- starters/tailwind/src/DropZone.tsx | 2 +- starters/tailwind/src/Field.tsx | 2 +- starters/tailwind/src/FieldButton.tsx | 34 + starters/tailwind/src/GridList.tsx | 7 +- starters/tailwind/src/ListBox.tsx | 2 +- starters/tailwind/src/Menu.tsx | 46 +- starters/tailwind/src/Meter.tsx | 2 +- starters/tailwind/src/NumberField.tsx | 4 +- starters/tailwind/src/Popover.tsx | 3 - starters/tailwind/src/ProgressBar.tsx | 2 +- starters/tailwind/src/RadioGroup.tsx | 10 +- starters/tailwind/src/RangeCalendar.tsx | 6 +- starters/tailwind/src/SearchField.tsx | 8 +- starters/tailwind/src/Select.tsx | 6 +- starters/tailwind/src/Slider.tsx | 8 +- starters/tailwind/src/Switch.tsx | 2 +- starters/tailwind/src/Table.tsx | 12 +- starters/tailwind/src/Tabs.tsx | 2 +- starters/tailwind/src/TagGroup.tsx | 10 +- starters/tailwind/src/TextField.tsx | 4 +- starters/tailwind/src/TimeField.tsx | 3 +- starters/tailwind/src/ToggleButton.tsx | 4 +- starters/tailwind/src/Toolbar.tsx | 2 +- starters/tailwind/src/Tree.tsx | 2 +- starters/tailwind/stories/Popover.stories.tsx | 2 +- 166 files changed, 3893 insertions(+), 2460 deletions(-) rename {packages/dev/s2-docs/pages/react-aria => starters/docs/src}/SegmentedControl.css (63%) create mode 100644 starters/docs/src/SegmentedControl.tsx create mode 100644 starters/docs/src/utilities.css create mode 100644 starters/tailwind/src/FieldButton.tsx diff --git a/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx b/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx index eb2b75a46c0..7eb6631ee96 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 {MenuTrigger, Menu, MenuItem, 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'); @@ -238,7 +238,7 @@ export function ExampleApp(): React.ReactNode { {item.common_name} {item.scientific_name} - + onAction(item, action)}> {item.isFavorite ? 'Unfavorite' : 'Favorite'} Edit… @@ -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..635bc602852 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'; @@ -82,7 +82,11 @@ function Example() { /*- end collapse -*/ return ( - + /*- begin highlight -*/ + {section => (
{section.name}
@@ -92,6 +96,7 @@ function Example() {
)}
+ /*- 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..2a6a9485353 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,11 +178,13 @@ 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..7c1cd29e33f 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,44 +363,43 @@ Use [renderEmptyState](#empty-state) to display a spinner during initial load. T ```tsx render "use client"; -import {Collection, GridListLoadMoreItem} from 'react-aria-components'; +import {Collection, GridListLoadMoreItem, Text} from 'react-aria-components'; import {GridList, GridListItem} from 'vanilla-starter/GridList'; 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 -*/} ` 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 +525,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 +533,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 +610,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 +878,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..7cde51caf47 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'; @@ -271,52 +271,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..eadafb37513 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'; @@ -235,7 +274,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 +305,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 +342,11 @@ function Example() { return ( - + {/*- begin highlight -*/} - - + + {/*- end highlight -*/} News Travel @@ -328,7 +372,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 +414,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 +466,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 +505,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..d6e89ef65a4 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 @@ -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 ( @@ -263,8 +261,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 +295,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 +318,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 +376,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 +390,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 +441,8 @@ Wrap the `` with a ``, and add a ` {/*- begin highlight -*/} - -
- File Name - -
-
- Size - -
- Date Modified - -
-
+ File Name + Size + Date Modified {/*- end highlight -*/}
@@ -492,8 +481,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 +522,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) { -