diff --git a/apps/vr-tests-react-components/package.json b/apps/vr-tests-react-components/package.json index 5970a49400a7d..7cd9112d122ed 100644 --- a/apps/vr-tests-react-components/package.json +++ b/apps/vr-tests-react-components/package.json @@ -66,6 +66,7 @@ "@fluentui/react-textarea": "*", "@fluentui/react-theme": "*", "@fluentui/react-timepicker-compat": "*", + "@fluentui/react-tag-picker-preview": "*", "@fluentui/react-toast": "*", "@fluentui/react-tooltip": "*", "@fluentui/react-toolbar": "*", diff --git a/apps/vr-tests-react-components/src/stories/TagPicker.stories.tsx b/apps/vr-tests-react-components/src/stories/TagPicker.stories.tsx new file mode 100644 index 0000000000000..b677cc341cf45 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/TagPicker.stories.tsx @@ -0,0 +1,427 @@ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { + TagPicker, + TagPickerControl, + TagPickerGroup, + TagPickerInput, + TagPickerList, + TagPickerOption, + TagPickerOptionGroup, + TagPickerProps, +} from '@fluentui/react-tag-picker-preview'; +import { Tag } from '@fluentui/react-tags'; +import { Avatar } from '@fluentui/react-avatar'; +import { DARK_MODE, HIGH_CONTRAST, RTL, getStoryVariant } from '../utilities/getStoryVariant'; +import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; +import { tokens } from '@fluentui/react-theme'; +import { Steps, StoryWright } from 'storywright'; +import { ArrowDownFilled } from '@fluentui/react-icons'; +import { Button } from '@fluentui/react-button'; + +export default { + title: 'TagPicker', +} as ComponentMeta; + +const options = [ + 'John Doe', + 'Jane Doe', + 'Max Mustermann', + 'Erika Mustermann', + 'Pierre Dupont', + 'Amelie Dupont', + 'Mario Rossi', + 'Maria Rossi', +]; + +export const Default = (props: Pick) => { + const [selectedOptions, setSelectedOptions] = React.useState([]); + const onOptionSelect: TagPickerProps['onOptionSelect'] = (e, data) => { + setSelectedOptions(data.selectedOptions); + }; + + return ( +
+ + + + {selectedOptions.map(option => ( + } + value={option} + > + {option} + + ))} + + + + + {options + .filter(option => !selectedOptions.includes(option)) + .map(option => ( + } + value={option} + key={option} + > + {option} + + ))} + + +
+ ); +}; + +Default.storyName = 'default'; +export const DefaultDarkMode = getStoryVariant(Default, DARK_MODE); +export const DefaultHighContrast = getStoryVariant(Default, HIGH_CONTRAST); +export const DefaultRTL = getStoryVariant(Default, RTL); + +export const DefaultOpen = () => { + const [selectedOptions, setSelectedOptions] = React.useState([]); + const onOptionSelect: TagPickerProps['onOptionSelect'] = (e, data) => { + setSelectedOptions(data.selectedOptions); + }; + + return ( + +
+ + + + {selectedOptions.map(option => ( + } + value={option} + > + {option} + + ))} + + + + + {options + .filter(option => !selectedOptions.includes(option)) + .map((option, index) => ( + } + value={option} + key={option} + > + {option} + + ))} + + +
+
+ ); +}; + +DefaultOpen.storyName = 'default open'; +export const DefaultOpenDarkMode = getStoryVariant(DefaultOpen, DARK_MODE); +export const DefaultOpenHighContrast = getStoryVariant(DefaultOpen, HIGH_CONTRAST); +export const DefaultOpenRTL = getStoryVariant(DefaultOpen, RTL); + +const useStyles = makeStyles({ + padding: { + ...shorthands.padding('20px'), + }, + darkBG: { + backgroundColor: tokens.colorNeutralBackgroundInverted, + color: tokens.colorNeutralForegroundInverted2, + ...shorthands.marginBlock('10px'), + ...shorthands.borderRadius(tokens.borderRadiusMedium), + }, +}); + +export const Appearance = () => { + const styles = useStyles(); + return ( + <> +
+

Outline

+ +
+
+

Underline

+ +
+
+

Filled Darker

+ +
+
+

Filled Lighter

+ +
+ + ); +}; + +Appearance.storyName = 'appearance'; +export const AppearanceDarkMode = getStoryVariant(Appearance, DARK_MODE); +export const AppearanceHighContrast = getStoryVariant(Appearance, HIGH_CONTRAST); +export const AppearanceRTL = getStoryVariant(Appearance, RTL); + +export const Size = () => ( + <> +
+

Extra Large

+ +
+
+

Large

+ +
+
+

Medium

+ +
+ +); +Size.storyName = 'size'; +export const SizeDarkMode = getStoryVariant(Size, DARK_MODE); +export const SizeHighContrast = getStoryVariant(Size, HIGH_CONTRAST); +export const SizeRTL = getStoryVariant(Size, RTL); + +export const Disabled = () => { + const [selectedOptions, setSelectedOptions] = React.useState([ + options[0], + options[1], + options[2], + options[3], + ]); + const onOptionSelect: TagPickerProps['onOptionSelect'] = (e, data) => { + setSelectedOptions(data.selectedOptions); + }; + + return ( + +
+ + + + {selectedOptions.map(option => ( + } + value={option} + > + {option} + + ))} + + + + + {options + .filter(option => !selectedOptions.includes(option)) + .map(option => ( + } + value={option} + key={option} + > + {option} + + ))} + + +
+
+ ); +}; +Disabled.storyName = 'disabled'; +export const DisabledDarkMode = getStoryVariant(Disabled, DARK_MODE); +export const DisabledHighContrast = getStoryVariant(Disabled, HIGH_CONTRAST); +export const DisabledRTL = getStoryVariant(Disabled, RTL); + +export const ExpandIcon = () => { + const [selectedOptions, setSelectedOptions] = React.useState([options[0]]); + const onOptionSelect: TagPickerProps['onOptionSelect'] = (event, data) => { + setSelectedOptions(data.selectedOptions); + }; + + return ( +
+ + }> + + {selectedOptions.map(option => ( + } + value={option} + > + {option} + + ))} + + + + + {options + .filter(option => !selectedOptions.includes(option)) + .map(option => ( + } + value={option} + key={option} + > + {option} + + ))} + + +
+ ); +}; +ExpandIcon.storyName = 'expand icon'; +export const ExpandIconDarkMode = getStoryVariant(ExpandIcon, DARK_MODE); +export const ExpandIconHighContrast = getStoryVariant(ExpandIcon, HIGH_CONTRAST); +export const ExpandIconRTL = getStoryVariant(ExpandIcon, RTL); + +const managers = ['John Doe', 'Jane Doe', 'Max Mustermann', 'Erika Mustermann']; +const devs = ['Pierre Dupont', 'Amelie Dupont', 'Mario Rossi', 'Maria Rossi']; + +export const Grouped = () => { + const [selectedOptions, setSelectedOptions] = React.useState([]); + const onOptionSelect: TagPickerProps['onOptionSelect'] = (e, data) => { + setSelectedOptions(data.selectedOptions); + }; + const unSelectedManagers = managers.filter(option => !selectedOptions.includes(option)); + const unSelectedDevs = devs.filter(option => !selectedOptions.includes(option)); + + return ( +
+ + + + {selectedOptions.map(option => ( + } + value={option} + > + {option} + + ))} + + + + + {unSelectedManagers.length > 0 && ( + + {unSelectedManagers.map(option => ( + } + value={option} + key={option} + > + {option} + + ))} + + )} + {unSelectedDevs.length > 0 && ( + + {unSelectedDevs.map(option => ( + } + value={option} + key={option} + > + {option} + + ))} + + )} + + +
+ ); +}; +Grouped.storyName = 'grouped'; +export const GroupedDarkMode = getStoryVariant(Grouped, DARK_MODE); +export const GroupedHighContrast = getStoryVariant(Grouped, HIGH_CONTRAST); +export const GroupedRTL = getStoryVariant(Grouped, RTL); + +export const SecondaryAction = () => { + const [selectedOptions, setSelectedOptions] = React.useState([options[0]]); + const onOptionSelect: TagPickerProps['onOptionSelect'] = (event, data) => { + setSelectedOptions(data.selectedOptions); + }; + const handleAllClear: React.MouseEventHandler = event => { + setSelectedOptions([]); + }; + + return ( +
+ + + All Clear + + } + > + + {selectedOptions.map(option => ( + } + value={option} + > + {option} + + ))} + + + + + {options + .filter(option => !selectedOptions.includes(option)) + .map(option => ( + } + value={option} + key={option} + > + {option} + + ))} + + +
+ ); +}; +SecondaryAction.storyName = 'secondary action'; +export const SecondaryActionDarkMode = getStoryVariant(SecondaryAction, DARK_MODE); +export const SecondaryActionHighContrast = getStoryVariant(SecondaryAction, HIGH_CONTRAST); +export const SecondaryActionRTL = getStoryVariant(SecondaryAction, RTL);