# React Bootstrap Dropdowns

React Bootstrap dropdown components positioned with Floating UI: button and split dropdowns, menu alignment, drop directions, auto close and keyboard support.

A dropdown tucks a list of actions or links behind one button, so they are close at hand without taking up room. The navbar menus of AdminKit are dropdowns.

Three React components build them: `Dropdown`, `DropdownToggle` and `DropdownMenu`. They open Bootstrap's dropdown menus from React state, without Bootstrap's JavaScript or react-bootstrap. They are in the free and PRO versions of [AdminKit for React](/react/).

You write Bootstrap's markup and classes. The components add `.show`, the ARIA attributes and the keyboard handling. The Floating UI library positions the menu 2px from the toggle, and flips it when there is no room.

## Example

Give the `Dropdown` wrapper the `dropdown` or `btn-group` class, since it adds no class of its own. The toggle needs `dropdown-toggle` for its caret.

```html
<div class="dropdown">
  <button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
    Actions
  </button>
  <ul class="dropdown-menu">
    <li><a class="dropdown-item" href="#">Edit</a></li>
    <li><a class="dropdown-item" href="#">Duplicate</a></li>
    <li><hr class="dropdown-divider"></li>
    <li><a class="dropdown-item" href="#">Archive</a></li>
  </ul>
</div>
```
```tsx code
import {
  Dropdown,
  DropdownMenu,
  DropdownToggle,
} from "@/components/bootstrap/dropdown";

export function ProjectActions() {
  return (
    <Dropdown className="dropdown">
      <DropdownToggle as="button" className="btn btn-primary dropdown-toggle">
        Actions
      </DropdownToggle>
      <DropdownMenu as="ul">
        <li><a className="dropdown-item" href="#">Edit</a></li>
        <li><a className="dropdown-item" href="#">Duplicate</a></li>
        <li><hr className="dropdown-divider" /></li>
        <li><a className="dropdown-item" href="#">Archive</a></li>
      </DropdownMenu>
    </Dropdown>
  );
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `as` | `ElementType` | `"div"` | The wrapper element, such as `"li"` in a navbar |
| `display` | `"dynamic" \| "static"` | `"dynamic"` | `"dynamic"` positions the menu with Floating UI; `"static"` leaves it where the CSS puts it, as in the navbar |
| `strategy` | `"absolute" \| "fixed"` | `"absolute"` | `"fixed"` positions the menu relative to the window, so it escapes containers that clip or scroll |
| `autoClose` | `boolean \| "inside" \| "outside"` | `true` | Which clicks close the menu, see [Auto close](#auto-close) |
| `drop` | `"down" \| "up" \| "start" \| "end"` | from the class | The side the menu opens on; read from `dropup`, `dropend` or `dropstart` in `className` |

Other props of `Dropdown`, such as `className`, go to the wrapper. The components are in `src/components/bootstrap/dropdown.tsx`.

- `DropdownToggle` is a link (`<a href="#" role="button">`) unless `as="button"`, which gets `type="button"`. It sets `aria-expanded` and `aria-controls` and gets `.show` while the menu is open. Its `onClick` and `onKeyDown` still run.
- `DropdownMenu` takes `as` (`"div"` by default) and `align` (`"start"` or `"end"`, read from `.dropdown-menu-end` by default). It adds `.dropdown-menu`.

## Split button

Use a split button when one action is the obvious choice and the others can wait in a menu. It is a `btn-group` with a normal button and a toggle with `dropdown-toggle-split`:

```html
<div class="btn-group">
  <button type="button" class="btn btn-success">Publish</button>
  <button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
    <span class="visually-hidden">More publish options</span>
  </button>
  <ul class="dropdown-menu">
    <li><a class="dropdown-item" href="#">Schedule</a></li>
    <li><a class="dropdown-item" href="#">Save as draft</a></li>
  </ul>
</div>
```
```tsx code
<Dropdown className="btn-group">
  <button type="button" className="btn btn-success" onClick={publish}>
    Publish
  </button>
  <DropdownToggle as="button" className="btn btn-success dropdown-toggle dropdown-toggle-split">
    <span className="visually-hidden">More publish options</span>
  </DropdownToggle>
  <DropdownMenu as="ul">
    <li><a className="dropdown-item" href="#">Schedule</a></li>
    <li><a className="dropdown-item" href="#">Save as draft</a></li>
  </DropdownMenu>
</Dropdown>
```

## Alignment and direction

Near the edge of the screen, or at the bottom of a card, you may want the menu somewhere else. `dropdown-menu-end` on the menu aligns it to the end of the toggle. `dropup`, `dropend` and `dropstart` on the wrapper open it above, to the right or to the left. The components read these classes, and the `align` and `drop` props set the same without them.

```html
<div class="btn-group me-2">
  <button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">End aligned</button>
  <ul class="dropdown-menu dropdown-menu-end">
    <li><a class="dropdown-item" href="#">Menu item</a></li>
    <li><a class="dropdown-item" href="#">Menu item</a></li>
  </ul>
</div>
<div class="btn-group dropup">
  <button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropup</button>
  <ul class="dropdown-menu">
    <li><a class="dropdown-item" href="#">Menu item</a></li>
    <li><a class="dropdown-item" href="#">Menu item</a></li>
  </ul>
</div>
```
```tsx code
<>
  <Dropdown className="btn-group me-2">
    <DropdownToggle as="button" className="btn btn-secondary dropdown-toggle">End aligned</DropdownToggle>
    <DropdownMenu as="ul" className="dropdown-menu-end">
      <li><a className="dropdown-item" href="#">Menu item</a></li>
      <li><a className="dropdown-item" href="#">Menu item</a></li>
    </DropdownMenu>
  </Dropdown>
  <Dropdown className="btn-group dropup">
    <DropdownToggle as="button" className="btn btn-secondary dropdown-toggle">Dropup</DropdownToggle>
    <DropdownMenu as="ul">
      <li><a className="dropdown-item" href="#">Menu item</a></li>
      <li><a className="dropdown-item" href="#">Menu item</a></li>
    </DropdownMenu>
  </Dropdown>
</>
```

In a table or a scrolling card, the container can cut off the menu. `strategy="fixed"` positions it relative to the window instead, as the menus of the tasks board and the AI chat history in AdminKit PRO do.

## In the navbar

The navbar menus are `li` elements with `display="static"`, so the navbar's CSS places the menu. Links to pages of the app use React Router's `Link`:

```tsx
import { Link } from "react-router";

<Dropdown as="li" className="nav-item dropdown" display="static">
  <DropdownToggle className="nav-link dropdown-toggle">Account</DropdownToggle>
  <DropdownMenu className="dropdown-menu-end">
    <Link className="dropdown-item" to="/pages-profile">Profile</Link>
    <Link className="dropdown-item" to="/pages-settings">Settings</Link>
    <div className="dropdown-divider" />
    <a className="dropdown-item" href="#">Log out</a>
  </DropdownMenu>
</Dropdown>
```

## Auto close

By default, a click on an item or anywhere outside closes the menu. `autoClose` changes which clicks do:

| `autoClose` | A click on an item | A click outside |
| --- | --- | --- |
| `true` (default) | Closes the menu | Closes the menu |
| `"inside"` | Closes the menu | Keeps it open |
| `"outside"` | Keeps it open | Closes the menu |
| `false` | Keeps it open | Keeps it open |

Only the toggle and Escape close a menu with `autoClose={false}`. Links and buttons inside a `<form>` in the menu never close it, so a form in a dropdown keeps its menu open while the user fills it in.

## Menu content

The menu takes Bootstrap's classes: `.dropdown-item` (on a link or a button), `.dropdown-item-text`, `.dropdown-header`, `.dropdown-divider`, and `.active` or `.disabled` on an item. See [Bootstrap's dropdown docs](https://getbootstrap.com/docs/5.3/components/dropdowns/) for all of them.

## Accessibility

- The toggle has `aria-expanded` and `aria-controls` pointing at the menu's `id`, which `Dropdown` generates.
- Arrow Down and Arrow Up on the toggle open the menu and focus its first or last item. In the menu they move between the items that are not disabled.
- Escape closes the menu and returns the focus to the toggle.
- A toggle with only an icon or a caret needs a text for screen readers, such as a `visually-hidden` span or an `aria-label`.
- Mark the current item with `.active` and `aria-current="page"` (or `"true"`).

## Related

- [Next.js Bootstrap dropdowns](/nextjs/docs/components/dropdowns/): the same components in AdminKit for Next.js
- [Bootstrap 5 dropdowns](/bootstrap/docs/components/dropdowns/): the dropdowns of the HTML version
- [Offcanvas](/react/docs/components/offcanvas/): a side panel for longer menus
- [Buttons demo](https://react-demo.adminkit.io/ui-buttons): button dropdowns in every theme color

---

Canonical HTML page: https://adminkit.io/react/docs/components/dropdowns/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
