Logo

Sidebar

Composable application sidebars with provider state, variants, collapsible modes, menu primitives, rail, trigger, skeletons, and RTL support.

Preview

Application shell

Composable sidebar layout

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

Usage

TS

import { FrSidebarModule } from '@frame-ui-ng/components/sidebar';

HTML

<div frSidebarProvider>
  <aside frSidebar>
    <div frSidebarHeader>
      <a frSidebarMenuButton size="lg" href="#">
        <span>Atlas Studio</span>
      </a>
    </div>

    <div frSidebarContent>
      <div frSidebarGroup>
        <div frSidebarGroupLabel>Workspace</div>
        <div frSidebarGroupContent>
          <ul frSidebarMenu>
            <li frSidebarMenuItem>
              <a frSidebarMenuButton active href="#">
                <span>Dashboard</span>
              </a>
            </li>
          </ul>
        </div>
      </div>
    </div>

    <div frSidebarFooter>
      <a frSidebarMenuButton variant="outline" href="#">
        <span>Settings</span>
      </a>
    </div>

    <div frSidebarRail></div>
  </aside>

  <main frSidebarInset>
    <button frSidebarTrigger type="button">Toggle sidebar</button>
  </main>
</div>

Examples

Basic

Wrap the sidebar and main content in a provider so triggers, rails, and menu state share one context.

Application shell

Composable sidebar layout

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

Icon Collapse

Use collapsible="icon" when the collapsed state should keep the sidebar rail visible for icon navigation.

Icon collapse

Collapsible

Composable sidebar layout

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

Variants

Use sidebar, floating, or inset variants depending on whether the panel should feel attached or card-like.

Application shell

Composable sidebar layout

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

Controlled

Bind the provider open input and listen for openChange when parent state should own expansion.

Controlled

Composable sidebar layout

Bind the provider open input and respond to openChange when parent state should own the sidebar.

Skeleton

Use menu skeleton rows while navigation data is loading or permissions are being resolved.

Application shell

Loading menu state

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

Right Side

Set side="right" for secondary panels, inspectors, or workflows that should attach to the opposite edge.

Application shell

Right-aligned sidebar

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

RTL

Use logical properties and side placement to support right-to-left application shells.

Application shell

RTL-ready navigation

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

Custom Styling

Override sidebar tokens on the provider, sidebar, or any ancestor to tune width, surfaces, borders, active states, radius, and motion.

Application shell

Composable sidebar layout

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

Token Inspector

Hover the provider, sidebar, header, content, menu, active button, badge, rail, trigger, or inset to inspect the tokens used by the composed shell.

Application shell

Composable sidebar layout

Use the provider to coordinate trigger, rail, sidebar state, and the surrounding inset content.

Design Tokens

Use these CSS custom properties to tune sidebar width, surfaces, text, borders, active states, menu rhythm, shadows, motion, and mobile layering.

SCSS

--frame-sidebar-width: 16rem;
--frame-sidebar-width-icon: 3.5rem;
--frame-sidebar-width-mobile: 18rem;
--frame-sidebar-bg: var(--frame-background, #fff);
--frame-sidebar-color: var(--frame-foreground, #09090b);
--frame-sidebar-muted-color: var(--frame-muted-foreground, #71717a);
--frame-sidebar-border: var(--frame-border, #e5e7eb);
--frame-sidebar-accent: var(--frame-accent, #f4f4f5);
--frame-sidebar-accent-color: var(--frame-accent-foreground, #18181b);
--frame-sidebar-primary: var(--frame-primary, #18181b);
--frame-sidebar-primary-color: var(--frame-primary-foreground, #fff);
--frame-sidebar-ring: var(--frame-ring, #18181b);
--frame-sidebar-radius: var(--frame-radius-lg, 0.75rem);
--frame-sidebar-margin: 0.5rem;
--frame-sidebar-padding: 0.5rem;
--frame-sidebar-gap: 0.5rem;
--frame-sidebar-menu-button-height: 2rem;
--frame-sidebar-menu-button-radius: var(--frame-radius-md, 0.5rem);
--frame-sidebar-shadow: 0 20px 60px rgb(0 0 0 / 0.12);
--frame-sidebar-transition-duration: 200ms;
--frame-sidebar-z-index: 40;
--frame-sidebar-mobile-backdrop: rgb(0 0 0 / 0.42);