View as Markdown
Menubar
A horizontal menu bar with dropdown menus, similar to desktop application menus.
100%
Loading...
<div class="flex items-start justify-center" style="min-height: 320px">
<twig:Menubar class="w-72">
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>File</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>New Tab<twig:Menubar:Shortcut>⌘T</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item>New Window<twig:Menubar:Shortcut>⌘N</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item disabled>New Incognito Window</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Sub>
<twig:Menubar:SubTrigger>
<twig:Button variant="ghost" size="sm" class="w-full justify-start" {{ ...menubar_sub_trigger_attrs }}>
Share
<twig:ux:icon name="lucide:chevron-right" class="ms-auto size-4" aria-hidden="true" />
</twig:Button>
</twig:Menubar:SubTrigger>
<twig:Menubar:SubContent>
<twig:Menubar:Item>Email link</twig:Menubar:Item>
<twig:Menubar:Item>Messages</twig:Menubar:Item>
<twig:Menubar:Item>Notes</twig:Menubar:Item>
</twig:Menubar:SubContent>
</twig:Menubar:Sub>
<twig:Menubar:Separator />
<twig:Menubar:Item>Print...<twig:Menubar:Shortcut>⌘P</twig:Menubar:Shortcut></twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>Edit</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>Undo<twig:Menubar:Shortcut>⌘Z</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item>Redo<twig:Menubar:Shortcut>⇧⌘Z</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Sub>
<twig:Menubar:SubTrigger>
<twig:Button variant="ghost" size="sm" class="w-full justify-start" {{ ...menubar_sub_trigger_attrs }}>
Find
<twig:ux:icon name="lucide:chevron-right" class="ms-auto size-4" aria-hidden="true" />
</twig:Button>
</twig:Menubar:SubTrigger>
<twig:Menubar:SubContent>
<twig:Menubar:Item>Search the web</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>Find...</twig:Menubar:Item>
<twig:Menubar:Item>Find Next</twig:Menubar:Item>
<twig:Menubar:Item>Find Previous</twig:Menubar:Item>
</twig:Menubar:SubContent>
</twig:Menubar:Sub>
<twig:Menubar:Separator />
<twig:Menubar:Item>Cut</twig:Menubar:Item>
<twig:Menubar:Item>Copy</twig:Menubar:Item>
<twig:Menubar:Item>Paste</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>View</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content class="w-44">
<twig:Menubar:CheckboxItem name="bookmarks">Bookmarks Bar</twig:Menubar:CheckboxItem>
<twig:Menubar:CheckboxItem name="urls" checked>Full URLs</twig:Menubar:CheckboxItem>
<twig:Menubar:Separator />
<twig:Menubar:Item>Reload<twig:Menubar:Shortcut>⌘R</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item disabled>Force Reload<twig:Menubar:Shortcut>⇧⌘R</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>Toggle Fullscreen</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>Hide Sidebar</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>Profiles</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:RadioGroup name="profile">
<twig:Menubar:RadioItem value="andy">Andy</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="benoit" checked>Benoit</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="luis">Luis</twig:Menubar:RadioItem>
</twig:Menubar:RadioGroup>
<twig:Menubar:Separator />
<twig:Menubar:Item>Edit...</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>Add Profile...</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
</twig:Menubar>
</div>
Installation
php bin/console ux:install menubar --kit shadcn
Install the following Composer dependencies:
composer require twig/extra-bundle twig/html-extra:^3.24.0 symfony/ux-icons symfony/ux-twig-component:^3.5 tales-from-a-dev/twig-tailwind-extra:^1.3.0
Copy the following file(s) into your app:
assets/controllers/menubar_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['menu', 'trigger'];
connect() {
this._closeOnOutsideClick = this._closeOnOutsideClick.bind(this);
this.closeAll();
}
disconnect() {
document.removeEventListener('click', this._closeOnOutsideClick, true);
}
toggle(event) {
const menu = this._menuFor(event.currentTarget);
if (!menu) return;
if (menu.dataset.state === 'open') {
this.closeAll();
} else {
this._open(menu);
}
}
// Once a menu is open, hovering another trigger switches to its menu; while closed, hovering does nothing.
enter(event) {
if (!this._hasOpenMenu()) return;
const menu = this._menuFor(event.currentTarget);
if (menu && menu.dataset.state !== 'open') {
this._open(menu);
}
}
closeAll() {
this.menuTargets.forEach((menu) => (menu.dataset.state = 'closed'));
this.triggerTargets.forEach((trigger) => trigger.setAttribute('aria-expanded', 'false'));
document.removeEventListener('click', this._closeOnOutsideClick, true);
}
_open(menu) {
this.menuTargets.forEach((other) => (other.dataset.state = other === menu ? 'open' : 'closed'));
this.triggerTargets.forEach((trigger) =>
trigger.setAttribute('aria-expanded', menu.contains(trigger) ? 'true' : 'false')
);
document.addEventListener('click', this._closeOnOutsideClick, true);
}
_hasOpenMenu() {
return this.menuTargets.some((menu) => menu.dataset.state === 'open');
}
_menuFor(trigger) {
return this.menuTargets.find((menu) => menu.contains(trigger)) || null;
}
_closeOnOutsideClick(event) {
if (!this.element.contains(event.target)) {
this.closeAll();
}
}
}
assets/controllers/menubar_sub_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static values = {
openDelay: { type: Number, default: 0 },
closeDelay: { type: Number, default: 0 },
};
connect() {
this.openTimeout = null;
this.closeTimeout = null;
this.element.dataset.state = 'closed';
}
disconnect() {
this.#clearTimeouts();
}
show() {
this.#clearTimeouts();
this.openTimeout = setTimeout(() => {
this.element.dataset.state = 'open';
this.openTimeout = null;
}, this.openDelayValue);
}
hide() {
this.#clearTimeouts();
this.closeTimeout = setTimeout(() => {
this.element.dataset.state = 'closed';
this.closeTimeout = null;
}, this.closeDelayValue);
}
#clearTimeouts() {
if (this.openTimeout) {
clearTimeout(this.openTimeout);
this.openTimeout = null;
}
if (this.closeTimeout) {
clearTimeout(this.closeTimeout);
this.closeTimeout = null;
}
}
}
templates/components/Menubar.html.twig
{# @block content A list of `Menubar:Menu` children. #}
<div
role="menubar"
data-slot="menubar"
{{ attributes.defaults({
class: 'flex h-9 items-center space-x-1 rounded-md border bg-background p-1 shadow-xs'|tailwind_classes,
'data-controller': 'menubar',
'data-action': 'keydown.esc->menubar#closeAll',
}) }}
>
{%- block content %}{% endblock -%}
</div>
templates/components/Menubar/CheckboxItem.html.twig
{# @prop name string|null The checkbox form field name. #}
{# @prop checked boolean Whether the checkbox is initially checked. #}
{# @block content The label text. #}
{%- props name = null, checked = false -%}
<label
data-slot="menubar-checkbox-item"
{{ attributes.defaults({
class: 'relative flex cursor-pointer select-none items-center rounded-sm py-1.5 ps-8 pe-2 text-sm outline-none hover:bg-accent hover:text-accent-foreground'|tailwind_classes,
}) }}
>
<input type="checkbox" class="peer sr-only" {% if name %}name="{{ name }}"{% endif %} {% if checked %}checked{% endif %}>
<span class="absolute start-2 flex size-4 items-center justify-center opacity-0 peer-checked:opacity-100">
<twig:ux:icon name="lucide:check" class="size-4" aria-hidden="true" />
</span>
{%- block content %}{% endblock -%}
</label>
templates/components/Menubar/Content.html.twig
{# @block content The menu items revealed on hover or focus. #}
<div
role="menu"
data-slot="menubar-content"
{{ attributes.defaults({
class: 'invisible opacity-0 group-data-[state=open]/menubar-menu:visible group-data-[state=open]/menubar-menu:opacity-100 transition-opacity absolute start-0 top-full z-50 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md'|tailwind_classes,
}) }}
>
{%- block content %}{% endblock -%}
</div>
templates/components/Menubar/Item.html.twig
{# @block content The menu item label. #}
<button
type="button"
role="menuitem"
data-slot="menubar-item"
{{ attributes.defaults({
class: 'relative flex w-full cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50'|tailwind_classes,
}) }}
>
{%- block content %}{% endblock -%}
</button>
templates/components/Menubar/Menu.html.twig
{# @block content A `Menubar:Trigger` and a `Menubar:Content`. #}
<div
data-slot="menubar-menu"
data-menubar-target="menu"
{{ attributes.defaults({
class: 'group/menubar-menu relative'|tailwind_classes,
}) }}
>
{%- block content %}{% endblock -%}
</div>
templates/components/Menubar/RadioGroup.html.twig
{# @prop name string|null The radio group form field name, shared by all `Menubar:RadioItem` children that omit their own. #}
{# @block content One or more `Menubar:RadioItem` components. #}
{%- props name = null -%}
{%- do provide('menubar.radioGroupName', name) -%}
<div
role="group"
data-slot="menubar-radio-group"
{{ attributes }}
>
{%- block content %}{% endblock -%}
</div>
templates/components/Menubar/RadioItem.html.twig
{# @prop name string|null The radio form field name. Falls back to the parent `Menubar:RadioGroup`'s `name` when omitted. #}
{# @prop value string The value submitted when this radio is selected. #}
{# @prop checked boolean Whether this radio is initially checked. #}
{# @block content The label text. #}
{%- props name = null, value = '', checked = false -%}
{%- set _menubar_radioGroupName = name ?? inject('menubar.radioGroupName', null) -%}
<label
data-slot="menubar-radio-item"
{{ attributes.defaults({
class: 'relative flex cursor-pointer select-none items-center rounded-sm py-1.5 ps-8 pe-2 text-sm outline-none hover:bg-accent hover:text-accent-foreground'|tailwind_classes,
}) }}
>
<input type="radio" class="peer sr-only" {% if _menubar_radioGroupName %}name="{{ _menubar_radioGroupName }}"{% endif %} value="{{ value }}" {% if checked %}checked{% endif %}>
<span class="absolute start-2 flex size-4 items-center justify-center opacity-0 peer-checked:opacity-100">
<twig:ux:icon name="lucide:circle" class="size-2 fill-current" aria-hidden="true" />
</span>
{%- block content %}{% endblock -%}
</label>
templates/components/Menubar/Separator.html.twig
<div
role="separator"
data-slot="menubar-separator"
{{ attributes.defaults({
class: '-mx-1 my-1 h-px bg-muted'|tailwind_classes,
}) }}
></div>
templates/components/Menubar/Shortcut.html.twig
{# @block content The shortcut label, e.g. "⌘T". #}
<span
data-slot="menubar-shortcut"
{{ attributes.defaults({
class: 'ml-auto text-xs tracking-widest text-muted-foreground'|tailwind_classes,
}) }}
>
{%- block content %}{% endblock -%}
</span>
templates/components/Menubar/Sub.html.twig
{# @prop openDelay number Delay in milliseconds before showing the sub-menu. #}
{# @prop closeDelay number Delay in milliseconds before hiding the sub-menu. #}
{# @block content A `Menubar:SubTrigger` and a `Menubar:SubContent`. #}
{%- props openDelay = 0, closeDelay = 0 -%}
<div
data-slot="menubar-sub"
data-menubar-sub-open-delay-value="{{ openDelay }}"
data-menubar-sub-close-delay-value="{{ closeDelay }}"
{{ attributes.defaults({
class: 'group/menubar-sub relative'|tailwind_classes,
'data-controller': 'menubar-sub',
'data-action': 'mouseenter->menubar-sub#show mouseleave->menubar-sub#hide',
}) }}
>
{%- block content %}{% endblock -%}
</div>
templates/components/Menubar/SubContent.html.twig
{# @block content The sub-menu items revealed on hover or focus. #}
<div
role="menu"
data-slot="menubar-sub-content"
{{ attributes.defaults({
class: 'invisible opacity-0 group-data-[state=open]/menubar-sub:visible group-data-[state=open]/menubar-sub:opacity-100 transition-opacity absolute start-full top-0 z-50 ms-1 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md'|tailwind_classes,
}) }}
>
{%- block content %}{% endblock -%}
</div>
templates/components/Menubar/SubTrigger.html.twig
{# @block content The sub-menu trigger label (e.g., a `button`) that opens the sub-menu on hover or focus. #}
{%- set menubar_sub_trigger_attrs = {
'data-slot': 'menubar-sub-trigger',
role: 'menuitem',
tabindex: 0,
'data-action': 'focus->menubar-sub#show blur->menubar-sub#hide'|html_attr_type('sst'),
} -%}
{%- block content %}{% endblock -%}
templates/components/Menubar/Trigger.html.twig
{# @block content The trigger label (e.g., a `button`) that opens the menu on click. #}
{%- set menubar_trigger_attrs = {
'data-slot': 'menubar-trigger',
'data-menubar-target': 'trigger',
role: 'menuitem',
tabindex: 0,
'aria-haspopup': 'menu',
'aria-expanded': 'false',
'data-action': 'click->menubar#toggle mouseenter->menubar#enter'|html_attr_type('sst'),
} -%}
{%- block content %}{% endblock -%}
Usage
<twig:Menubar>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>File</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>New Tab</twig:Menubar:Item>
<twig:Menubar:Item>New Window</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>Edit</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>Undo</twig:Menubar:Item>
<twig:Menubar:Item>Redo</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
</twig:Menubar>
Examples
Checkbox Items
Use Menubar:CheckboxItem for options that can be toggled on and off. Set the checked prop to make an item checked initially.
100%
Loading...
<div class="flex items-start justify-center" style="min-height: 280px">
<twig:Menubar class="w-72">
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>View</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content class="w-64">
<twig:Menubar:CheckboxItem name="bookmarks-bar">Always Show Bookmarks Bar</twig:Menubar:CheckboxItem>
<twig:Menubar:CheckboxItem name="full-urls" checked>Always Show Full URLs</twig:Menubar:CheckboxItem>
<twig:Menubar:Separator />
<twig:Menubar:Item>Reload<twig:Menubar:Shortcut>⌘R</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item disabled>Force Reload<twig:Menubar:Shortcut>⇧⌘R</twig:Menubar:Shortcut></twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>Format</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:CheckboxItem name="strikethrough" checked>Strikethrough</twig:Menubar:CheckboxItem>
<twig:Menubar:CheckboxItem name="code">Code</twig:Menubar:CheckboxItem>
<twig:Menubar:CheckboxItem name="superscript">Superscript</twig:Menubar:CheckboxItem>
</twig:Menubar:Content>
</twig:Menubar:Menu>
</twig:Menubar>
</div>
Radio Group
Wrap Menubar:RadioItem components in a Menubar:RadioGroup so only one can be selected at a time. The group's name is shared with every item, so you only set it once.
100%
Loading...
<div class="flex items-start justify-center" style="min-height: 240px">
<twig:Menubar class="w-72">
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>Profiles</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:RadioGroup name="profile">
<twig:Menubar:RadioItem value="andy">Andy</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="benoit" checked>Benoit</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="luis">Luis</twig:Menubar:RadioItem>
</twig:Menubar:RadioGroup>
<twig:Menubar:Separator />
<twig:Menubar:Item>Edit...</twig:Menubar:Item>
<twig:Menubar:Item>Add Profile...</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>Theme</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:RadioGroup name="theme">
<twig:Menubar:RadioItem value="light">Light</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="dark">Dark</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="system" checked>System</twig:Menubar:RadioItem>
</twig:Menubar:RadioGroup>
</twig:Menubar:Content>
</twig:Menubar:Menu>
</twig:Menubar>
</div>
Submenus
Nest a Menubar:Sub inside a Menubar:Content to build a submenu, with its own Menubar:SubTrigger and Menubar:SubContent.
100%
Loading...
<div class="flex items-start justify-center" style="min-height: 320px">
<twig:Menubar class="w-72">
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>File</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Sub>
<twig:Menubar:SubTrigger>
<twig:Button variant="ghost" size="sm" class="w-full justify-start" {{ ...menubar_sub_trigger_attrs }}>
Share
<twig:ux:icon name="lucide:chevron-right" class="ms-auto size-4" aria-hidden="true" />
</twig:Button>
</twig:Menubar:SubTrigger>
<twig:Menubar:SubContent>
<twig:Menubar:Item>Email link</twig:Menubar:Item>
<twig:Menubar:Item>Messages</twig:Menubar:Item>
<twig:Menubar:Item>Notes</twig:Menubar:Item>
</twig:Menubar:SubContent>
</twig:Menubar:Sub>
<twig:Menubar:Separator />
<twig:Menubar:Item>Print...<twig:Menubar:Shortcut>⌘P</twig:Menubar:Shortcut></twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>Edit</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>Undo<twig:Menubar:Shortcut>⌘Z</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item>Redo<twig:Menubar:Shortcut>⇧⌘Z</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Sub>
<twig:Menubar:SubTrigger>
<twig:Button variant="ghost" size="sm" class="w-full justify-start" {{ ...menubar_sub_trigger_attrs }}>
Find
<twig:ux:icon name="lucide:chevron-right" class="ms-auto size-4" aria-hidden="true" />
</twig:Button>
</twig:Menubar:SubTrigger>
<twig:Menubar:SubContent>
<twig:Menubar:Item>Find...</twig:Menubar:Item>
<twig:Menubar:Item>Find Next</twig:Menubar:Item>
<twig:Menubar:Item>Find Previous</twig:Menubar:Item>
</twig:Menubar:SubContent>
</twig:Menubar:Sub>
<twig:Menubar:Separator />
<twig:Menubar:Item>Cut</twig:Menubar:Item>
<twig:Menubar:Item>Copy</twig:Menubar:Item>
<twig:Menubar:Item>Paste</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
</twig:Menubar>
</div>
With Icons
Add a ux:icon inside a Menubar:Item to pair each entry with an icon.
100%
Loading...
<div class="flex items-start justify-center" style="min-height: 200px">
<twig:Menubar class="w-72">
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>File</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>
<twig:ux:icon name="lucide:file" class="me-2 size-4" />
New File<twig:Menubar:Shortcut>⌘N</twig:Menubar:Shortcut>
</twig:Menubar:Item>
<twig:Menubar:Item>
<twig:ux:icon name="lucide:folder" class="me-2 size-4" />
Open Folder
</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>
<twig:ux:icon name="lucide:save" class="me-2 size-4" />
Save<twig:Menubar:Shortcut>⌘S</twig:Menubar:Shortcut>
</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>Edit</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>
<twig:ux:icon name="lucide:settings" class="me-2 size-4" />
Preferences
</twig:Menubar:Item>
<twig:Menubar:Item>
<twig:ux:icon name="lucide:trash" class="me-2 size-4" />
Delete
</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>
<twig:ux:icon name="lucide:help-circle" class="me-2 size-4" />
Help
</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
</twig:Menubar>
</div>
RTL
To enable RTL support, set the dir="rtl" attribute on the root element.
100%
Loading...
<div class="flex flex-col items-center gap-6" style="min-height: 480px">
{# Arabic #}
<div dir="rtl">
<twig:Menubar class="w-72">
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>ملف</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>علامة تبويب جديدة<twig:Menubar:Shortcut>⌘T</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item>نافذة جديدة<twig:Menubar:Shortcut>⌘N</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item disabled>نافذة التصفح المتخفي الجديدة</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Sub>
<twig:Menubar:SubTrigger>
<twig:Button variant="ghost" size="sm" class="w-full justify-start" {{ ...menubar_sub_trigger_attrs }}>
مشاركة
<twig:ux:icon name="lucide:chevron-right" class="ms-auto size-4 rtl:rotate-180" aria-hidden="true" />
</twig:Button>
</twig:Menubar:SubTrigger>
<twig:Menubar:SubContent>
<twig:Menubar:Item>رابط البريد الإلكتروني</twig:Menubar:Item>
<twig:Menubar:Item>الرسائل</twig:Menubar:Item>
<twig:Menubar:Item>الملاحظات</twig:Menubar:Item>
</twig:Menubar:SubContent>
</twig:Menubar:Sub>
<twig:Menubar:Separator />
<twig:Menubar:Item>طباعة...<twig:Menubar:Shortcut>⌘P</twig:Menubar:Shortcut></twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>تعديل</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>تراجع<twig:Menubar:Shortcut>⌘Z</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item>إعادة<twig:Menubar:Shortcut>⇧⌘Z</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Sub>
<twig:Menubar:SubTrigger>
<twig:Button variant="ghost" size="sm" class="w-full justify-start" {{ ...menubar_sub_trigger_attrs }}>
بحث
<twig:ux:icon name="lucide:chevron-right" class="ms-auto size-4 rtl:rotate-180" aria-hidden="true" />
</twig:Button>
</twig:Menubar:SubTrigger>
<twig:Menubar:SubContent>
<twig:Menubar:Item>البحث على الويب</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>بحث...</twig:Menubar:Item>
<twig:Menubar:Item>البحث التالي</twig:Menubar:Item>
<twig:Menubar:Item>البحث السابق</twig:Menubar:Item>
</twig:Menubar:SubContent>
</twig:Menubar:Sub>
<twig:Menubar:Separator />
<twig:Menubar:Item>قص</twig:Menubar:Item>
<twig:Menubar:Item>نسخ</twig:Menubar:Item>
<twig:Menubar:Item>لصق</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>عرض</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content class="w-44">
<twig:Menubar:CheckboxItem name="ar-bookmarks">شريط الإشارات المرجعية</twig:Menubar:CheckboxItem>
<twig:Menubar:CheckboxItem name="ar-urls" checked>عناوين URL الكاملة</twig:Menubar:CheckboxItem>
<twig:Menubar:Separator />
<twig:Menubar:Item>إعادة تحميل<twig:Menubar:Shortcut>⌘R</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item disabled>إعادة تحميل قسري<twig:Menubar:Shortcut>⇧⌘R</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>تبديل وضع ملء الشاشة</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>إخفاء الشريط الجانبي</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>الملفات الشخصية</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:RadioGroup name="ar-profile">
<twig:Menubar:RadioItem value="andy">Andy</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="benoit" checked>Benoit</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="luis">Luis</twig:Menubar:RadioItem>
</twig:Menubar:RadioGroup>
<twig:Menubar:Separator />
<twig:Menubar:Item>تعديل...</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>إضافة ملف شخصي...</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
</twig:Menubar>
</div>
{# Hebrew #}
<div dir="rtl">
<twig:Menubar class="w-72">
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>קובץ</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>כרטיסייה חדשה<twig:Menubar:Shortcut>⌘T</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item>חלון חדש<twig:Menubar:Shortcut>⌘N</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item disabled>חלון גלישה בסתר חדש</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Sub>
<twig:Menubar:SubTrigger>
<twig:Button variant="ghost" size="sm" class="w-full justify-start" {{ ...menubar_sub_trigger_attrs }}>
שתף
<twig:ux:icon name="lucide:chevron-right" class="ms-auto size-4 rtl:rotate-180" aria-hidden="true" />
</twig:Button>
</twig:Menubar:SubTrigger>
<twig:Menubar:SubContent>
<twig:Menubar:Item>קישור אימייל</twig:Menubar:Item>
<twig:Menubar:Item>הודעות</twig:Menubar:Item>
<twig:Menubar:Item>הערות</twig:Menubar:Item>
</twig:Menubar:SubContent>
</twig:Menubar:Sub>
<twig:Menubar:Separator />
<twig:Menubar:Item>הדפס...<twig:Menubar:Shortcut>⌘P</twig:Menubar:Shortcut></twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>ערוך</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:Item>בטל<twig:Menubar:Shortcut>⌘Z</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item>בצע שוב<twig:Menubar:Shortcut>⇧⌘Z</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Sub>
<twig:Menubar:SubTrigger>
<twig:Button variant="ghost" size="sm" class="w-full justify-start" {{ ...menubar_sub_trigger_attrs }}>
מצא
<twig:ux:icon name="lucide:chevron-right" class="ms-auto size-4 rtl:rotate-180" aria-hidden="true" />
</twig:Button>
</twig:Menubar:SubTrigger>
<twig:Menubar:SubContent>
<twig:Menubar:Item>חפש באינטרנט</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>מצא...</twig:Menubar:Item>
<twig:Menubar:Item>מצא הבא</twig:Menubar:Item>
<twig:Menubar:Item>מצא הקודם</twig:Menubar:Item>
</twig:Menubar:SubContent>
</twig:Menubar:Sub>
<twig:Menubar:Separator />
<twig:Menubar:Item>גזור</twig:Menubar:Item>
<twig:Menubar:Item>העתק</twig:Menubar:Item>
<twig:Menubar:Item>הדבק</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>תצוגה</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content class="w-44">
<twig:Menubar:CheckboxItem name="he-bookmarks">סרגל סימניות</twig:Menubar:CheckboxItem>
<twig:Menubar:CheckboxItem name="he-urls" checked>כתובות URL מלאות</twig:Menubar:CheckboxItem>
<twig:Menubar:Separator />
<twig:Menubar:Item>רענן<twig:Menubar:Shortcut>⌘R</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Item disabled>רענן בכוח<twig:Menubar:Shortcut>⇧⌘R</twig:Menubar:Shortcut></twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>החלף מסך מלא</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>הסתר סרגל צד</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
<twig:Menubar:Menu>
<twig:Menubar:Trigger>
<twig:Button variant="ghost" size="sm" {{ ...menubar_trigger_attrs }}>פרופילים</twig:Button>
</twig:Menubar:Trigger>
<twig:Menubar:Content>
<twig:Menubar:RadioGroup name="he-profile">
<twig:Menubar:RadioItem value="andy">Andy</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="benoit" checked>Benoit</twig:Menubar:RadioItem>
<twig:Menubar:RadioItem value="luis">Luis</twig:Menubar:RadioItem>
</twig:Menubar:RadioGroup>
<twig:Menubar:Separator />
<twig:Menubar:Item>ערוך...</twig:Menubar:Item>
<twig:Menubar:Separator />
<twig:Menubar:Item>הוסף פרופיל...</twig:Menubar:Item>
</twig:Menubar:Content>
</twig:Menubar:Menu>
</twig:Menubar>
</div>
</div>
API Reference
<twig:Menubar>
| Block | Description |
|---|---|
content |
A list of Menubar:Menu children. |
<twig:Menubar:CheckboxItem>
| Prop | Type | Default |
|---|---|---|
name The checkbox form field name.
|
string|null |
null |
checked Whether the checkbox is initially checked.
|
boolean |
false |
| Block | Description |
|---|---|
content |
The label text. |
<twig:Menubar:Content>
| Block | Description |
|---|---|
content |
The menu items revealed on hover or focus. |
<twig:Menubar:Item>
| Block | Description |
|---|---|
content |
The menu item label. |
<twig:Menubar:Menu>
| Block | Description |
|---|---|
content |
A Menubar:Trigger and a Menubar:Content. |
<twig:Menubar:RadioGroup>
| Prop | Type | Default |
|---|---|---|
name The radio group form field name, shared by all
Menubar:RadioItem children that omit their own. |
string|null |
null |
| Block | Description |
|---|---|
content |
One or more Menubar:RadioItem components. |
<twig:Menubar:RadioItem>
| Prop | Type | Default |
|---|---|---|
name The radio form field name. Falls back to the parent
Menubar:RadioGroup's name when omitted. |
string|null |
null |
value The value submitted when this radio is selected.
|
string |
'' |
checked Whether this radio is initially checked.
|
boolean |
false |
| Block | Description |
|---|---|
content |
The label text. |
<twig:Menubar:Shortcut>
| Block | Description |
|---|---|
content |
The shortcut label, e.g. "⌘T". |
<twig:Menubar:Sub>
| Prop | Type | Default |
|---|---|---|
openDelay Delay in milliseconds before showing the sub-menu.
|
number |
0 |
closeDelay Delay in milliseconds before hiding the sub-menu.
|
number |
0 |
| Block | Description |
|---|---|
content |
A Menubar:SubTrigger and a Menubar:SubContent. |
<twig:Menubar:SubContent>
| Block | Description |
|---|---|
content |
The sub-menu items revealed on hover or focus. |
<twig:Menubar:SubTrigger>
| Block | Description |
|---|---|
content |
The sub-menu trigger label (e.g., a button) that opens the sub-menu on hover or focus. |
<twig:Menubar:Trigger>
| Block | Description |
|---|---|
content |
The trigger label (e.g., a button) that opens the menu on click. |