BladewindUI: Sidebar Navigation Component

Sidebar

Sidebar provides structured application navigation with named sections, nested groups, explicit active state, desktop collapse, and a Bladewind Drawer on mobile. It uses one navigation tree for both presentations, so item state, group state, IDs, and the accessible navigation landmark stay synchronized.

Monday, 28 August

Orders

Open orders

12

Ready to ship

7

Attention needed

2

Today's fulfilment

Orders due before the 4:00 PM collection.

ORD-1048, Kofi AddoGHS 840
ORD-1049, Akosua OwusuGHS 315
<x-bladewind::sidebar name="workspace-navigation" label="Workspace navigation" active="orders" collapsible="true" mobile="drawer">
    <x-slot:header>Acme Workspace</x-slot:header>
    <x-bladewind::sidebar.group name="workspace" label="Workspace" icon="squares-2x2" expanded="true">
        <x-bladewind::sidebar.item name="overview" label="Overview" href="/dashboard" icon="home" />
        <x-bladewind::sidebar.item name="orders" label="Orders" href="/orders" icon="shopping-bag" description="Review fulfilment" badge="12" />
        <x-bladewind::sidebar.item name="customers" label="Customers" href="/customers" icon="users" />
    </x-bladewind::sidebar.group>
    <x-slot:footer><x-bladewind::avatar image="/images/avatar.png" name="Ama Mensah" /></x-slot:footer>
</x-bladewind::sidebar>

Desktop Expanded and Collapsed States

Set collapsible="true" to allow compact icon-only presentation. The optional collapse control is shown by default for a collapsible Sidebar. Labels remain available through accessible names and native tooltips. Nested destinations stay in the navigation tree and group state is preserved.

Navigation Sections and Active State

Groups create named navigation sections. Set active on the Sidebar to one item name. This value is the canonical active state and takes precedence over item-level active values. If the Sidebar has no active value, the first enabled item marked active wins. Sidebar does not inspect the current request URL.

Only the selected destination receives aria-current="page". Set multiple-active="true" only when the application intentionally has several current destinations.

Nested and Collapsible Navigation

Groups can contain items and other groups. The example below uses three practical navigation levels. An active descendant opens every ancestor. A collapsed group hides its descendants from visual and keyboard navigation without deleting their state.

Mobile Drawer Presentation

mobile="drawer" is the default. Below 1024 pixels, openSidebar() moves the same Sidebar into the existing Bladewind Drawer. Drawer supplies Escape dismissal, backdrop dismissal, focus trapping, focus restoration, and body scroll locking. The Sidebar returns to its desktop host after close.

close-on-navigate defaults to true. It closes the mobile Drawer after an enabled item is activated. Persistence and route matching are not enabled automatically. Set mobile="none" when no mobile presentation is needed.

Left and Right Placement

left and right are physical edges in desktop and mobile layouts. start and end follow the computed text direction. This makes logical placement suitable when one layout serves both left-to-right and right-to-left languages.

Multiple Independent Sidebars

Every helper resolves one named instance. Groups with the same name can safely exist in separate Sidebars because state and persistence are scoped to the Sidebar root.

collapseSidebar('project-navigation');
expandSidebarGroup('account-navigation', 'settings');

Persistent State

Persistence is opt-in. Set persist="true" for desktop collapse state and persist-groups="true" for expanded groups. The default key is bladewind:sidebar:{name}. Supply storage-key when an application needs a different namespace. Invalid or unavailable browser storage is ignored safely.

<x-bladewind::sidebar name="admin-navigation" persist="true" persist-groups="true" storage-key="acme:admin-sidebar">
    ...
</x-bladewind::sidebar>

Long Labels and Large Navigation Sets

Long labels wrap inside the available width. Full-height and content-height Sidebars cap themselves at the viewport and keep scrolling inside the navigation region. The header and footer remain sticky while a large tree scrolls.



Dark Mode

Sidebar follows the page dark class and keeps active, hover, focus, border, description, and badge contrast readable. Drawer uses the same dark theme because it receives the original Sidebar DOM.

RTL Behavior

Set dir="rtl" on the Sidebar or an ancestor. Logical start and end placement reverse automatically. Indentation, alignment, and horizontal keyboard behavior follow the computed direction. In RTL, Left Arrow opens or enters a group and Right Arrow closes or returns to its parent.

Accessibility and Keyboard Guidance

Sidebar renders one labelled navigation landmark with semantic lists. Active links use aria-current="page". Group buttons use aria-expanded and aria-controls. Disabled items cannot receive focus or activate.

KeyBehavior
Enter or SpaceActivate a group button or button-like item.
Up Arrow or Down ArrowMove through visible enabled controls.
Home or EndMove to the first or last visible control.
Right ArrowOpen or enter a group in LTR. Close or return in RTL.
Left ArrowClose or return in LTR. Open or enter in RTL.
EscapeClose the mobile Drawer and restore focus to its trigger.

Events

Before events are cancelable. Call preventDefault() to stop the related state change or navigation action. Details include sidebarName, presentation, placement, source, and triggeringElement. State events add previous and next state. Group and item events add their names.

Event suffixWhen it runs
before-open, before-closeBefore mobile Drawer presentation changes.
opened, closedAfter Drawer finishes the change.
before-collapse, before-expandBefore desktop compact state changes.
collapsed, expandedAfter desktop compact state changes.
group:before-change, group:changedBefore and after a named group changes.
item-activateWhen a button-like item is activated.
before-navigateBefore a link continues and configured mobile auto-close runs.

Full List of Attributes

Sidebar Attributes

AttributeDefaultDescription
nameGeneratedUnique public helper and state scope.
labelSidebar navigationAccessible navigation name.
activenullCanonical active item name.
placementleftleft, right, start, or end.
mobiledrawerdrawer or none.
mobile-sizesmallExisting Drawer size.
collapsiblefalseEnables desktop compact mode.
collapsedfalseInitial desktop state.
show-collapse-controltrueShows the control when collapsible.
close-on-navigatetrueCloses mobile Drawer after activation.
persistfalsePersists desktop collapsed state.
persist-groupsfalsePersists group state.
storage-keyDerived from nameSidebar-specific localStorage key.
heightfullfull or content.
multiple-activefalseAllows several explicit active items only when root active is omitted.
collapse-labelCollapse navigationAccessible collapse control label.
expand-labelExpand navigationAccessible expand control label.
close-labelClose navigationAccessible mobile close label.

Sidebar Group Attributes

AttributeDefaultDescription
nameRequiredName scoped to its Sidebar.
labelRequiredVisible and accessible section label.
iconnullHeroicon name.
icon-typeoutlineIcon type.
icon-diremptyCustom icon directory.
expandedfalseInitial expanded state.
disabledfalsePrevents group activation.

Sidebar Item Attributes

AttributeDefaultDescription
nameRequiredActive state and event identifier.
labelemptyVisible and accessible label.
hrefnullLink destination. Omit for a button action.
iconnullHeroicon name.
icon-typeoutlineIcon type.
icon-diremptyCustom icon directory.
descriptionnullSecondary item text.
badgenullCounter or status value.
badge-labelDerivedScreen reader meaning for the badge.
activefalseExplicit active state when root active is omitted.
disabledfalseRemoves activation and focus.
externalfalseAdds external link semantics and indicator.
targetnullLink target.

Slots

SlotDescription
sidebar headerBrand, workspace switcher, or composed header content.
sidebar defaultSidebar groups and items.
sidebar footerAccount, status, or footer actions.
group defaultNested groups and items.
item defaultCustom item copy while Sidebar keeps icon, badge, and action semantics.

JavaScript API

Helpers return true on success or when the requested state already applies. They return false for missing, disabled, unsupported, or canceled targets.

openSidebar('workspace-navigation');
closeSidebar('workspace-navigation');
toggleSidebar('workspace-navigation');
collapseSidebar('workspace-navigation');
expandSidebar('workspace-navigation');
toggleSidebarGroup('workspace-navigation', 'settings');
expandSidebarGroup('workspace-navigation', 'settings');
collapseSidebarGroup('workspace-navigation', 'settings');
resetSidebar('workspace-navigation');

Sidebar with all attributes defined

<x-bladewind::sidebar
    name="account-navigation"
    label="Account navigation"
    active="billing"
    placement="start"
    mobile="drawer"
    mobile-size="small"
    collapsible="true"
    collapsed="false"
    show-collapse-control="true"
    close-on-navigate="true"
    persist="true"
    persist-groups="true"
    storage-key="acme:account-navigation"
    height="full"
    multiple-active="false"
    collapse-label="Collapse account navigation"
    expand-label="Expand account navigation"
    close-label="Close account navigation"
    class="account-sidebar"
    data-region="account">
    <x-slot:header>Acme Account</x-slot:header>
    <x-bladewind::sidebar.group name="settings" label="Settings" icon="cog-6-tooth" icon-type="outline" icon-dir="" expanded="true" disabled="false">
        <x-bladewind::sidebar.item name="billing" label="Billing" href="/billing" icon="credit-card" icon-type="outline" icon-dir="" description="Plans and invoices" badge="2" badge-label="2 unpaid invoices" active="false" disabled="false" external="false" target="_self" class="billing-link" data-area="finance" />
    </x-bladewind::sidebar.group>
    <x-slot:footer>Account footer</x-slot:footer>
</x-bladewind::sidebar>
The source files for this component are available in resources > views > components > bladewind > sidebar