Dropdown
A form input for making a single selection from a list of items.
- Install
npm install @pluralsight/ps-design-system-dropdown
- Import
import Dropdown from '@pluralsight/ps-design-system-dropdown'
Examples
Controlling with value
Selected: int
import React from 'react'import Dropdown from '@pluralsight/ps-design-system-dropdown'import Button from '@pluralsight/ps-design-system-button'function Example() {const options = [{ value: 'beg', label: 'Beginner' },{ value: 'int', label: 'Intermediate' },{ value: 'adv', label: 'Advanced' }]const [value, setValue] = React.useState(options[1].value)return (<div className="example-flex-column"><Dropdownlabel="Level"placeholder="Select"onChange={(evt, value, label) => setValue(value)}menu={options.map(opt => (<Dropdown.Item key={opt.value} value={opt.value}>{opt.label}</Dropdown.Item>))}value={value}/><div>Selected: {value}</div><div><Buttonappearance="secondary"size="xSmall"onClick={() => setValue('beg')}>Set Beginner</Button></div></div>)}export default Example
Label
Primary identification of a dropdown comes through the label. Usage hints are given in the placeholder. Supporting text and error messaging is set in the subLabel.
Which audience is this course aimed at?
import React from 'react'import Dropdown from '@pluralsight/ps-design-system-dropdown'const Comp = () => (<div className="example-flex-column"><Dropdownlabel="Level"placeholder="Select level"subLabel="Which audience is this course aimed at?"menu={<><Dropdown.Item>Beginner</Dropdown.Item><Dropdown.Item>Intermediate</Dropdown.Item><Dropdown.Item>Advanced</Dropdown.Item></>}/></div>)export default Comp
Appearance
When using the dark theme, a subtle
appearance is available. (Switch theme to dark)
import React from 'react'import Dropdown from '@pluralsight/ps-design-system-dropdown'const Comp = () => (<Dropdownappearance={Dropdown.appearances.subtle}label="Level"placeholder="Select level"menu={<React.Fragment><Dropdown.Item>Beginner</Dropdown.Item><Dropdown.Item>Intermediate</Dropdown.Item><Dropdown.Item>Advanced</Dropdown.Item></React.Fragment>}/>)export default Comp
Sizes
For table rows, step down to the small
size.
import React from 'react'import Dropdown from '@pluralsight/ps-design-system-dropdown'const Comp = () => (<div className="example-flex-column"><Dropdownplaceholder="Medium dropdown"menu={<><Dropdown.Item>Beginner</Dropdown.Item><Dropdown.Item>Intermediate</Dropdown.Item><Dropdown.Item>Advanced</Dropdown.Item></>}/><Dropdownsize={Dropdown.sizes.small}placeholder="Small dropdown"menu={<><Dropdown.Item>Beginner</Dropdown.Item><Dropdown.Item>Intermediate</Dropdown.Item><Dropdown.Item>Advanced</Dropdown.Item></>}/></div>)export default Comp
Disabled
Disabled dropdowns are unmodifiable, not interactive, and diminished visually.
import React from 'react'import Dropdown from '@pluralsight/ps-design-system-dropdown'const Comp = () => (<Dropdown disabled label="Can't touch this" placeholder="Just try it" />)export default Comp
Error
Error states are engaged with the error
flag. Error-related messaging is sent to the subLabel
prop.
import React from 'react'import Dropdown from '@pluralsight/ps-design-system-dropdown'const Comp = () => (<Dropdownerrorlabel="Level"placeholder="Select level"menu={<><Dropdown.Item>Beginner</Dropdown.Item><Dropdown.Item>Intermediate</Dropdown.Item><Dropdown.Item>Advanced</Dropdown.Item></>}/>)export default Comp
Customizing with icon
import React from 'react'import Dropdown, { useDropdown } from '@pluralsight/ps-design-system-dropdown'import { CalendarIcon } from '@pluralsight/ps-design-system-icon'interface DropdownWithIconProps extends HTMLAttributes<HTMLButtonElement> {icon: React.ReactNodemenu: React.ReactNode}const DropdownWithIcon = React.forwardRef<HTMLButtonElement,DropdownWithIconProps>(({ icon, ...props }, forwardedRef) => {const allProps = useDropdown(props, forwardedRef)return (<Dropdown.Layout{...allProps.layout}label={<Dropdown.Label {...allProps.label} />}menu={<DropdownContext.Provider {...allProps.value}><Dropdown.Menu {...allProps.menu} /></DropdownContext.Provider>}subLabel={<Dropdown.SubLabel {...allProps.subLabel} />}button={<Dropdown.Button {...allProps.button}>{icon}<div style={{ height: '100%', position: 'relative', flex: 1 }}><Dropdown.Selected {...allProps.selected} /></div></Dropdown.Button>}/>)})function Example() {return (<DropdownWithIconicon={<CalendarIcon style={{ marginRight: 8 }} />}menu={<><Dropdown.Item>Trailing 14 Days</Dropdown.Item><Dropdown.Item>Last Month</Dropdown.Item><Dropdown.Item>Trailing 30 Days</Dropdown.Item><Dropdown.Item>Last Quater</Dropdown.Item><Dropdown.Item>Trailing 90 Days</Dropdown.Item><Dropdown.Item>Custom</Dropdown.Item></>}/>)}export default Example
Customizing with dynamic icon
import React, { HTMLAttributes } from 'react'import Dropdown, { useDropdown } from '@pluralsight/ps-design-system-dropdown'import { CalendarIcon } from '@pluralsight/ps-design-system-icon'interface DropdownWithIconPropsextends Omit<HTMLAttributes<HTMLButtonElement>, 'onChange'> {icon: React.ReactNodeonChange?: (e: React.MouseEvent, value: React.ReactText) => voidmenu: React.ReactNode}const DropdownWithIcon = React.forwardRef<HTMLButtonElement,DropdownWithIconProps>(({ icon, ...props }, forwardedRef) => {const allProps = useDropdown(props, forwardedRef)return (<Dropdown.Layout{...allProps.layout}label={<Dropdown.Label {...allProps.label} />}menu={<DropdownContext.Provider {...allProps.value}><Dropdown.Menu {...allProps.menu} /></DropdownContext.Provider>}subLabel={<Dropdown.SubLabel {...allProps.subLabel} />}button={<Dropdown.Button {...allProps.button}>{icon}<div style={{ height: '100%', position: 'relative', flex: 1 }}><Dropdown.Selected {...allProps.selected} /></div></Dropdown.Button>}/>)})function Example() {const [selected, setSelected] = React.useState<null | string>()const values = {channel: {value: 'channel',icon: <ChannelIcon style={{ marginRight: 8 }} />,label: 'Channel'},analytics: {value: 'analytics',icon: <AnalyticsIcon style={{ marginRight: 8 }} />,label: 'Analytics'},authorKit: {value: 'authorKit',icon: <AuthorKitIcon style={{ marginRight: 8 }} />,label: 'Author Kit'},labs: {value: 'labs',icon: <LabsIcon style={{ marginRight: 8 }} />,label: 'Labs'}}const handleChange = (e: React.MouseEvent, value: React.ReactText) => {setSelected(value)}const icon = values[selected] ? (values[selected].icon) : (<div style={{ width: 24, height: 24, marginRight: 8 }} />)return (<DropdownWithIconicon={icon}onChange={handleChange}menu={Object.values(values).map(({ value, icon, label }) => (<Dropdown.Item value={value} key={value} icon={icon}>{label}</Dropdown.Item>))}/>)}export default Example
Menu scrolling
The dropdown component menu has a max height of 400px and will scroll for content needing more vertical space.
import React from 'react'import Dropdown from '@pluralsight/ps-design-system-dropdown'const Example = () => (<Dropdownlabel="Max height example"menu={<><Dropdown.Item>One item</Dropdown.Item><Dropdown.Item>Two item</Dropdown.Item><Dropdown.Item>Three item</Dropdown.Item><Dropdown.Item>Four item</Dropdown.Item><Dropdown.Item>Five item</Dropdown.Item><Dropdown.Item>Six item</Dropdown.Item><Dropdown.Item>Seven item</Dropdown.Item><Dropdown.Item>Eight item</Dropdown.Item><Dropdown.Item>Nine item</Dropdown.Item><Dropdown.Item>Ten item</Dropdown.Item><Dropdown.Item>Eleven item</Dropdown.Item><Dropdown.Item>Twelve item</Dropdown.Item><Dropdown.Item>Thirteen item</Dropdown.Item><Dropdown.Item>Fourteen item</Dropdown.Item><Dropdown.Item>Fifteen item</Dropdown.Item></>}/>)export default Example
Accessibility
WCAG 2.1 AA Compliance
100% axe-core testsNo manual audit
WAI-ARIA Patterns: Listbox
Props
Dropdown
Name | Type | Description | Default |
---|---|---|---|
appearance |
| visual style (from Dropdown.appearances) | default |
disabled | boolean | standard input disabled flag |
|
error | boolean | error state flag |
|
label | string | identifying string for dropdown |
|
menu | Dropdown.Item(s) | menu items for dropdown | <span></span> |
onChange | (Event, value, label) => void | triggered when an item selected |
|
placeholder | string | in-field usage hint |
|
size |
| sets dropdown size (from Dropdown.sizes) | medium |
subLabel | string | supporting text or error messaging |
|
uniqueId | (prefix: string) => string | override internal id generation for test stability |
|
Dropdown.Item
Name | Type | Description | Default |
---|---|---|---|
disabled | boolean | visually disabled, non-interactive |
|
icon | *Icon | An Icon component |
|
onClick | (Event, value) => void | override default onClick behavior passed to Dropdown.props.onChange |
|
value | string | number | value sent to ActionMenu#onChange |
|