Skip to content

Navigation

Drawer (navigation)

The Drawer used for navigation and settings panels that slide in from the left or right edge.

<script>
  import { Drawer } from "@codeatlasdev/ui";
  let open = $state(false);
</script>

<Drawer bind:open side="left" title="Navigation">...</Drawer>

This is the same component as the Drawer in Feedback, shown here with the two navigation patterns: a left menu and a right settings panel. It is a native modal <dialog> in the top layer: focus is trapped, Escape and a press on the overlay close it, and focus returns to the trigger. See that page for the full props table, the bottom side and the footer actions snippet.

#157

Left and right

Left for navigation, right for settings or details.

Reference #157 · Pick in the gallery

Code
svelte
<script lang="ts">
  import { Drawer, Button } from '@codeatlasdev/ui';
  import { Settings } from '@lucide/svelte';

  let leftOpen = $state(false);
  let rightOpen = $state(false);
</script>

<Button variant="outlined" onclick={() => (leftOpen = true)}>Open left drawer</Button>
<Button variant="outlined" onclick={() => (rightOpen = true)}>
  {#snippet leading()}<Settings size={16} stroke-width={2} />{/snippet}
  Open settings
</Button>

<Drawer bind:open={leftOpen} side="left" title="Navigation">
  <nav class="nav" aria-label="Demo navigation">
    {#each ['Home', 'Components', 'Foundation', 'About'] as item}
      <a href="#top" class="nav__item" onclick={() => (leftOpen = false)}>{item}</a>
    {/each}
  </nav>
</Drawer>

<Drawer bind:open={rightOpen} side="right" title="Settings">
  <div class="settings">
    {#each [['Theme', 'Amber'], ['Language', 'English'], ['Notifications', 'Enabled']] as [label, value]}
      <div class="row">
        <p class="label">{label}</p>
        <p class="value">{value}</p>
      </div>
    {/each}
  </div>
</Drawer>

<style>
  .nav { display: flex; flex-direction: column; gap: 2px; }
  .nav__item {
    padding: 10px 16px;
    border-radius: var(--ca-radius-sm);
    font-size: var(--ca-font-size-body2);
    font-weight: 500;
    color: var(--ca-text-primary);
    text-decoration: none;
    transition: background var(--ca-duration-fast) var(--ca-ease-standard);
  }
  .nav__item:hover { background: var(--ca-action-hover); }
  .row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 0;
    border-bottom: 1px solid var(--ca-outline-subtle);
  }
  .label, .value { margin: 0; font-size: var(--ca-font-size-body2); }
  .label { color: var(--ca-text-secondary); }
  .value { font-weight: 500; color: var(--ca-text-primary); }
</style>