Menu with Search
JSThis component requires JavaScript.
An alternative version of the menu that includes site search.
For more information on usage, implementation and accessibility, please visit the Menu page.
Example
<div class="bux-menu-wrapper">
<div
class="bux-container bux-grid bux-container__menu bux-container__menu--with-search"
>
<nav
id="bux-main-menu"
aria-label="Main"
class="disclosure-nav disclosure-nav-orientation-horizontal"
>
<ul class="bux-menu">
<li class="bux-menu__item">
<a
data-button-aria-label="More Level 1 Link Items"
class="bux-menu__link bux-menu__link--active disclosure-nav-item-with-submenu"
href="#"
rel="noopener"
>
Level 1 Link
</a>
<ul class="disclosure-nav-submenu disclosure-nav-submenu-closed">
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link bux-menu__link--active disclosure-nav-item-with-submenu mobile-depth-cutoff"
href="#"
rel="noopener"
>
Level 2 Link
</a>
<ul
class="disclosure-nav-submenu disclosure-nav-submenu-closed mobile-visible"
>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link bux-menu__link--active disclosure-nav-item-with-submenu"
href="#"
rel="noopener"
>
Level 3 Link
</a>
<ul
class="disclosure-nav-submenu disclosure-nav-submenu-closed"
>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link disclosure-nav-item-with-submenu"
href="#"
rel="noopener"
>
Level 4 Link
</a>
<ul
class="disclosure-nav-submenu disclosure-nav-submenu-closed"
>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 5 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 5 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 4 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 3 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link disclosure-nav-item-with-submenu"
href="#"
rel="noopener"
>
Level 1 Link
</a>
<ul class="disclosure-nav-submenu disclosure-nav-submenu-closed">
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 1 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link disclosure-nav-item-with-submenu"
href="#"
rel="noopener"
>
Level 1 Link
</a>
<ul class="disclosure-nav-submenu disclosure-nav-submenu-closed">
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 2 Link
</a>
</li>
</ul>
</li>
<li class="bux-menu__item">
<a
data-button-aria-label="More Stuff"
class="bux-menu__link"
href="#"
rel="noopener"
>
Level 1 Link
</a>
</li>
</ul>
</nav>
<div class="bux-menu__search">
<div
class="bux-form__text-field--menu-search__wrapper"
role="dialog"
aria-modal="true"
>
<form id="site-search" class="bux-search" role="search">
<label class="bux-search__label visually-hidden" for="bux-search">
Search
</label>
<input
id="bux-search"
class="bux-search__input bux-form__text-field bux-form__text-field--menu-search"
placeholder="Search"
tabindex="-1"
/>
<button class="bux-search__submit is-hidden" tabindex="-1">
<span class="visually-hidden">Submit search</span>
</button>
</form>
</div>
<button
id="menu-search-btn"
type="button"
aria-expanded="false"
aria-controls="site-search"
>
<span class="visually-hidden">Toggle search dialog</span>
<span
id="search-icon"
class="icon icon-search"
aria-hidden="true"
></span>
</button>
</div>
</div>
</div>
{#
Buckeye UX - version 1.5.0
Copyright (C) 2026 The Ohio State University
#}
{#
Menu
Available Variables:
- nav_id: Unique ID for the menu.
- aria_label: Aria-label for the menu.
- mobile_depth_cutoff: Boolean. Hide deep menu levels on desktop.
- items: Array of menu items: title, url, active, aria_label, subitems.
- label: Optional. Set to 'with-search' if using the search variant.
- modifier: Optional. Menu variant: null, with-search.
- input_id: Optional. Unique ID for the search input.
- search_form_id: Optional. Unique ID for the search form.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 04-01-2026 12:15:38
#}
{# ===================================================
Macros
==================================================== #}
{% macro link(item, depth, mobile_depth_cutoff) %}
{% set linkClasses = ['bux-menu__link'] %}
{% if item.active %}
{% set linkClasses = linkClasses|merge(['bux-menu__link--active']) %}
{% endif %}
{% if item.subitems %}
{% set linkClasses = linkClasses|merge(['disclosure-nav-item-with-submenu']) %}
{% endif %}
{% if item.subitems and mobile_depth_cutoff and depth == 1 %}
{% set linkClasses = linkClasses|merge(['mobile-depth-cutoff']) %}
{% endif %}
{% embed '@bux/link/link.twig'
with {
base_class: linkClasses|join(' '),
link_url: item.url,
attributes: {
'data-button-aria-label': item.aria_label
}
}
%}
{% block content %}
{{ item.title }}
{% endblock content %}
{% endembed %}
{% endmacro %}
{% macro submenu(items, depth, mobile_depth_cutoff) %}
{% import _self as menu %}
{% if items %}
{% set submenuClasses = ['disclosure-nav-submenu', 'disclosure-nav-submenu-closed'] %}
{% if mobile_depth_cutoff and depth == 2 %}
{% set submenuClasses = submenuClasses|merge(['mobile-visible']) %}
{% endif %}
<ul class="{{ submenuClasses|join(' ') }}">
{% for item in items %}
<li class="bux-menu__item">
{{ menu.link(item, depth, mobile_depth_cutoff) }}
{% if item.subitems %}
{{ menu.submenu(item.subitems, depth + 1, mobile_depth_cutoff) }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{# ===================================================
Markup
==================================================== #}
{% import _self as menu %}
<div class="bux-menu-wrapper">
<div class="bux-container bux-grid bux-container__menu{{ modifier ? ' bux-container__menu--' ~ modifier : '' }}">
<nav id="{{ nav_id }}" aria-label="{{ aria_label }}" class="disclosure-nav disclosure-nav-orientation-horizontal">
{% if items %}
<ul class="bux-menu">
{% for item in items %}
<li class="bux-menu__item">
{{ menu.link(item, 0, mobile_depth_cutoff) }}
{% if item.subitems %}
{{ menu.submenu(item.subitems, 1, mobile_depth_cutoff) }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</nav>
{% if modifier == 'with-search' %}
<div class="bux-menu__search">
<div class="bux-form__text-field--menu-search__wrapper" role="dialog" aria-modal="true">
{# {% include '@bux/search-form/search-form.twig' with {
site_search_action: 'submit'
} %} #}
<form id="{{ search_form_id }}" class="bux-search" role="search">
<label class="bux-search__label visually-hidden" for="{{ input_id }}">Search</label>
<input
id="{{ input_id }}"
class="bux-search__input bux-form__text-field bux-form__text-field--menu-search"
placeholder="Search"
tabindex="-1"
/>
<button class="bux-search__submit is-hidden" tabindex="-1">
<span class="visually-hidden">Submit search</span>
</button>
</form>
</div>
<button id="menu-search-btn" type="button" aria-expanded="false" aria-controls="{{ search_form_id }}">
<span class="visually-hidden">Toggle search dialog</span>
<span id="search-icon" class="icon icon-search" aria-hidden="true"></span>
</button>
</div>
{% endif %}
</div>
</div>
Implementation Notes
By default, mobileDepthCutoff is set to true, which hides links of a depth
greater than two in the menu tree on large viewports. This is meant to overlap
with the Sidebar Navigation which by default is
hidden on smaller viewports.
References
- BUX Design Principle: Design Elements