Dashboard UI Kit

Apps PreviewDownload Design Package

Dropdown

import { Dropdown, DropdownItem, DropdownMenu } from '@duik/it'
import Dropdown, { DropdownItem, DropdownMenu } from '@duik/dropdown'

Use buttons in forms, as links with many varieties.

Basic Usage

You can control apperence by simply passing boolean props to render some predefined stylings or you can pass your className or style props as well.

<Dropdown buttonText={<strong>Click me</strong>}>
<DropdownItem>Item 1</DropdownItem>
<DropdownItem>Item 2</DropdownItem>
<DropdownItem Component={Link} to="#somewhere">Item as Link</DropdownItem>
</Dropdown>
ReactHTML Snippet

Close on option click

By default, the dropdown doesn't close when you click on the dropdown item. This is intentional. If you want to close the dropdown after clicking the option, you can pass closeOnOptionClick prop as true. If you want to have a better control and decide per item, then check the example below.

<Dropdown buttonText={<strong>Click me</strong>}>
<DropdownItem>Item 1</DropdownItem>
<DropdownItem>Item 2</DropdownItem>
<DropdownItem Component={Link} to="#somewhere">Item as Link</DropdownItem>
</Dropdown>
ReactHTML Snippet

Better control over the dropdown

It wouldn't be really useful if you cannot control the state of the dropdown, for example you want to close the dropdown on selecting an option. Surely this could be implemented directly, but with this approach, we are giving you a better control over the state rather than enforcing the behaviour, especially when there are many use cases where you don't really want to close the dropdown.

<Dropdown>
  {({ handleClose, handleOpen, handleToggle, setOpenState, isOpen }) => (
    <>
      <DropdownItem>Item 1</DropdownItem>
      <DropdownItem onClick={handleClose}>Item 2 with close</DropdownItem>
    </>
  )}
</Dropdown>
ReactHTML Snippet

As it is clear from example, children can be a classic ReactNode or in this case a functional component format (props) => <>Something</> which can accept several handlers. In most cases, you want to use handleClose or handleToggle, but for conveniency, other handlers are exposed as well.

The handlers are documented in useOpenState hook documentation, which is used for handling the state of the dropdown.

By default, the menu position is set to bottom-right (bottom from the click element, overflowing to the right). You can change this by passing menuPosition prop. These values are supported

  • bottom-left
  • bottom-center
  • bottom-right
  • top-left
  • top-center
  • top-right
  • left-top
  • left-center
  • left-bottom
  • right-top
  • right-center
  • right-bottom

For Typescript, enum DropdownMenuPosition is available.

If the menu doesn't fit the window viewport, the default menu component will try to reposition itself automatically. You would need to perform this action by yourself if you use custom MenuComponent as a prop.

<Dropdown buttonText="Bottom Left" menuPosition="bottom-left">
  <DropdownItem>
    Long Item to click
  </DropdownItem>
</Dropdown>
ReactHTML Snippet
<Dropdown buttonText="Top Center" menuPosition="top-center">
  <DropdownItem>
    Long Item to click
  </DropdownItem>
</Dropdown>
ReactHTML Snippet
<Dropdown buttonText="Left Center" menuPosition="left-center">
  <DropdownItem>
    Dropdown Item
  </DropdownItem>
  <DropdownItem>
    Dropdown Item
  </DropdownItem>
  <DropdownItem>
    Dropdown Item
  </DropdownItem>
</Dropdown>
ReactHTML Snippet
<Dropdown buttonText="Right Bottom" menuPosition="right-bottom">
  <DropdownItem>
    Dropdown Item
  </DropdownItem>
  <DropdownItem>
    Dropdown Item
  </DropdownItem>
  <DropdownItem>
    Dropdown Item
  </DropdownItem>
</Dropdown>
ReactHTML Snippet

In the previous examples, only DropdownItem has been used. However this doesn't mean that Dropdown limited to it. Let's render custom dropdown content.

<Dropdown
  buttonText="Upgrade Account"
  menuPosition="bottom-left"
>
  {({ handleClose, handleOpen, handleToggle, setOpenState, isOpen }) => (
    <div style={{ padding: 30, minWidth: 360 }}>
      <h3>Would you like to upgrade your account for $10?</h3>
      <div>
        <Button primary onClick={handleClose}>Upgrade to PRO</Button>
        <Button onClick={handleClose}>Maybe later</Button>
      </div>
    </div>
  )}
</Dropdown>
ReactHTML Snippet

Custom Button Component

You have 2 ways how to customize the button.

Simpler way, the clickable button component is @duik/button in it's core. You can customize it by passing props to it with "buttonProps". See example below.

<Dropdown
  buttonProps={{
    primary: true
  }}
  menuPosition="bottom-left"
>
  <DropdownItem>
    Item to click
  </DropdownItem>
</Dropdown>
ReactHTML Snippet

Hide the up down arrow

<Dropdown
  buttonProps={{
    hideArrows: true,
    primary: true
  }}
  menuPosition="bottom-left"
>
  <DropdownItem>
    Item to click
  </DropdownItem>
</Dropdown>
ReactHTML Snippet

You can also define totally new Button component and pass it to the Dropdown! Your component should accept useOpenState handlers. See example below.

import { DropdownButtonProps, Button } from '@duik/it'

// Defining button (TS), don't forget class "dropdown-toggle"
const ExampleButton = ({
  // useOpenState hook handlers
  handleToggle, handleClose, handleOpen, setOpenState, isOpen
}: DropdownButtonProps) => (
  <Button success onClick={handleToggle} square>
    <Icon>edit</Icon>
  </Button>
)

// Using custom button
<Dropdown ButtonComponent={ExampleButton}>
  <DropdownItem>Item to click</DropdownItem>
</Dropdown>
ReactHTML Snippet

Dropdown Props

children

false

type: React.ReactNode or React.FunctionalComponent
You can pass regular react node or a render prop which can accepts several handlers to control the UI state. Your functional component will receive useOpenState controls as props.
className

false

type: string
Passed to the wrapping element OuterEventsHandler
buttonText

false

type: React.ReactNode

default value: "Actions"

Text or node you want to appear in the button.
ButtonComponent

false

type: React.FunctionalComponent

default value: DropdownButton

You can pass your custom button component. Your component will receive set of useOpenState controls as props.
buttonProps

false

type: Props of ButtonComponent
This comes handy if you want to pass some props to the button without defining a new ButtonComponent, such as className etc.
menuPosition

false

type: DropdownMenuPosition

default value: "bottom-right"

See Menu Positioning for more details
MenuComponent

false

type: React.FunctionalComponent

default value: DropdownMenu

You can pass your custom menu component. Your component will receive set of useOpenState controls as props.
menuProps

false

type: Props of MenuComponent
This comes handy if you want to pass some props to the button without defining a new MenuComponent, such as className etc.
...rest

false

type: any
Other properties are passed down to the wrapping element OuterEventsHandler

DropdownItem Props

DropdownItem is just a styled Button component and it supports all the props that are accepted by the Button, including appearence, sizes, Component prop and others.