OWL
overlay
Dropdown
Odoo 19 OWL component — Dropdown (core)
Live preview
Interactive
Source excerpt
web/static/src/core/dropdown/dropdown.js
import {
Component,
onMounted,
onRendered,
onWillUpdateProps,
reactive,
status,
useEffect,
xml,
} from "@odoo/owl";
import { useDropdownGroup } from "@web/core/dropdown/_behaviours/dropdown_group_hook";
import { useDropdownNesting } from "@web/core/dropdown/_behaviours/dropdown_nesting";
import { DropdownPopover } from "@web/core/dropdown/_behaviours/dropdown_popover";
import { useDropdownState } from "@web/core/dropdown/dropdown_hooks";
import { useNavigation } from "@web/core/navigation/navigation";
import { usePopover } from "@web/core/popover/popover_hook";
import { mergeClasses } from "@web/core/utils/classname";
import { useChildRef, useService } from "@web/core/utils/hooks";
import { deepMerge } from "@web/core/utils/objects";
import { effect } from "@web/core/utils/reactive";
import { utils } from "@web/core/ui/ui_service";
import { hasTouch } from "@web/core/browser/feature_detection";
export function getFirstElementOfNode(node) {
if (!node) {
return null;
}
if (node.el) {
return node.el.nodeType === Node.ELEMENT_NODE ? node.el : null;
}
if (node.bdom || node.child) {
return getFirstElementOfNode(node.bdom || node.child);
}
if (node.children) {
for (const child of node.children) {
const el = getFirstElementOfNode(child);
if (el) {
return el;
}
}
}
return null;
}
/**
* The Dropdown component allows to define a menu that will
* show itself when a target is toggled.
*
* Items are defined using DropdownItems. Dropdowns are
* also allowed as items to be able to create nested
* dropdown menus.
*/
export class Dropdown extends Component {
static template = xml`<t t-slot="default"/>`;
static components = {};
static props = {
menuClass: { optional: true },
position: { type: String, optional: true },
slots: {
type: Object,
shape: {
default: { optional: true },
content: { optional: true },
},
},
items: {
optional: true,
type: Array,
elements: {
type: Object,
shape: {
label: String,
onSelected: Function,
class: { optional: true },
"*": true,
},
},
},
menuRef: { type: Function, optional: true }, // to be used with useChildRef
disabled: { type: Boolean, optional: true },
holdOnHover: { type: Boolean, optional: true },
focusToggleOnClosed: { type: Boolean, optional: true },
beforeOpen: { type: Function, optional: true },
onOpened: { type: Function, optional: true },
onStateChanged: { type: Function, optional: true },
/** Manual state handling, @see useDropdownState */
state: {
type: Object,
shape: {
isOpen: Boolean,
close: Function,
open: Function,
"*": true,
},
optional: true,
},
manual: { type: Boolean, optional: true },
/** When true, do not add optional styling css classes on the target*/
noClasses: { type: Boolean, optional: true },
/**
* Override the internal navigation hook options
* @type {import("@web/core/navigation/navigation").NavigationOptions}
*/
navigationOptions: { type: Object, optional: true },
bottomSheet: { type: Boolean, optional: true },
};
static defaultProps = {
disabled: false,
holdOnHover: false,
focusToggleOnClosed: true,
menuClass: "",
state: undefined,
noClasses: false,
navigationOptions: {},
Registry / API
- Registry name
Dropdown- Category
—- Module
web- Slug
dropdown- Nav group
overlay