This kit's options
prop requires an array of objects, each of which will be used as the selectable options within the dropdown. Each option object can support any number of key-value pairs, but each must contain label
and value
.
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownDefault = (props) => { const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ]; return ( <div> <Dropdown options={options} /> </div> ) } export default DropdownDefault
The autocomplete
prop can be used to add autocomplete or typeahead functionality to the Dropdown's default Trigger. This prop is set to 'false' by default.
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownWithAutocomplete = (props) => { const options = [ { label: "United States", value: "United States", areaCode: "+1", icon: "πΊπΈ", id: "us" }, { label: "United Kingdom", value: "United Kingdom", areaCode: "+44", icon: "π¬π§", id: "gb" }, { label: "Pakistan", value: "Pakistan", areaCode: "+92", icon: "π΅π°", id: "pk" } ] return ( <div> <Dropdown autocomplete options={options} /> </div> ) } export default DropdownWithAutocomplete
For the subtle
variant, it is recommended that you set the Separators
prop to false
to remove the separator lines between the options for a cleaner look.
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownSubtleVariant = (props) => { const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ]; return ( <> <Dropdown options={options} separators={false} variant="subtle" /> </> ) } export default DropdownSubtleVariant
The dropdown is built using all of the following subcomponents:
Dropdown.Trigger
is the UI component that users interact with to toggle the dropdown.
Dropdown.Container
is the floating container that wraps the list of dropdown options.
Dropdown.Option
renders options that are passed to the container.
Each of these subcomponents can be altered using global props and/or their respective props. See doc examples below for more information on each.
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownSubcomponentStructure = (props) => { const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ]; return ( <div> <Dropdown options={options} > <Dropdown.Trigger/> <Dropdown.Container> {options.map((option) => ( <Dropdown.Option key={option.id} option={option} /> ))} </Dropdown.Container> </Dropdown> </div> ) } export default DropdownSubcomponentStructure
autocomplete
prop can also be used in conjunction with the subcomponent structure.
import React from 'react' import { Dropdown, Badge, Flex, FlexItem, User } from 'playbook-ui' const DropdownWithAutocompleteWithSubcomponents = (props) => { const options = [ { label: "Jasper Furniss", value: "Jasper Furniss", territory: "PHL", title: "Lead UX Engineer", id: "jasper-furniss", status: "Offline" }, { label: "Ramon Ruiz", value: "Ramon Ruiz", territory: "PHL", title: "Senior UX Designer", id: "ramon-ruiz", status: "Away" }, { label: "Carlos Lima", value: "Carlos Lima", territory: "PHL", title: "Nitro Developer", id: "carlos-lima", status: "Online" }, { label: "Courtney Long", value: "Courtney Long", territory: "PHL", title: "Lead UX Designer", id: "courtney-long", status: "Online" } ]; return ( <div> <Dropdown autocomplete options={options} > {options.map((option) => ( <Dropdown.Option key={option.id} option={option} > <Flex align="center" justify="between" > <FlexItem> <User align="left" avatar name={option.label} orientation="horizontal" territory={option.territory} title={option.title} /> </FlexItem> <FlexItem> <Badge dark rounded text={option.status} variant={`${ option.status === "Offline" ? "neutral" : option.status === "Online" ? "success" : "warning" }`} /> </FlexItem> </Flex> </Dropdown.Option> ))} </Dropdown> </div> ) } export default DropdownWithAutocompleteWithSubcomponents
The top-level Dropdown component optionally accepts any string through a label
prop to produce a label above your trigger element.
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownDefault = (props) => { const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ]; return ( <div> <Dropdown label="Select a Country" options={options} > {options.map((option) => ( <Dropdown.Option key={option.id} option={option} /> ))} </Dropdown> </div> ) } export default DropdownDefault
Dropdown.Option
subcomponent accepts any child components to customize the options' contents and display. By default, options are Body kit text that is set by the label
value from the option
object.
import React from 'react' import { Dropdown, FlexItem, Icon, Body, Flex } from 'playbook-ui' const DropdownWithCustomOptions = (props) => { const options = [ { label: "United States", value: "United States", areaCode: "+1", icon: "πΊπΈ", id: "United-states" }, { label: "Canada", value: "Canada", areaCode: "+1", icon: "π¨π¦", id: "canada" }, { label: "Pakistan", value: "Pakistan", areaCode: "+92", icon: "π΅π°", id: "pakistan" } ]; return ( <div> <Dropdown options={options} > {options.map((option) => ( <Dropdown.Option key={option.id} option={option} > <Flex align="center" justify="between" > <FlexItem> <Flex> <Icon icon={option.icon} paddingRight="xs" /> <Body text={option.label} /> </Flex> </FlexItem> <FlexItem> <Body color="light" text={option.areaCode} /> </FlexItem> </Flex> </Dropdown.Option> ))} </Dropdown> </div> ) } export default DropdownWithCustomOptions
Optionally utilize customDisplay
on the Dropdown.Trigger
subcomponent to customize its content after an option is selected. The component passed to customDisplay will be rendered to the left of the default text-based display. In this example the Avatar kit is being used.
The placeholder
prop can also be used to customize the placeholder text for the default Dropdown.Trigger
.
The onSelect
prop returns the selected option as an object to be utilized by the dev. In this example we are using the onSelect
to set a state with the selected option and using it to customize the customDisplay
.
import React, { useState } from 'react' import { Dropdown, Badge, Flex, FlexItem, Avatar, User } from 'playbook-ui' const DropdownWithCustomDisplay = (props) => { const [selectedOption, setSelectedOption] = useState(); const options = [ { label: "Jasper Furniss", value: "Jasper Furniss", territory: "PHL", title: "Lead UX Engineer", id: "jasper-furniss", status: "Offline" }, { label: "Ramon Ruiz", value: "Ramon Ruiz", territory: "PHL", title: "Senior UX Designer", id: "ramon-ruiz", status: "Away" }, { label: "Carlos Lima", value: "Carlos Lima", territory: "PHL", title: "Nitro Developer", id: "carlos-lima", status: "Online" }, { label: "Courtney Long", value: "Courtney Long", territory: "PHL", title: "Lead UX Designer", id: "courtney-long", status: "Online" } ]; const CustomDisplay = () => { return ( <> { selectedOption && ( <Avatar name={selectedOption.label} size="xs" /> ) } </> ) }; return ( <div> <Dropdown onSelect={(selectedItem) => setSelectedOption(selectedItem)} options={options} > <Dropdown.Trigger customDisplay={<CustomDisplay/>} placeholder="Select a User" /> {options.map((option) => ( <Dropdown.Option key={option.id} option={option} > <Flex align="center" justify="between" > <FlexItem> <User align="left" avatar name={option.label} orientation="horizontal" territory={option.territory} title={option.title} /> </FlexItem> <FlexItem> <Badge dark rounded text={option.status} variant={`${ option.status === "Offline" ? "neutral" : option.status === "Online" ? "success" : "warning" }`} /> </FlexItem> </Flex> </Dropdown.Option> ))} </Dropdown> </div> ) } export default DropdownWithCustomDisplay
Optionally replace the default trigger's select element by passing child components directly to the Dropdown.Trigger
.
import React, { useState } from 'react' import { Dropdown, FlexItem, Icon, Body, Flex, IconCircle } from 'playbook-ui' const DropdownWithCustomTrigger = (props) => { const [selectedOption, setSelectedOption] = useState(); const options = [ { label: "United States", value: "United States", areaCode: "+1", icon: "πΊπΈ", id: "United-states" }, { label: "Canada", value: "Canada", areaCode: "+1", icon: "π¨π¦", id: "canada" }, { label: "Pakistan", value: "Pakistan", areaCode: "+92", icon: "π΅π°", id: "pakistan" } ]; return ( <div> <Dropdown onSelect={(selectedItem) => setSelectedOption(selectedItem)} options={options} > <Dropdown.Trigger> <div key={selectedOption ? selectedOption.icon : "flag"}> <IconCircle cursor="pointer" icon={selectedOption ? selectedOption.icon : "flag"} variant="royal" /> </div> </Dropdown.Trigger> <Dropdown.Container maxWidth="xs"> {options.map((option) => ( <Dropdown.Option key={option.id} option={option} > <Flex align="center" justify="between" > <FlexItem> <Flex> <Icon icon={option.icon} paddingRight="xs" /> <Body text={option.label} /> </Flex> </FlexItem> <FlexItem> <Body color="light" text={option.areaCode} /> </FlexItem> </Flex> </Dropdown.Option> ))} </Dropdown.Container> </Dropdown> </div> ) } export default DropdownWithCustomTrigger
The optional searchbar
boolean prop can also be used on the Dropdown.Container
to render a searchbar with typeahead functionality within the dropdown itself. This is especially useful when a custom trigger is being used.
searchbar
is set to false by default.
import React, { useState } from 'react' import { Dropdown, IconCircle } from 'playbook-ui' const DropdownWithSearch = (props) => { const [selectedOption, setSelectedOption] = useState(); const options = [ { label: "United States", value: "United States", icon: "πΊπΈ", id: "United-states" }, { label: "United Kingdom", value: "United Kingdom", icon: "π¬π§", id: "united-kingdom" }, { label: "Pakistan", value: "Pakistan", icon: "π΅π°", id: "pakistan" } ]; return ( <div> <Dropdown onSelect={(selectedItem) => setSelectedOption(selectedItem)} options={options} > <Dropdown.Trigger> <div key={selectedOption ? selectedOption.icon : "flag"}> <IconCircle cursor="pointer" icon={selectedOption ? selectedOption.icon : "flag"} variant="royal" /> </div> </Dropdown.Trigger> <Dropdown.Container maxWidth="xs" searchbar > {options.map((option) => ( <Dropdown.Option key={option.id} option={option} /> ))} </Dropdown.Container> </Dropdown> </div> ) } export default DropdownWithSearch
By default, dropdown option paddingX is set to sm
and paddingY is set to xs
, but this padding can be overridden using our global padding props. In this example we are setting the option padding to sm
all around.
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownWithCustomPadding = (props) => { const options = [ { label: "United States", value: "United States", areaCode: "+1", icon: "πΊπΈ", id: "United-states" }, { label: "Canada", value: "Canada", areaCode: "+1", icon: "π¨π¦", id: "canada" }, { label: "Pakistan", value: "Pakistan", areaCode: "+92", icon: "π΅π°", id: "pakistan" } ]; return ( <div> <Dropdown options={options} > {options.map((option) => ( <Dropdown.Option key={option.id} option={option} padding="sm" /> ))} </Dropdown> </div> ) } export default DropdownWithCustomPadding
import React, { useState } from 'react' import { Dropdown, Icon } from 'playbook-ui' const DropdownError = (props) => { const [selectedOption, setSelectedOption] = useState() const error = selectedOption?.value ? null : (<> <Icon icon="warning" /> Please make a valid selection </>) const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ] return ( <> <Dropdown error={error} onSelect={(selectedItem) => setSelectedOption(selectedItem)} options={options} /> </> ) } export default DropdownError
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownDefaultValue = (props) => { const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ]; return ( <> <Dropdown defaultValue={options[2]} options={options} /> </> ) } export default DropdownDefaultValue
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownBlankSelection = (props) => { const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ]; return ( <> <Dropdown blankSelection="Select one..." options={options} /> </> ) } export default DropdownBlankSelection
To use an external control (like a reset button) to clear Dropdown selection, you can make use of the useRef
hook. You must pass a ref to the Dropdown component and use that ref within the onClick for the external control in the way shown in the code snippet below.
import React, { useRef } from 'react' import { Button, Dropdown } from 'playbook-ui' const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ] const DropdownClearSelection = (props) => { const dropdownRef = useRef(null) const handleReset = () => { if (dropdownRef.current) { dropdownRef.current.clearSelected() } } return ( <> <Dropdown defaultValue={options[2]} options={options} ref={dropdownRef} /> <Button marginTop="md" onClick={handleReset} text="Reset" /> </> ) } export default DropdownClearSelection
import React from 'react' import { Dropdown } from 'playbook-ui' const DropdownSeparatorsHidden = (props) => { const options = [ { label: "United States", value: "United States", }, { label: "Canada", value: "Canada", }, { label: "Pakistan", value: "Pakistan", } ]; return ( <div> <Dropdown options={options} separators={false} /> </div> ) } export default DropdownSeparatorsHidden
The useDropdown
hook can also be used to toggle the dropdown open and closed using an external control. To do so, you must manage state with the custom hook, pass the dropdown:'pb-dropdown-trigger'
data attribute to the external control and use the isClosed
prop as shown.
import React from 'react' import { Dropdown, useDropdown, Button } from 'playbook-ui' const DropdownWithExternalControl = (props) => { const [isDropDownClosed, setIsDropdownClosed] = useDropdown(true); const options = [ { label: "United States", value: "United States", areaCode: "+1", icon: "πΊπΈ", id: "United-states" }, { label: "Canada", value: "Canada", areaCode: "+1", icon: "π¨π¦", id: "canada" }, { label: "Pakistan", value: "Pakistan", areaCode: "+92", icon: "π΅π°", id: "pakistan" } ]; return ( <div> <Button data={{dropdown:'pb-dropdown-trigger'}} marginBottom='sm' onClick={() => setIsDropdownClosed(!isDropDownClosed)} padding="none" tabIndex={0} variant="link" > {isDropDownClosed ? "Open Dropdown" : "Close Dropdown"} </Button> <Dropdown isClosed={isDropDownClosed} options={options} > {options.map((option) => ( <Dropdown.Option key={option.id} option={option} /> ))} </Dropdown> </div> ) } export default DropdownWithExternalControl