diff --git a/packages/react-aria-components/src/GridList.tsx b/packages/react-aria-components/src/GridList.tsx index c77794e9827..f98cbdc36ab 100644 --- a/packages/react-aria-components/src/GridList.tsx +++ b/packages/react-aria-components/src/GridList.tsx @@ -513,7 +513,7 @@ export interface GridListLoadMoreItemProps extends Omit(props: GridListLoadMoreItemProps, ref: ForwardedRef, item: Node) { +export const GridListLoadMoreItem = createLeafComponent('loader', function GridListLoadingIndicator(props: GridListLoadMoreItemProps, ref: ForwardedRef, item: Node) { let state = useContext(ListStateContext)!; let {isVirtualized} = useContext(CollectionRendererContext); let {isLoading, onLoadMore, scrollOffset, ...otherProps} = props; diff --git a/packages/react-aria-components/src/ListBox.tsx b/packages/react-aria-components/src/ListBox.tsx index f0f95b04af7..969fccceb9e 100644 --- a/packages/react-aria-components/src/ListBox.tsx +++ b/packages/react-aria-components/src/ListBox.tsx @@ -483,7 +483,7 @@ export interface ListBoxLoadMoreItemProps extends Omit(props: ListBoxLoadMoreItemProps, ref: ForwardedRef, item: Node) { +export const ListBoxLoadMoreItem = createLeafComponent('loader', function ListBoxLoadingIndicator(props: ListBoxLoadMoreItemProps, ref: ForwardedRef, item: Node) { let state = useContext(ListStateContext)!; let {isLoading, onLoadMore, scrollOffset, ...otherProps} = props; @@ -525,7 +525,7 @@ export const ListBoxLoadMoreItem = createLeafComponent('loader', function ListBo // aria-selected isn't needed here since this option is not selectable. // eslint-disable-next-line jsx-a11y/role-has-required-aria-props role="option" - ref={ref}> + ref={ref as ForwardedRef}> {renderProps.children} )} diff --git a/packages/react-aria-components/src/Table.tsx b/packages/react-aria-components/src/Table.tsx index be7b140af72..031d4b051eb 100644 --- a/packages/react-aria-components/src/Table.tsx +++ b/packages/react-aria-components/src/Table.tsx @@ -1359,7 +1359,7 @@ export interface TableLoadMoreItemProps extends Omit(props: TableLoadMoreItemProps, ref: ForwardedRef, item: Node) { +export const TableLoadMoreItem = createLeafComponent('loader', function TableLoadingIndicator(props: TableLoadMoreItemProps, ref: ForwardedRef, item: Node) { let state = useContext(TableStateContext)!; let {isVirtualized} = useContext(CollectionRendererContext); let {isLoading, onLoadMore, scrollOffset, ...otherProps} = props; @@ -1411,7 +1411,7 @@ export const TableLoadMoreItem = createLeafComponent('loader', function TableLoa {...mergeProps(filterDOMProps(props, {global: true}), rowProps)} {...renderProps} role="row" - ref={ref as any}> + ref={ref as ForwardedRef}> {renderProps.children} diff --git a/packages/react-aria-components/stories/Autocomplete.stories.tsx b/packages/react-aria-components/stories/Autocomplete.stories.tsx index aa4bcfee813..57982bc271a 100644 --- a/packages/react-aria-components/stories/Autocomplete.stories.tsx +++ b/packages/react-aria-components/stories/Autocomplete.stories.tsx @@ -11,8 +11,8 @@ */ import {action} from '@storybook/addon-actions'; -import {Autocomplete, Button, Collection, DialogTrigger, Header, Input, Keyboard, Label, ListBox, ListBoxSection, ListLayout, Popover, SearchField, Select, SelectValue, Separator, SubmenuTrigger, Text, TextField, Virtualizer} from 'react-aria-components'; -import {Menu, MenuItem, MenuSection, MenuTrigger} from '../src/Menu'; +import {Autocomplete, Button, Collection, DialogTrigger, Header, Input, Keyboard, Label, ListBox, ListBoxSection, ListLayout, Menu, MenuItem, MenuSection, MenuTrigger, Popover, SearchField, Select, SelectValue, Separator, SubmenuTrigger, Text, TextField, Virtualizer} from 'react-aria-components'; +import {Meta, StoryObj} from '@storybook/react'; import {MyListBoxItem, MyMenuItem} from './utils'; import React from 'react'; import styles from '../example/index.css'; @@ -21,6 +21,7 @@ import {useFilter} from 'react-aria'; export default { title: 'React Aria Components/Autocomplete', + component: Autocomplete, args: { onAction: action('onAction'), selectionMode: 'multiple', @@ -46,7 +47,11 @@ export default { options: ['clearSelection', 'none'] } } -}; +} as Meta; + +export type AutocompleteStory = StoryObj; +export type MenuStory = StoryObj; +export type ListBoxStory = StoryObj; let StaticMenu = (props) => { return ( @@ -113,7 +118,7 @@ function AutocompleteWrapper(props) { ); } -export const AutocompleteExample = { +export const AutocompleteExample: AutocompleteStory = { render: (args) => { return ( @@ -131,7 +136,7 @@ export const AutocompleteExample = { name: 'Autocomplete complex static with textfield' }; -export const AutocompleteSearchfield = { +export const AutocompleteSearchfield: AutocompleteStory = { render: (args) => { return ( @@ -289,7 +294,7 @@ let dynamicRenderFuncSections = (item: ItemNode) => { } }; -export const AutocompleteMenuDynamic = { +export const AutocompleteMenuDynamic: AutocompleteStory = { render: (args) => { return ( <> @@ -313,7 +318,7 @@ export const AutocompleteMenuDynamic = { name: 'Autocomplete, dynamic menu' }; -export const AutocompleteOnActionOnMenuItems = { +export const AutocompleteOnActionOnMenuItems: AutocompleteStory = { render: (args) => { return ( @@ -342,7 +347,7 @@ interface AutocompleteItem { let items: AutocompleteItem[] = [{id: '1', name: 'Foo'}, {id: '2', name: 'Bar'}, {id: '3', name: 'Baz'}]; -export const AutocompleteDisabledKeys = { +export const AutocompleteDisabledKeys: AutocompleteStory = { render: (args) => { return ( @@ -362,7 +367,7 @@ export const AutocompleteDisabledKeys = { name: 'Autocomplete, disabled key' }; -const AsyncExample = (args) => { +const AsyncExample = (args: any): React.ReactElement => { let list = useAsyncList({ async load({filterText}) { let json = await new Promise(resolve => { @@ -413,7 +418,7 @@ const AsyncExample = (args) => { ); }; -export const AutocompleteAsyncLoadingExample = { +export const AutocompleteAsyncLoadingExample: StoryObj = { render: (args) => { return ; }, @@ -445,14 +450,14 @@ const CaseSensitiveFilter = (args) => { ); }; -export const AutocompleteCaseSensitive = { +export const AutocompleteCaseSensitive: AutocompleteStory = { render: (args) => { return ; }, name: 'Autocomplete, case sensitive filter' }; -export const AutocompleteWithListbox = { +export const AutocompleteWithListbox: AutocompleteStory = { render: (args) => { return ( @@ -529,7 +534,7 @@ function VirtualizedListBox(props) { ); } -export const AutocompleteWithVirtualizedListbox = { +export const AutocompleteWithVirtualizedListbox: AutocompleteStory = { render: (args) => { return ( @@ -615,7 +620,7 @@ function ShellExample() { ); } -export const AutocompleteInPopover = { +export const AutocompleteInPopover: MenuStory = { render: () => { return ( @@ -660,7 +665,7 @@ export const AutocompleteInPopover = { } }; -export const AutocompleteInPopoverDialogTrigger = { +export const AutocompleteInPopoverDialogTrigger: MenuStory = { render: () => { return ( @@ -771,7 +776,7 @@ const MyMenu2 = () => { ); }; -export function AutocompleteWithExtraButtons() { +export function AutocompleteWithExtraButtons(): React.ReactElement { return (
@@ -787,7 +792,7 @@ export function AutocompleteWithExtraButtons() { // TODO: note that Space is used to select an item in a multiselect menu but that is also reserved for the // autocomplete input field. Should we add logic to allow Space to select menu items when focus is in the Menu // or is that a rare/unlikely use case for menus in general? -export const AutocompleteMenuInPopoverDialogTrigger = { +export const AutocompleteMenuInPopoverDialogTrigger: MenuStory = { render: (args) => { return ( @@ -831,7 +836,7 @@ export const AutocompleteMenuInPopoverDialogTrigger = { let manyItems = [...Array(100)].map((_, i) => ({id: i, name: `Item ${i}`})); -export const AutocompleteSelect = () => ( +export const AutocompleteSelect = (): React.ReactElement => ( - - -); +; +export type ColorFieldStory = StoryObj<(props: ColorFieldProps & {label: string}) => ReturnType>; -ColorFieldExample.args = { - label: 'Test', - defaultValue: '#f00' +export const ColorFieldExample: ColorFieldStory = { + render: (args) => ( + (v?.getChannelValue('red') === 0 ? 'Invalid value' : null)}> + + + + + ), + args: { + label: 'Test', + defaultValue: '#f00' + } }; diff --git a/packages/react-aria-components/stories/ColorPicker.stories.tsx b/packages/react-aria-components/stories/ColorPicker.stories.tsx index c1048922560..b29058dc23c 100644 --- a/packages/react-aria-components/stories/ColorPicker.stories.tsx +++ b/packages/react-aria-components/stories/ColorPicker.stories.tsx @@ -11,25 +11,29 @@ */ import {Button, ColorSpace, ColorSwatchPicker, ColorSwatchPickerItem, Dialog, DialogTrigger, getColorChannels, Input, Label, Popover} from '../src'; -import {ColorAreaExample} from './ColorArea.stories'; +import {ColorAreaExampleRender} from './ColorArea.stories'; import {ColorField} from '../src/ColorField'; import {ColorPicker} from '../src/ColorPicker'; -import {ColorSliderExample} from './ColorSlider.stories'; -import {ColorSwatchExample} from './ColorSwatch.stories'; +import {ColorSliderExampleRender} from './ColorSlider.stories'; +import {ColorSwatchExampleRender} from './ColorSwatch.stories'; +import {Meta, StoryObj} from '@storybook/react'; import React, {useState} from 'react'; export default { - title: 'React Aria Components/ColorPicker' -}; + title: 'React Aria Components/ColorPicker', + component: ColorPicker +} as Meta; + +export type ColorPickerStory = StoryObj; -export const ColorPickerExample = (args) => { +function ColorPickerExampleRender(args) { let [format, setFormat] = useState('hex'); return ( - - - + + + - {color.toFormat(colorSpace).getColorChannels().map(c => )} - + {color.toFormat(colorSpace).getColorChannels().map(c => )} + )} ); +} + +export const ColorPickerSliders: ColorPickerStory = { + render: (args) => }; function ColorPickerTrigger({children}) { return ( ; + +export type ColorSliderStory = StoryObj; const TRACK_THICKNESS = 28; const THUMB_SIZE = 20; -export const ColorSliderExample = (args) => ( - -
-
- ({ - height: TRACK_THICKNESS, - width: '100%', - borderRadius: 4, - background: ` - ${defaultStyle.background}, - repeating-conic-gradient(#CCC 0% 25%, white 0% 50%) 50% / 16px 16px` - })}> - ({ - top: TRACK_THICKNESS / 2, - border: '2px solid white', - boxShadow: '0 0 0 1px black, inset 0 0 0 1px black', - width: isFocusVisible ? TRACK_THICKNESS + 4 : THUMB_SIZE, - height: isFocusVisible ? TRACK_THICKNESS + 4 : THUMB_SIZE, - borderRadius: '50%', - boxSizing: 'border-box', - background: color.toString() - })} /> - -
-); - -ColorSliderExample.args = { - channel: 'hue', - defaultValue: 'hsl(0, 100%, 50%)' -}; +export function ColorSliderExampleRender(args: ColorSliderProps): JSX.Element { + return ( + +
+
+ ({ + height: TRACK_THICKNESS, + width: '100%', + borderRadius: 4, + background: ` + ${defaultStyle.background}, + repeating-conic-gradient(#CCC 0% 25%, white 0% 50%) 50% / 16px 16px` + })}> + ({ + top: TRACK_THICKNESS / 2, + border: '2px solid white', + boxShadow: '0 0 0 1px black, inset 0 0 0 1px black', + width: isFocusVisible ? TRACK_THICKNESS + 4 : THUMB_SIZE, + height: isFocusVisible ? TRACK_THICKNESS + 4 : THUMB_SIZE, + borderRadius: '50%', + boxSizing: 'border-box', + background: color.toString() + })} /> + +
+ ); +} -ColorSliderExample.argTypes = { - channel: { - control: 'select', - options: ['hue', 'saturation', 'lightness', 'alpha'] +export const ColorSliderExample: ColorSliderStory = { + render: (args) => , + args: { + channel: 'hue', + defaultValue: 'hsl(0, 100%, 50%)' + }, + argTypes: { + channel: { + control: 'select', + options: ['hue', 'saturation', 'lightness', 'alpha'] + } } }; diff --git a/packages/react-aria-components/stories/ColorSwatch.stories.tsx b/packages/react-aria-components/stories/ColorSwatch.stories.tsx index b9671c1bc6c..c4a53050121 100644 --- a/packages/react-aria-components/stories/ColorSwatch.stories.tsx +++ b/packages/react-aria-components/stories/ColorSwatch.stories.tsx @@ -10,14 +10,18 @@ * governing permissions and limitations under the License. */ -import {ColorSwatch} from '../src/ColorSwatch'; -import React from 'react'; +import {ColorSwatch, ColorSwatchProps} from '../src/ColorSwatch'; +import {Meta, StoryObj} from '@storybook/react'; +import React, {JSX} from 'react'; export default { - title: 'React Aria Components/ColorSwatch' -}; + title: 'React Aria Components/ColorSwatch', + component: ColorSwatch +} as Meta; + +export type ColorSwatchStory = StoryObj; -export const ColorSwatchExample = (args) => ( +export const ColorSwatchExampleRender = (args: ColorSwatchProps): JSX.Element => ( ({ @@ -31,12 +35,14 @@ export const ColorSwatchExample = (args) => ( })} /> ); -ColorSwatchExample.args = { - color: 'rgb(255, 0, 0)' -}; - -ColorSwatchExample.argTypes = { - color: { - control: 'color' +export const ColorSwatchExample: ColorSwatchStory = { + render: (args) => , + args: { + color: 'rgb(255, 0, 0)' + }, + argTypes: { + color: { + control: 'color' + } } }; diff --git a/packages/react-aria-components/stories/ColorWheel.stories.tsx b/packages/react-aria-components/stories/ColorWheel.stories.tsx index cf71bf79946..71555c27c1a 100644 --- a/packages/react-aria-components/stories/ColorWheel.stories.tsx +++ b/packages/react-aria-components/stories/ColorWheel.stories.tsx @@ -11,18 +11,22 @@ */ import {ColorThumb, ColorWheel, ColorWheelTrack} from '../src'; +import {Meta, StoryFn} from '@storybook/react'; import React from 'react'; export default { - title: 'React Aria Components/ColorWheel' -}; + title: 'React Aria Components/ColorWheel', + component: ColorWheel +} as Meta; + +export type ColorWheelStory = StoryFn; const RADIUS = 100; const TRACK_THICKNESS = 28; const THUMB_SIZE = 20; -export const ColorWheelExample = (args) => ( +export const ColorWheelExample: ColorWheelStory = (args) => ( ; + +export type ComboBoxStory = StoryFn; +export type ComboBoxStoryObj = StoryObj; -export const ComboBoxExample = () => ( +export const ComboBoxExample: ComboBoxStory = () => (
@@ -49,7 +54,7 @@ interface ComboBoxItem { } let items: ComboBoxItem[] = [{id: '1', name: 'Foo'}, {id: '2', name: 'Bar'}, {id: '3', name: 'Baz'}]; -export const ComboBoxRenderPropsStatic = () => ( +export const ComboBoxRenderPropsStatic: ComboBoxStory = () => ( {({isOpen}) => ( <> @@ -72,7 +77,7 @@ export const ComboBoxRenderPropsStatic = () => ( ); -export const ComboBoxRenderPropsDefaultItems = () => ( +export const ComboBoxRenderPropsDefaultItems: ComboBoxStory = () => ( {({isOpen}) => ( <> @@ -93,7 +98,7 @@ export const ComboBoxRenderPropsDefaultItems = () => ( ); -export const ComboBoxRenderPropsItems = { +export const ComboBoxRenderPropsItems: ComboBoxStoryObj = { render: () => ( {({isOpen}) => ( @@ -121,7 +126,7 @@ export const ComboBoxRenderPropsItems = { } }; -export const ComboBoxRenderPropsListBoxDynamic = () => ( +export const ComboBoxRenderPropsListBoxDynamic: ComboBoxStory = () => ( {({isOpen}) => ( <> @@ -142,7 +147,7 @@ export const ComboBoxRenderPropsListBoxDynamic = () => ( ); -export const ComboBoxAsyncLoadingExample = () => { +export const ComboBoxAsyncLoadingExample: ComboBoxStory = () => { let list = useAsyncList({ async load({filterText}) { let json = await new Promise(resolve => { @@ -185,7 +190,7 @@ export const ComboBoxAsyncLoadingExample = () => { ); }; -export const ComboBoxImeExample = () => ( +export const ComboBoxImeExample: ComboBoxStory = () => (
@@ -211,7 +216,7 @@ export const ComboBoxImeExample = () => ( let manyItems = [...Array(10000)].map((_, i) => ({id: i, name: `Item ${i}`})); -export const VirtualizedComboBox = (args) => { +const VirtualizedComboBoxRender = (args: ComboBoxProps & {isLoading: boolean}) => { const [searchTerm, setSearchTerm] = useState(''); const {contains} = useFilter({sensitivity: 'base'}); const filteredItems = useMemo(() => { @@ -241,7 +246,8 @@ export const VirtualizedComboBox = (args) => { ); }; -VirtualizedComboBox.story = { +export const VirtualizedComboBox: StoryObj = { + render: (args) => , args: { isLoading: false } @@ -262,14 +268,14 @@ interface Character { birth_year: number } -export const AsyncVirtualizedDynamicCombobox = (args) => { +const AsyncVirtualizedDynamicComboboxRender = (props: {delay: number}): JSX.Element => { let list = useAsyncList({ async load({signal, cursor, filterText}) { if (cursor) { cursor = cursor.replace(/^http:\/\//i, 'https://'); } - await new Promise(resolve => setTimeout(resolve, args.delay)); + await new Promise(resolve => setTimeout(resolve, props.delay)); let res = await fetch(cursor || `https://swapi.py4e.com/api/people/?search=${filterText}`, {signal}); let json = await res.json(); @@ -306,7 +312,8 @@ export const AsyncVirtualizedDynamicCombobox = (args) => { ); }; -AsyncVirtualizedDynamicCombobox.story = { +export const AsyncVirtualizedDynamicCombobox: StoryObj = { + render: (args) => , args: { delay: 50 } diff --git a/packages/react-aria-components/stories/ComboBoxReproductions.stories.tsx b/packages/react-aria-components/stories/ComboBoxReproductions.stories.tsx index 56be87b6c27..f9030a3628f 100644 --- a/packages/react-aria-components/stories/ComboBoxReproductions.stories.tsx +++ b/packages/react-aria-components/stories/ComboBoxReproductions.stories.tsx @@ -11,14 +11,19 @@ */ import {Button, ComboBox, Input, Label, ListBox, ListBoxItem, Popover} from 'react-aria-components'; +import {Meta, StoryFn} from '@storybook/react'; import React from 'react'; import './combobox-reproductions.css'; + export default { - title: 'React Aria Components/ComboBoxReproductions' -}; + title: 'React Aria Components/ComboBoxReproductions', + component: ComboBox +} as Meta; + +export type ComboBoxReproductionStory = StoryFn; -export const ComboBoxReproductionExample = () => ( +export const ComboBoxReproductionExample: ComboBoxReproductionStory = () => (
diff --git a/packages/react-aria-components/stories/DateField.stories.tsx b/packages/react-aria-components/stories/DateField.stories.tsx index 9fcfcf46040..68c7dd1a7b0 100644 --- a/packages/react-aria-components/stories/DateField.stories.tsx +++ b/packages/react-aria-components/stories/DateField.stories.tsx @@ -14,6 +14,7 @@ import {action} from '@storybook/addon-actions'; import {Button, DateField, DateInput, DateSegment, FieldError, Form, Input, Label, TextField} from 'react-aria-components'; import clsx from 'clsx'; import {fromAbsolute, getLocalTimeZone, parseAbsoluteToLocal} from '@internationalized/date'; +import {Meta, StoryFn} from '@storybook/react'; import React from 'react'; import styles from '../example/index.css'; @@ -48,10 +49,16 @@ export default { }, args: { onChange: action('OnChange') - } -}; + }, + component: DateField +} as Meta; + +export type DateFieldStory = StoryFn & { + minValue?: number, + maxValue?: number +}>; -export const DateFieldExample = (props) => ( +export const DateFieldExample: DateFieldStory = (props) => ( ; -export const DatePickerExample = () => ( +export type DatePickerStory = StoryFn; + +export const DatePickerExample: DatePickerStory = () => ( @@ -53,7 +57,7 @@ export const DatePickerExample = () => ( ); -export const DatePickerTriggerWidthExample = () => ( +export const DatePickerTriggerWidthExample: DatePickerStory = () => ( @@ -88,7 +92,7 @@ export const DatePickerTriggerWidthExample = () => ( ); -export const DateRangePickerExample = () => ( +export const DateRangePickerExample: DatePickerStory = () => ( @@ -127,7 +131,7 @@ export const DateRangePickerExample = () => ( ); -export const DateRangePickerTriggerWidthExample = () => ( +export const DateRangePickerTriggerWidthExample: DatePickerStory = () => ( diff --git a/packages/react-aria-components/stories/Disclosure.stories.tsx b/packages/react-aria-components/stories/Disclosure.stories.tsx index 2da2d1e861b..5a5444452f6 100644 --- a/packages/react-aria-components/stories/Disclosure.stories.tsx +++ b/packages/react-aria-components/stories/Disclosure.stories.tsx @@ -12,15 +12,18 @@ import {Button, Heading} from 'react-aria-components'; import {Disclosure, DisclosurePanel} from '../src/Disclosure'; +import {Meta, StoryFn} from '@storybook/react'; import React from 'react'; import './styles.css'; export default { title: 'React Aria Components/Disclosure', component: Disclosure -}; +} as Meta; + +export type DisclosureStory = StoryFn; -export const DisclosureExample = (args: any) => ( +export const DisclosureExample: DisclosureStory = (args) => ( {({isExpanded}) => ( <> @@ -35,7 +38,7 @@ export const DisclosureExample = (args: any) => ( ); -export const DisclosureControlledExample = (args: any) => { +export const DisclosureControlledExample: DisclosureStory = (args) => { let [isExpanded, setExpanded] = React.useState(false); return ( diff --git a/packages/react-aria-components/stories/Dropzone.stories.tsx b/packages/react-aria-components/stories/Dropzone.stories.tsx index 40ac1e2d759..95897172b02 100644 --- a/packages/react-aria-components/stories/Dropzone.stories.tsx +++ b/packages/react-aria-components/stories/Dropzone.stories.tsx @@ -14,14 +14,19 @@ import {action} from '@storybook/addon-actions'; import {Button, DropZone, FileTrigger, Link, Text} from 'react-aria-components'; import {classNames} from '@react-spectrum/utils'; import {FocusRing, mergeProps, useButton, useClipboard, useDrag} from 'react-aria'; +import {Meta, StoryFn, StoryObj} from '@storybook/react'; import React, {useRef} from 'react'; import styles from '../example/index.css'; export default { - title: 'React Aria Components/Dropzone' -}; + title: 'React Aria Components/Dropzone', + component: DropZone +} as Meta; + +export type DropzoneStory = StoryFn; +export type DropzoneStoryObj = StoryObj; -export const DropzoneExampleWithFileTriggerLink = (props) => ( +export const DropzoneExampleWithFileTriggerLink: DropzoneStory = (props) => (
(
); -export const DropzoneExampleWithFileTriggerButton = (props) => ( +export const DropzoneExampleWithFileTriggerButton: DropzoneStory = (props) => (
(
); -export const DropzoneExampleWithDraggableAndFileTrigger = (props) => ( +export const DropzoneExampleWithDraggableAndFileTrigger: DropzoneStory = (props) => (
(
); -export const DropZoneOnlyAcceptPNGWithFileTrigger = (props) => ( +export const DropZoneOnlyAcceptPNGWithFileTrigger: DropzoneStory = (props) => (
types.has('image/png') ? 'copy' : 'cancel'} className={styles.dropzone} - onPress={action('OnPress')} onDrop={action('OnDrop')} onDropEnter={action('OnDropEnter')} onDropExit={action('OnDropExit')} > @@ -87,13 +91,12 @@ export const DropZoneOnlyAcceptPNGWithFileTrigger = (props) => (
); -export const DropZoneWithCaptureMobileOnly = (props) => ( +export const DropZoneWithCaptureMobileOnly: DropzoneStory = (props) => (
types.has('image/png') ? 'copy' : 'cancel'} className={styles.dropzone} - onPress={action('OnPress')} onDrop={action('OnDrop')} onDropEnter={action('OnDropEnter')} onDropExit={action('OnDropExit')} > @@ -104,7 +107,7 @@ export const DropZoneWithCaptureMobileOnly = (props) => (
); -export const DropzoneExampleWithDraggableObject = (props) => ( +export const DropzoneExampleWithDraggableObject: DropzoneStory = (props) => (
(
); -export const DropzoneExampleWithCopyableObject = (props) => ( +export const DropzoneExampleWithCopyableObject: DropzoneStory = (props) => (
(
); -export const DropzoneWithRenderProps = { +export const DropzoneWithRenderProps: DropzoneStoryObj = { args: { isDisabled: false }, diff --git a/packages/react-aria-components/stories/FileTrigger.stories.tsx b/packages/react-aria-components/stories/FileTrigger.stories.tsx index 60373f28217..7b6f9083825 100644 --- a/packages/react-aria-components/stories/FileTrigger.stories.tsx +++ b/packages/react-aria-components/stories/FileTrigger.stories.tsx @@ -12,13 +12,17 @@ import {action} from '@storybook/addon-actions'; import {Button, FileTrigger, Link} from 'react-aria-components'; +import {Meta, StoryFn} from '@storybook/react'; import React from 'react'; export default { - title: 'React Aria Components/FileTrigger' -}; + title: 'React Aria Components/FileTrigger', + component: FileTrigger +} as Meta; + +export type FileTriggerStory = StoryFn; -export const FileTriggerButton = (props) => ( +export const FileTriggerButton: FileTriggerStory = (props) => ( ( ); -export const FileTriggerDirectories = (props) => { +export const FileTriggerDirectories: FileTriggerStory = (props) => { let [files, setFiles] = React.useState([]); return ( @@ -52,7 +56,7 @@ export const FileTriggerDirectories = (props) => { ); }; -export const FileTriggerLinkAllowsMultiple = (props) => ( +export const FileTriggerLinkAllowsMultiple: FileTriggerStory = (props) => ( ; + +export type FormStory = StoryFn; -export const FormAutoFillExample = () => { +export const FormAutoFillExample: FormStory = () => { return (
; + +export type GridListStory = StoryFn; -export const GridListExample = (args) => ( +export const GridListExample: GridListStory = (args) => ( { ); }; -export function VirtualizedGridList(args) { +const VirtualizedGridListRender = (args: GridListProps & {isLoading: boolean}) => { let items: {id: number, name: string}[] = []; for (let i = 0; i < 10000; i++) { items.push({id: i, name: `Item ${i}`}); @@ -184,15 +190,16 @@ export function VirtualizedGridList(args) { ); -} +}; -VirtualizedGridList.story = { +export const VirtualizedGridList: StoryObj = { + render: (args) => , args: { isLoading: false } }; -export function VirtualizedGridListGrid() { +export let VirtualizedGridListGrid: GridListStory = () => { let items: {id: number, name: string}[] = []; for (let i = 0; i < 10000; i++) { items.push({id: i, name: `Item ${i}`}); @@ -209,7 +216,7 @@ export function VirtualizedGridListGrid() { ); -} +}; let renderEmptyState = ({isLoading}) => { return ( @@ -242,14 +249,14 @@ const MyGridListLoaderIndicator = (props) => { ); }; -export const AsyncGridList = (args) => { +function AsyncGridListRender(props: {delay: number}): JSX.Element { let list = useAsyncList({ async load({signal, cursor, filterText}) { if (cursor) { cursor = cursor.replace(/^http:\/\//i, 'https://'); } - await new Promise(resolve => setTimeout(resolve, args.delay)); + await new Promise(resolve => setTimeout(resolve, props.delay)); let res = await fetch(cursor || `https://swapi.py4e.com/api/people/?search=${filterText}`, {signal}); let json = await res.json(); @@ -274,22 +281,23 @@ export const AsyncGridList = (args) => { ); -}; +} -AsyncGridList.story = { +export let AsyncGridList: StoryObj = { + render: (args) => , args: { delay: 50 } }; -export const AsyncGridListVirtualized = (args) => { +function AsyncGridListVirtualizedRender(props: {delay: number}): JSX.Element { let list = useAsyncList({ async load({signal, cursor, filterText}) { if (cursor) { cursor = cursor.replace(/^http:\/\//i, 'https://'); } - await new Promise(resolve => setTimeout(resolve, args.delay)); + await new Promise(resolve => setTimeout(resolve, props.delay)); let res = await fetch(cursor || `https://swapi.py4e.com/api/people/?search=${filterText}`, {signal}); let json = await res.json(); return { @@ -320,13 +328,14 @@ export const AsyncGridListVirtualized = (args) => { ); }; -AsyncGridListVirtualized.story = { +export let AsyncGridListVirtualized: StoryObj = { + render: (args) => , args: { delay: 50 } }; -export function TagGroupInsideGridList() { +export let TagGroupInsideGridList: GridListStory = () => { return ( ); -} +}; const GridListDropdown = () => { const [isOpen, setIsOpen] = useState(false); @@ -411,7 +420,7 @@ const GridListDropdown = () => { ); }; -function GridListInModalPickerRender(props) { +function GridListInModalPickerRender(props: ModalOverlayProps): JSX.Element { const [mainModalOpen, setMainModalOpen] = useState(true); return ( <> @@ -456,7 +465,7 @@ function GridListInModalPickerRender(props) { ); } -export const GridListInModalPicker = { +export let GridListInModalPicker: StoryObj = { render: (args) => , parameters: { docs: { diff --git a/packages/react-aria-components/stories/Link.stories.tsx b/packages/react-aria-components/stories/Link.stories.tsx index 098c06c7b01..7670e148612 100644 --- a/packages/react-aria-components/stories/Link.stories.tsx +++ b/packages/react-aria-components/stories/Link.stories.tsx @@ -11,13 +11,17 @@ */ import {Link} from 'react-aria-components'; +import {Meta, StoryFn} from '@storybook/react'; import React from 'react'; export default { - title: 'React Aria Components/Link' -}; + title: 'React Aria Components/Link', + component: Link +} as Meta; + +export type LinkStory = StoryFn; -export const LinkExample = () => { +export const LinkExample: LinkStory = () => { return ( The missing link diff --git a/packages/react-aria-components/stories/ListBox.stories.tsx b/packages/react-aria-components/stories/ListBox.stories.tsx index 97b7e43c7a1..19fc5b98aa1 100644 --- a/packages/react-aria-components/stories/ListBox.stories.tsx +++ b/packages/react-aria-components/stories/ListBox.stories.tsx @@ -12,18 +12,23 @@ import {action} from '@storybook/addon-actions'; import {Collection, DropIndicator, GridLayout, Header, ListBox, ListBoxItem, ListBoxProps, ListBoxSection, ListLayout, Separator, Text, useDragAndDrop, Virtualizer, WaterfallLayout} from 'react-aria-components'; -import {ListBoxLoadMoreItem} from '../src/ListBox'; +import {ListBoxLoadMoreItem} from '../'; import {LoadingSpinner, MyListBoxItem} from './utils'; -import React from 'react'; +import {Meta, StoryFn, StoryObj} from '@storybook/react'; +import React, {JSX} from 'react'; import {Size} from '@react-stately/virtualizer'; import styles from '../example/index.css'; import {useAsyncList, useListData} from 'react-stately'; export default { - title: 'React Aria Components/ListBox' -}; + title: 'React Aria Components/ListBox', + component: ListBox +} as Meta; + +export type ListBoxStory = StoryFn; +export type ListBoxStoryObj = StoryObj; -export const ListBoxExample = (args) => ( +export const ListBoxExample: ListBoxStory = (args) => ( Foo Bar @@ -62,7 +67,7 @@ ListBoxExample.story = { // Known accessibility false positive: https://github.com/adobe/react-spectrum/wiki/Known-accessibility-false-positives#listbox // also has a aXe landmark error, not sure what it means -export const ListBoxSections = () => ( +export const ListBoxSections: ListBoxStory = () => (
Section 1
@@ -79,7 +84,7 @@ export const ListBoxSections = () => (
); -export const ListBoxComplex = () => ( +export const ListBoxComplex: ListBoxStory = () => ( Item 1 @@ -96,8 +101,14 @@ export const ListBoxComplex = () => ( ); +interface Album { + id: number, + image: string, + title: string, + artist: string +} -let albums = [ +let albums: Album[] = [ { 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', @@ -130,7 +141,8 @@ let albums = [ } ]; -export const ListBoxDnd = (props: ListBoxProps) => { +type AlbumListBoxStory = StoryFn>; +export const ListBoxDnd: AlbumListBoxStory = (props) => { let list = useListData({ initialItems: albums }); @@ -181,7 +193,7 @@ ListBoxDnd.story = { } }; -export const ListBoxDndCustomDropIndicator = (props: ListBoxProps) => { +export const ListBoxDndCustomDropIndicator: StoryFn> = (props) => { let list = useListData({ initialItems: albums }); @@ -333,7 +345,7 @@ export const ListBoxPreviewOffset = { } }; -export const ListBoxHover = () => ( +export const ListBoxHover: ListBoxStory = () => ( Hover Bar @@ -342,7 +354,7 @@ export const ListBoxHover = () => ( ); -export const ListBoxGrid = (args) => ( +export const ListBoxGrid: ListBoxStory = (args) => ( )} - + ); } -VirtualizedListBox.story = { +export const VirtualizedListBox: StoryObj = { + render: (args) => , args: { variableHeight: false, isLoading: false } }; -export function VirtualizedListBoxEmpty() { - return ( +export let VirtualizedListBoxEmpty: ListBoxStoryObj = { + render: () => (
- ); -} + ) +}; -export function VirtualizedListBoxDnd() { +export let VirtualizedListBoxDnd: ListBoxStory = () => { let items: {id: number, name: string}[] = []; for (let i = 0; i < 10000; i++) { items.push({id: i, name: `Item ${i}`}); @@ -497,9 +510,9 @@ export function VirtualizedListBoxDnd() {
); -} +}; -function VirtualizedListBoxGridExample({minSize = 80, maxSize = 100, preserveAspectRatio = false}) { +function VirtualizedListBoxGridExample({minSize = 80, maxSize = 100, preserveAspectRatio = false}: {minSize: number, maxSize: number, preserveAspectRatio: boolean}): JSX.Element { let items: {id: number, name: string}[] = []; for (let i = 0; i < 10000; i++) { items.push({id: i, name: `Item ${i}`}); @@ -550,8 +563,8 @@ function VirtualizedListBoxGridExample({minSize = 80, maxSize = 100, preserveAsp ); } -export const VirtualizedListBoxGrid = { - render(args) { +export const VirtualizedListBoxGrid: StoryObj = { + render: (args) => { return ; }, args: { @@ -563,7 +576,7 @@ export const VirtualizedListBoxGrid = { let lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'.split(' '); -export function VirtualizedListBoxWaterfall({minSize = 80, maxSize = 100}) { +export function VirtualizedListBoxWaterfall({minSize = 80, maxSize = 100}: {minSize: number, maxSize: number}): JSX.Element { let items: {id: number, name: string}[] = []; for (let i = 0; i < 1000; i++) { let words = Math.max(2, Math.floor(Math.random() * 25)); @@ -627,7 +640,7 @@ const MyListBoxLoaderIndicator = (props) => { ); }; -export const AsyncListBox = (args) => { +function AsyncListBoxRender(args: {delay: number, orientation: 'horizontal' | 'vertical'}): JSX.Element { let list = useAsyncList({ async load({signal, cursor, filterText}) { if (cursor) { @@ -674,7 +687,8 @@ export const AsyncListBox = (args) => { ); }; -AsyncListBox.story = { +export const AsyncListBox: StoryObj = { + render: (args) => , args: { orientation: 'horizontal', delay: 50 @@ -687,7 +701,7 @@ AsyncListBox.story = { } }; -export const AsyncListBoxVirtualized = (args) => { +export const AsyncListBoxVirtualized: StoryFn = (args) => { let list = useAsyncList({ async load({signal, cursor, filterText}) { if (cursor) { diff --git a/packages/react-aria-components/stories/Menu.stories.tsx b/packages/react-aria-components/stories/Menu.stories.tsx index 8732983f517..362d800d79d 100644 --- a/packages/react-aria-components/stories/Menu.stories.tsx +++ b/packages/react-aria-components/stories/Menu.stories.tsx @@ -11,16 +11,20 @@ */ import {action} from '@storybook/addon-actions'; -import {Button, Header, Heading, Input, Keyboard, Label, Menu, MenuSection, MenuTrigger, Popover, Separator, SubmenuTrigger, Text, TextField} from 'react-aria-components'; +import {Button, Header, Heading, Input, Keyboard, Label, Menu, MenuSection, MenuTrigger, Popover, Separator, SubmenuTrigger, SubmenuTriggerProps, Text, TextField} from 'react-aria-components'; +import {Meta, StoryFn, StoryObj} from '@storybook/react'; import {MyMenuItem} from './utils'; -import React from 'react'; +import React, {JSX} from 'react'; import styles from '../example/index.css'; export default { - title: 'React Aria Components/Menu' -}; + title: 'React Aria Components/Menu', + component: Menu +} as Meta; + +export type MenuStory = StoryFn; -export const MenuExample = () => ( +export const MenuExample: MenuStory = () => ( @@ -43,7 +47,7 @@ export const MenuExample = () => ( ); -export const MenuComplex = () => ( +export const MenuComplex: MenuStory = () => ( @@ -68,7 +72,7 @@ export const MenuComplex = () => ( ); -export const MenuScrollPaddingExample = () => ( +export const MenuScrollPaddingExample: MenuStory = () => ( @@ -116,60 +120,84 @@ export const MenuScrollPaddingExample = () => ( ); -export const SubmenuExample = (args) => ( - - - - - Foo - - Bar - - - Submenu Foo - Submenu Bar - Submenu Baz - - - - Baz - Google - - - -); - -export const SubmenuNestedExample = (args) => ( - - - - - Foo - - Bar - - - Submenu Foo - Submenu Bar - +function SubmenuExampleRender(args: Omit & {delay: number}): JSX.Element { + return ( + + + + + Foo + + Bar + + + Submenu Foo + Submenu Bar Submenu Baz - - - Second Submenu Foo - Second Submenu Bar - Second Submenu Baz - - - - - - - Baz - Google - - - -); + + + + Baz + Google + + + + ); +} +type SubmenuExampleStory = StoryObj; +export const SubmenuExample: SubmenuExampleStory = { + render: (args) => , + args: { + delay: 200 + }, + argTypes: { + delay: { + control: 'number' + } + } +}; + +export const SubmenuNestedExample: SubmenuExampleStory = { + render: (args) => ( + + + + + Foo + + Bar + + + Submenu Foo + Submenu Bar + + Submenu Baz + + + Second Submenu Foo + Second Submenu Bar + Second Submenu Baz + + + + + + + Baz + Google + + + + ), + args: { + delay: 200 + }, + argTypes: { + delay: { + control: 'number' + } + } +}; let manyItemsSubmenu = [ {id: 'Lvl 1 Item 1', name: 'Lvl 1 Item 1'}, @@ -201,168 +229,189 @@ let dynamicRenderFunc = (item, args) => { } }; -export const SubmenuManyItemsExample = (args) => ( - - - - - {(item) => dynamicRenderFunc(item, args)} - - - -); - -export const SubmenuDisabledExample = (args) => ( - - - - - Foo - - Bar - - - Submenu Foo - Submenu Bar - Submenu Baz - - - - Baz - Google - - - -); +export const SubmenuManyItemsExample: SubmenuExampleStory = { + render: (args) => ( + + + + + {(item) => dynamicRenderFunc(item, args)} + + + + ), + args: { + delay: 200 + }, + argTypes: { + delay: { + control: 'number' + } + } +}; -export const SubmenuSectionsExample = (args) => ( - - - - - -
Section 1
- Foo +export const SubmenuDisabledExample: SubmenuExampleStory = { + render: (args) => ( + + + + + Foo Bar - -
Submenu Section 1
- Submenu Foo - Submenu Bar - Submenu Baz - Google -
- - -
Submenu Section 2
- Submenu Foo - Submenu Bar - Submenu Baz -
+ Submenu Foo + Submenu Bar + Submenu Baz
- Baz - Google - - - -
Section 2
- Foo - Bar - Baz -
-
-
-
-); + Baz + Google +
+
+
+ ), + args: { + delay: 200 + }, + argTypes: { + delay: { + control: 'number' + } + } +}; -// TODO: figure out why it is autofocusing the Menu in the SubDialog -export const SubdialogExample = (args) => ( - - - - - Foo - - Bar - - - Sign up - - - - - - - - - - - SubMenu - - - 1 - 2 - 3 - - - - - SubDialog - - - Contact - - - - - - - - - - - - - C - - - - - - Baz - Google - - - -); +export const SubmenuSectionsExample: SubmenuExampleStory = { + render: (args) => ( + + + + + +
Section 1
+ Foo + + Bar + + + +
Submenu Section 1
+ Submenu Foo + Submenu Bar + Submenu Baz + Google +
+ + +
Submenu Section 2
+ Submenu Foo + Submenu Bar + Submenu Baz +
+
+
+
+ Baz + Google +
+ + +
Section 2
+ Foo + Bar + Baz +
+
+
+
+ ) +}; -let submenuArgs = { +// TODO: figure out why it is autofocusing the Menu in the SubDialog +export const SubdialogExample: SubmenuExampleStory = { + render: (args) => ( + + + + + Foo + + Bar + +
+ Sign up + + + + + + + + + + + SubMenu + + + 1 + 2 + 3 + + + + + SubDialog + + + Contact + + + + + + + + + + + + + C +
+ + +
+
+ Baz + Google +
+
+
+ ), args: { delay: 200 }, @@ -372,9 +421,3 @@ let submenuArgs = { } } }; - -SubmenuExample.story = {...submenuArgs}; -SubmenuNestedExample.story = {...submenuArgs}; -SubmenuManyItemsExample.story = {...submenuArgs}; -SubmenuDisabledExample.story = {...submenuArgs}; -SubdialogExample.story = {...submenuArgs}; diff --git a/packages/react-aria-components/stories/Meter.stories.tsx b/packages/react-aria-components/stories/Meter.stories.tsx index 33ca1e0d018..505d17dd0fd 100644 --- a/packages/react-aria-components/stories/Meter.stories.tsx +++ b/packages/react-aria-components/stories/Meter.stories.tsx @@ -11,6 +11,7 @@ */ import {Label, Meter} from 'react-aria-components'; +import {Meta, StoryFn} from '@storybook/react'; import React from 'react'; export default { @@ -24,9 +25,11 @@ export default { minValue: {control: 'number'}, maxValue: {control: 'number'} } -}; +} as Meta; + +export type MeterStory = StoryFn; -export const MeterExample = (args) => { +export const MeterExample: MeterStory = (args) => { return ( {({percentage, valueText}) => ( diff --git a/packages/react-aria-components/stories/Modal.stories.tsx b/packages/react-aria-components/stories/Modal.stories.tsx index f97532547cb..22afb086256 100644 --- a/packages/react-aria-components/stories/Modal.stories.tsx +++ b/packages/react-aria-components/stories/Modal.stories.tsx @@ -11,13 +11,17 @@ */ import {Button, Dialog, DialogTrigger, Heading, Modal, ModalOverlay} from 'react-aria-components'; +import {Meta, StoryFn} from '@storybook/react'; import React, {useEffect} from 'react'; export default { - title: 'React Aria Components/Modal' -}; + title: 'React Aria Components/Modal', + component: Modal +} as Meta; + +export type ModalStory = StoryFn; -export const ModalExample = () => ( +export const ModalExample: ModalStory = () => ( ( ); -export const ModalInteractionOutsideExample = () => { +export const ModalInteractionOutsideExample: ModalStory = () => { useEffect(() => { let button = document.createElement('button'); @@ -128,7 +132,7 @@ export const ModalInteractionOutsideExample = () => { ); }; -export const ModalInteractionOutsideDefaultOverlayExample = () => { +export const ModalInteractionOutsideDefaultOverlayExample: ModalStory = () => { useEffect(() => { let button = document.createElement('button'); diff --git a/packages/react-aria-components/stories/NumberField.stories.tsx b/packages/react-aria-components/stories/NumberField.stories.tsx index 8b5045db13b..d67cd086b65 100644 --- a/packages/react-aria-components/stories/NumberField.stories.tsx +++ b/packages/react-aria-components/stories/NumberField.stories.tsx @@ -11,13 +11,17 @@ */ import {Button, FieldError, Group, Input, Label, NumberField, NumberFieldProps} from 'react-aria-components'; +import {Meta, StoryObj} from '@storybook/react'; import React, {useState} from 'react'; export default { - title: 'React Aria Components/NumberField' -}; + title: 'React Aria Components/NumberField', + component: NumberField +} as Meta; + +export type NumberFieldStory = StoryObj; -export const NumberFieldExample = { +export const NumberFieldExample: NumberFieldStory = { args: { defaultValue: 0, minValue: 0, diff --git a/packages/react-aria-components/stories/Popover.stories.tsx b/packages/react-aria-components/stories/Popover.stories.tsx index 718a4e1d9e3..b66d97470dd 100644 --- a/packages/react-aria-components/stories/Popover.stories.tsx +++ b/packages/react-aria-components/stories/Popover.stories.tsx @@ -11,13 +11,17 @@ */ import {Button, Dialog, DialogTrigger, Heading, OverlayArrow, Popover} from 'react-aria-components'; -import React, {useEffect, useRef, useState} from 'react'; +import {Meta, StoryFn, StoryObj} from '@storybook/react'; +import React, {JSX, useEffect, useRef, useState} from 'react'; export default { - title: 'React Aria Components/Popover' -}; + title: 'React Aria Components/Popover', + component: Popover +} as Meta; + +export type PopoverStory = StoryFn; -export const PopoverExample = () => ( +export const PopoverExample: PopoverStory = () => ( ( const COUNTDOWN = 5000; -function PopoverTriggerObserver() { +function PopoverTriggerObserver(): JSX.Element { const buttonRef = useRef(null); const [countdown, setCountdown] = useState(COUNTDOWN); @@ -118,11 +122,235 @@ function PopoverTriggerObserver() { } -export const PopoverTriggerObserverExample = { - render: PopoverTriggerObserver +export const PopoverTriggerObserverExample: StoryObj = { + render: () => }; -export const PopoverArrowBoundaryOffsetExample = { +function PopoverArrowBoundaryOffsetExampleRender({topLeft, topRight, leftTop, leftBottom, rightTop, rightBottom, bottomLeft, bottomRight}: + {topLeft: number, topRight: number, leftTop: number, leftBottom: number, rightTop: number, rightBottom: number, bottomLeft: number, bottomRight: number}): JSX.Element { + return ( +
+
+
+ + + + + + + + + +
Top left
+
+
+
+
+
+ + + + + + + + + +
Top right
+
+
+
+
+
+
+
+ + + + + + + + + +
Left top
+
+
+
+
+
+ + + + + + + + + +
Left bottom
+
+
+
+
+
+
+
+ + + + + + + + + +
Right top
+
+
+
+
+
+ + + + + + + + + +
Right bottom
+
+
+
+
+
+
+
+ + + + + + + + + +
Bottom left
+
+
+
+
+
+ + + + + + + + + +
Bottom right
+
+
+
+
+
+
+ ); +} + +export const PopoverArrowBoundaryOffsetExample: StoryObj = { args: { topLeft: 25, topRight: 25, @@ -191,231 +419,10 @@ export const PopoverArrowBoundaryOffsetExample = { } } }, - render: ({topLeft, topRight, leftTop, leftBottom, rightTop, rightBottom, bottomLeft, bottomRight}: any) => { - return ( -
-
-
- - - - - - - - - -
Top left
-
-
-
-
-
- - - - - - - - - -
Top right
-
-
-
-
-
-
-
- - - - - - - - - -
Left top
-
-
-
-
-
- - - - - - - - - -
Left bottom
-
-
-
-
-
-
-
- - - - - - - - - -
Right top
-
-
-
-
-
- - - - - - - - - -
Right bottom
-
-
-
-
-
-
-
- - - - - - - - - -
Bottom left
-
-
-
-
-
- - - - - - - - - -
Bottom right
-
-
-
-
-
-
- ); - } + render: (args) => }; -export const PopoverTriggerWidthExample = () => ( +export const PopoverTriggerWidthExample: PopoverStory = () => ( ; + +export type ProgressBarStory = StoryFn; -export const ProgressBarExample = (args) => { +export const ProgressBarExample: ProgressBarStory = (args) => { return ( {({percentage, valueText}) => ( diff --git a/packages/react-aria-components/stories/RadioGroup.stories.tsx b/packages/react-aria-components/stories/RadioGroup.stories.tsx index d85d5c74d63..015fce1fde8 100644 --- a/packages/react-aria-components/stories/RadioGroup.stories.tsx +++ b/packages/react-aria-components/stories/RadioGroup.stories.tsx @@ -11,14 +11,18 @@ */ import {Button, Dialog, DialogTrigger, FieldError, Form, Label, Modal, ModalOverlay, Radio, RadioGroup} from 'react-aria-components'; +import {Meta, StoryFn} from '@storybook/react'; import React, {useState} from 'react'; import styles from '../example/index.css'; export default { - title: 'React Aria Components/RadioGroup' -}; + title: 'React Aria Components/RadioGroup', + component: RadioGroup +} as Meta; + +export type RadioGroupStory = StoryFn; -export const RadioGroupExample = () => { +export const RadioGroupExample: RadioGroupStory = () => { return ( { ); }; -export const RadioGroupControlledExample = () => { +export const RadioGroupControlledExample: RadioGroupStory = () => { let [selected, setSelected] = useState(null); return ( @@ -48,7 +52,7 @@ export const RadioGroupControlledExample = () => { ); }; -export const RadioGroupInDialogExample = () => { +export const RadioGroupInDialogExample: RadioGroupStory = () => { return ( @@ -82,7 +86,14 @@ export const RadioGroupInDialogExample = () => {
- + + + Dog + Cat + Dragon +
{ ); }; -export const RadioGroupSubmitExample = () => { +export const RadioGroupSubmitExample: RadioGroupStory = () => { return ( ; + +export type SearchFieldStory = StoryFn; -export const SearchFieldExample = () => { +export const SearchFieldExample: SearchFieldStory = () => { return ( diff --git a/packages/react-aria-components/stories/Select.stories.tsx b/packages/react-aria-components/stories/Select.stories.tsx index 3058b949132..c5b392d9d83 100644 --- a/packages/react-aria-components/stories/Select.stories.tsx +++ b/packages/react-aria-components/stories/Select.stories.tsx @@ -13,21 +13,25 @@ import {Button, Collection, FieldError, Form, Input, Label, ListBox, ListLayout, OverlayArrow, Popover, Select, SelectValue, TextField, Virtualizer} from 'react-aria-components'; import {ListBoxLoadMoreItem} from '../src/ListBox'; import {LoadingSpinner, MyListBoxItem} from './utils'; -import React from 'react'; +import {Meta, StoryFn, StoryObj} from '@storybook/react'; +import React, {JSX} from 'react'; import styles from '../example/index.css'; import {useAsyncList} from 'react-stately'; export default { title: 'React Aria Components/Select', + component: Select, argTypes: { validationBehavior: { control: 'select', options: ['native', 'aria'] } } -}; +} as Meta; + +export type SelectStory = StoryFn; -export const SelectExample = () => ( +export const SelectExample: SelectStory = () => ( ); -export const SelectRenderProps = () => ( +export const SelectRenderProps: SelectStory = () => (