diff --git a/packages/@react-spectrum/actionbar/stories/ActionBar.stories.tsx b/packages/@react-spectrum/actionbar/stories/ActionBar.stories.tsx index bb59aa636d2..f76da3ceae3 100644 --- a/packages/@react-spectrum/actionbar/stories/ActionBar.stories.tsx +++ b/packages/@react-spectrum/actionbar/stories/ActionBar.stories.tsx @@ -11,24 +11,42 @@ */ import {action} from '@storybook/addon-actions'; +import {ActionBar} from '../src'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import {Example} from './Example'; import React from 'react'; -import {storiesOf} from '@storybook/react'; import {useViewportSize} from '@react-aria/utils'; -storiesOf('ActionBar', module) - .add( - 'default', - () => - ) - .add( - 'isEmphasized', - () => - ) - .add( - 'full width', - () => { - let viewport = useViewportSize(); - return ; + +export default { + title: 'ActionBar', + component: ActionBar, + args: { + onAction: action('onAction') + }, + argTypes: { + onAction: { + table: { + disable: true + } + }, + isEmphasized: { + control: 'boolean' } - ); + } +} as ComponentMeta; + +export type ActionBarStory = ComponentStoryObj; + +export const Default: ActionBarStory = { + render: (args) => +}; + +export const FullWidthStory: ActionBarStory = { + render: (args) => +}; + +function FullWidth(props) { + let viewport = useViewportSize(); + return ; +} diff --git a/packages/@react-spectrum/actiongroup/stories/ActionGroup.stories.tsx b/packages/@react-spectrum/actiongroup/stories/ActionGroup.stories.tsx index 9b15fbcca76..f585c3f8181 100644 --- a/packages/@react-spectrum/actiongroup/stories/ActionGroup.stories.tsx +++ b/packages/@react-spectrum/actiongroup/stories/ActionGroup.stories.tsx @@ -14,6 +14,7 @@ import {action} from '@storybook/addon-actions'; import {ActionGroup} from '../'; import BookIcon from '@spectrum-icons/workflow/Book'; import Brush from '@spectrum-icons/workflow/Brush'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import CopyIcon from '@spectrum-icons/workflow/Copy'; import DeleteIcon from '@spectrum-icons/workflow/Delete'; import DocumentIcon from '@spectrum-icons/workflow/Document'; @@ -29,18 +30,8 @@ import React from 'react'; import Sampler from '@spectrum-icons/workflow/Sampler'; import Select from '@spectrum-icons/workflow/Select'; import SettingsIcon from '@spectrum-icons/workflow/Settings'; -import {storiesOf} from '@storybook/react'; -import TagBold from '@spectrum-icons/workflow/TagBold'; -import TagItalic from '@spectrum-icons/workflow/TagItalic'; -import TagUnderline from '@spectrum-icons/workflow/TagUnderline'; import {Text} from '@react-spectrum/text'; -import TextAlignCenter from '@spectrum-icons/workflow/TextAlignCenter'; -import TextAlignJustify from '@spectrum-icons/workflow/TextAlignJustify'; -import TextAlignLeft from '@spectrum-icons/workflow/TextAlignLeft'; -import TextAlignRight from '@spectrum-icons/workflow/TextAlignRight'; import TextIcon from '@spectrum-icons/workflow/Text'; -import TextStrikethrough from '@spectrum-icons/workflow/TextStrikethrough'; -import TextStyle from '@spectrum-icons/workflow/TextStyle'; import {Tooltip, TooltipTrigger} from '@react-spectrum/tooltip'; import VectorDraw from '@spectrum-icons/workflow/VectorDraw'; import {View} from '@react-spectrum/view'; @@ -48,11 +39,8 @@ import ViewCardIcon from '@spectrum-icons/workflow/ViewCard'; import ViewGridIcon from '@spectrum-icons/workflow/ViewGrid'; import ViewListIcon from '@spectrum-icons/workflow/ViewList'; -const docItems = [{children: 'Document setup', name: '1'}, {children: 'Settings', name: '2'}]; -const editItems = [{children: 'Edit', name: '1'}, {children: 'Copy', name: '2'}, {children: 'Delete', name: '3'}]; -const viewItems2 = [{children: 'Grid view', name: '1'}, {children: 'List view', name: '2'}]; + const viewItems = [{children: 'Grid view', name: '1'}, {children: 'List view', name: '2'}, {children: 'Gallery view', name: '3'}]; -const dataItems = [{children: 'Properties', name: '1'}, {children: 'Info', name: '2'}, {children: 'Keywords', name: '3'}]; let onSelectionChange = action('onSelectionChange'); let iconMap = { @@ -69,519 +57,247 @@ let iconMap = { 'Keywords': BookIcon }; -storiesOf('ActionGroup', module) - .addParameters({providerSwitcher: {status: 'negative'}}) - .add( - 'default', - () => ( - - - { - docItems.map((itemProps) => ( - - )) - } - - - { - docItems.map((itemProps) => { - let IconElement = iconMap[itemProps.children]; - return ( - - {itemProps.children} - - - ); - }) - } - - - { - docItems.map((itemProps) => { - let IconElement = iconMap[itemProps.children]; - return ( - - - - ); - }) - } - - - ) - ) - .add( - 'with falsy item key', - () => ( - - Add - Delete - Edit - - ) - ) - .add( - 'isDisabled', - () => render({isDisabled: true, defaultSelectedKeys: ['1']}, docItems) - ) - .add( - 'all keys disabled', - () => render({disabledKeys: ['1', '2']}, docItems) - ) - .add( - 'compact', - () => render({density: 'compact', defaultSelectedKeys: ['1']}, viewItems) - ) - .add( - 'isJustified', - () => render({isJustified: true, defaultSelectedKeys: ['1']}, viewItems2) - ) - .add( - 'compact, isJustified', - () => render({density: 'compact', isJustified: true, defaultSelectedKeys: ['1']}, viewItems2) - ) - .add( - 'isQuiet', - () => render({isQuiet: true, defaultSelectedKeys: ['1']}, editItems) - ) - .add( - 'compact, isQuiet', - () => render({density: 'compact', isQuiet: true, defaultSelectedKeys: ['1']}, editItems) - ) - .add( - 'isEmphasized', - () => render({isEmphasized: true, defaultSelectedKeys: ['1']}, docItems) - ) - .add( - 'compact, isEmphasized', - () => render({isEmphasized: true, density: 'compact', defaultSelectedKeys: ['1']}, viewItems) - ) - .add( - 'isQuiet, isEmphasized', - () => render({isEmphasized: true, isQuiet: true, defaultSelectedKeys: ['1', '2'], disabledKeys: ['2']}, viewItems) - ) - .add( - 'staticColor=white', - () => ( - - {render({staticColor: 'white', defaultSelectedKeys: ['1']}, viewItems)} - - ) - ) - .add( - 'staticColor=white, isQuiet', - () => ( - - {render({staticColor: 'white', isQuiet: true, defaultSelectedKeys: ['1']}, viewItems)} - - ) - ) - .add( - 'staticColor=black', - () => ( - - {render({staticColor: 'black', defaultSelectedKeys: ['1']}, viewItems)} - - ) - ) - .add( - 'staticColor=black, isQuiet', - () => ( - - {render({staticColor: 'black', isQuiet: true, defaultSelectedKeys: ['1']}, viewItems)} - - ) - ) - .add( - 'selectionMode: multiple', - () => render({selectionMode: 'multiple', defaultSelectedKeys: ['1', '2']}, dataItems) - ) - .add( - 'selectionMode: single, disallowEmptySelection', - () => render({selectionMode: 'single', disallowEmptySelection: true, defaultSelectedKeys: ['1']}, dataItems) - ) - .add( - 'selectionMode: multiple, isQuiet', - () => render({isQuiet: true, selectionMode: 'multiple', defaultSelectedKeys: ['1', '2']}, dataItems) - ) - .add( - 'selectionMode: multiple, isQuiet, compact', - () => render({isQuiet: true, density: 'compact', selectionMode: 'multiple', defaultSelectedKeys: ['1', '2']}, dataItems) - ) - .add( - 'selectionMode: multiple, isEmphasized', - () => render({isEmphasized: true, selectionMode: 'multiple', defaultSelectedKeys: ['1', '2']}, dataItems) - ) - .add( - 'selectionMode: multiple, isEmphasized, compact', - () => render({isEmphasized: true, density: 'compact', selectionMode: 'multiple', defaultSelectedKeys: ['1', '2']}, dataItems) - ) - .add( - 'selectionMode: multiple, isEmphasized, isQuiet', - () => render({isEmphasized: true, isQuiet: true, selectionMode: 'multiple', defaultSelectedKeys: ['1', '2']}, dataItems) - ) - .add( - 'selectionMode: multiple, isEmphasized, isQuiet, compact', - () => render({isEmphasized: true, isQuiet: true, density: 'compact', selectionMode: 'multiple', defaultSelectedKeys: ['1', '2']}, dataItems) - ) - // no selection mode none, it's covered in the default story visually - .add( - 'vertical', - () => render({orientation: 'vertical', defaultSelectedKeys: ['1']}, docItems) - ) - .add( - 'vertical, isJustified', - () => render({isJustified: true, orientation: 'vertical', defaultSelectedKeys: ['1']}, docItems) - ) - .add( - 'vertical, compact', - () => render({density: 'compact', orientation: 'vertical', defaultSelectedKeys: ['1']}, viewItems) - ) - .add( - 'vertical, isJustified, compact', - () => render({isJustified: true, density: 'compact', orientation: 'vertical', defaultSelectedKeys: ['1']}, viewItems) - ) - .add( - 'vertical, isQuiet', - () => render({isQuiet: true, orientation: 'vertical', defaultSelectedKeys: ['1']}, editItems) - ) - .add( - 'vertical, isQuiet, compact', - () => render({isQuiet: true, density: 'compact', orientation: 'vertical', defaultSelectedKeys: ['1']}, viewItems) - ) - .add( - 'disabledKeys', - () => render({disabledKeys: ['1', '2'], selectionMode: 'multiple'}, dataItems) - ) - .add( - 'dynamic default', - () => ( - - {item => {item.children}} - - ) - ) - .add( - 'dynamic single selection', - () => ( - onSelectionChange([...s])} items={viewItems}> - {item => {item.children}} - - ) - ) - .add( - 'with tooltips', - () => renderTooltips({}) - ) - .add( - 'overflowMode: wrap', - () => ( -
- - - - Edit - - - - Copy - - - - Delete - - - - Move - - - - Duplicate - - -
- ) - ) - .add( - 'overflowMode: collapse', - () => ( -
- {renderCollapsible()} - {renderCollapsible({density: 'compact'})} - {renderCollapsible({density: 'compact', isJustified: true})} - {renderCollapsible({isQuiet: true})} -
- ) - ) - .add( - 'overflowMode: collapse, disabledKeys', - () => ( -
- {renderCollapsible({disabledKeys: ['edit', 'duplicate']})} - {renderCollapsible({density: 'compact', disabledKeys: ['edit', 'duplicate']})} - {renderCollapsible({density: 'compact', disabledKeys: ['edit', 'duplicate'], isJustified: true})} - {renderCollapsible({disabledKeys: ['edit', 'duplicate'], isQuiet: true})} -
- ) - ) - .add( - 'buttonLabelBehavior: hide', - () => ( -
- {renderCollapsible({buttonLabelBehavior: 'hide'})} - {renderCollapsibleText({buttonLabelBehavior: 'hide'})} -
- ) - ) - .add( - 'buttonLabelBehavior: collapse', - () => ( -
- {renderCollapsible({buttonLabelBehavior: 'collapse'})} - {renderCollapsibleText({buttonLabelBehavior: 'collapse'})} -
- ) - ) - .add( - 'overflowMode: collapse, selection', - () => ( -
- {renderCollapsibleFormatting({density: 'compact', maxWidth: '50%', isEmphasized: true})} - {renderCollapsibleAlignment({density: 'compact', maxWidth: '50%', isEmphasized: true})} -
- ) - ) - .add( - 'overflowMode: collapse, summaryIcon', - () => ( -
- {renderCollapsibleFormatting({density: 'compact', overflowMode: 'collapse', summaryIcon: , isEmphasized: true})} - {renderCollapsibleAlignment({density: 'compact', overflowMode: 'collapse', isEmphasized: true})} -
- ) - ) - .add( - 'overflowMode: collapse, single selection', - () => ( -
- {renderCollapsibleAlignment({density: 'compact', maxWidth: '50%', isEmphasized: true})} - {renderCollapsibleAlignment({density: 'compact', maxWidth: '50%', isEmphasized: true, buttonLabelBehavior: 'show'})} - {renderCollapsibleAlignmentNoIcons({density: 'compact', maxWidth: '50%', isEmphasized: true, buttonLabelBehavior: 'show'})} -
- ) - ) - .add( - 'orientation: vertical, overflowMode: collapse', - () => ( -
- {renderCollapsible({orientation: 'vertical', buttonLabelBehavior: 'hide', maxHeight: '100%', marginBottom: 0})} -
- ) - ) - .add( - 'orientation: vertical, overflowMode: collapse, selection', - () => ( - -

Note: this is currently unsupported by Spectrum. Container should scroll.

-
- {renderTools({orientation: 'vertical', buttonLabelBehavior: 'hide', maxHeight: '100%'})} -
-
- ) - ); +export default { + title: 'ActionGroup', + component: ActionGroup, + args: { + onAction: action('onAction'), + onSelectionChange: s => onSelectionChange([...s]) + }, + argTypes: { + onAction: { + table: { + disable: true + } + }, + onSelectionChange: { + table: { + disable: true + } + }, + disabledKeys: { + table: { + disable: true + } + }, + items: { + table: { + disable: true + } + }, + summaryIcon: { + table: { + disable: true + } + }, + selectionMode: { + control: 'select', + options: ['none', 'single', 'multiple'] + }, + isDisabled: { + control: 'boolean' + }, + density: { + control: 'select', + options: ['compact', 'regular', 'spacious'] + }, + isJustified: { + control: 'boolean' + }, + isQuiet: { + control: 'boolean' + }, + isEmphasized: { + control: 'boolean' + }, + disallowEmptySelection: { + control: 'boolean' + }, + orientation: { + control: 'select', + options: ['horizontal', 'vertical'] + }, + overflowMode: { + control: 'select', + options: ['wrap', 'collapse'] + }, + buttonLabelBehavior: { + control: 'select', + options: ['show', 'hide', 'collapse'] + } + } +} as ComponentMeta; +export type ActionGroupStory = ComponentStoryObj; -function render(props, items) { - return ( - - {renderText(props, items)} - {renderBoth(props, items)} - {renderIcons(props, items)} - - ); -} +export const Default: ActionGroupStory = { + args: {items: viewItems}, + render: (args) => render(args) +}; -function renderText(props, items: any = docItems) { - return ( - onSelectionChange([...s])} {...props}> - { - items.map((itemProps) => ( - - )) - } +export const FalsyKeys: ActionGroupStory = { + render: (args) => ( + + Add + Delete + Edit - ); -} + ) +}; -function renderBoth(props, items: any = docItems) { - return ( - onSelectionChange([...s])} {...props}> - { - items.map((itemProps) => { - let IconElement = iconMap[itemProps.children]; - return ( - - {itemProps.children} - - - ); - }) - } - - ); -} +export const AllKeysDisabled: ActionGroupStory = { + ...Default, + args: {disabledKeys: ['1', '2', '3'], items: viewItems} +}; -function renderIcons(props, items: any = docItems) { - return ( - onSelectionChange([...s])} {...props}> - { - items.map((itemProps) => { - let IconElement = iconMap[itemProps.children]; - return ( - - - - ); - }) - } - - ); -} +export const SomeKeysDisabled: ActionGroupStory = { + ...Default, + args: {disabledKeys: ['1', '2'], items: viewItems} +}; -function renderTooltips(props, items: any = docItems) { +export const StaticColorWhite: ActionGroupStory = { + args: {staticColor: 'white', defaultSelectedKeys: ['1'], items: viewItems}, + render: (args) => ( + + {render(args)} + + ), + storyName: 'staticColor=white' +}; + +export const StaticColorBlack: ActionGroupStory = { + args: {staticColor: 'black', defaultSelectedKeys: ['1'], items: viewItems}, + render: (args) => ( + + {render(args)} + + ), + storyName: 'staticColor=black' +}; + +export const WithTooltips: ActionGroupStory = { + args: {items: viewItems}, + render: (args) => renderTooltips(args) +}; + +export const Overflow: ActionGroupStory = { + args: {disabledKeys: ['1', '5']}, + render: (args) => renderOverflow(args), + storyName: 'overflowMode' +}; + +export const SummaryIcon: ActionGroupStory = { + ...Overflow, + args: {disabledKeys: ['1', '5'], summaryIcon: }, + storyName: 'summary icon overflow' +}; + +export const VerticalOverflow: ActionGroupStory = { + render: (args) => ( + +

Note: this is currently unsupported by Spectrum. Container should scroll.

+
+ {renderTools({orientation: 'vertical', buttonLabelBehavior: 'hide', maxHeight: '100%', ...args})} +
+
+ ), + storyName: 'special vertical overflow case' +}; + + +function render(props) { return ( - onSelectionChange([...s])} {...props}> - { - items.map((itemProps) => { - let IconElement = iconMap[itemProps.children]; - return ( - - - - - {itemProps.children} - - ); - }) - } - + + {renderText(props)} + {renderBoth(props)} + {renderIcons(props)} + ); } -function renderCollapsible(props = {}) { +function renderText(props) { return ( - - - - Edit - - - - Copy - - - Delete - - - - - Move - - - - Duplicate - + + {(item: any) => {item.children}} ); } -function renderCollapsibleText(props = {}) { +function renderBoth(props) { return ( - - Edit - Copy - Delete - Move - Duplicate + + {(item: any) => { + let IconElement = iconMap[item.children]; + return ( + + {item.children} + + + ); + }} ); } -function renderCollapsibleFormatting(props = {}) { +function renderIcons(props) { return ( - - - - Bold - - - - Italic - - - - Underline - - - - Strikethrough - + + {(item: any) => { + let IconElement = iconMap[item.children]; + return ( + + + + ); + }} ); } -function renderCollapsibleAlignment(props = {}) { +function renderTooltips(props) { return ( - - - - Align Left - - - - Align Center - - - Align Right - - - - - Justify - + + {(item: any) => { + let IconElement = iconMap[item.children]; + return ( + + + + + {item.children} + + ); + }} ); } -function renderCollapsibleAlignmentNoIcons(props = {}) { +function renderOverflow(props) { return ( - - Align Left - Align Center - Align Right - Justify - +
+ } maxHeight="100%"> + + + Edit + + + + Copy + + + + Delete + + + + Move + + + + Duplicate + + +
); } diff --git a/packages/@react-spectrum/alert/stories/Alert.stories.js b/packages/@react-spectrum/alert/stories/Alert.stories.js deleted file mode 100644 index 21907190f49..00000000000 --- a/packages/@react-spectrum/alert/stories/Alert.stories.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2020 Adobe. All rights reserved. - * This file is licensed to you under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - * OF ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - */ - -import _123 from '@spectrum-icons/workflow/123'; -import {Alert} from '../'; -import CalendarCheckColor from '@spectrum-icons/color/CalendarCheckColor'; -import React from 'react'; -import {storiesOf} from '@storybook/react'; - -storiesOf('Alert', module) - .addParameters({providerSwitcher: {status: 'negative'}}) - .add( - 'header', - () => render({title: 'info', variant: 'info'}) - ) - .add( - 'variant: info', - () => render({title: 'info', variant: 'info'}) - ) - .add( - 'variant: help', - () => render({title: 'help', variant: 'help'}) - ) - .add( - 'variant: success', - () => render({title: 'success', variant: 'success'}) - ) - .add( - 'variant: error', - () => render({title: 'error', variant: 'error'}) - ) - .add( - 'variant: warning', - () => render({title: 'warning', variant: 'warning'}) - ) - .add( - 'aria-live: polite', - () => render({title: 'error', variant: 'error', 'aria-live': 'polite'}) - ) - .add( - 'aria-live: off', - () => render({title: 'error', variant: 'error', 'aria-live': 'off'}) - ); - -function render(props = {}, children = 'This is a React Spectrum alert') { - return ( - - {children} - <_123 /> - - - ); -} diff --git a/packages/@react-spectrum/alert/stories/Alert.stories.tsx b/packages/@react-spectrum/alert/stories/Alert.stories.tsx new file mode 100644 index 00000000000..8817f3a847b --- /dev/null +++ b/packages/@react-spectrum/alert/stories/Alert.stories.tsx @@ -0,0 +1,56 @@ +/* + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import _123 from '@spectrum-icons/workflow/123'; +import {Alert} from '../'; +import CalendarCheckColor from '@spectrum-icons/color/CalendarCheckColor'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; +import React from 'react'; + +export default { + title: 'Alert', + component: Alert, + args: { + 'title': 'Title', + variant: 'info' + }, + argTypes: { + variant: { + control: 'select', + options: ['info', 'help', 'success', 'error', 'warning'] + }, + title: { + control: 'text' + }, + 'aria-live': { + control: 'select', + options: ['polite', 'off'] + } + } +} as ComponentMeta; + +export type ActionGroupStory = ComponentStoryObj; + +export const Default: ActionGroupStory = { + render: (args) => render(args) +}; + +function render(props) { + return ( + + This is a React Spectrum alert + <_123 /> + + + ); +} diff --git a/packages/@react-spectrum/breadcrumbs/stories/Breadcrumbs.stories.tsx b/packages/@react-spectrum/breadcrumbs/stories/Breadcrumbs.stories.tsx index 11ff625f693..c5a648801d6 100644 --- a/packages/@react-spectrum/breadcrumbs/stories/Breadcrumbs.stories.tsx +++ b/packages/@react-spectrum/breadcrumbs/stories/Breadcrumbs.stories.tsx @@ -12,158 +12,132 @@ import {action} from '@storybook/addon-actions'; import {Breadcrumbs} from '../'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; // import {Heading} from '@react-spectrum/text'; import {Item} from '@react-stately/collections'; import React from 'react'; -import {storiesOf} from '@storybook/react'; let styles = { width: '100vw' }; const CenterDecorator = storyFn =>
{storyFn()}
; -storiesOf('Breadcrumbs', module) - .addDecorator(CenterDecorator) - .addParameters({providerSwitcher: {status: 'negative'}}) - .add( - 'Default (with 3 items)', - () => render() - ) - .add( - 'Default (with 7 items)', - () => renderMany({}) - ) - .add( - 'isMultiline', - () => render({isMultiline: true}) - ) - .add( - 'size: S', - () => render({size: 'S'}) - ) - .add( - 'size: S, isMultiline', - () => render({size: 'S', isMultiline: true}) - ) - .add( - 'size: M', - () => render({size: 'M'}) - ) - .add( - 'size: M, isMultiline', - () => render({size: 'M', isMultiline: true}) - ) - .add( - 'truncated', - () => ( -
- {render({})} -
- ) - ) - .add( - 'truncated, isMultiline', - () => ( -
- {render({isMultiline: true})} -
- ) - ) - .add( - 'many items, showRoot: true', - () => renderMany({showRoot: true}) - ) - .add( - 'many items, isMultiline', - () => renderMany({isMultiline: true}) - ) - .add( - 'many items, isMultiline, showRoot: true', - () => renderMany({maxVisibleItems: 'auto', isMultiline: true, showRoot: true}) - ) - .add( - 'isDisabled: true', - () => render({isDisabled: true}) - ) - .add( - 'isDisabled: true, isMultiline', - () => render({isDisabled: true, isMultiline: true}) - ) - .add( - 'resizeable', - () => ( -
- {renderMany({})} -
- ) - ) - // .add( - // 'last item Heading', - // () => renderHeading() - // ) - // .add( - // 'last item Heading, size: S', - // () => renderHeading({size: 'S'}) - // ) - // .add( - // 'last item Heading, size: M', - // () => renderHeading({size: 'M'}) - // ) - // .add( - // 'last item Heading, isMultiline', - // () => renderHeading({isMultiline: true}) - // ) - // .add( - // 'last item Heading, size: S, isMultiline', - // () => renderHeading({isMultiline: true, size: 'S'}) - // ) - // .add( - // 'last item Heading, size: M, isMultiline', - // () => renderHeading({isMultiline: true, size: 'M'}) - // ) - .add( - 'Only one item', - () => ( - - Root - - ) - ) - .add( - 'Only one item, isMultiline', - () => ( - - Root - - ) - ) - .add( - 'Only one item, showRoot', - () => ( - - Root - - ) - ) - .add( - 'autoFocusCurrent', - () => ( -
- {renderMany({autoFocusCurrent: true})} -
- ) +export type BreadcrumbsStory = ComponentStoryObj; + +export default { + title: 'Breadcrumbs', + component: Breadcrumbs, + decorators: [storyFn => CenterDecorator(storyFn)], + args: { + onAction: action('onAction') + }, + argTypes: { + onAction: { + table: { + disable: true + } + }, + isMultiline: { + control: 'boolean' + }, + showRoot: { + control: 'boolean' + }, + isDisabled: { + control: 'boolean' + }, + autoFocusCurrent: { + control: 'boolean' + }, + size: { + control: 'select', + options: ['S', 'M', 'L'] + } + } +} as ComponentMeta; + +export const Default: BreadcrumbsStory = { + render: (args) => render(args), + storyName: '3 items' +}; + +export const DefaultTruncated: BreadcrumbsStory = { + render: (args) => ( +
+ {render(args)} +
+ ), + storyName: 'truncated' +}; + +export const RenderMany: BreadcrumbsStory = { + render: (args) => ( +
+ {renderMany(args)} +
+ ), + storyName: '7 items, resizable container' +}; + +export const OneItem: BreadcrumbsStory = { + render: (args) => ( + + Root + + ), + storyName: '1 item' +}; + +function render(props) { + return ( + + The quick brown fox jumps over + My Documents + Kangaroos jump high + ); +} -function render(props = {}) { +function renderMany(props = {}) { return ( The quick brown fox jumps over My Documents Kangaroos jump high + Koalas are very cute + Wombat's noses + Wattle trees + April 7 ); } +// TODO: add back in when heading case is fixed? +// .add( +// 'last item Heading', +// () => renderHeading() +// ) +// .add( +// 'last item Heading, size: S', +// () => renderHeading({size: 'S'}) +// ) +// .add( +// 'last item Heading, size: M', +// () => renderHeading({size: 'M'}) +// ) +// .add( +// 'last item Heading, isMultiline', +// () => renderHeading({isMultiline: true}) +// ) +// .add( +// 'last item Heading, size: S, isMultiline', +// () => renderHeading({isMultiline: true, size: 'S'}) +// ) +// .add( +// 'last item Heading, size: M, isMultiline', +// () => renderHeading({isMultiline: true, size: 'M'}) +// ) + // function renderHeading(props = {}) { // return ( // @@ -181,17 +155,3 @@ function render(props = {}) { // // ); // } - -function renderMany(props = {}) { - return ( - - The quick brown fox jumps over - My Documents - Kangaroos jump high - Koalas are very cute - Wombat's noses - Wattle trees - April 7 - - ); -} diff --git a/packages/@react-spectrum/button/stories/ActionButton.stories.tsx b/packages/@react-spectrum/button/stories/ActionButton.stories.tsx index aacefb522e2..2a135792096 100644 --- a/packages/@react-spectrum/button/stories/ActionButton.stories.tsx +++ b/packages/@react-spectrum/button/stories/ActionButton.stories.tsx @@ -13,87 +13,93 @@ import {action} from '@storybook/addon-actions'; import {ActionButton} from '../'; import Add from '@spectrum-icons/workflow/Add'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import {Flex} from '@react-spectrum/layout'; import React from 'react'; -import {storiesOf} from '@storybook/react'; import {Text} from '@react-spectrum/text'; import {View} from '@react-spectrum/view'; -storiesOf('Button/ActionButton', module) - .addParameters({providerSwitcher: {status: 'positive'}}) - .add( - 'default', - () => render() - ) - .add( - 'icon', - () => renderWithIcon() - ) - .add( - 'icon only', - () => ( - - - - - - - - - ) - ) - .add( - 'isQuiet', - () => render({isQuiet: true}) - ) - .add( - 'autoFocus', - () => render({autoFocus: true}) - ) - .add( - 'staticColor: white', - () => ( - - - {renderWithIcon({staticColor: 'white'})} - {renderWithIcon({staticColor: 'white', isQuiet: true})} - - - ) - ) - .add( - 'staticColor: black', - () => ( - - - {renderWithIcon({staticColor: 'black'})} - {renderWithIcon({staticColor: 'black', isQuiet: true})} - - - ) - ); +export type ActionButtonStory = ComponentStoryObj; + +export default { + title: 'Button/ActionButton', + component: ActionButton, + args: { + onPress: action('press'), + onPressStart: action('pressstart'), + onPressEnd: action('pressend') + }, + argTypes: { + onPress: { + table: { + disable: true + } + }, + onPressStart: { + table: { + disable: true + } + }, + onPressEnd: { + table: { + disable: true + } + }, + staticColor: { + table: { + disable: true + } + }, + isQuiet: { + control: 'boolean' + }, + autoFocus: { + control: 'boolean' + } + } +} as ComponentMeta; + + +export const Default: ActionButtonStory = { + render: (args) => render(args) +}; + +export const WithIcon: ActionButtonStory = { + render: (args) => renderWithIcon(args) +}; + +export const IconOnly: ActionButtonStory = { + render: (args) => renderOnlyIcon(args) +}; + +export const StaticWhite: ActionButtonStory = { + args: {staticColor: 'white'}, + render: (args) => ( + + {renderWithIcon(args)} + + ), + storyName: 'staticColor: white' +}; + +export const StaticBlack: ActionButtonStory = { + args: {staticColor: 'black'}, + render: (args) => ( + + {renderWithIcon(args)} + + ), + storyName: 'staticColor: black' +}; function render(props = {}) { return ( Default Disabled @@ -106,17 +112,11 @@ function renderWithIcon(props = {}) { return ( Default Disabled @@ -125,3 +125,21 @@ function renderWithIcon(props = {}) { ); } + +function renderOnlyIcon(props = {}) { + return ( + + + + + + + + + ); +} diff --git a/packages/@react-spectrum/button/stories/Button.stories.tsx b/packages/@react-spectrum/button/stories/Button.stories.tsx index 2a3c6e9d275..92541290c81 100644 --- a/packages/@react-spectrum/button/stories/Button.stories.tsx +++ b/packages/@react-spectrum/button/stories/Button.stories.tsx @@ -13,91 +13,101 @@ import {action} from '@storybook/addon-actions'; import Bell from '@spectrum-icons/workflow/Bell'; import {Button} from '../'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import {Flex} from '@react-spectrum/layout'; -import {mergeProps} from '@react-aria/utils'; import React, {ElementType} from 'react'; import {SpectrumButtonProps} from '@react-types/button'; -import {storiesOf} from '@storybook/react'; import {Text} from '@react-spectrum/text'; import {Tooltip, TooltipTrigger} from '@react-spectrum/tooltip'; import {View} from '@react-spectrum/view'; -const parameters = { +export type ButtonStory = ComponentStoryObj; + +export default { + title: 'Button', + component: Button, args: { - variant: 'cta', - style: undefined, - staticColor: undefined + onPress: action('press'), + onPressStart: action('pressstart'), + onPressEnd: action('pressend') }, argTypes: { - variant: { - control: { - type: 'radio', - options: ['accent', 'primary', 'secondary', 'negative', 'cta', 'overBackground'] + onPress: { + table: { + disable: true } }, - style: { - control: { - type: 'radio', - options: [undefined, 'fill', 'outline'] + onPressStart: { + table: { + disable: true } }, - staticColor: { - control: { - type: 'radio', - options: [undefined, 'white', 'black'] + onPressEnd: { + table: { + disable: true } + }, + autoFocus: { + control: 'boolean' + }, + variant: { + control: 'select', + options: ['accent', 'primary', 'secondary', 'negative', 'cta', 'overBackground'] + }, + style: { + control: 'select', + options: ['fill', 'outline'] + }, + staticColor: { + control: 'select', + options: ['white', 'black'] } } +} as ComponentMeta; + +export const Default: ButtonStory = { + render: (args) => render(args) +}; + +export const WithIcon: ButtonStory = { + render: (args) => renderIconText(args) }; -let actions = { - onPress: action('press'), - onPressStart: action('pressstart'), - onPressEnd: action('pressend') +export const IconOnly: ButtonStory = { + render: (args) => renderIconOnly(args) }; +export const AnchorElement: ButtonStory = { + render: (args) => render({elementType: 'a', ...args}), + storyName: 'element: a' +}; -storiesOf('Button', module) - .addParameters({providerSwitcher: {status: 'positive'}, ...parameters}) - .add( - 'default', - (args) => render(args) - ) - .add( - 'with icon', - (args) => renderIconText(args) - ) - .add( - 'icon only', - (args) => renderIconOnly(args) - ) - .add( - 'element: a', - (args) => render({elementType: 'a', ...args}) - ) - .add( - 'element: a, href: \'//example.com\', target: \'_self\'', - (args) => render({elementType: 'a', href: '//example.com', target: '_self', ...args}) - ) - .add( - 'element: a, rel: \'noopener noreferrer\'', - (args) => render({elementType: 'a', href: '//example.com', rel: 'noopener noreferrer', ...args}) - ) - .add( - 'user-select:none on press test', - () => , - {description: {data: 'Pressing and holding on either buttons shouldn\'t trigger text selection on the button labels (wait for buttons to turn red).'}} - ); +export const AnchorElementWithSelf: ButtonStory = { + render: (args) => render({elementType: 'a', href: '//example.com', target: '_self', ...args}), + storyName: 'element: a, href: \'//example.com\', target: \'_self\'' +}; -function render(props: SpectrumButtonProps = {variant: 'primary'}) { - let buttonProps = mergeProps(props, actions); +export const AnchorElementNoRefferer: ButtonStory = { + render: (args) => render({elementType: 'a', href: '//example.com', rel: 'noopener noreferrer', ...args}), + storyName: 'element: a, rel: \'noopener noreferrer\'' +}; +export const UserSelect: ButtonStory = { + render: () => , + parameters: { + description: { + data: 'Pressing and holding on either buttons shouldn\'t trigger text selection on the button labels (wait for buttons to turn red).' + } + } +}; + +function render(props: SpectrumButtonProps = {variant: 'primary'}) { let buttons = ( - - @@ -123,15 +133,13 @@ function render(props: SpectrumButtonProps } function renderIconText(props: SpectrumButtonProps = {variant: 'primary'}) { - let buttonProps = mergeProps(props, actions); - let buttons = ( - - @@ -158,18 +166,16 @@ function renderIconText(props: SpectrumButtonP } function renderIconOnly(props: SpectrumButtonProps = {variant: 'primary'}) { - let buttonProps = mergeProps(props, actions); - let buttons = ( - Notifications - Notifications diff --git a/packages/@react-spectrum/button/stories/LogicButton.stories.tsx b/packages/@react-spectrum/button/stories/LogicButton.stories.tsx index e0fe28b2729..ef3d084cf4e 100644 --- a/packages/@react-spectrum/button/stories/LogicButton.stories.tsx +++ b/packages/@react-spectrum/button/stories/LogicButton.stories.tsx @@ -11,36 +11,59 @@ */ import {action} from '@storybook/addon-actions'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import {LogicButton} from '../'; import React from 'react'; -import {storiesOf} from '@storybook/react'; -storiesOf('Button/LogicButton', module) - .addParameters({providerSwitcher: {status: 'positive'}}) - .add( - 'logic variant: and', - () => render({variant: 'and', label: 'and'}) - ) - .add( - 'logic variant: or', - () => render({variant: 'or', label: 'or'}) - ); +export type LogicButtonStory = ComponentStoryObj; + +export default { + title: 'Button/LogicButton', + component: LogicButton, + args: { + onPress: action('press'), + onPressStart: action('pressstart'), + onPressEnd: action('pressend') + }, + argTypes: { + onPress: { + table: { + disable: true + } + }, + onPressStart: { + table: { + disable: true + } + }, + onPressEnd: { + table: { + disable: true + } + }, + autoFocus: { + control: 'boolean' + }, + variant: { + control: 'select', + options: ['and', 'or'] + } + } +} as ComponentMeta; + +export const Default: LogicButtonStory = { + render: (args) => render(args) +}; function render(props: any = {}) { return (
Default Disabled diff --git a/packages/@react-spectrum/button/stories/ToggleButton.stories.tsx b/packages/@react-spectrum/button/stories/ToggleButton.stories.tsx index 75f410b27df..831e73f7b5e 100644 --- a/packages/@react-spectrum/button/stories/ToggleButton.stories.tsx +++ b/packages/@react-spectrum/button/stories/ToggleButton.stories.tsx @@ -12,73 +12,118 @@ import {action} from '@storybook/addon-actions'; import Add from '@spectrum-icons/workflow/Add'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import {Flex, Text, View} from '@adobe/react-spectrum'; import React, {useState} from 'react'; -import {storiesOf} from '@storybook/react'; import {ToggleButton} from '../'; -const parameters = { +export type ToggleButtonStory = ComponentStoryObj; + +export default { + title: 'Button/ToggleButton', + component: ToggleButton, args: { - isQuiet: false, - isEmphasized: false, - isDisabled: false + onPress: action('press'), + onPressStart: action('pressstart'), + onPressEnd: action('pressend'), + variant: 'cta' + }, + argTypes: { + onPress: { + table: { + disable: true + } + }, + onPressStart: { + table: { + disable: true + } + }, + onPressEnd: { + table: { + disable: true + } + }, + staticColor: { + table: { + disable: true + } + }, + isQuiet: { + control: 'boolean' + }, + isEmphasized: { + control: 'boolean' + }, + isDisabled: { + control: 'boolean' + }, + autoFocus: { + control: 'boolean' + } } +} as ComponentMeta; + +export const Default: ToggleButtonStory = { + render: (args) => render(args) +}; + +export const StaticWhite: ToggleButtonStory = { + args: {staticColor: 'white'}, + render: (args) => ( + + + {render(args)} + + + ), + storyName: 'staticColor: white' }; -storiesOf('Button/ToggleButton', module) - .addParameters({providerSwitcher: {status: 'positive'}, ...parameters}) - .add( - 'default', - args => render(args) - ) - .add( - 'staticColor: white', - args => ( - - - {render({...args, staticColor: 'white'})} - - - ) - ) - .add( - 'staticColor: black', - args => ( - - - {render({...args, staticColor: 'black'})} - - - ) - ) - .add( - 'styles to check WHCM support', - () => ( - - - {render()} - {render({isEmphasized: true})} - {render({isQuiet: true})} - {render({isQuiet: true, isEmphasized: true})} - - - ) - ) - .add('controlled state', () => ( - - )); +export const StaticBlack: ToggleButtonStory = { + args: {staticColor: 'black'}, + render: (args) => ( + + + {render(args)} + + + ), + storyName: 'staticColor: black' +}; + +export const WHCM: ToggleButtonStory = { + render: () => ( + + + {render()} + {render({isEmphasized: true})} + {render({isQuiet: true})} + {render({isQuiet: true, isEmphasized: true})} + + + ), + storyName: 'styles to check WHCM support' +}; + +export const Controlled: ToggleButtonStory = { + render: () => , + storyName: 'controlled state' +}; function render(props = {}) { - return ( - - - Default - - - - Selected - - ); + return ( + + + + Default + + + + Selected + + + ); } function ControlledToggleButton() { diff --git a/packages/@react-spectrum/buttongroup/stories/ButtonGroup.stories.tsx b/packages/@react-spectrum/buttongroup/stories/ButtonGroup.stories.tsx index 6832be10bc8..9be8a8c8724 100644 --- a/packages/@react-spectrum/buttongroup/stories/ButtonGroup.stories.tsx +++ b/packages/@react-spectrum/buttongroup/stories/ButtonGroup.stories.tsx @@ -14,57 +14,42 @@ import {action} from '@storybook/addon-actions'; import Bell from '@spectrum-icons/workflow/Bell'; import {Button} from '@react-spectrum/button'; import {ButtonGroup} from '../'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import React, {useState} from 'react'; -import {storiesOf} from '@storybook/react'; import {Text} from '@react-spectrum/text'; -storiesOf('ButtonGroup', module) - .add( - 'default', - () => render({}) - ) - .add( - 'isDisabled', - () => render({isDisabled: true}) - ) - .add( - 'orientation: vertical', - () => render({orientation: 'vertical'}) - ) - .add( - 'orientation: vertical, align: end', - () => render({orientation: 'vertical', align: 'end'}) - ) - .add( - 'isDisabled, orientation: vertical', - () => render({isDisabled: true, orientation: 'vertical'}) - ) - .add( - 'align: end', - () => render({align: 'end'}) - ) - .add( - 'align: center', - () => render({align: 'center'}) - ) - .add( - 'align: center, orientation: vertical', - () => render({align: 'center', orientation: 'vertical'}) - ) - .add( - 'resizeable container', - () => ( -
- {render({})} -
- ) +export type ButtonGroupStory = ComponentStoryObj; + +export default { + title: 'ButtonGroup', + component: ButtonGroup, + argTypes: { + isDisabled: { + control: 'boolean' + }, + orientation: { + control: 'select', + options: ['horizontal', 'vertical'] + }, + align: { + control: 'select', + options: ['start', 'end', 'center'] + } + } +} as ComponentMeta; + +export const Default: ButtonGroupStory = { + render: (args) => ( +
+ {render(args)} +
) - .add( - 'constant container, changing siblings', - () => ( - - ) - ); +}; + +export const ConstantContainer: ButtonGroupStory = { + render: (args) => , + storyName: 'constant container, changing siblings' +}; function render(props) { return ; @@ -73,7 +58,7 @@ function render(props) { let ExpandingSibling = (props = {}) => { let [isExpanded, setIsExpanded] = useState(false); return ( -
+
@@ -88,7 +73,6 @@ let Component = (props) => { - - - - - - ); - } - ) - .add( - 'controlled', - () => { - let [color, setColor] = useState(parseColor('hsl(0, 100%, 50%)')); - let colorCSS = color?.toString('css'); - return ( - -
- ); +export type ColorWheelStory = ComponentStoryObj; + +export default { + title: 'ColorWheel', + component: ColorWheel, + excludeStories: ['ControlledHSL'], + args: { + onChange: action('onChange'), + onChangeEnd: action('onChangeEnd') + }, + argTypes: { + onChange: { + table: { + disable: true + } + }, + onChangeEnd: { + table: { + disable: true + } + }, + isDisabled: { + control: 'boolean' + }, + size: { + control: 'text' } + } +} as ComponentMeta; + +export const Default: ColorWheelStory = { + args: {defaultValue: 'hsl(0, 100%, 50%)'}, + render: (args) => +}; + +export const Controlled: ColorWheelStory = { + render: (args) => ( + + + ) - .add( - 'controlled hsl', - () => - ); +}; export function ControlledHSL(props) { let [color, setColor] = useState(props.defaultValue || parseColor('hsl(0, 100%, 50%)')); diff --git a/packages/@react-spectrum/combobox/stories/ComboBox.stories.tsx b/packages/@react-spectrum/combobox/stories/ComboBox.stories.tsx index f575420fe62..6081e5cd880 100644 --- a/packages/@react-spectrum/combobox/stories/ComboBox.stories.tsx +++ b/packages/@react-spectrum/combobox/stories/ComboBox.stories.tsx @@ -18,6 +18,7 @@ import Bell from '@spectrum-icons/workflow/Bell'; import {ButtonGroup} from '@react-spectrum/buttongroup'; import {chain} from '@react-aria/utils'; import {ComboBox, Item, Section} from '../'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import {Content} from '@react-spectrum/view'; import {ContextualHelp} from '@react-spectrum/contextualhelp'; import Copy from '@spectrum-icons/workflow/Copy'; @@ -26,11 +27,8 @@ import Draw from '@spectrum-icons/workflow/Draw'; import {Flex} from '@react-spectrum/layout'; import {Heading} from '@react-spectrum/text'; import {Link} from '@react-spectrum/link'; -import {mergeProps} from '@react-aria/utils'; import React, {useRef, useState} from 'react'; -import {storiesOf} from '@storybook/react'; import {Text} from '@react-spectrum/text'; -import {TextField} from '@react-spectrum/textfield'; import {useAsyncList} from '@react-stately/data'; import {useFilter} from '@react-aria/i18n'; import {useListData, useTreeData} from '@react-stately/data'; @@ -64,453 +62,372 @@ for (let i = 0; i < 50; i++) { lotsOfSections.push({name: 'Section ' + i, children}); } -let actions = { - onOpenChange: action('onOpenChange'), - onInputChange: action('onInputChange'), - onSelectionChange: action('onSelectionChange'), - onBlur: action('onBlur'), - onFocus: action('onFocus') +export type ComboBoxStory = ComponentStoryObj; + +export default { + title: 'ComboBox', + component: ComboBox, + args: { + label: 'Combobox', + onOpenChange: action('onOpenChange'), + onInputChange: action('onInputChange'), + onSelectionChange: action('onSelectionChange'), + onBlur: action('onBlur'), + onFocus: action('onFocus') + }, + argTypes: { + defaultItems: { + table: { + disable: true + } + }, + contextualHelp: { + table: { + disable: true + } + }, + onOpenChange: { + table: { + disable: true + } + }, + disabledKeys: { + table: { + disable: true + } + }, + inputValue: { + table: { + disable: true + } + }, + defaultInputValue: { + table: { + disable: true + } + }, + defaultSelectedKey: { + table: { + disable: true + } + }, + selectedKey: { + table: { + disable: true + } + }, + onInputChange: { + table: { + disable: true + } + }, + onSelectionChange: { + table: { + disable: true + } + }, + onBlur: { + table: { + disable: true + } + }, + onFocus: { + table: { + disable: true + } + }, + label: { + control: 'text' + }, + 'aria-label': { + control: 'text' + }, + isDisabled: { + control: 'boolean' + }, + isQuiet: { + control: 'boolean' + }, + isReadOnly: { + control: 'boolean' + }, + autoFocus: { + control: 'boolean' + }, + isRequired: { + control: 'boolean' + }, + necessityIndicator: { + control: 'select', + options: ['icon', 'label'] + }, + labelAlign: { + control: 'select', + options: ['end', 'start'] + }, + labelPosition: { + control: 'select', + options: ['top', 'side'] + }, + validationState: { + control: 'select', + options: [null, 'valid', 'invalid'] + }, + description: { + control: 'text' + }, + errorMessage: { + control: 'text' + }, + menuTrigger: { + control: 'select', + options: ['focus', 'manual'] + }, + direction: { + control: 'select', + options: ['top', 'bottom'] + }, + allowsCustomValue: { + control: 'boolean' + }, + width: { + control: 'text' + } + } +} as ComponentMeta; + +export const Default: ComboBoxStory = { + render: (args) => render(args), + storyName: 'static items' }; -storiesOf('ComboBox', module) - .add( - 'static items', - () => render({}) - ) - .add( - 'dynamic items', - () => ( - - {(item) => {item.name}} - - ) - ) - .add( - 'no items', - () => ( - - {(item: any) => {item.name}} - - ) - ) - .add( - 'with mapped items (defaultItem and items undef)', - () => ( - - ) - ) - .add( - 'with sections', - () => ( - - {(item) => ( -
- {(item) => {item.name}} -
- )} -
- ) - ) - .add( - 'with many sections', - () => ( - - {(item) => ( -
- {(item: any) => {item.name}} -
- )} -
- ) +export const Dynamic: ComboBoxStory = { + args: {defaultItems: items}, + render: (args) => ( + + {(item: any) => {item.name}} + + ), + storyName: 'dynamic items' +}; + +export const NoItems: ComboBoxStory = { + ...Dynamic, + args: {defaultItems: []}, + storyName: 'no items' +}; + +export const MappedItems: ComboBoxStory = { + args: {defaultSelectedKey: '2'}, + render: (args) => , + storyName: 'with mapped items (defaultItem and items undef)' +}; + +export const Sections: ComboBoxStory = { + args: {defaultItems: withSection}, + render: (args) => ( + + {(item: any) => ( +
+ {(item: any) => {item.name}} +
+ )} +
+ ), + storyName: 'with sections' +}; + +export const ManySections: ComboBoxStory = { + ...Sections, + args: {defaultItems: lotsOfSections}, + storyName: 'with many sections' +}; + +export const ComplexItems: ComboBoxStory = { + args: {label: 'Select action'}, + render: (args) => ( + + + + Add to queue + Add to current watch queue. + + + + Add review + Post a review for the episode. + + + + Subscribe to series + + Add series to your subscription list and be notified when a new episode + airs. + + + + + Report + Report an issue/violation. + + ) - .add( - 'complex items', - () => ( - - - - Add to queue - Add to current watch queue. - - - - Add review - Post a review for the episode. - - - - Subscribe to series - - Add series to your subscription list and be notified when a new episode - airs. - - - - - Report - Report an issue/violation. +}; + +export const UserProvidedLabel: ComboBoxStory = { + args: {label: 'Select action'}, + render: (args) => ( + + + + Item One + + + Item Two + Item Three - ) - ) - .add( - 'user provided id and label', - () => ( - - - - Item One - - - Item Two - - Item Three - - - ) - ) - .add( - 'menuTrigger: focus', - () => render({menuTrigger: 'focus'}) - ) - .add( - 'menuTrigger: manual', - () => ( - - - - Item One - - - Item Two - - Item Three - - - - ) - ) - .add( - 'disabled keys', - () => ( - - {(item) => ( -
- {(item) => {item.name}} -
- )} -
- ) - ) - .add( - 'isQuiet', - () => render({isQuiet: true}) - ) - .add( - 'isDisabled', - () => render({isDisabled: true}) - ) - .add( - 'isDisabled, isQuiet', - () => render({isDisabled: true, isQuiet: true}) - ) - .add( - 'isReadOnly', - () => render({isReadOnly: true, defaultSelectedKey: 'two'}) - ) - .add( - 'labelPosition: top, labelAlign: end', - () => render({labelAlign: 'end'}) - ) - .add( - 'labelPosition: side', - () => render({labelPosition: 'side'}) - ) - .add( - 'no visible label', - () => ( - - {(item: any) => {item.name}} - - ) - ) - .add( - 'no visible label, isQuiet', - () => ( - - {(item: any) => {item.name}} - - ) - ) - .add( - 'with descrption, labelAlign: end', - () => render({description: 'Please select your spirit animal.', labelAlign: 'end'}) +
) - .add( - 'with error message, labelPosition: side', - () => render({errorMessage: 'You did not select a valid spirit animal.', validationState: 'invalid', labelPosition: 'side'}) +}; + +export const DisabledKeys: ComboBoxStory = { + args: {defaultItems: withSection, label: 'Combobox', disabledKeys: ['Snake', 'Ross']}, + render: (args) => ( + + {(item: any) => ( +
+ {(item: any) => {item.name}} +
+ )} +
) - .add( - 'contextual help', - () => render({contextualHelp: ( +}; + +export const ContextualHelpStory: ComboBoxStory = { + ...Default, + args: { + ...Default.args, + contextualHelp: ( What is a segment? Segments identify who your visitors are, what devices and services they use, where they navigated from, and much more. - )}) - ) - .add( - 'isRequired', - () => render({isRequired: true}) - ) - .add( - 'isRequired, necessityIndicator: label', - () => render({isRequired: true, necessityIndicator: 'label'}) - ) - .add( - 'validationState: invalid', - () => render({validationState: 'invalid', defaultSelectedKey: 'two'}) - ) - .add( - 'validationState: valid', - () => render({validationState: 'valid', defaultSelectedKey: 'two'}) - ) - .add( - 'validationState: invalid, isQuiet', - () => render({validationState: 'invalid', isQuiet: true, defaultSelectedKey: 'two'}) - ) - .add( - 'validationState: valid, isQuiet', - () => render({validationState: 'valid', isQuiet: true, defaultSelectedKey: 'two'}) - ) - .add( - 'autoFocus: true', - () => render({autoFocus: true}) - ) - .add( - 'direction: top', - () => render({direction: 'top'}) - ) - .add( - 'allowsCustomValue: true', - () => ( - ) - ) - .add( - 'customWidth', - () => ( - - - Item One - - - Item Two - - Item Three - - - Item One - - - Item Two - - Item Three - - - Item One - - - Item Two - - Item Three - - - ) - ) - .add( - 'no visible label, customWidth', - () => ( - - - Item One - - - Item Two - - Item Three - - - Item One - - - Item Two - - Item Three - - - Item One - - - Item Two - - Item Three - - - ) - ) - .add( - 'resize', - () => - ) - .add( - 'in small div', - () => ( - - - Item One - - - Item Two - - Item Three - - - ) - ) - .add( - 'inputValue (controlled)', - () => ( - - ) - ) - .add( - 'defaultInputValue (uncontrolled)', - () => render({defaultInputValue: 'Item Three', disabledKeys: ['two']}) - ) - .add( - 'selectedKey (controlled)', - () => ( - - ) - ) - .add( - 'defaultSelectedKey (uncontrolled)', - () => render({defaultSelectedKey: 'two', disabledKeys: ['one']}) - ) - .add( - 'inputValue and selectedKey (controlled)', - () => ( - - ) - ) - .add( - 'inputValue and selectedKey, allowsCustomValue (controlled)', - () => ( - - ) - ) - .add( - 'defaultInputValue and defaultSelectedKey (uncontrolled)', - () => render({defaultInputValue: 'Item Two', defaultSelectedKey: 'two', disabledKeys: ['two']}) - ) - .add( - 'inputValue and defaultSelectedKey (controlled by inputvalue)', - () => ( - - ) - ) - .add( - 'defaultInputValue and selectedKey (controlled by selectedKey)', - () => ( - - ) - ) - .add( - 'custom filter', - () => ( - - ) - ) - .add( - 'loadingState', - () => - ) - .add( - 'loadingState = "loading", validationState: invalid', - () => - ) - .add( - 'loadingState = "loading", isQuiet', - () => - ) - .add( - 'loadingState = "loading", isQuiet, validationState: invalid', - () => - ) - .add( - 'filtering with useListData', - () => ( - - ) - ) - .add( - 'server side filtering with useAsyncList', - () => ( - - ) - ) - .add( - 'server side filtering with useAsyncList (controlled key)', - () => ( - - ) - ) - .add( - 'server side filtering with controlled key and inputValue reset if not focused', - () => ( - - ) - ) - .add( - '2 comboboxes', - () => ( - - - {(item) => {item.name}} - - - {(item) => {item.name}} - - - ) - ) - .add( - 'within a dialog', - () => - ) - .add( - 'within a dialog, allowsCustomValue: true', - () => - ) - .add( - 'WHCM test', - () => ( - - Shows the different states from spectrum - {renderRow({placeholder: 'Type here...'})} - {renderRow()} - {renderRow({labelPosition: 'side'})} - {renderRow({isQuiet: true, placeholder: 'Type here...'})} - {renderRow({isQuiet: true})} - {renderRow({isRequired: true})} - {renderRow({isRequired: true, isQuiet: true})} - {renderRow({validationState: 'invalid'})} - {renderRow({validationState: 'invalid', isQuiet: true})} - - ) - ); + }, + storyName: 'contextual help' +}; + +export const Resize: ComboBoxStory = { + render: (args) => +}; + +export const SmallDiv: ComboBoxStory = { + render: (args) => ( + + {render(args)} + + ), + storyName: 'in small div' +}; + +export const ControlledInputValueStory: ComboBoxStory = { + args: {inputValue: 'Snake', disabledKeys: ['2', '6']}, + render: (args) => , + storyName: 'inputValue (controlled)' +}; + +export const DefaultInputValue: ComboBoxStory = { + ...Default, + args: {defaultInputValue: 'Item Three', disabledKeys: ['two']}, + storyName: 'defaultInputValue (uncontrolled)' +}; + +export const ControlledSelectedKey: ComboBoxStory = { + args: {selectedKey: '4', disabledKeys: ['2', '6']}, + render: (args) => , + storyName: 'selectedKey (controlled)' +}; +export const DefaultSelectedKey: ComboBoxStory = { + ...Default, + args: {defaultSelectedKey: 'two', disabledKeys: ['one']}, + storyName: 'defaultSelectedKey (uncontrolled)' +}; + +export const AllControlled: ComboBoxStory = { + args: {selectedKey: '2', inputValue: 'Kangaroo', disabledKeys: ['2', '6']}, + render: (args) => , + storyName: 'inputValue and selectedKey (controlled)' +}; + +export const DefaultInputAndKey: ComboBoxStory = { + ...Default, + args: {defaultInputValue: 'Item Two', defaultSelectedKey: 'two', disabledKeys: ['two']}, + storyName: 'defaultInputValue and defaultSelectedKey (uncontrolled)' +}; + +export const ControlledInputDefaultKey: ComboBoxStory = { + ...ControlledInputValueStory, + args: {inputValue: 'K', defaultSelectedKey: 'two', disabledKeys: ['2', '6']}, + storyName: 'inputValue and defaultSelectedKey (controlled by inputvalue)' +}; + +export const ControlledInputValue: ComboBoxStory = { + ...ControlledSelectedKey, + args: {defaultInputValue: 'Blah', selectedKey: '2', disabledKeys: ['2', '6']}, + storyName: 'defaultInputValue and selectedKey (controlled by selectedKey)' +}; + +export const CustomFilter: ComboBoxStory = { + render: (args) => +}; + +export const LoadingState: ComboBoxStory = { + render: (args) => +}; + +export const FilteringListData: ComboBoxStory = { + render: (args) => , + storyName: 'filtering with useListData' +}; + +export const SeverSideFiltering: ComboBoxStory = { + render: (args) => , + storyName: 'server side filtering with useAsyncList' +}; + +export const SeverSideFilteringControlled: ComboBoxStory = { + render: (args) => , + storyName: 'server side filtering with useAsyncList (controlled key)' +}; + +export const SeverSideFilteringControlledReset: ComboBoxStory = { + render: (args) => , + storyName: 'server side filtering with controlled key and inputValue reset if not focused' +}; + +export const InDialog: ComboBoxStory = { + render: (args) => , + storyName: 'within a dialog' +}; + +export const WHCM: ComboBoxStory = { + render: () => ( + + Shows the different states from spectrum + {renderRow({placeholder: 'Type here...'})} + {renderRow()} + {renderRow({labelPosition: 'side'})} + {renderRow({isQuiet: true, placeholder: 'Type here...'})} + {renderRow({isQuiet: true})} + {renderRow({isRequired: true})} + {renderRow({isRequired: true, isQuiet: true})} + {renderRow({validationState: 'invalid'})} + {renderRow({validationState: 'invalid', isQuiet: true})} + + ) +}; function LoadingExamples(props) { return ( @@ -531,7 +448,7 @@ function LoadingExamples(props) { ); } -function ListDataExample() { +function ListDataExample(props) { let {contains} = useFilter({sensitivity: 'base'}); let list = useListData({ initialItems: items, @@ -546,6 +463,7 @@ function ListDataExample() { return ( { if (reason === 'manual' && open) { setShowAll(true); @@ -558,20 +476,21 @@ function ListDataExample() { setShowAll(false); list.setFilterText(value); }}> - {item => {item.name}} + {(item: any) => {item.name}} - {item => {item.name}} + {(item: any) => {item.name}} ); } -function AsyncLoadingExample() { +function AsyncLoadingExample(props) { interface StarWarsChar { name: string, url: string @@ -598,18 +517,18 @@ function AsyncLoadingExample() { return ( - {item => {item.name}} + onLoadMore={chain(props?.onLoadMore, list.loadMore)}> + {(item: any) => {item.name}} ); } -function AsyncLoadingExampleControlledKey() { +function AsyncLoadingExampleControlledKey(props) { interface StarWarsChar { name: string, url: string @@ -653,20 +572,20 @@ function AsyncLoadingExampleControlledKey() { return ( - {item => {item.name}} + onLoadMore={list.loadMore}> + {(item: any) => {item.name}} ); } -function AsyncLoadingExampleControlledKeyWithReset() { +function AsyncLoadingExampleControlledKeyWithReset(props) { interface StarWarsChar { name: string, url: string @@ -720,17 +639,17 @@ function AsyncLoadingExampleControlledKeyWithReset() { let selectedKey = (list.selectedKeys as Set).values().next().value; return ( isFocused.current = focus} label="Star Wars Character Lookup" + {...props} + onFocusChange={(focus) => isFocused.current = focus} selectedKey={selectedKey} onSelectionChange={onSelectionChange} items={list.items} inputValue={list.filterText} onInputChange={onInputChange} loadingState={list.loadingState} - onLoadMore={list.loadMore} - onOpenChange={action('onOpenChange')}> - {item => {item.name}} + onLoadMore={list.loadMore}> + {(item: any) => {item.name}} ); } @@ -749,8 +668,8 @@ let CustomFilterComboBox = (props) => { return ( @@ -810,10 +729,10 @@ function AllControlledComboBox(props) { Clear key - - {item => ( + + {(item: any) => (
- {item => {item.value.name}} + {(item: any) => {item.value.name}}
)}
@@ -850,7 +769,7 @@ let ControlledKeyComboBox = (props) => { Clear key - + {(item: any) => (
{(item: any) => {item.name}} @@ -882,30 +801,7 @@ let ControlledValueComboBox = (props) => { Clear field - - {(item: any) => ( -
- {(item: any) => {item.name}} -
- )} -
-
- ); -}; - -let CustomValueComboBox = (props) => { - let [selectedKey, setSelectedKey] = React.useState(props.selectedKey); - - let onSelectionChange = (key) => { - setSelectedKey(key); - }; - - actions['onKeyDown'] = action('onKeyDown'); - - return ( -
-
Selected Key: {selectedKey}
- + {(item: any) => (
{(item: any) => {item.name}} @@ -916,13 +812,13 @@ let CustomValueComboBox = (props) => { ); }; -function ResizeCombobox() { +function ResizeCombobox(props) { let [size, setSize] = useState(true); return (
- + Item One @@ -938,7 +834,7 @@ function ResizeCombobox() { function render(props = {}) { return ( - + Item One @@ -952,7 +848,7 @@ function render(props = {}) { function renderRow(props = {}) { return ( - + Option 1 @@ -960,7 +856,7 @@ function renderRow(props = {}) { Option 3 - + Option 1 @@ -990,7 +886,7 @@ function ComboBoxWithMap(props) { return ( - + {items.map((item) => ( {item.name} @@ -1024,6 +920,7 @@ function ComboBoxWithinDialog(props) { - {(item) => ( + {(item: any) => (
- {(item) => {item.name}} + {(item: any) => {item.name}}
)}
diff --git a/packages/@react-spectrum/contextualhelp/stories/ContextualHelp.stories.tsx b/packages/@react-spectrum/contextualhelp/stories/ContextualHelp.stories.tsx index 9b86e18382b..0940ee58f2c 100644 --- a/packages/@react-spectrum/contextualhelp/stories/ContextualHelp.stories.tsx +++ b/packages/@react-spectrum/contextualhelp/stories/ContextualHelp.stories.tsx @@ -25,7 +25,6 @@ export default { }, placement: { control: 'select', - defaultValue: 'bottom', options: [ 'bottom', 'bottom left', 'bottom right', 'bottom start', 'bottom end', 'top', 'top left', 'top right', 'top start', 'top end', @@ -42,25 +41,21 @@ export default { }, offset: { control: 'number', - defaultValue: 0, min: -500, max: 500 }, crossOffset: { control: 'number', - defaultValue: 0, min: -500, max: 500 }, containerPadding: { control: 'number', - defaultValue: 0, min: -500, max: 500 }, shouldFlip: { - control: 'boolean', - defaultValue: true + control: 'boolean' }, children: { table: {disable: true} diff --git a/packages/@react-spectrum/datepicker/stories/DateField.stories.tsx b/packages/@react-spectrum/datepicker/stories/DateField.stories.tsx index e71a858b4b0..502c17b181e 100644 --- a/packages/@react-spectrum/datepicker/stories/DateField.stories.tsx +++ b/packages/@react-spectrum/datepicker/stories/DateField.stories.tsx @@ -12,6 +12,7 @@ import {action} from '@storybook/addon-actions'; import {CalendarDate, CalendarDateTime, parseAbsolute, parseAbsoluteToLocal, parseDate, parseDateTime, parseZonedDateTime, toZoned} from '@internationalized/date'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import {Content} from '@react-spectrum/view'; import {ContextualHelp} from '@react-spectrum/contextualhelp'; import {DateField} from '../'; @@ -20,189 +21,230 @@ import {Heading} from '@react-spectrum/text'; import {Item, Picker, Section} from '@react-spectrum/picker'; import {Provider} from '@react-spectrum/provider'; import React from 'react'; -import {storiesOf} from '@storybook/react'; import {useLocale} from '@react-aria/i18n'; + +export type DateFieldStory = ComponentStoryObj; const BlockDecorator = storyFn =>
{storyFn()}
; -storiesOf('Date and Time/DateField', module) - .addDecorator(BlockDecorator) - .add( - 'default', - () => render() - ) - .add( - 'defaultValue', - () => render({defaultValue: parseDate('2020-02-03')}) - ) - .add( - 'controlled value', - () => render({value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'defaultValue, zoned', - () => render({defaultValue: toZoned(parseDate('2020-02-03'), 'America/Los_Angeles')}) - ) - .add( - 'granularity: minute', - () => render({granularity: 'minute'}) - ) - .add( - 'granularity: second', - () => render({granularity: 'second'}) - ) - .add( - 'hourCycle: 12', - () => render({granularity: 'minute', hourCycle: 12}) - ) - .add( - 'hourCycle: 24', - () => render({granularity: 'minute', hourCycle: 24}) - ) - .add( - 'granularity: minute, defaultValue', - () => render({granularity: 'minute', defaultValue: parseDateTime('2021-03-14T08:45')}) - ) - .add( - 'granularity: minute, defaultValue, zoned', - () => render({granularity: 'minute', defaultValue: parseZonedDateTime('2021-11-07T00:45-07:00[America/Los_Angeles]')}) - ) - .add('granularity: minute, defaultValue, zoned, absolute', - () => render({granularity: 'minute', defaultValue: parseAbsoluteToLocal('2021-11-07T07:45:00Z')}) - ) - .add('granularity: minute, defaultValue, zoned, absolute, timeZone', - () => render({granularity: 'minute', defaultValue: parseAbsolute('2021-11-07T07:45:00Z', 'America/New_York')}) - ) - .add( - 'defaultValue with time, granularity: day', - () => render({granularity: 'day', defaultValue: parseDateTime('2021-03-14T08:45')}) - ) - .add( - 'hideTimeZone', - () => render({granularity: 'minute', defaultValue: parseZonedDateTime('2021-11-07T00:45-07:00[America/Los_Angeles]'), hideTimeZone: true}) - ) - .add( - 'isDisabled', - () => render({isDisabled: true, value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'isQuiet, isDisabled', - () => render({isQuiet: true, isDisabled: true, value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'isReadOnly', - () => render({isReadOnly: true, value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'autoFocus', - () => render({autoFocus: true}) - ) - .add( - 'validationState: invalid', - () => render({validationState: 'invalid', value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'validationState: valid', - () => render({validationState: 'valid', value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'minValue: 2010/1/1, maxValue: 2020/1/1', - () => render({minValue: new CalendarDate(2010, 0, 1), maxValue: new CalendarDate(2020, 0, 1)}) - ) - .add( - 'placeholderValue: 1980/1/1', - () => render({placeholderValue: new CalendarDate(1980, 1, 1)}) - ) - .add( - 'placeholderValue: 1980/1/1 8 AM', - () => render({placeholderValue: new CalendarDateTime(1980, 1, 1, 8)}) - ) - .add( - 'placeholderValue: 1980/1/1, zoned', - () => render({placeholderValue: toZoned(new CalendarDate(1980, 1, 1), 'America/Los_Angeles')}) - ) - .add( - 'showFormatHelpText', - () => render({showFormatHelpText: true}) - ) - .add( - 'all the events', - () => render({onBlur: action('onBlur'), onFocus: action('onFocus'), onFocusChange: action('onFocusChange'), onKeyDown: action('onKeyDown'), onKeyUp: action('onKeyUp'), onOpenChange: action('onOpenChange')}) - ); +export default { + title: 'Date and Time/DateField', + component: DateField, + decorators: [storyFn => BlockDecorator(storyFn)], + args: { + onChange: action('onChange') + }, + argTypes: { + onChange: { + table: { + disable: true + } + }, + defaultValue: { + table: { + disable: true + } + }, + value: { + table: { + disable: true + } + }, + minValue: { + table: { + disable: true + } + }, + maxValue: { + table: { + disable: true + } + }, + placeholderValue: { + table: { + disable: true + } + }, + onBlur: { + table: { + disable: true + } + }, + onFocus: { + table: { + disable: true + } + }, + onFocusChange: { + table: { + disable: true + } + }, + onKeyDown: { + table: { + disable: true + } + }, + onKeyUp: { + table: { + disable: true + } + }, + contextualHelp: { + table: { + disable: true + } + }, + label: { + control: 'text' + }, + granularity: { + control: 'select', + options: ['day', 'hour', 'minute', 'second'] + }, + hourCycle: { + control: 'select', + options: [12, 24] + }, + hideTimeZone: { + control: 'boolean' + }, + isDisabled: { + control: 'boolean' + }, + isQuiet: { + control: 'boolean' + }, + isReadOnly: { + control: 'boolean' + }, + isRequired: { + control: 'boolean' + }, + necessityIndicator: { + control: 'select', + options: ['icon', 'label'] + }, + validationState: { + control: 'select', + options: [null, 'valid', 'invalid'] + }, + description: { + control: 'text' + }, + errorMessage: { + control: 'text' + }, + labelAlign: { + control: 'select', + options: ['end', 'start'] + }, + labelPosition: { + control: 'select', + options: ['top', 'side'] + }, + autoFocus: { + control: 'boolean' + }, + showFormatHelpText: { + control: 'boolean' + }, + 'aria-label': { + control: 'text' + }, + width: { + control: 'text' + } + } +} as ComponentMeta; + +export const Default: DateFieldStory = { + render: (args) => render(args) +}; + +export const DefaultValue: DateFieldStory = { + ...Default, + args: {defaultValue: parseDate('2020-02-03')} +}; + +export const ControlledValue: DateFieldStory = { + ...Default, + args: {value: new CalendarDate(2020, 2, 3)} +}; + +export const DefaultValueZoned: DateFieldStory = { + ...Default, + args: {defaultValue: toZoned(parseDate('2020-02-03'), 'America/Los_Angeles')}, + storyName: 'defaultValue date, zoned' +}; + +export const DateTimeValue: DateFieldStory = { + ...Default, + args: {defaultValue: parseDateTime('2021-03-14T08:45')} +}; + +export const DateTimeValueZoned: DateFieldStory = { + ...Default, + args: {defaultValue: parseZonedDateTime('2021-11-07T00:45-07:00[America/Los_Angeles]')} +}; -storiesOf('Date and Time/DateField/styling', module) - .addDecorator(BlockDecorator) - .add( - 'isQuiet', - () => render({isQuiet: true}) - ) - .add( - 'labelPosition: side', - () => render({labelPosition: 'side'}) - ) - .add( - 'labelAlign: end', - () => render({labelPosition: 'top', labelAlign: 'end'}) - ) - .add( - 'required', - () => render({isRequired: true}) - ) - .add( - 'required with label', - () => render({isRequired: true, necessityIndicator: 'label'}) - ) - .add( - 'optional', - () => render({necessityIndicator: 'label'}) - ) - .add( - 'no visible label', - () => render({'aria-label': 'Date', label: null}) - ) - .add( - 'quiet no visible label', - () => render({isQuiet: true, 'aria-label': 'Date', label: null}) - ) - .add( - 'custom width', - () => render({width: 'size-3000'}) - ) - .add( - 'quiet custom width', - () => render({isQuiet: true, width: 'size-3000'}) - ) - .add( - 'custom width no visible label', - () => render({width: 'size-3000', label: null, 'aria-label': 'Date'}) - ) - .add( - 'custom width, labelPosition=side', - () => render({width: 'size-3000', labelPosition: 'side'}) - ) - .add( - 'description', - () => render({description: 'Help text'}) - ) - .add( - 'errorMessage', - () => render({errorMessage: 'Enter a date after today', validationState: 'invalid'}) - ) - .add( - 'contextual help', - () => render({contextualHelp: ( +export const DateTimeValueAbsolute: DateFieldStory = { + ...Default, + args: {defaultValue: parseAbsoluteToLocal('2021-11-07T07:45:00Z')} +}; + +export const DateTimeValueAbsoluteZoned: DateFieldStory = { + ...Default, + args: {defaultValue: parseAbsolute('2021-11-07T07:45:00Z', 'America/New_York')} +}; + +export const MinMaxValue: DateFieldStory = { + ...Default, + args: {minValue: new CalendarDate(2010, 0, 1), maxValue: new CalendarDate(2020, 0, 1)}, + storyName: 'minValue: 2010/1/1, maxValue: 2020/1/1' +}; + +export const PlaceholderVal: DateFieldStory = { + ...Default, + args: {placeholderValue: new CalendarDate(1980, 1, 1)}, + storyName: 'placeholder value: 1980/1/1' +}; + +export const PlaceholderValTime: DateFieldStory = { + ...Default, + args: {placeholderValue: new CalendarDateTime(1980, 1, 1, 8)}, + storyName: 'placeholder value: 1980/1/1 8AM' +}; + +export const PlaceholderValTimeZoned: DateFieldStory = { + ...Default, + args: {placeholderValue: toZoned(new CalendarDate(1980, 1, 1), 'America/Los_Angeles')}, + storyName: 'placeholder value: 1980/1/1 zoned' +}; + +export const AllEvents: DateFieldStory = { + ...Default, + args: {onBlur: action('onBlur'), onFocus: action('onFocus'), onFocusChange: action('onFocusChange'), onKeyDown: action('onKeyDown'), onKeyUp: action('onKeyUp')}, + storyName: 'all the events' +}; + +export const ContextualHelpStory: DateFieldStory = { + ...Default, + args: { + contextualHelp: ( What is a segment? Segments identify who your visitors are, what devices and services they use, where they navigated from, and much more. - )}) - ); + ) + }, + storyName: 'contextual help' +}; function render(props = {}) { return ( ); diff --git a/packages/@react-spectrum/datepicker/stories/DatePicker.stories.tsx b/packages/@react-spectrum/datepicker/stories/DatePicker.stories.tsx index f8af2f767b5..b4baeef745c 100644 --- a/packages/@react-spectrum/datepicker/stories/DatePicker.stories.tsx +++ b/packages/@react-spectrum/datepicker/stories/DatePicker.stories.tsx @@ -14,6 +14,7 @@ import {action} from '@storybook/addon-actions'; import {ActionButton} from '@react-spectrum/button'; import {CalendarDate, CalendarDateTime, getLocalTimeZone, parseAbsolute, parseAbsoluteToLocal, parseDate, parseDateTime, parseZonedDateTime, today, toZoned} from '@internationalized/date'; import {chain} from '@react-aria/utils'; +import {ComponentMeta, ComponentStoryObj} from '@storybook/react'; import {Content} from '@react-spectrum/view'; import {ContextualHelp} from '@react-spectrum/contextualhelp'; import {DatePicker} from '../'; @@ -23,212 +24,263 @@ import {Heading} from '@react-spectrum/text'; import {Item, Picker, Section} from '@react-spectrum/picker'; import {Provider} from '@react-spectrum/provider'; import React from 'react'; -import {storiesOf} from '@storybook/react'; import {useLocale} from '@react-aria/i18n'; +export type DatePickerStory = ComponentStoryObj; const BlockDecorator = storyFn =>
{storyFn()}
; -storiesOf('Date and Time/DatePicker', module) - .addDecorator(BlockDecorator) - .add( - 'default', - () => render() - ) - .add( - 'defaultValue', - () => render({defaultValue: parseDate('2020-02-03')}) - ) - .add( - 'controlled value', - () => - ) - .add( - 'defaultValue, zoned', - () => render({defaultValue: toZoned(parseDate('2020-02-03'), 'America/Los_Angeles')}) - ) - .add( - 'granularity: minute', - () => render({granularity: 'minute'}) - ) - .add( - 'granularity: second', - () => render({granularity: 'second'}) - ) - .add( - 'hourCycle: 12', - () => render({granularity: 'minute', hourCycle: 12}) - ) - .add( - 'hourCycle: 24', - () => render({granularity: 'minute', hourCycle: 24}) - ) - .add( - 'granularity: minute, defaultValue', - () => render({granularity: 'minute', defaultValue: parseDateTime('2021-03-14T08:45')}) - ) - .add( - 'granularity: minute, defaultValue, zoned', - () => render({granularity: 'minute', defaultValue: parseZonedDateTime('2021-11-07T00:45-07:00[America/Los_Angeles]')}) - ) - .add('granularity: minute, defaultValue, zoned, absolute', - () => render({granularity: 'minute', defaultValue: parseAbsoluteToLocal('2021-11-07T07:45:00Z')}) - ) - .add('granularity: minute, defaultValue, zoned, absolute, timeZone', - () => render({granularity: 'minute', defaultValue: parseAbsolute('2021-11-07T07:45:00Z', 'America/New_York')}) - ) - .add( - 'defaultValue with time, granularity: day', - () => render({granularity: 'day', defaultValue: parseDateTime('2021-03-14T08:45')}) - ) - .add( - 'hideTimeZone', - () => render({granularity: 'minute', defaultValue: parseZonedDateTime('2021-11-07T00:45-07:00[America/Los_Angeles]'), hideTimeZone: true}) - ) - .add( - 'isDisabled', - () => render({isDisabled: true, value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'isQuiet, isDisabled', - () => render({isQuiet: true, isDisabled: true, value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'isReadOnly', - () => render({isReadOnly: true, value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'autoFocus', - () => render({autoFocus: true}) - ) - .add( - 'validationState: invalid', - () => render({validationState: 'invalid', value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'validationState: valid', - () => render({validationState: 'valid', value: new CalendarDate(2020, 2, 3)}) - ) - .add( - 'minValue: 2010/1/1, maxValue: 2020/1/1', - () => render({minValue: new CalendarDate(2010, 0, 1), maxValue: new CalendarDate(2020, 0, 1)}) - ) - .add( - 'isDateUnavailable', - () => render({isDateUnavailable: (date: DateValue) => { +export default { + title: 'Date and Time/DatePicker', + component: DatePicker, + decorators: [storyFn => BlockDecorator(storyFn)], + args: { + onChange: action('onChange') + }, + argTypes: { + onChange: { + table: { + disable: true + } + }, + defaultValue: { + table: { + disable: true + } + }, + value: { + table: { + disable: true + } + }, + minValue: { + table: { + disable: true + } + }, + maxValue: { + table: { + disable: true + } + }, + placeholderValue: { + table: { + disable: true + } + }, + onBlur: { + table: { + disable: true + } + }, + onFocus: { + table: { + disable: true + } + }, + onFocusChange: { + table: { + disable: true + } + }, + onKeyDown: { + table: { + disable: true + } + }, + onKeyUp: { + table: { + disable: true + } + }, + onOpenChange: { + table: { + disable: true + } + }, + contextualHelp: { + table: { + disable: true + } + }, + isDateUnavailable: { + table: { + disable: true + } + }, + label: { + control: 'text' + }, + granularity: { + control: 'select', + options: ['day', 'hour', 'minute', 'second'] + }, + hourCycle: { + control: 'select', + options: [12, 24] + }, + hideTimeZone: { + control: 'boolean' + }, + isDisabled: { + control: 'boolean' + }, + isQuiet: { + control: 'boolean' + }, + isReadOnly: { + control: 'boolean' + }, + isRequired: { + control: 'boolean' + }, + necessityIndicator: { + control: 'select', + options: ['icon', 'label'] + }, + validationState: { + control: 'select', + options: [null, 'valid', 'invalid'] + }, + description: { + control: 'text' + }, + errorMessage: { + control: 'text' + }, + labelAlign: { + control: 'select', + options: ['end', 'start'] + }, + labelPosition: { + control: 'select', + options: ['top', 'side'] + }, + autoFocus: { + control: 'boolean' + }, + showFormatHelpText: { + control: 'boolean' + }, + 'aria-label': { + control: 'text' + }, + width: { + control: 'text' + }, + maxVisibleMonths: { + control: 'number' + }, + shouldFlip: { + control: 'boolean' + }, + defaultOpen: { + control: 'boolean' + }, + isOpen: { + control: 'boolean' + } + } +} as ComponentMeta; + +export const Default: DatePickerStory = { + render: (args) => render(args) +}; + +export const DefaultValue: DatePickerStory = { + ...Default, + args: {defaultValue: parseDate('2020-02-03')} +}; + +export const ControlledValue: DatePickerStory = { + args: {value: new CalendarDate(2020, 2, 3)}, + render: (args) => +}; + +export const DefaultValueZoned: DatePickerStory = { + ...Default, + args: {defaultValue: toZoned(parseDate('2020-02-03'), 'America/Los_Angeles')}, + storyName: 'defaultValue date, zoned' +}; + +export const DateTimeValue: DatePickerStory = { + ...Default, + args: {defaultValue: parseDateTime('2021-03-14T08:45')} +}; + +export const DateTimeValueZoned: DatePickerStory = { + ...Default, + args: {defaultValue: parseZonedDateTime('2021-11-07T00:45-07:00[America/Los_Angeles]')} +}; + +export const DateTimeValueAbsolute: DatePickerStory = { + ...Default, + args: {defaultValue: parseAbsoluteToLocal('2021-11-07T07:45:00Z')} +}; + +export const DateTimeValueAbsoluteZoned: DatePickerStory = { + ...Default, + args: {defaultValue: parseAbsolute('2021-11-07T07:45:00Z', 'America/New_York')} +}; + + +export const MinMaxValue: DatePickerStory = { + ...Default, + args: {minValue: new CalendarDate(2010, 0, 1), maxValue: new CalendarDate(2020, 0, 1)}, + storyName: 'minValue: 2010/1/1, maxValue: 2020/1/1' +}; + +export const PlaceholderVal: DatePickerStory = { + ...Default, + args: {placeholderValue: new CalendarDate(1980, 1, 1)}, + storyName: 'placeholder value: 1980/1/1' +}; + +export const PlaceholderValTime: DatePickerStory = { + ...Default, + args: {placeholderValue: new CalendarDateTime(1980, 1, 1, 8)}, + storyName: 'placeholder value: 1980/1/1 8AM' +}; + +export const PlaceholderValTimeZoned: DatePickerStory = { + ...Default, + args: {placeholderValue: toZoned(new CalendarDate(1980, 1, 1), 'America/Los_Angeles')}, + storyName: 'placeholder value: 1980/1/1 zoned' +}; + +export const DateUnavailable: DatePickerStory = { + ...Default, + args: { + isDateUnavailable: (date: DateValue) => { const disabledIntervals = [[today(getLocalTimeZone()), today(getLocalTimeZone()).add({weeks: 1})], [today(getLocalTimeZone()).add({weeks: 2}), today(getLocalTimeZone()).add({weeks: 3})]]; return disabledIntervals.some((interval) => date.compare(interval[0]) > 0 && date.compare(interval[1]) < 0); - }}) - ) - .add( - 'placeholderValue: 1980/1/1', - () => render({placeholderValue: new CalendarDate(1980, 1, 1)}) - ) - .add( - 'placeholderValue: 1980/1/1 8 AM', - () => render({placeholderValue: new CalendarDateTime(1980, 1, 1, 8)}) - ) - .add( - 'placeholderValue: 1980/1/1, zoned', - () => render({placeholderValue: toZoned(new CalendarDate(1980, 1, 1), 'America/Los_Angeles')}) - ) - .add( - 'maxVisibleMonths: 2', - () => render({maxVisibleMonths: 2, granularity: 'minute'}) - ) - .add( - 'maxVisibleMonths: 3', - () => render({maxVisibleMonths: 3, granularity: 'minute'}) - ) - .add( - 'showFormatHelpText', - () => render({showFormatHelpText: true}) - ) - .add( - 'all the events', - () => render({onBlur: action('onBlur'), onFocus: action('onFocus'), onFocusChange: action('onFocusChange'), onKeyDown: action('onKeyDown'), onKeyUp: action('onKeyUp'), onOpenChange: action('onOpenChange')}) - ); + } + }, + storyName: 'isDateUnavailable' +}; -storiesOf('Date and Time/DatePicker/styling', module) - .addDecorator(BlockDecorator) - .add( - 'isQuiet', - () => render({isQuiet: true}) - ) - .add( - 'labelPosition: side', - () => render({labelPosition: 'side'}) - ) - .add( - 'labelAlign: end', - () => render({labelPosition: 'top', labelAlign: 'end'}) - ) - .add( - 'required', - () => render({isRequired: true}) - ) - .add( - 'required with label', - () => render({isRequired: true, necessityIndicator: 'label'}) - ) - .add( - 'optional', - () => render({necessityIndicator: 'label'}) - ) - .add( - 'no visible label', - () => render({'aria-label': 'Date', label: null}) - ) - .add( - 'quiet no visible label', - () => render({isQuiet: true, 'aria-label': 'Date', label: null}) - ) - .add( - 'custom width', - () => render({width: 'size-3000'}) - ) - .add( - 'quiet custom width', - () => render({isQuiet: true, width: 'size-3000'}) - ) - .add( - 'custom width no visible label', - () => render({width: 'size-3000', label: null, 'aria-label': 'Date'}) - ) - .add( - 'custom width, labelPosition=side', - () => render({width: 'size-3000', labelPosition: 'side'}) - ) - .add( - 'description', - () => render({description: 'Help text'}) - ) - .add( - 'errorMessage', - () => render({errorMessage: 'Enter a date after today', validationState: 'invalid'}) - ) - .add( - 'invalid with time', - () => render({validationState: 'invalid', granularity: 'minute', defaultValue: parseDateTime('2021-03-14T08:45')}) - ) - .add( - 'contextual help', - () => render({contextualHelp: ( +export const AllEvents: DatePickerStory = { + ...Default, + args: {onBlur: action('onBlur'), onFocus: action('onFocus'), onFocusChange: action('onFocusChange'), onKeyDown: action('onKeyDown'), onKeyUp: action('onKeyUp'), onOpenChange: action('onOpenChange')}, + storyName: 'all the events' +}; + +export const ContextualHelpStory: DatePickerStory = { + ...Default, + args: { + contextualHelp: ( What is a segment? Segments identify who your visitors are, what devices and services they use, where they navigated from, and much more. - )}) - ) - .add( - 'shouldFlip: false', - () => render({shouldFlip: false}) - ); + ) + }, + storyName: 'contextual help' +}; function render(props = {}) { return ( ); @@ -312,7 +364,7 @@ function ControlledExample(props) { return ( - + setValue(new CalendarDate(2020, 2, 3))}>Change value setValue(null)}>Clear diff --git a/packages/@react-spectrum/label/stories/Label.stories.tsx b/packages/@react-spectrum/label/stories/Label.stories.tsx index cbd318b371a..4854b8c529c 100644 --- a/packages/@react-spectrum/label/stories/Label.stories.tsx +++ b/packages/@react-spectrum/label/stories/Label.stories.tsx @@ -19,22 +19,18 @@ type LabelStory = ComponentStoryObj; const argTypes = { labelAlign: { control: 'radio', - defaultValue: 'start', options: ['end', 'start'] }, labelPosition: { control: 'radio', - defaultValue: 'top', options: ['side', 'top'] }, necessityIndicator: { control: 'radio', - defaultValue: 'icon', options: ['icon', 'label'] }, isRequired: { - control: 'boolean', - defaultValue: false + control: 'boolean' }, htmlFor: {control: {disable: true}} }; diff --git a/packages/@react-spectrum/picker/stories/Picker.stories.tsx b/packages/@react-spectrum/picker/stories/Picker.stories.tsx index ec30826419c..1e91bf53666 100644 --- a/packages/@react-spectrum/picker/stories/Picker.stories.tsx +++ b/packages/@react-spectrum/picker/stories/Picker.stories.tsx @@ -112,27 +112,22 @@ export default { control: 'text' }, isDisabled: { - control: 'boolean', - defaultValue: false + control: 'boolean' }, labelAlign: { control: 'radio', - defaultValue: 'start', options: ['end', 'start'] }, labelPosition: { control: 'radio', - defaultValue: 'top', options: ['side', 'top'] }, necessityIndicator: { control: 'radio', - defaultValue: 'icon', options: ['icon', 'label'] }, isRequired: { - control: 'boolean', - defaultValue: false + control: 'boolean' }, validationState: { control: { @@ -141,8 +136,7 @@ export default { } }, isQuiet: { - control: 'boolean', - defaultValue: false + control: 'boolean' }, width: { control: { @@ -157,12 +151,10 @@ export default { } }, isLoading: { - control: 'boolean', - defaultValue: false + control: 'boolean' }, autoFocus: { - control: 'boolean', - defaultValue: false + control: 'boolean' }, isOpen: { control: 'boolean' diff --git a/packages/@react-spectrum/tooltip/stories/Tooltip.stories.tsx b/packages/@react-spectrum/tooltip/stories/Tooltip.stories.tsx index daf9d2884f0..d3feb84c956 100644 --- a/packages/@react-spectrum/tooltip/stories/Tooltip.stories.tsx +++ b/packages/@react-spectrum/tooltip/stories/Tooltip.stories.tsx @@ -18,17 +18,14 @@ type TooltipStory = ComponentStoryObj; const argTypes = { placement: { control: 'radio', - defaultValue: 'top', options: ['top', 'bottom', 'left', 'right'] }, variant: { control: 'radio', - defaultValue: undefined, options: [undefined, 'neutral', 'info', 'positive', 'negative'] }, showIcon: { - control: 'boolean', - defaultValue: false + control: 'boolean' }, isOpen: { control: {disable: true} diff --git a/packages/@react-spectrum/tooltip/stories/TooltipTrigger.stories.tsx b/packages/@react-spectrum/tooltip/stories/TooltipTrigger.stories.tsx index 29db0844629..ef58f95120e 100644 --- a/packages/@react-spectrum/tooltip/stories/TooltipTrigger.stories.tsx +++ b/packages/@react-spectrum/tooltip/stories/TooltipTrigger.stories.tsx @@ -37,45 +37,37 @@ type TooltipTriggerStory = ComponentStoryObj; const argTypes = { placement: { control: 'select', - defaultValue: 'bottom', options: ['bottom', 'bottom left', 'bottom right', 'bottom start', 'bottom end', 'top', 'top left', 'top right', 'top start', 'top end', 'left', 'left top', 'left bottom', 'start', 'start top', 'start bottom', 'right', 'right top', 'right bottom', 'end', 'end top', 'end bottom'] }, delay: { control: 'number', - defaultValue: 1500, min: 0, max: 50000, step: 500 }, offset: { control: 'number', - defaultValue: 0, min: -500, max: 500 }, crossOffset: { control: 'number', - defaultValue: 0, min: -500, max: 500 }, containerPadding: { control: 'number', - defaultValue: 0, min: -500, max: 500 }, isDisabled: { - control: 'boolean', - defaultValue: false + control: 'boolean' }, shouldFlip: { - control: 'boolean', - defaultValue: true + control: 'boolean' }, trigger: { control: 'radio', - defaultValue: undefined, options: [undefined, 'focus'] }, children: {