Skip to content
Navigation

Navigation Drawer

MD3 navigation drawer — the sidebar of a dashboard, in all three of the shapes a dashboard needs it in.

Walkthrough

1. Standard

Sections group items and badge rides on the end of a row — the sidebar of a dashboard with more pages than one flat list can hold.

<script lang="ts">	import { NavigationDrawer, NavigationDrawerItem, NavigationDrawerSection } from 'omaris';​	let selected = $state('inbox');</script>​<div class="h-80 w-72 max-w-full overflow-hidden rounded-shape-lg border border-border">	<NavigationDrawer label="Mail">		<NavigationDrawerSection label="Mail">			<NavigationDrawerItem				label="Inbox"				badge={12}				selected={selected === 'inbox'}				onclick={() => (selected = 'inbox')}			/>			<NavigationDrawerItem				label="Sent"				selected={selected === 'sent'}				onclick={() => (selected = 'sent')}			/>		</NavigationDrawerSection>​		<NavigationDrawerSection label="Commerce" divider>			<NavigationDrawerItem label="Orders" badge="New">				{#snippet submenu()}					<NavigationDrawerItem label="Open" badge={4} />					<NavigationDrawerItem label="Shipped" />				{/snippet}			</NavigationDrawerItem>		</NavigationDrawerSection>	</NavigationDrawer></div>

2. Collapsed rail

Collapsed, it becomes MD3's rail: icons only, labels as tooltips. What a laptop wants once the content needs the width more than the labels.

<script lang="ts">	import { Button, NavigationDrawer, NavigationDrawerItem } from 'omaris';​	let collapsed = $state(true);</script>​{#snippet overview()}	...{/snippet}​{#snippet orders()}	...{/snippet}​{#snippet team()}	...{/snippet}​<div class="flex w-full flex-col items-start gap-3">	<Button size="xs" variant="outlined" onclick={() => (collapsed = !collapsed)}>		{collapsed ? 'Expand' : 'Collapse'}	</Button>​	<div class="h-64 overflow-hidden rounded-shape-lg border border-border">		<NavigationDrawer bind:collapsed label="Sections">			<NavigationDrawerItem label="Overview" selected>				{#snippet icon()}{@render overview()}{/snippet}			</NavigationDrawerItem>			<NavigationDrawerItem label="Orders">				{#snippet icon()}{@render orders()}{/snippet}			</NavigationDrawerItem>			<NavigationDrawerItem label="Team">				{#snippet icon()}{@render team()}{/snippet}			</NavigationDrawerItem>		</NavigationDrawer>	</div></div>

3. Modal

mode="modal" slides it over the page on a scrim. In an app, responsive is the one to reach for: a sidebar above the breakpoint, this modal below it, so you write one drawer instead of two.

<script lang="ts">	import { Button, NavigationDrawer, NavigationDrawerItem } from 'omaris';​	let open = $state(false);</script>​<Button variant="tonal" onclick={() => (open = true)}>Open the drawer</Button>​<NavigationDrawer bind:open mode="modal" label="Sections">	{#snippet header()}		<span class="px-2 py-1 text-title-md">omaris</span>	{/snippet}	<NavigationDrawerItem label="Overview" selected />	<NavigationDrawerItem label="Orders" badge={12} />	<NavigationDrawerItem label="Settings" /></NavigationDrawer>