# Dropdown Component
## Overview
As dropdowns are common in Odoo, we decided to make a generic dropdown component.
It contains all the logic you can usually expect a dropdown to behave.
### Features
- Toggle the list on click
- Direct siblings dropdowns: when one is open, toggle others on hover
- Close on outside click
- Close the list when an item is selected
- Emits an event to inform which list item is clicked
- Infinite multi-level support
- SIY: style it yourself
- Configurable hotkey to open/close a dropdown or select a dropdown item
- Keyboard navigation (arrows, enter...)
## API
### Behind the scenes
A `` component is simply a `
` having a `` next to an unordered list (`
`). The button is responsible for the list being present in the DOM or not.
A `` is simply a list item (``). On click, you can ask this item to return you a payload (which you'll receive back in a custom `dropdown-item-selected` event). This payload is an object, so feel free to put anything you want in it. Most likely, you will use ids as payloads to know which item was clicked.
Illustration of what the final DOM could look like:
```html
Menu Item 1
Menu Item 2
```
#### Slots
In order to properly use a `` component, you need to populate two [OWL slots](https://github.com/odoo/owl/blob/master/doc/reference/slots.md):
The default slot
It contains the toggler elements of your dropdown and will take place inside your dropdown <button><span/></button> elements.
The menu slot
It contains the elements of the dropdown menu itself and will take place inside your dropdown <ul/> element.
Although it is not mandatory, you will usually place at least one <DropdownItem/> element in the menu slot.
#### Manage items selection
When a `` gets selected, it emits a custom `dropdown-item-selected` event containing its payload. (see [OWL Business Events](https://github.com/odoo/owl/blob/master/doc/reference/event_handling.md#business-dom-events))
If you want to react when a `` gets selected, you need to define two things:
The dropdown-item-selected event listener
It will receive the payload of the selected item.
A payload for each <DropdownItem/> element
They are just JS objects you declare the way you want. If a payload is not specified, it defaults to null.
### Direct Siblings Dropdowns
When many dropdowns share **_a single parent in the DOM_**, they will automatically notify each other about their state changes.
Doing so, **_when one sibling dropdown is open_**, the others will **_automatically open themselves on hover_**.
### Available Properties
#### `` props
| Prop name | Default Value | Value type | Description |
| -------------- | ------------- | ---------- | --------------------------------------------------------------- |
| `startOpen` | `false` | boolean | initial dropdown open state |
| `menuClass` | / | string | could be used to style the dropdown menu `
` |
| `togglerClass` | / | string | could be used to style the toggler `` |
| `hotkey` | / | string | could be used to toggle the opening through keyboard |
| `beforeOpen` | / | function | hook to execute logic just before opening |
| `manualOnly` | `false` | boolean | if true, only toggle the dropdown when the button is clicked on |
#### `` props
| Prop name | Default Value | Value type | Description |
| ------------------- | ------------- | ---------------------------- | -------------------------------------------------------------------------------------- |
| `payload` | null | Object | item payload that will be part of the `dropdown-item-selected` event |
| `parentClosingMode` | `all` | `none` \| `closest` \| `all` | when item clicked, control which parent dropdown will get closed: none, closest or all |
| `hotkey` | / | string | click on the item via an hotkey activation |
### Z-Index
As Odoo previous dropdown menus made use of Bootstrap dropdowns, we added the same `z-index` value for the dropdown menu. See [Bootstrap documentation](https://getbootstrap.com/docs/4.5/layout/overview/#z-index).
```scss
.o_dropdown_menu {
z-index: 1000;
}
```
## Usage
### Step 1: make it appear on your app
So in your qweb template, you would write something like that:
```xml
Click me to toggle the dropdown menu !
Menu Item 1Menu Item 2
```
And in the DOM it would get translated similarly to:
```xml
Menu Item 1
Menu Item 2
```
### Step 2: make it react to clicks
So in your qweb template you would write something like that:
```xml
…
…
Menu Item
…
```
And in your JS file, when an item is selected, you would receive the payload back like that:
```js
itemSelected(event) {
const eventDetail = event.detail;
const itemPayload = eventDetail.payload;
console.log(itemPayload.a === 15);
}
```
In this case, if you click on this menu item, the console will print « true ».
### Step 3: make it shine
Now that you understand the basics of the Dropdown Component, all you need to do is style it the way you want.
✨ Are you ready to make it shine? ✨
Default CSS classes are:
- `.o_dropdown` : the whole dropdown
- `.o_dropdown_toggler` : the dropdown button
- `.o_dropdown_menu` : the dropdown menu list
- `.o_dropdown_item` : a dropdown item
But you can go even further by extending them:
- `` will become
```xml
...
```
- `` will become
```xml
...
```
- `` will become
```xml
...
```
- `` will become
```xml
...
```
#### You can also make dropdown right aligned by passing 'o_dropdown_menu_right' in menuClass
- `` will become
```xml
...
```
## More Examples
### Direct Siblings Dropdown
When one dropdown toggler is clicked (**File**, **Edit** or **About**), the others will open themselves on hover.
This example uses the dropdown components without added style.
```xml
File
OpenNew DocumentNew Spreadsheet
Edit
UndoRedoSearch
About
HelpCheck update
```
### Multi-level Dropdown
This example uses the dropdown components without added style.
#### Flat version
```xml
File
OpenSave
New
DocumentSpreadsheet
Save as...
CSVPDF
```
#### Nested version
```xml
File
Open
New
DocumentSpreadsheetSave
Save as...
CSVPDF
```
### Recursive Multi-level Dropdown
This example make use of inline style.
```xml