Dropdown displays a menu with actions or options next to a trigger and supports disabled, loading, footer, and keyboard interaction states.

Add the progress attribute to kbq-dropdown-item to show a loading shimmer on the item. It can be combined with disabled to also prevent interaction while loading.

You can add an extra button inside a menu item (for example, to go to settings). It works independently: clicking it doesn't close the menu, and you can reach it with the Tab key.

The menu item itself should be a regular block, not a button.

If the item is in a loading state, the extra button stays visible but becomes unavailable.

A menu item can be made into a regular link — then the entire block will navigate to another page.

You can place auxiliary elements in the footer: buttons, links, hints.

This mechanism prevents an open nested submenu from closing prematurely while the pointer is moving. The submenu stays open even if the pointer touches sibling items along the way, as long as the movement stays within the designated area. It can be configured in two ways:

  • locally — for a specific nested dropdown through the safeArea property;
  • globally — through KBQ_DROPDOWN_DEFAULT_OPTIONS.

A "cyclic navigation" mode where reaching one end of the list loops back to the other end.

Recursive rendering of an array or object, allowing the creation of nested dropdown menus.

The kbqDropdownSearch directive turns a kbq-form-field into the panel's search field: it styles the field for the panel and takes over the keyboard.

The caret stays in the field while the menu is open: ArrowUp and ArrowDown move the highlight across the items, Enter picks the highlighted one, the first Escape clears the query and the second one closes the menu.

Search splits a multi-word query into parts and searches for them independently, trims leading and trailing spaces, is case-insensitive, and folds diacritics. The algorithm is described in the Smart search guide.

Use the xPosition property to control horizontal alignment of the dropdown panel relative to the trigger. Supported values: 'after' (default), 'before', and 'center'.

By default the panel grows with its content, is never narrower than its trigger or than 200px, and stops at 640px. This is configured with the same panelWidth, panelMinWidth and panelMaxWidth attributes as select and autocomplete:

<!-- Match the trigger exactly -->
<kbq-dropdown panelWidth="auto" />

<!-- An exact width; panelMinWidth is not applied -->
<kbq-dropdown [panelWidth]="400" />

<!-- Let the panel grow further with its content -->
<kbq-dropdown [panelMaxWidth]="800" />

The 640px cap is soft: it limits growth by content only, so a trigger wider than 640px still gets a panel as wide as itself, and an explicit panelWidth is never clamped.

The defaults come from design tokens, which can be overridden by a theme:

Token Default
--kbq-dropdown-size-container-width-min 200px
--kbq-dropdown-size-container-width-max var(--kbq-panel-size-width-max, 640px)

--kbq-panel-size-width-max is shared by every dropdown panel in the library, so setting it once on :root caps select, tree-select, autocomplete and dropdown together.

Nested panels and panels that overlap the trigger vertically are not matched to the trigger — they follow the tokens only.

When the trigger is only a part of a larger control, set KbqDropdownTrigger.widthOrigin to the element the panel should match instead. Split button does this through its panelAutoWidth input.

Suggestions for improvement
If you found a mistake or want to improve the article, create an issue on GitHub.