# Dropdown

Display contextual menus from buttons and links in any Bootstrap direction.

```twig
<div class="d-flex justify-content-center align-items-start align-self-stretch w-100">
    <twig:Dropdown>
        <twig:Dropdown:Toggle id="demo-dropdown">Dropdown button</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu labelledBy="demo-dropdown">
            <twig:Dropdown:Item href="#">Action</twig:Dropdown:Item>
            <twig:Dropdown:Item href="#">Another action</twig:Dropdown:Item>
            <twig:Dropdown:Item href="#">Something else here</twig:Dropdown:Item>
        </twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

## Installation

```shell
php bin/console ux:install dropdown --kit bootstrap
```
## Usage

```twig
<twig:Dropdown>
    <twig:Dropdown:Toggle id="actions-dropdown">Actions</twig:Dropdown:Toggle>
    <twig:Dropdown:Menu labelledBy="actions-dropdown">
        <twig:Dropdown:Item href="/edit">Edit</twig:Dropdown:Item>
        <twig:Dropdown:Item href="/duplicate">Duplicate</twig:Dropdown:Item>
        <twig:Dropdown:Divider />
        <twig:Dropdown:Item href="/archive">Archive</twig:Dropdown:Item>
    </twig:Dropdown:Menu>
</twig:Dropdown>
```

## Accessibility

Bootstrap dropdowns are generic popovers, so the component does not add ARIA menu roles automatically. Add `role="menu"`, `role="menuitem"`, and the matching keyboard behavior only when the dropdown implements the complete ARIA menu pattern.

Use a button for actions and reserve link toggles and items for navigation. Give a toggle an `id` and pass it to the menu's `labelledBy` prop when an explicit accessible relationship is useful. Disabled links receive `aria-disabled="true"` and are removed from sequential keyboard navigation, but application code must still prevent any custom activation behavior.

## Examples

### Single button

Use buttons or links with Bootstrap's contextual colors.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-start gap-2 w-100">
    {% for color in ['primary', 'secondary', 'success', 'info', 'warning', 'danger'] %}
        <twig:Dropdown>
            <twig:Dropdown:Toggle color="{{ color }}">{{ color|title }}</twig:Dropdown:Toggle>
            <twig:Dropdown:Menu>
                <twig:Dropdown:Item href="#">Action</twig:Dropdown:Item>
                <twig:Dropdown:Item href="#">Another action</twig:Dropdown:Item>
                <twig:Dropdown:Item href="#">Something else here</twig:Dropdown:Item>
            </twig:Dropdown:Menu>
        </twig:Dropdown>
    {% endfor %}
    <twig:Dropdown>
        <twig:Dropdown:Toggle tag="a" color="primary">Dropdown link</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu>
            <twig:Dropdown:Item href="#">Action</twig:Dropdown:Item>
            <twig:Dropdown:Item href="#">Another action</twig:Dropdown:Item>
        </twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Split button

Separate the primary action from the menu toggle.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-start gap-2 w-100">
    {% for color in ['primary', 'secondary', 'success', 'info', 'warning', 'danger'] %}
        <twig:Dropdown grouped>
            <button type="button" class="btn btn-{{ color }}">{{ color|title }}</button>
            <twig:Dropdown:Toggle color="{{ color }}" split />
            <twig:Dropdown:Menu>
                <twig:Dropdown:Item href="#">Action</twig:Dropdown:Item>
                <twig:Dropdown:Item href="#">Another action</twig:Dropdown:Item>
                <twig:Dropdown:Divider />
                <twig:Dropdown:Item href="#">Separated link</twig:Dropdown:Item>
            </twig:Dropdown:Menu>
        </twig:Dropdown>
    {% endfor %}
</div>
```

### Sizing

Create large and small regular or split dropdown buttons.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-center gap-3 w-100">
    <twig:Dropdown>
        <twig:Dropdown:Toggle color="secondary" size="lg">Large button</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown grouped>
        <button class="btn btn-light btn-lg" type="button">Large split button</button>
        <twig:Dropdown:Toggle color="light" size="lg" split />
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown>
        <twig:Dropdown:Toggle color="secondary" size="sm">Small button</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown grouped>
        <button class="btn btn-light btn-sm" type="button">Small split button</button>
        <twig:Dropdown:Toggle color="light" size="sm" split />
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Dark dropdowns

Render a dark menu with a visible active item.

```twig
<div class="d-flex justify-content-center align-items-start align-self-stretch w-100">
    <twig:Dropdown>
        <twig:Dropdown:Toggle id="dark-dropdown" color="secondary">Dropdown button</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu dark labelledBy="dark-dropdown">
            <twig:Dropdown:Item href="#" active>Action</twig:Dropdown:Item>
            <twig:Dropdown:Item href="#">Another action</twig:Dropdown:Item>
            <twig:Dropdown:Item href="#">Something else here</twig:Dropdown:Item>
            <twig:Dropdown:Divider />
            <twig:Dropdown:Item href="#">Separated link</twig:Dropdown:Item>
        </twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Directions

Open menus from the center, above, or from either side.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-center gap-3 w-100">
    <twig:Dropdown direction="center">
        <twig:Dropdown:Toggle>Centered dropdown</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="up">
        <twig:Dropdown:Toggle>Dropup</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="up" grouped>
        <button type="button" class="btn btn-secondary">Split dropup</button>
        <twig:Dropdown:Toggle split />
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="up-center">
        <twig:Dropdown:Toggle>Centered dropup</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="end">
        <twig:Dropdown:Toggle>Dropend</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="end" grouped>
        <button type="button" class="btn btn-secondary">Split dropend</button>
        <twig:Dropdown:Toggle split />
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="start">
        <twig:Dropdown:Toggle>Dropstart</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="start" grouped>
        <twig:Dropdown:Toggle split />
        <button type="button" class="btn btn-secondary">Split dropstart</button>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Menu items

Use links, buttons, or non-interactive text as menu content.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-start gap-4 w-100">
    <twig:Dropdown:Menu class="d-block position-static">
        <twig:Dropdown:Item href="#">Action</twig:Dropdown:Item>
        <twig:Dropdown:Item href="#">Another action</twig:Dropdown:Item>
        <twig:Dropdown:Item href="#">Something else here</twig:Dropdown:Item>
    </twig:Dropdown:Menu>
    <twig:Dropdown:Menu class="d-block position-static">
        <twig:Dropdown:Item tag="button">Action</twig:Dropdown:Item>
        <twig:Dropdown:Item tag="button">Another action</twig:Dropdown:Item>
        <twig:Dropdown:Item tag="button">Something else here</twig:Dropdown:Item>
    </twig:Dropdown:Menu>
    <twig:Dropdown:Menu class="d-block position-static">
        <twig:Dropdown:Text>Dropdown item text</twig:Dropdown:Text>
        <twig:Dropdown:Item href="#">Action</twig:Dropdown:Item>
    </twig:Dropdown:Menu>
</div>
```

### Active and disabled items

Communicate the current item and unavailable choices.

```twig
<twig:Dropdown:Menu class="d-block position-static">
    <twig:Dropdown:Item href="#">Regular link</twig:Dropdown:Item>
    <twig:Dropdown:Item href="#" active>Active link</twig:Dropdown:Item>
    <twig:Dropdown:Item href="#" disabled>Disabled link</twig:Dropdown:Item>
</twig:Dropdown:Menu>
```

### Menu alignment

Align a menu against the end of its toggle.

```twig
<div class="d-flex justify-content-center align-items-start align-self-stretch w-100">
    <twig:Dropdown>
        <twig:Dropdown:Toggle id="aligned-dropdown">Right-aligned menu</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu align="end" labelledBy="aligned-dropdown">
            <twig:Dropdown:Item href="#">Action</twig:Dropdown:Item>
            <twig:Dropdown:Item href="#">Another action</twig:Dropdown:Item>
            <twig:Dropdown:Item href="#">Something else here</twig:Dropdown:Item>
        </twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Responsive alignment

Change menu alignment at Bootstrap breakpoints.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-start gap-3 w-100">
    <twig:Dropdown>
        <twig:Dropdown:Toggle data-bs-display="static">Left-aligned but right-aligned when large screen</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu align="lg-end"><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown>
        <twig:Dropdown:Toggle data-bs-display="static">Right-aligned but left-aligned when large screen</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu :align="['end', 'lg-start']"><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Alignment options

Combine responsive alignment with dropdowns that open in different directions.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-center gap-3 w-100">
    <twig:Dropdown>
        <twig:Dropdown:Toggle>Dropdown</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu>
            <twig:Dropdown:Item href="#">Menu item</twig:Dropdown:Item>
            <twig:Dropdown:Item href="#">Menu item</twig:Dropdown:Item>
        </twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="end">
        <twig:Dropdown:Toggle>Dropend</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu :align="['end', 'lg-start']">
            <twig:Dropdown:Item href="#">Right-aligned, left-aligned when large</twig:Dropdown:Item>
        </twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="start">
        <twig:Dropdown:Toggle>Dropstart</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu align="lg-end">
            <twig:Dropdown:Item href="#">Left-aligned, right-aligned when large</twig:Dropdown:Item>
        </twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown direction="up">
        <twig:Dropdown:Toggle>Dropup</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu align="end"><twig:Dropdown:Item href="#">Right-aligned menu</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Headers, dividers, and text

Structure longer menus with headings, separators, and explanatory copy.

```twig
<twig:Dropdown:Menu class="d-block position-static">
    <twig:Dropdown:Header>Dropdown header</twig:Dropdown:Header>
    <twig:Dropdown:Item href="#">Action</twig:Dropdown:Item>
    <twig:Dropdown:Item href="#">Another action</twig:Dropdown:Item>
    <twig:Dropdown:Divider />
    <twig:Dropdown:Text>Some example text that's free-flowing within the dropdown menu.</twig:Dropdown:Text>
    <twig:Dropdown:Item href="#">Separated link</twig:Dropdown:Item>
</twig:Dropdown:Menu>
```

### Forms

Display a static form or open one from a dropdown toggle.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-start gap-4 w-100">
    <twig:Dropdown:Menu tag="form" class="d-block position-static p-4">
        <div class="mb-3">
            <label for="dropdown-email" class="form-label">Email address</label>
            <input type="email" class="form-control" id="dropdown-email" placeholder="email@example.com">
        </div>
        <div class="mb-3">
            <label for="dropdown-password" class="form-label">Password</label>
            <input type="password" class="form-control" id="dropdown-password" placeholder="Password">
        </div>
        <div class="mb-3">
            <div class="form-check">
                <input type="checkbox" class="form-check-input" id="dropdown-check">
                <label class="form-check-label" for="dropdown-check">Remember me</label>
            </div>
        </div>
        <button type="submit" class="btn btn-primary">Sign in</button>
    </twig:Dropdown:Menu>
    <twig:Dropdown>
        <twig:Dropdown:Toggle>Dropdown form</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu tag="form" class="p-4">
            <div class="mb-3">
                <label for="menu-email" class="form-label">Email address</label>
                <input type="email" class="form-control" id="menu-email">
            </div>
            <button type="submit" class="btn btn-primary">Sign in</button>
        </twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Dropdown options

Configure Popper's offset and reference element with Bootstrap data attributes.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-start gap-3 w-100">
    <twig:Dropdown>
        <twig:Dropdown:Toggle data-bs-offset="10,20">Offset</twig:Dropdown:Toggle>
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
    <twig:Dropdown grouped>
        <button type="button" class="btn btn-secondary">Reference</button>
        <twig:Dropdown:Toggle split data-bs-reference="parent" />
        <twig:Dropdown:Menu><twig:Dropdown:Item href="#">Action</twig:Dropdown:Item></twig:Dropdown:Menu>
    </twig:Dropdown>
</div>
```

### Auto close behavior

Choose which inside or outside interactions dismiss the menu.

```twig
<div class="d-flex flex-wrap justify-content-center align-items-start gap-3 w-100">
    {% for behavior, label in {
    true: 'Default dropdown',
    inside: 'Clickable inside',
    outside: 'Clickable outside',
    false: 'Manual close',
    } %}
        <twig:Dropdown>
            <twig:Dropdown:Toggle data-bs-auto-close="{{ behavior }}">{{ label }}</twig:Dropdown:Toggle>
            <twig:Dropdown:Menu>
                <twig:Dropdown:Item href="#">Menu item</twig:Dropdown:Item>
                <twig:Dropdown:Item href="#">Menu item</twig:Dropdown:Item>
            </twig:Dropdown:Menu>
        </twig:Dropdown>
    {% endfor %}
</div>
```

## API Reference

### `<twig:Dropdown>`

| Prop | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| `direction` | `'down'\|'center'\|'up'\|'up-center'\|'end'\|'start'` | `'down'` | The direction in which the menu opens. |
| `grouped` | `boolean` | `false` | Whether to use a button group wrapper, as required by split toggles. |

| Block | Description |
|:------|:------------|
| `content` | The dropdown toggle and menu. |
### `<twig:Dropdown:Header>`

| Prop | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| `tag` | `'h1'\|'h2'\|'h3'\|'h4'\|'h5'\|'h6'` | `'h6'` | The heading element to render. |

| Block | Description |
|:------|:------------|
| `content` | The dropdown section heading. |
### `<twig:Dropdown:Item>`

| Prop | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| `tag` | `'a'\|'button'` | `'a'` | The interactive element to render. |
| `href` | `string` | `'#'` | The destination used by link items. |
| `active` | `boolean` | `false` | Whether the item represents the current selection. |
| `disabled` | `boolean` | `false` | Whether the item is unavailable. |

| Block | Description |
|:------|:------------|
| `content` | The dropdown item label. |
### `<twig:Dropdown:Menu>`

| Prop | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| `tag` | `'ul'\|'div'\|'form'` | `'ul'` | The menu container element to render. |
| `dark` | `boolean` | `false` | Whether to use Bootstrap's dark menu variant. |
| `align` | `string\|array<string>\|null` | `null` | One or more Bootstrap alignment suffixes, such as `end` or `lg-end`. |
| `labelledBy` | `string\|null` | `null` | The identifier of the toggle that labels the menu. |

| Block | Description |
|:------|:------------|
| `content` | The dropdown menu items and custom content. |
### `<twig:Dropdown:Text>`

| Block | Description |
|:------|:------------|
| `content` | The non-interactive dropdown text. |
### `<twig:Dropdown:Toggle>`

| Prop | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| `tag` | `'button'\|'a'` | `'button'` | The interactive element to render. |
| `color` | `'primary'\|'secondary'\|'success'\|'danger'\|'warning'\|'info'\|'light'\|'dark'` | `'secondary'` | The Bootstrap contextual color. |
| `outline` | `boolean` | `false` | Whether to render the outline variant. |
| `size` | `'sm'\|'lg'\|null` | `null` | The optional button size. |
| `split` | `boolean` | `false` | Whether to render only the split-menu caret. |
| `disabled` | `boolean` | `false` | Whether the toggle is disabled. |

| Block | Description |
|:------|:------------|
| `content` | The visible toggle label. |