UNPKG

@wix/design-system

Version:

@wix/design-system

563 lines (513 loc) 16.8 kB
## Feature Examples ### Size - description: <p>Adjust the component size using the <code>size</code> prop. It supports 3 sizes.</p><li>Give the dropdown more emphasis with the <code>large</code> size. </li><li><code>medium</code> is the default size and should be used in most cases.</li><li>In layouts with a lot of dense content use <code>small</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"> <AutoComplete placeholder="Large" size="large" options={options} /> <AutoComplete placeholder="Medium" size="medium" options={options} /> <AutoComplete placeholder="Small" size="small" options={options} /> </StorybookComponents.Stack> ); }; ``` ### Border - description: <p>Style the component using the <code>border</code> prop, which supports 4 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"> <AutoComplete placeholder="Standard" border="standard" options={options} /> <AutoComplete placeholder="Round" border="round" options={options} /> <AutoComplete placeholder="Bottom line" border="bottomLine" options={options} /> <AutoComplete placeholder="None" border="none" options={options} /> </StorybookComponents.Stack> ); }; ``` ### Status - description: <p>Control the component's state using the <code>status</code> prop. There are 3 states:</p><li><code>error</code> highlights an invalid selection.</li><li><code>warning</code> highlights a value that can't be validated or impacts the user's business.</li><li><code>loading</code> shows that the server is loading the value.</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"> <AutoComplete placeholder="Error" status="error" options={options} /> <AutoComplete placeholder="Warning" status="warning" options={options} /> <AutoComplete placeholder="Loading" status="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 input 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."> <AutoComplete 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> <AutoComplete 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 <AutoComplete placeholder="Disabled" disabled />; ``` ### Affix - description: <p>Explain field value with additional information added to <code>prefix</code> and <code>suffix</code>. Props can contain text, icons and even buttons.</p> - example: ```jsx () => { const languageOptions = [ { id: 0, value: 'English' }, { id: 1, value: 'French' }, { id: 2, value: 'Spanish' }, ]; const nameOptions = [ { id: 0, value: 'Jason Sudeikis' }, { id: 1, value: 'John Krasinski' }, { id: 2, value: 'Emma Stone' }, ]; return ( <StorybookComponents.Stack flexDirection="column"> <AutoComplete placeholder="Select language" prefix={ <Input.IconAffix> <Icons.Languages /> </Input.IconAffix> } options={languageOptions} /> <AutoComplete placeholder="Assign a person" defaultValue="Emma Stone" prefix={ <Input.Affix> <Avatar size="size18"></Avatar> </Input.Affix> } suffix={<Input.Affix>12 April 2015</Input.Affix>} options={nameOptions} /> </StorybookComponents.Stack> ); }; ``` ### Clear button - description: <p>Enable a button that clears the selected value with the <code>clearButton</code> prop. Show it when the field value is optional or often has to be cleared.</p> - example: ```jsx () => { const options = [ { id: 0, value: 'Click clear button to remove selection' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; const [value, setValue] = React.useState(options[0].value); return ( <AutoComplete placeholder="Select" clearButton options={options} value={value} onClear={() => setValue('')} /> ); }; ``` ### Fixed header and footer - description: <p>Add a list of related actions to a fixed footer or header area. These areas keep their positions on scroll. </p> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; return ( <AutoComplete placeholder="Click to see fixed areas" fixedHeader={<ListItemAction title="Fixed Header" />} fixedFooter={<ListItemAction title="Fixed Footer" />} options={options} /> ); }; ``` ### List item builders - description: <p>There are a few props for building custom layouts:</p><li>Group list items into sections with titles using <code>listItemSectionBuilder</code>.</li><li>Add text buttons for related list actions with <code>listItemActionBuilder</code>.</li><li>Build custom options list designs with <code>listItemSelectBuilder</code>.</li> - example: ```jsx () => { const sectionOptions = [ 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 actionOptions = [ listItemActionBuilder({ id: 0, title: 'Action', }), { id: 1, value: 'Option 1' }, { id: 2, value: 'Option 2' }, { id: 3, value: 'Option 3' }, ]; const selectOptions = [ 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"> <AutoComplete placeholder="List item section" options={sectionOptions} /> <AutoComplete placeholder="List item action" options={actionOptions} /> <AutoComplete placeholder="List item select" options={selectOptions} /> </StorybookComponents.Stack> ); }; ``` ### List container dimensions - description: <p>There are a few ways to control the container size:</p><li>Specify the max height for longer lists with <code>maxHeightPixels</code> prop.</li><li>Set the width to 'auto' or 'max-content' to match the content width or specify it in pixels with <code>dropdownWidth</code> prop.</li><li>Increase the dropdown popover width manually using <code>minWidthPixels</code> prop.</li> - 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 ( <AutoComplete placeholder="Look at proportions" maxHeightPixels="200px" dropdownWidth="auto" minWidthPixels="400px" options={options} popoverProps={{ placement: 'bottom-start', }} /> ); }; ``` ### Marked option - description: <p>Control what to highlight with a hover state when autocomplete dropdown is opened with the <code>markedOption</code> prop.</p> - example: ```jsx () => { const options = [ { id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }, ]; return ( <AutoComplete placeholder="Select an option" markedOption={1} options={options} /> ); }; ``` ### Infinite scroll - description: <p>Load items gradually with <code>infiniteScroll</code>, <code>loadMore</code> and <code>hasMore</code> props.</p> - example: ```jsx () => { const [options, setOptions] = React.useState([]); const fetchMoreData = () => Promise.resolve( fetch(`/api/dropdown?limit=${5}&offset=${options.length}`), ).then(results => setOptions([...options, ...results])); React.useEffect(() => { fetchMoreData(); }, []); return ( <AutoComplete infiniteScroll hasMore loadMore={fetchMoreData} options={options} placeholder={'Start typing'} /> ); }; ``` ### Text overflow - description: <p>Control text overflow in the input field itself with<code>textOverflow</code>. This allows you to clip the content or add ellipsis.</p><p></p><p>For the dropdown items, the text wraps by default. To add ellipsis, use the <code>listItemSelectBuilder</code> prop.</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 optionsLongValue = [ { 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 optionsListBuilder = [ 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 - ellipsis"> <AutoComplete options={options} placeholder="This field is showing ellipsis at the end of this line" textOverflow="ellipsis" /> </FormField> <FormField label="Input value - clip"> <AutoComplete options={options} placeholder="This field is clipping content at the end of this line" textOverflow="clip" /> </FormField> </StorybookComponents.Stack> <StorybookComponents.Stack> <FormField label="Options - wrapping"> <AutoComplete options={optionsLongValue} placeholder="Select option that wraps" /> </FormField> <FormField label="Options - with ellipsis"> <AutoComplete options={optionsListBuilder} placeholder="Select option that clips" /> </FormField> </StorybookComponents.Stack> </StorybookComponents.Stack> ); }; ``` ## Common Use Case Examples ### Custom lists - description: <p>To create a custom options layout with avatars, icons, images and more, use the <code>listItemSelectBuilder</code>.</p> - example: ```jsx () => { const [searchValue, setSearchValue] = React.useState('') const [selectedId, setSelectedId] = React.useState() const options = [ listItemSectionBuilder({ title: 'General roles', }), listItemSelectBuilder({ id: 0, title: 'Website manager', label: 'Website manager', subtitle: 'Has access to manage, edit & publish site, but cannot manage billing, delete, duplicate or transfer site.', }), listItemSelectBuilder({ id: 1, title: 'Website designer', label: 'Website designer', subtitle: 'Can edit the site, manage settings and apps but cannot access Inbox, contacts and other sensitive info.', }), listItemSelectBuilder({ id: 2, title: 'Back office manager', label: 'Back office manager', subtitle: 'Can access the Dashboard to manage site settings and apps but cannot edit the site.', }), listItemSectionBuilder({ type: 'divider', }), listItemSectionBuilder({ title: 'Content manager roles', }), listItemSelectBuilder({ id: 3, title: 'Content collection manager', label: 'Content collection manager', subtitle: 'Can add and modify content for all collections, but cannot edit other areas of your site.', }), listItemSectionBuilder({ type: 'divider', }), listItemSectionBuilder({ title: 'Blog roles', }), listItemSelectBuilder({ id: 4, title: 'Blog editor', label: 'Blog editor', subtitle: 'Can fully manage the blog but not other areas of your site.', }), listItemSelectBuilder({ id: 5, title: 'Blog writer', label: 'Blog writer', subtitle: 'Can write and publish posts. Cannot create or manage categories.', }), listItemSelectBuilder({ id: 6, title: 'Guest writer', label: 'Guest writer', subtitle: 'Can write posts but cannot publish them. Posts must be approved and published by a Blog Editor or site owner.', }), listItemSectionBuilder({ type: 'divider', }), listItemSectionBuilder({ title: 'Events roles', }), listItemSelectBuilder({ id: 7, title: 'Events check-in assistant', label: 'Events check-in assistant', subtitle: 'Can see the guest list, check-in guests and scan tickets on the Wix Owner App.', }), ] function includesCaseInsensitive(a = '', b = '') { return !b || a.toLowerCase().indexOf(b.toLowerCase()) !== -1 } return ( <FormField label="Role"> <AutoComplete placeholder="Select" maxHeightPixels="300px" options={options} selectedId={selectedId} value={searchValue} onSelect={(option) => { setSelectedId(option.id) setSearchValue(option.label) }} onChange={(event) => setSearchValue(event.target.value)} predicate={(option) => includesCaseInsensitive(option.label, searchValue.trim()) } /> </FormField> ) } ```