UNPKG

@wix/design-system

Version:

@wix/design-system

775 lines (729 loc) 22 kB
## Feature Examples ### Size - description: <p>Adjust the component size using the size prop.</p><li><code>large</code> emphasize fields in onboarding flows.</li><li><code>medium</code> is the default size used in most cases.</li><li><code>small</code> should be used in dense layouts.</li> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; return ( <StorybookComponents.Stack flexDirection="column"> <Dropdown size="large" placeholder="Large" options={options} /> <Dropdown size="medium" placeholder="Medium" options={options} /> <Dropdown size="small" placeholder="Small" options={options} /> </StorybookComponents.Stack> ); }; ``` ### Border - description: <p>Style the component using the border prop which supports four styles:</p><li>For forms, use <code>standard</code>.</li><li>When the component is used to filter, use <code>round</code>.</li><li>For titles that can be edited on click, use <code>bottomLine</code>.</li><li>In the Content Manager’s spreadsheet, use <code>none</code>.</li> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; return ( <StorybookComponents.Stack flexDirection="column"> <Dropdown border="standard" placeholder="Standard" options={options} /> <Dropdown border="round" placeholder="Round" options={options} /> <Dropdown border="bottomLine" placeholder="Bottom Line" options={options} /> <Dropdown border="none" placeholder="None" options={options} /> </StorybookComponents.Stack> ); }; ``` ### Status - description: <p>Use the <code>status</code> prop to control component status. </p><li><code>error</code> highlights an invalid selection.</li><li><code>warning</code> highlights a value that can’t be validated or impacts a user’s business.</li><li><code>loading</code> shows that the value is loading.</li><p></p><p>Hide the status suffix and indicate the state with a border color by setting <code>hideStatusSuffix</code>to true. </p> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; return ( <StorybookComponents.Stack flexDirection="column"> <Dropdown status="error" placeholder="Error" options={options} /> <Dropdown status="warning" placeholder="Warning" options={options} /> <Dropdown status="loading" placeholder="Loading" options={options} /> </StorybookComponents.Stack> ); }; ``` ### Status message - description: <p>Add text that explains the status or what action the user should take with the <code>statusMessage</code> prop.</p><p></p><p>Showing the status message inline, directly below the dropdown is preferred in all default cases.</p><li>To add an accessible inline message, wrap the component in a <code><FormField/></code> and add the <code>statusMessage</code>.</li><li>To add a status message in a tooltip that requires users to hover on the icon, use the <code>statusMessage</code> prop. Control tooltip placement with <code>tooltipPlacement</code> prop.</li><p></p><p>View more inline status message examples in <code><FormField/></code>.</p> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; return ( <StorybookComponents.Stack flexDirection="column"> <StorybookComponents.Stack flexDirection="column" gap="12px"> <Text secondary>For all default cases:</Text> <FormField status="error" statusMessage="This is an error message."> <Dropdown placeholder="See message below" tooltipPlacement="top-end" options={options} /> </FormField> </StorybookComponents.Stack> <StorybookComponents.Stack flexDirection="column" gap="12px"> <Text secondary>For narrow layouts only:</Text> <Dropdown placeholder="Hover on status icon" status="error" statusMessage="This is an error message." tooltipPlacement="top-end" options={options} /> </StorybookComponents.Stack> </StorybookComponents.Stack> ); }; ``` ### Disabled - description: <p>Disable all input interactions with the <code>disabled</code> prop. Use it to highlight unavailable functions.</p> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; return <Dropdown disabled placeholder="Disabled" options={options} />; }; ``` ### Affix - description: <p>Add additional information to <code>prefix</code> and <code>suffix</code> props (e.g. text, icons, buttons) to support the dropdown value.</p> - example: ```jsx () => { const discountSuffixOptions = [ { id: 0, value: '5' }, { id: 1, value: '10' }, { id: 2, value: '15' }, ]; const discountAffixOptions = [ { id: 0, value: '10' }, { id: 1, value: '20' }, { id: 2, value: '30' }, ]; const languageOptions = [ { id: 0, value: 'English' }, { id: 1, value: 'French' }, { id: 2, value: 'Spanish' }, ]; const employeeOptions = [ { id: 0, value: 'Employee 1' }, { id: 1, value: 'Employee 2' }, { id: 2, value: 'Employee 3' }, ]; return ( <StorybookComponents.Stack flexDirection="column"> <Dropdown placeholder="Select discount size" suffix={<Input.Affix>%</Input.Affix>} options={discountSuffixOptions} /> <Dropdown placeholder="Select discount size" prefix={<Input.Affix>$</Input.Affix>} options={discountAffixOptions} /> <Dropdown placeholder="Select language" prefix={ <Input.IconAffix> <Icons.Languages /> </Input.IconAffix> } options={languageOptions} /> <Dropdown placeholder="Select employee" prefix={ <Input.Affix> <Avatar size="size18" /> </Input.Affix> } options={employeeOptions} /> </StorybookComponents.Stack> ); }; ``` ### Clear button - description: <p>Enable a button that clears the dropdown value by using the <code>clearButton</code> prop. Show it when the field value is optional or has to be cleared often.</p> - example: ```jsx () => { const [selectedOption, setSelectedOption] = React.useState(0); const options = [ { id: 0, value: 'Click clear button to remove selection' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; return ( <Dropdown placeholder="Select" clearButton onClear={() => setSelectedOption(null)} onSelect={option => setSelectedOption(option.id)} selectedId={selectedOption} options={options} /> ); }; ``` ### Fixed header and footer - description: <p>Add related actions to <code>fixedFooter</code> or <code>fixedHeader</code> areas. These headers and footers keep their position on scroll.</p> - example: ```jsx () => { const options = [ { id: 1, value: 'Option 1' }, { id: 2, value: 'Option 2' }, { id: 3, value: 'Option 3' }, { id: 4, value: 'Option 4' }, { id: 5, value: 'Option 5' }, { id: 6, value: 'Option 6' }, { id: 7, value: 'Option 7' }, { id: 8, value: 'Option 8' }, { id: 9, value: 'Option 9' }, ]; return ( <Dropdown placeholder="Select" fixedHeader={<ListItemAction title="Fixed Header" />} fixedFooter={<ListItemAction title="Fixed Footer" />} options={options} /> ); }; ``` ### List item builders - description: <p>Use three props to build custom layouts:</p><li><code>listItemSectionBuilder</code> groups items into sections by type. <a href="https://www.wix-style-react.com/storybook/?path=/story/components-form-dropdownlistitems--listitemsection"></a></li><li><code>listItemActionBuilder</code> adds a text button for related list actions. <a href="https://www.wix-style-react.com/storybook/?path=/story/components-form-dropdownlistitems--listitemaction"></a></li><li><code>listItemSelectBuilder</code> builds custom list designs. <a href="https://www.wix-style-react.com/storybook/?path=/story/components-form-dropdownlistitems--listitemselect"></a></li> - example: ```jsx () => { const listItemSectionOptions = [ listItemSectionBuilder({ id: 0, type: 'title', title: 'Group Title', }), { id: 1, value: 'Option 1' }, { id: 2, value: 'Option 2' }, { id: 3, value: 'Option 3' }, listItemSectionBuilder({ id: 3, type: 'divider', }), { id: 4, value: 'Option 4' }, ]; const listItemActionOptions = [ listItemActionBuilder({ id: 0, title: 'Action', }), { id: 1, value: 'Option 1' }, { id: 2, value: 'Option 2' }, { id: 3, value: 'Option 3' }, ]; const listItemSelectOptions = [ listItemSelectBuilder({ id: 0, prefix: <Avatar size="size30" />, title: 'Title', subtitle: 'Subtitle', suffix: 'Suffix', }), listItemSelectBuilder({ id: 1, prefix: <Avatar size="size30" />, title: 'Title', subtitle: 'Subtitle', suffix: 'Suffix', }), listItemSelectBuilder({ id: 2, prefix: <Avatar size="size30" />, title: 'Title', subtitle: 'Subtitle', suffix: 'Suffix', }), ]; return ( <StorybookComponents.Stack flexDirection="column"> <Dropdown placeholder="List Item Section" options={listItemSectionOptions} /> <Dropdown placeholder="List Item Action" options={listItemActionOptions} /> <Dropdown placeholder="List Item Select" options={listItemSelectOptions} /> </StorybookComponents.Stack> ); }; ``` ### List container dimensions - description: <p>Control the container size for the list of options with these props:</p><li><code>maxHeightPixels</code> specifies the maximum height for longer lists.</li><li><code>dropdownWidth</code> matches content width or specifies pixels. Set width to ‘auto’ or ‘max-content.’</li><li><code>minWidthPixels</code> manually increases dropdown popover width.</li><p></p><p>By default, the dropdown matches the input field width.</p> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, { id: 3, value: 'Option 4' }, { id: 4, value: 'Option 5' }, { id: 5, value: 'Option 6' }, { id: 6, value: 'Option 7' }, { id: 7, value: 'Option 8' }, ]; return ( <StorybookComponents.Stack> <Dropdown placeholder="Look at proportions" maxHeightPixels="200px" dropdownWidth="auto" minWidthPixels="400px" options={options} popoverProps={{ placement: 'bottom-start', }} /> </StorybookComponents.Stack> ); }; ``` ### Marked option - description: <p>Once the dropdown is opened, use the <code>markedOption</code> to highlight the option.</p> - example: ```jsx <Dropdown placeholder="Select an option" markedOption={1} options={[ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]} />; ``` ### Native support - description: <p>Switch to <code>native</code> support for mobile usage. Avoid using it for desktop applications.</p> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, { id: 3, value: 'Option 4' }, ]; return <Dropdown options={options} placeholder="Select as native" native />; }; ``` ### Text overflow - description: <p>Control text overflow in the field with the <code>textOverflow</code>. Apply <code>clip</code> or <code>ellipsis</code>.</p><p></p><p>Dropdown list options wrap by default. To apply ellipsis, select the items to be displayed with the <code>listItemSelectBuilder</code>. This isn't recommended.</p> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, { id: 3, value: 'Option 4' }, ]; const longOptions = [ { id: 0, value: 'This is a long value that make dropdown layout grow', }, { id: 1, value: 'This is a long value that make dropdown layout grow', }, { id: 2, value: 'This is a long value that make dropdown layout grow', }, ]; const longOptionsWithEllipsis = [ listItemSelectBuilder({ id: 0, title: 'This is a long value that make dropdown layout grow', ellipsis: true, }), listItemSelectBuilder({ id: 0, title: 'This is a long value that make dropdown layout grow', ellipsis: true, }), listItemSelectBuilder({ id: 0, title: 'This is a long value that make dropdown layout grow', ellipsis: true, }), ]; return ( <StorybookComponents.Stack flexDirection="column"> <StorybookComponents.Stack> <FormField label="Input value with ellipsis::"> <Dropdown options={options} placeholder="This field is showing ellipsis at the end of this line" textOverflow="ellipsis" /> </FormField> <FormField label="Input value clipped:"> <Dropdown options={options} placeholder="This field is clipping content at the end of this line" textOverflow="clip" /> </FormField> </StorybookComponents.Stack> <StorybookComponents.Stack> <FormField label="Options wrapped:"> <Dropdown options={longOptions} placeholder="Select wrapped option" /> </FormField> <FormField label="Options with ellipsis:"> <Dropdown options={longOptionsWithEllipsis} placeholder="Select clipped option" /> </FormField> </StorybookComponents.Stack> </StorybookComponents.Stack> ); }; ``` ## Developer Examples ### Lazy loading - description: <p>Gradually load items with <code>infiniteScroll</code>, <code>loadMore</code> and <code>hasMore</code> props.</p> - example: ```jsx () => { const [data, setData] = React.useState([]); const fetchMoreData = () => Promise.resolve( fetch(`/api/dropdown?limit=${5}&offset=${data.length}`), ).then(results => setData([...data, ...results])); React.useEffect(() => { fetchMoreData(); }, []); return ( <Dropdown placeholder="Select" options={data} infiniteScroll hasMore={true} loadMore={fetchMoreData} /> ); }; ``` ### Controlled - description: <p>Component can be used in controlled mode by passing <code>selectedId</code> and <code>onSelect</code> props.</p> - example: ```jsx () => { const [selectedId, setSelected] = React.useState(0); const options = [ listItemSelectBuilder({ id: 0, prefix: ( <Box> <Icons.Home /> </Box> ), title: 'Home address', label: 'Home address', }), listItemSelectBuilder({ id: 1, title: 'Work address', label: 'Work address', prefix: ( <Box> <Icons.Toolbox /> </Box> ), }), listItemSelectBuilder({ id: 2, title: 'Mailing address', label: 'Mailing address', prefix: ( <Box> <Icons.Email /> </Box> ), }), listItemSelectBuilder({ id: 3, title: 'Shipping address', label: 'Shipping address', prefix: ( <Box> <Icons.Archive /> </Box> ), }), listItemSelectBuilder({ id: 4, title: 'Other', label: 'Other', prefix: ( <Box> <Icons.Category /> </Box> ), }), ]; return ( <Dropdown placeholder="Select" selectedId={selectedId} valueParser={(option) => option.label} onSelect={(e) => setSelected(e.id)} options={options} /> ); }; ``` ## Common Use Case Examples ### Settings panel - description: <p>Use dropdown to let users select a single item from a predefined list of options in a settings panel.</p> - example: ```jsx () => { const [selectedOption, setSelectedOption] = React.useState(0); const [value, setValue] = React.useState(2); const options = [ { id: 0, value: 'Image' }, { id: 1, value: 'Video' }, { id: 2, value: 'Image and video' }, { id: 3, value: 'Document' }, { id: 4, value: 'Audio' }, ]; return ( <SidePanel maxHeight="576px" width="288px" skin="floating"> <SidePanel.Header title="Upload Settings" /> <SidePanel.Content noPadding> <SidePanel.Field> <FormField label="Supported file type"> <Dropdown placeholder="Select" size="small" options={options} onSelect={(option) => setSelectedOption(option.id)} selectedId={selectedOption} /> </FormField> </SidePanel.Field> <SidePanel.Field> <FieldSet gap="small" legend="Max number of files" columns="auto 60px" > <Slider onChange={setValue} min={0} max={10} value={value} displayMarks={false} /> <Input size="small" value={value} onChange={(e) => setValue(e.target.value)} /> </FieldSet> </SidePanel.Field> <SidePanel.Field> <FormField label="This field is"> <Checkbox size="small" checked> Required </Checkbox> </FormField> </SidePanel.Field> <SidePanel.Section title="Display settings"> <SidePanel.Field> <FormField label="Field title"> <Input size="small" placeholder="Enter field title"/> </FormField> </SidePanel.Field> <SidePanel.Field> <FormField label="Button text"> <Input size="small" value="Choose file"/> </FormField> </SidePanel.Field> </SidePanel.Section> </SidePanel.Content> </SidePanel> ); }; ``` ### Prefix icon - description: <p>Use <code>listItemSelectBuilder</code> to create custom layouts for options in the dropdown. For example, use avatars, icons or images as prefix icons.</p> - example: ```jsx () => { const options = [ listItemSelectBuilder({ id: 0, prefix: ( <Box> <Icons.Home /> </Box> ), title: 'Home address', label: 'Home address', }), listItemSelectBuilder({ id: 1, title: 'Work address', label: 'Work address', prefix: ( <Box> <Icons.Toolbox /> </Box> ), }), listItemSelectBuilder({ id: 2, title: 'Mailing address', label: 'Mailing address', prefix: ( <Box> <Icons.Email /> </Box> ), }), listItemSelectBuilder({ id: 3, title: 'Shipping address', label: 'Shipping address', prefix: ( <Box> <Icons.Archive /> </Box> ), }), listItemSelectBuilder({ id: 4, title: 'Other', label: 'Other', prefix: ( <Box> <Icons.Category /> </Box> ), }), ]; return ( <FormField label="Address type"> <Dropdown placeholder="Select" valueParser={option => option.label} options={options} /> </FormField> ); }; ``` ### Grouping - description: <p>Use <code>listItemSectionBuilder</code> within the drop down to group options into categories.</p> - example: ```jsx <Layout> <Cell span={12}> <FormField label="Product"> <Dropdown placeholder="Select" options={[ listItemSectionBuilder({ title: 'Most popular', }), { id: 1, value: 'Wix Stores' }, { id: 2, value: 'Wix Bookings' }, { id: 3, value: 'Wix Blog' }, listItemSectionBuilder({ title: 'Other', }), { id: 4, value: 'Wix Events' }, { id: 5, value: 'Wix Forum' }, { id: 6, value: 'Wix Restaurants' }, ]} /> </FormField> </Cell> <Cell span={12}> <FormField label="Role"> <Dropdown placeholder="Select" options={[ listItemSectionBuilder({ title: 'General', type: 'subheader', suffix: 'Edit', }), { id: 0, value: 'Website manager' }, { id: 1, value: 'Website designer' }, { id: 2, value: 'Back office manager' }, listItemSectionBuilder({ title: 'Content manager roles', type: 'subheader', suffix: 'Edit', }), { id: 3, value: 'Content collection manager' }, listItemSectionBuilder({ title: 'Blog roles', type: 'subheader', suffix: 'Edit', }), { id: 4, value: 'Blog editor' }, { id: 5, value: 'Blog writer' }, { id: 6, value: 'Guest writer' }, listItemSectionBuilder({ title: 'Booking roles', type: 'subheader', suffix: 'Edit', }), { id: 7, value: 'Bookings admin' }, { id: 8, value: 'Bookings staff member' }, ]} /> </FormField> </Cell> </Layout>; ```