Skip to Content
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