Sidebar
Vertical navigation panel. Default, compact (icon-only), and dark variants.
Overview
The Sidebar component is a core building block of the Byteion design system, providing a robust, accessibility-compliant interface for its specific UI capabilities.
Why this exists
The sidebar is the primary vertical navigation for dashboard and admin interfaces. It organizes dozens of routes into scannable groups with icons.
Mental model
A sidebar is a persistent vertical navigation with grouped links. It can collapse to icons to save space, and expand on hover for full labels.
When to use
When not to use
Basic example
The following example demonstrates standard usage, fully compliant with Byteion's token-first approach.
import { Sidebar, SidebarHeader, SidebarNav, SidebarSection, SidebarItem, SidebarFooter } from '@byteion/react';
export default function SidebarDemo() {
return (
<Sidebar>
<SidebarHeader><strong>Byteion</strong></SidebarHeader>
<SidebarNav>
<SidebarSection label="Workspace">
<SidebarItem href="/" icon={<i className="ti ti-home" />} active>Dashboard</SidebarItem>
<SidebarItem href="/projects" icon={<i className="ti ti-folder" />}>Projects</SidebarItem>
<SidebarItem href="/team" icon={<i className="ti ti-users" />} badge="3">Team</SidebarItem>
</SidebarSection>
<SidebarSection label="Account">
<SidebarItem href="/settings" icon={<i className="ti ti-settings" />}>Settings</SidebarItem>
</SidebarSection>
</SidebarNav>
<SidebarFooter>v1.0.0</SidebarFooter>
</Sidebar>
);
}
<script setup lang="ts">
import { Sidebar, SidebarHeader, SidebarNav, SidebarSection, SidebarItem, SidebarFooter } from '@byteion/vue';
</script>
<template>
<Sidebar>
<SidebarHeader><strong>Byteion</strong></SidebarHeader>
<SidebarNav>
<SidebarSection label="Workspace">
<SidebarItem href="/" active>
<template #icon><i class="ti ti-home" /></template>
Dashboard
</SidebarItem>
<SidebarItem href="/projects">
<template #icon><i class="ti ti-folder" /></template>
Projects
</SidebarItem>
<SidebarItem href="/team" badge="3">
<template #icon><i class="ti ti-users" /></template>
Team
</SidebarItem>
</SidebarSection>
<SidebarSection label="Account">
<SidebarItem href="/settings">
<template #icon><i class="ti ti-settings" /></template>
Settings
</SidebarItem>
</SidebarSection>
</SidebarNav>
<SidebarFooter>v1.0.0</SidebarFooter>
</Sidebar>
</template>
Variants
Each variant communicates a different meaning. Choose based on priority, not aesthetics.
Single default variant.
Sizes
Size should match the importance and context of the component.
- md — md size.
States
This component reacts seamlessly to the following interaction and data states:
- default — Resting appearance before interaction.
- hover — Pointer is over the element — visual feedback via color or shadow.
- focus — Keyboard or tab focus — shows ring indicator for accessibility.
- active — Currently selected or in use.
- disabled — Non-interactive — grayed out, cursor not-allowed.
Anatomy
Usage guidelines
- Group related routes together.
- Show active page clearly.
- Support collapsed (icons-only) mode.
Do and Don't
Do
- Group logically.
- Highlight active page.
- Support collapse mode.
Don't
- Do not mix app nav and page nav in one sidebar.
- Do not exceed 3 levels of nesting.
- Do not hide the active indicator.
Accessibility
Uses <nav> with aria-label. Collapsed mode must still provide labels via tooltip or aria-label.
Role:navigation
Customization
Width, background, and active indicator follow layout tokens.
Compose with React cva()
Use the exportedcva() +cn() utilities to compose your own variant on top of the Byteion tokens.
import { cva, cn, type VariantProps } from '@byteion/react';
const mySidebar = cva('base classes…', {
variants: {
accent: { soft:'border-primary-200', loud:'border-primary-500' },
},
defaultVariants: { accent:'soft' },
});
type Props = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof mySidebar>;
Compose with Vue cva()
Use the exportedcva() +cn() utilities inside standard Vue setup blocks.
<script setup lang="ts">
import { computed, useAttrs } from 'vue';
import { cva, type VariantProps } from '@byteion/vue';
interface Props { accent?:'soft' |'loud' }
const props = withDefaults(defineProps<Props>(), { accent:'soft' });
const attrs = useAttrs();
const mySidebar = cva('base classes…', {
variants: { accent: { soft:'border-primary-200', loud:'border-primary-500' } },
});
const cls = computed(() => mySidebar({ accent: props.accent, class: attrs.class as string | undefined }));
</script>
Runtime events
Byteion keeps framework APIs idiomatic: HTML uses DOM custom events, React uses callback props, and Vue uses emitted events / v-model updates.
HTML / JS events
No HTML runtime events are declared by this adapter.
React callbacks
No React callback events are declared by this adapter.
Vue emits
No Vue emitted events are declared by this adapter.
Remote / AJAX
This component does not implement Byteion JS remote loading. Use normal HTML form submission, framework state, or your application data layer around it.
API Reference
Static HTML with optional JS for collapse/expand.
HTML Data Attributes
No custom data attributes required.
React Props · SidebarProps
Extracted directly fromreact/src/components/Sidebar.tsx.
export interface SidebarProps extends HTMLAttributes<HTMLElement> {
/** Visual style. */
variant?: 'default' | 'compact' | 'dark';
children?: ReactNode;
}
Vue Props · SidebarProps
Extracted directly fromvue/src/components/Sidebar.vue.
export interface SidebarProps {
variant?: 'default' | 'compact' | 'dark';
}
Developer tips
Common mistakes
- Too many top-level items — split into sections with labels.
- No active route indicator — always set
active+aria-current="page". - Using sidebar for page-level table of contents — use a separate ToC component.
- Icon-only compact mode without
aria-label— useiconOnlywhich sets it automatically from child text. - Relying only on Tooltip for compact labels — every link must have programmatic accessible text.
- More than 2 levels of nesting — restructure the information architecture.
- Mixing app navigation with page actions — keep actions in the page header or toolbar.
- Hardcoded raw colors instead of tokens — use
bg-card,text-foreground, etc. - Poor contrast in dark variant — verify
bg-foreground+text-mutedmeets WCAG AA. - Mobile sidebar with no close/escape path — wrap in a Drawer for dismissal.
Production usage tips
- Test active route state on every route — a stale active indicator confuses users.
- Test keyboard tab order — focus should flow through all links in visual order.
- Test compact mode with screen readers — every icon-only link needs an
aria-label. - Test dark variant contrast in both light and dark themes.
- Test long nav lists — ensure scrolling works within the sidebar and does not overflow the layout.
- Test mobile fallback via Drawer or Navbar — ensure the sidebar is hidden on small screens and accessible via a toggle.
- Keep React and Vue output aligned with the core HTML composition — use the same token classes and structure.
Premium examples
Advanced patterns available in Byteion Pro:
aria-label on every link.
• Responsive Sidebar + Drawer shell — sidebar becomes a Drawer on mobile via media queries.Related components
Unlock Premium Patterns
Get access to copy-paste ready Pro blocks, SaaS templates, and advanced data-tables built with this component.
Explore Pro Components