Side Navigation
The app rail: logo, search, page links and the account, expanded or icons only.
Preview
Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.
Installation
Add the component
npx ritla add side-navigationAlso works with shadcn:
npx shadcn@latest add @ritla/side-navigationDependencies it brings
@phosphor-icons/reactOr copy by hand
Installing by hand copies the component's source into your project. The source comes with a Ritla UI license, so the CLI is the short way to the same files.
Usage
import { NavItem, SideNavigation, SideNavigationGroup } from "@/components/ui/side-navigation";<SideNavigation aria-label="Main"> <SideNavigationGroup> <NavItem href="/" icon={HouseIcon} label="Home" selected /> <NavItem href="/payments" icon={ReceiptIcon} label="Payments" count={3} /> </SideNavigationGroup></SideNavigation>Examples
Collapsed
80px, icons only; each link keeps its name for screen readers.
App shell
A workspace switcher, titled groups and the user with Sign out (Figma Sidebar app shell, Beta).
API reference
SideNavigation
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "expanded" | "collapsed" | "expanded" | Figma's Style: Expanded (296px) or Collapsed (80px). |
aria-label | string | None | Names the navigation landmark. |
NavItem
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | None | Figma's Label. |
icon | IconComponent | None | Figma's Icon: any Phosphor icon. |
selected | boolean | false | State Selected: the current page, as aria-current="page". |
count | number | None | Figma's Show count: a count badge at the end. |
render | ReactElement | None | A link element to render instead of <a>, such as Next's <Link>. |
SideNavigationWorkspace
| Prop | Type | Default | Description |
|---|---|---|---|
avatar / name / description | ReactNode | None | The workspace's avatar, name and description; a button that opens a Menu of workspaces. |
SideNavigationGroup
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | None | An optional group title, hidden when collapsed. |
Usage guidelines
Side navigation holds an app's destinations on desktop, in a column beside the content. Its order, its side in Arabic, the collapsed rail, the featured card, and the checks before handoff.
1. Order and grouping
Main destinations first, then a spacer, then settings and support. The account row is always last.
Do
- Order by how often people go there.
- Keep Settings and Support at the bottom in every app.
Don't
- Sort alphabetically.
- Add dividers between every item.
2. Arabic and RTL
The rail sits on the right in Arabic. Icons stay on the inline start of each item; chevrons and counts move to the end.
3. Collapsed rail
Collapsed shows icons only at 80 px, and each label stays as the link's accessible name. Show it in a Tooltip on hover and focus.
Do
- Keep the selected state visible when collapsed.
- Let the person expand it again with the toggle at the top.
Don't
- Hide the account row when collapsed; show the avatar.
4. Featured card
One optional card for an onboarding task or offer. It has a title, one line and up to two actions.
Do
- Let the person dismiss it.
- Replace it with the next task when done.
Don't
- Stack two cards.
- Use it for errors; use an Alert in the content.
Before handoff
- Expanded and collapsed placed in both directions.
- Selected state shown on a real destination.
- Phone behaviour noted: the same items move into a side Sheet.
Accessibility
Keyboard
Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.
| Key | Action |
|---|---|
| Tab | Moves through the links in order. |
ARIA
- The rail is a named
<nav>, and the links sit in a<ul>. - The current page is
aria-current="page". - When collapsed the label stays as visually hidden text, so every link keeps its name.
Arabic and RTL notes
Mirrors
- The rail sits on the right in Arabic, with its rule on its left.
- The icon starts the row and the count ends it.
Does not mirror
- The logo and the email address don't mirror.
- Icons without a direction (home, card) stay as they are.
- Numerals
- The count follows the
RitlaProvidernumerals setting. - Arabic typography
- Labels are
label-16Medium; the selected one is Semibold. - Mixed-direction text
- The email address is isolated LTR.
Do
- The RTL variant, so the selected bar sits on the correct edge.
- Keep the logo on the inline start.
Don't
- Mirror the brand logo or product icons.
- Keep the rail on the left for Arabic because the code did.