Skip to content

Dropdown

The h-dropdown webcomponent provides a solid foundation for creating dropdowns, select lists, tooltips or whatever else. h-dropdown webcomponent uses the h-portal webcomponent to render its content in a different location. Every dropdown is portaled to a <h-portal-target name="dropdown-name"> which is direct children of document body element to avoid z-index issues.

Note: h- stands for headless. This is naming convention used for every webcomponent as they must have a two-part name.

Features:

  • Keyboard support
  • Allows to close the dropdown by clicking somewhere else on a page
  • Opens the dropdown in one of the variations provided by TDropdownDirection
  • Repositions the dropdown when it turns out to be off the screen vertically
  • Allows toggling a dropdown on mouse hover
  • Adds appropriate ARIA roles
  • Provides additional webcomponents for facilitate use

Dropdown uses slots to render content within itself. The following slots are available:

  • toggler
  • content

Attributes

Attribute name Type Default Description
name string '' a name of the dropdown we want to link with the h-portal-target
direction TDropdownDirection bottom-center decides how the dropdown should be positioned after it is rendered
opened boolean false decides if dropdown is opened on render
toggleOnHover boolean false decides whether a dropdown should be opened on mouse hover or not
mobile-position 'left' or 'right' left decides on which side of the screen will the dropdown open on the mobile resolution

NOTE: The name attribute must always be provided and unique for each dropdown

DOM events

This webcomponent listens to the following DOM events:

This webcomponent also dispatches the following DOM events:

Basic Dropdown

HTML
    <h-dropdown name="dropdown-basic" direction="bottom-left">
        <h-dropdown-toggler name="dropdown-basic">
            <button>Open dropdown somewhere</button>
        </h-dropdown-toggler>

        <h-dropdown-content name="dropdown-basic">
            <h3>Here is the content of the dropdown</h3>
            <button>It can contain any elements</button>
            <div>
                <a href="/">They can be styled individually and nested</a>
            </div>
        </h-dropdown-content>
    </h-dropdown>

Inner h-dropdown components

To facilitate dropdown creation we provide several components that may be used within dropdown. They do hide implemenation that is often repetitive. For example h-dropdown-toggler markup looks like this:

h-dropdown-toggler
<div name="dropdown-name" slot="toggler" role="button"></div>

So this is the same:

<h-dropdown name="dropdown-toggle-example" direction="top-center">
    <div name="dropdown-toggle-example" slot="toggler" role="button">
        Toggler
    </div>
</h-dropdown>
<h-dropdown name="dropdown-toggle-example" direction="top-center">
    <h-dropdown-toggler name="dropdown-toggle-example">
        Toggler
    </h-dropdown-toggler>
</h-dropdown>

And h-dropdown-content markup looks like this:

h-dropdown-toggler
<div name="dropdown-name" slot="content" role="menu"></div>
With each of it's children having an attribute of role set to menuitem.

So this is also the same:

<h-dropdown name="dropdown-content-example" direction="top-right">
    <div name="dropdown-content-example" slot="content" role="menu">
        <p role="menuitem">Content</p>
    </div>
</h-dropdown>
<h-dropdown name="dropdown-content-example" direction="top-right">
    <h-dropdown-content name="dropdown-content-example">
        <p>Content</p>
    </h-dropdown-content>
</h-dropdown>

Notice the importance of role attributes that provide additional accessibility for the screen readers. For the h-dropdown-toggler we use role="button" unless it is a button HTML tag. For the h-dropdown-content we use role="menu" and role="menuitem" for all of it's children elements.

h-dropdown-toggler

The h-dropdown-toggler is a webcomponent that has ability to toggle a dropdown. By default it is put in toggler slot in the dropdown. It has to be child of the dropdown it wants to close and have the same name attribute.

h-dropdown-content

The h-dropdown-content is a webcomponent that contains the dropdown content. By default it is put in content slot in the dropdown. It has to be child of the dropdown and have the same name attribute.

Opened dropdown

Opened dropdown
    <h-dropdown name="dropdown-opened-example" direction="bottom-left" opened>
        <h-dropdown-toggler name="dropdown-opened-example">
            Simple toggler
        </h-dropdown-toggler>

        <h-dropdown-content name="dropdown-opened-example">
            Simple content
        </h-dropdown-content>
    </h-dropdown>
Dropdown toggled on hover opened on the right side of the container
    <h-dropdown name="dropdown-hover" direction="bottom-left" toggleOnHover>
        <h-dropdown-toggler name="dropdown-hover">
            Simple toggler
        </h-dropdown-toggler>

        <h-dropdown-content name="dropdown-hover">
            Simple content
        </h-dropdown-content>
    </h-dropdown>

API

As webcomponent is basically a custom HTML element you can get reference to it and use the API that it provides. h-dropdown has three public methods:

toggle(): void

Toggles dropdown

const dropdown = document.querySelector('h-dropdown[name="dropdown-name"]');
toggle();

open(): void

Opens dropdown

const dropdown = document.querySelector('h-dropdown[name="dropdown-name"]');
dropdown.open();

close(): void

Closes dropdown

const dropdown = document.querySelector('h-dropdown[name="dropdown-name"]');
dropdown.close();

Customization

h-dropdown is fully customizable. You can provide own HTML elements or webcomponents to change how the dropdown looks.

Customized dropdown
    <h-dropdown name="dropdown-custom" direction="top-left" class="custom-dropdown">
        <button name="dropdown-custom" slot="toggler" class="custom-dropdown-toggler">
            Custom toggler
        </button>

        <div name="dropdown-custom" slot="content" role="menu" class="custom-dropdown-content">
            <p role="menuitem">Custom content</p>
        </div>
    </h-dropdown>

Advanced examples of usage

You might need to use a dropdown in a bit more complex manner. We support every possibility that you wish for. One of them might be the nested dropdown:

Single nested dropdown
    <h-dropdown name="dropdown" direction="bottom-left">
        <h-dropdown-toggler name="dropdown">
            Simple toggler
        </h-dropdown-toggler>

        <h-dropdown-content name="dropdown">
            Simple content
            <h-dropdown name="dropdown-nested" direction="bottom-center">
                <h-dropdown-toggler name="dropdown-nested">
                    Nedted dropdown toggler
                </h-dropdown-toggler>

                <h-dropdown-content name="dropdown-nested">
                    Nested dropdown content
                </h-dropdown-content>
            </h-dropdown>
        </h-dropdown-content>
    </h-dropdown>

You can of course nest it as many times as you want:

Multiple nested dropdown
    <h-dropdown name="dropdown" direction="bottom-left">
        <h-dropdown-toggler name="dropdown">
            Simple toggler
        </h-dropdown-toggler>

        <h-dropdown-content name="dropdown">
            Simple content
            <h-dropdown name="dropdown-nested" direction="bottom-center">
                <h-dropdown-toggler name="dropdown-nested">
                    Nested dropdown toggler
                </h-dropdown-toggler>

                <h-dropdown-content name="dropdown-nested">
                    Nested dropdown content
                    <h-dropdown name="dropdown-double-nested" direction="bottom-left">
                        <h-dropdown-toggler name="dropdown-double-nested">
                            Double nested dropdown content
                        </h-dropdown-toggler>

                        <h-dropdown-content name="dropdown-double-nested">
                            Double nested dropdown content
                            <h-dropdown name="dropdown-triple-nested" direction="bottom-center">
                                <h-dropdown-toggler name="dropdown-triple-nested">
                                    Triple nested dropdown toggler
                                </h-dropdown-toggler>

                                <h-dropdown-content name="dropdown-triple-nested">
                                    Triple nested dropdown content
                                    <h-dropdown name="dropdown-quadruple-nested" direction="bottom-left">
                                        <h-dropdown-toggler name="dropdown-quadruple-nested">
                                            Quadruple nested dropdown content
                                        </h-dropdown-toggler>

                                        <h-dropdown-content name="dropdown-quadruple-nested">
                                            Quadruple nested dropdown content
                                            <h-dropdown name="dropdown-quintuple-nested" direction="bottom-center">
                                                <h-dropdown-toggler name="dropdown-quintuple-nested">
                                                    Quintuple nested dropdown toggler
                                                </h-dropdown-toggler>

                                                <h-dropdown-content name="dropdown-quintuple-nested">
                                                    Quintuple nested dropdown content
                                                </h-dropdown-content>
                                            </h-dropdown>
                                        </h-dropdown-content>
                                    </h-dropdown>
                                </h-dropdown-content>
                            </h-dropdown>
                        </h-dropdown-content>
                    </h-dropdown>
                </h-dropdown-content>
            </h-dropdown>
        </h-dropdown-content>
    </h-dropdown>

And you can also add a toggleOnHover prop in nested dropdowns like this:

Clickable dropdown nested inside a toggle dropdown
    <h-dropdown name="dropdown" direction="bottom-left">
        <h-dropdown-toggler name="dropdown">
            Simple toggler
        </h-dropdown-toggler>

        <h-dropdown-content name="dropdown">
            Simple content
            <h-dropdown name="dropdown-nested" direction="bottom-center" toggleOnHover>
                <h-dropdown-toggler name="dropdown-nested">
                    Nested dropdown toggler
                </h-dropdown-toggler>

                <h-dropdown-content name="dropdown-nested">
                    Nested dropdown content opened on hover
                    <h-dropdown name="dropdown-double-nested" direction="bottom-center">
                        <h-dropdown-toggler name="dropdown-double-nested">
                            Nested dropdown toggler opened on click
                        </h-dropdown-toggler>

                        <h-dropdown-content name="dropdown-double-nested">
                            Clicking on me doesn't close the hover dropdown
                        </h-dropdown-content>
                    </h-dropdown>
                </h-dropdown-content>
            </h-dropdown>
        </h-dropdown-content>
    </h-dropdown>

Notice how you can nest a dropdown togglable on click inside a dropdown togglable on hover. That is the whole magic of our dropdowns.

Objects reference

Webcomponents reference