Skip to main content
/
/
/
Dropdown

Dropdown

import Dropdown from "@intility/bifrost-react/Dropdown";

Rewritten in 5.0

Single child element

The nested content of <Dropdown> needs to be a single element able to hold a ref, unless an element reference is passed to the reference prop. It should work with most Bifrost components and default html elements.

Basic Dropdown

Renders a dropdown with content when a user clicks (or taps) on its children. Use a focusable element (like <Button>) to make sure it's accessible for keyboard users.

Not to be confused with <Select> or <Tooltip>

<Dropdown content={<div>Dropdown content</div>}> <Button>Click to show dropdown</Button> </Dropdown>
<Dropdown content={<div>Dropdown content</div>}> <Button>Click to show dropdown</Button> </Dropdown>

Placement

The dropdown will be aligned to the left ('bottom-start') by default, but you can place it anywhere you like by using the placement prop supplied by floating-ui

For example, you can use bottom-end to align the dropdown to the bottom right.

<Dropdown content={<div>Dropdown content</div>}> <Button>Default (bottom-start)</Button> </Dropdown> <Dropdown content={<div>Dropdown content</div>} placement='bottom-end'> <Button>bottom-end</Button> </Dropdown>
<Dropdown content={<div>Dropdown content</div>}> <Button>Default (bottom-start)</Button> </Dropdown> <Dropdown content={<div>Dropdown content</div>} placement='bottom-end'> <Button>bottom-end</Button> </Dropdown>

You can create a dropdown menu by styling <button> with an optional icon using <Dropdown.Item>.

For links we recommend placing a <Box.Arrow> (using <Inline>) on the right-hand side.

Optionally use <hr /> to separate sections.

<Dropdown content={ <> <button type="button"> <Dropdown.Item>Button</Dropdown.Item> </button> <button type="button"> <Dropdown.Item icon={faCheck}>With icon</Dropdown.Item> </button> <a href="#path"> <Dropdown.Item icon={faUserCircle}> <Inline align="center"> <Inline.Stretch>Link with arrow</Inline.Stretch> <Box.Arrow /> </Inline> </Dropdown.Item> </a> <a href="https://www.intility.com" target="_blank"> <Dropdown.Item icon={faGlobe}> <Inline align="center"> <Inline.Stretch>External link</Inline.Stretch> <Box.Arrow external /> </Inline> </Dropdown.Item> </a> <hr /> <button type="button"> <Dropdown.Item> <Icon color="var(--bfc-base-c-success)" icon={faCheck} marginRight /> Custom icon </Dropdown.Item> </button> </> } > <Button>Dropdown.Item examples</Button> </Dropdown>
<Dropdown content={ <> <button type="button"> <Dropdown.Item>Button</Dropdown.Item> </button> <button type="button"> <Dropdown.Item icon={faCheck}>With icon</Dropdown.Item> </button> <a href="#path"> <Dropdown.Item icon={faUserCircle}> <Inline align="center"> <Inline.Stretch>Link with arrow</Inline.Stretch> <Box.Arrow /> </Inline> </Dropdown.Item> </a> <a href="https://www.intility.com" target="_blank"> <Dropdown.Item icon={faGlobe}> <Inline align="center"> <Inline.Stretch>External link</Inline.Stretch> <Box.Arrow external /> </Inline> </Dropdown.Item> </a> <hr /> <button type="button"> <Dropdown.Item> <Icon color="var(--bfc-base-c-success)" icon={faCheck} marginRight /> Custom icon </Dropdown.Item> </button> </> } > <Button>Dropdown.Item examples</Button> </Dropdown>
New in 5.0

The <Dropdown.Group> component provides a styled button for nested dropdown menu hierarchy. It's meant to be used inside content of <Dropdown>.

  • name prop for labelling the button (supports JSX)
  • Optional icon prop, styled equivalent to <Dropdown.Item icon>
  • children content will be placed inside a toggleable sub-dropdown
<Dropdown content={ <Dropdown.Group name="Group"> <Dropdown.Item>Item 1</Dropdown.Item> <Dropdown.Item>Item 2</Dropdown.Item> </Dropdown.Group> } > <Button>Two levels</Button> </Dropdown>
<Dropdown content={ <Dropdown.Group name="Group"> <Dropdown.Item>Item 1</Dropdown.Item> <Dropdown.Item>Item 2</Dropdown.Item> </Dropdown.Group> } > <Button>Two levels</Button> </Dropdown>

You can also nest them inside eachother, although we recommend keeping it to as few levels as possible for usability.

<Dropdown content={ <Dropdown.Group name="Group"> <Dropdown.Group name="Nested Group A"> <Dropdown.Item>Item A1</Dropdown.Item> <Dropdown.Item>Item A2</Dropdown.Item> </Dropdown.Group> <Dropdown.Group name="Nested Group B"> <Dropdown.Item>Item B1</Dropdown.Item> <Dropdown.Item>Item B2</Dropdown.Item> </Dropdown.Group> </Dropdown.Group> } > <Button>Three levels</Button> </Dropdown>
<Dropdown content={ <Dropdown.Group name="Group"> <Dropdown.Group name="Nested Group A"> <Dropdown.Item>Item A1</Dropdown.Item> <Dropdown.Item>Item A2</Dropdown.Item> </Dropdown.Group> <Dropdown.Group name="Nested Group B"> <Dropdown.Item>Item B1</Dropdown.Item> <Dropdown.Item>Item B2</Dropdown.Item> </Dropdown.Group> </Dropdown.Group> } > <Button>Three levels</Button> </Dropdown>

Controlled state

By passing a boolean to the visible prop you can control programmatically whether the dropdown is open. Keep your state in sync with an onHide handler.

import { useState } from "react";
import Dropdown from "@intility/bifrost-react/Dropdown";
import Button from "@intility/bifrost-react/Button";

export default function () {
  const [open, setOpen] = useState(false);
  return (
    <Dropdown
      content={<div>Click anywhere outside to close me</div>}
      visible={open}
      onHide={() => setOpen(false)}
    >
      <Button onClick={() => setOpen(!open)}>Click me to toggle</Button>
    </Dropdown>
  );
}