Bar
Contents
import { Navigation } from '@skeletonlabs/skeleton-react';
import { BookIcon } from 'lucide-react';
import { HouseIcon } from 'lucide-react';
import { PopcornIcon } from 'lucide-react';
import { TvIcon } from 'lucide-react';
export default function Default() {
const links = [
{ label: 'Home', href: '#', icon: HouseIcon },
{ label: 'Books', href: '#', icon: BookIcon },
{ label: 'Movies', href: '#', icon: PopcornIcon },
{ label: 'Television', href: '#', icon: TvIcon },
];
let anchorBar = 'btn hover:preset-tonal flex-col items-center gap-1';
return (
<div className="w-[375px] h-[667px] grid grid-rows-[1fr_auto] border border-surface-200-800">
<div className="flex justify-center items-center">
<p>Contents</p>
</div>
<Navigation layout="bar">
<Navigation.Menu className="grid grid-cols-4 gap-2">
{links.map((link) => {
const Icon = link.icon;
return (
<a key={link.label} href={link.href} className={anchorBar}>
<Icon className="size-5" />
<span className="text-xs">{link.label}</span>
</a>
);
})}
</Navigation.Menu>
</Navigation>
</div>
);
}Contents
<script lang="ts">
import { BikeIcon, BookIcon, HouseIcon, TreePalmIcon } from '@lucide/svelte';
import { Navigation } from '@skeletonlabs/skeleton-svelte';
const links = [
{ label: 'Home', href: '#', icon: HouseIcon },
{ label: 'Entertainment', href: '#', icon: BookIcon },
{ label: 'Recreation', href: '#', icon: BikeIcon },
{ label: 'Relaxation', href: '#', icon: TreePalmIcon },
];
let anchorBar = 'btn hover:preset-tonal flex-col items-center gap-1';
</script>
<div class="w-[375px] h-[667px] grid grid-rows-[1fr_auto] border border-surface-200-800">
<div class="flex justify-center items-center">
<p>Contents</p>
</div>
<!-- --- -->
<Navigation layout="bar">
<Navigation.Menu class="grid grid-cols-4 gap-2">
{#each links as link (link)}
{@const Icon = link.icon}
<a href={link.href} class={anchorBar}>
<Icon class="size-5" />
<span class="text-[10px]">{link.label}</span>
</a>
{/each}
</Navigation.Menu>
</Navigation>
<!-- --- -->
</div>- Recommended for small sized screens (ex: mobile).
- Ideal for vertical screen layouts.
- Should be fixed to the bottom of the viewport.
- Supports 3-5 tiles based on contents and viewport width.
- Consider progressive enhancement with the Virtual Keyboard API .
Rail
Contents
import { Navigation } from '@skeletonlabs/skeleton-react';
import { BookIcon } from 'lucide-react';
import { HouseIcon } from 'lucide-react';
import { PopcornIcon } from 'lucide-react';
import { SkullIcon } from 'lucide-react';
import { SettingsIcon } from 'lucide-react';
import { TvIcon } from 'lucide-react';
export default function Default() {
const links = [
{ label: 'Home', href: '#', icon: HouseIcon },
{ label: 'Books', href: '#', icon: BookIcon },
{ label: 'Movies', href: '#', icon: PopcornIcon },
{ label: 'Television', href: '#', icon: TvIcon },
];
let anchorRail = 'btn hover:preset-tonal aspect-square w-full max-w-[84px] flex flex-col items-center gap-0.5';
return (
<div className="w-full h-[728px] grid grid-cols-[auto_1fr] border border-surface-200-800">
<Navigation layout="rail">
<Navigation.Header>
<a href="/" className={anchorRail} title="View Homepage" aria-label="View Homepage">
<SkullIcon className="size-8" />
</a>
</Navigation.Header>
<Navigation.Content>
<Navigation.Menu>
{links.map((link) => {
const Icon = link.icon;
return (
<a key={link.label} href={link.href} className={anchorRail}>
<Icon className="size-5" />
<span className="text-xs">{link.label}</span>
</a>
);
})}
</Navigation.Menu>
</Navigation.Content>
<Navigation.Footer>
<a href="#" className={anchorRail} title="Settings" aria-label="Settings">
<SettingsIcon className="size-5" />
</a>
</Navigation.Footer>
</Navigation>
<div className="flex justify-center items-center">
<p className="opacity-50">Contents</p>
</div>
</div>
);
}Contents
<script lang="ts">
import { BikeIcon, BookIcon, HouseIcon, SettingsIcon, SkullIcon, TreePalmIcon } from '@lucide/svelte';
import { Navigation } from '@skeletonlabs/skeleton-svelte';
const links = [
{ label: 'Home', href: '#', icon: HouseIcon },
{ label: 'Entertainment', href: '#', icon: BookIcon },
{ label: 'Recreation', href: '#', icon: BikeIcon },
{ label: 'Relaxation', href: '#', icon: TreePalmIcon },
];
let anchorRail = 'btn hover:preset-tonal aspect-square w-full max-w-[84px] flex flex-col items-center gap-0.5';
</script>
<div class="w-full h-[640px] grid grid-cols-[auto_1fr] border border-surface-200-800">
<!-- --- -->
<Navigation layout="rail">
<Navigation.Header>
<a href="/" class={anchorRail} title="View Homepage" aria-label="View Homepage">
<SkullIcon class="size-8" />
</a>
</Navigation.Header>
<Navigation.Content>
<Navigation.Menu>
{#each links as link (link)}
{@const Icon = link.icon}
<a href={link.href} class={anchorRail}>
<Icon class="size-5" />
<span class="text-xs">{link.label}</span>
</a>
{/each}
</Navigation.Menu>
</Navigation.Content>
<Navigation.Footer>
<a href="#" class={anchorRail} title="Settings" aria-label="Settings">
<SettingsIcon class="size-5" />
</a>
</Navigation.Footer>
</Navigation>
<!-- --- -->
<div class="flex justify-center items-center">
<p class="opacity-50">Contents</p>
</div>
</div>- Recommended for medium sized screens (ex: tablet).
- Ideal for horizontal screen layouts.
- Should be fixed to the left or right of the viewport.
- Supports 3-7 tiles based on contents and viewport height.
Sidebar
import { Navigation } from '@skeletonlabs/skeleton-react';
import { BikeIcon } from 'lucide-react';
import { BookIcon } from 'lucide-react';
import { HouseIcon } from 'lucide-react';
import { MountainIcon } from 'lucide-react';
import { PopcornIcon } from 'lucide-react';
import { SailboatIcon } from 'lucide-react';
import { SettingsIcon } from 'lucide-react';
import { SkullIcon } from 'lucide-react';
import { TvIcon } from 'lucide-react';
import { WavesIcon } from 'lucide-react';
export default function Default() {
const linksSidebar = {
entertainment: [
{ label: 'Books', href: '#', icon: BookIcon },
{ label: 'Movies', href: '#', icon: PopcornIcon },
{ label: 'Television', href: '#', icon: TvIcon },
],
recreation: [
{ label: 'Biking', href: '#', icon: BikeIcon },
{ label: 'Sailing', href: '#', icon: SailboatIcon },
{ label: 'Hiking', href: '#', icon: MountainIcon },
{ label: 'Swimming', href: '#', icon: WavesIcon },
],
};
let anchorSidebar = 'btn hover:preset-tonal justify-start px-2 w-full';
return (
<div className="w-full h-[728px] grid grid-cols-[auto_1fr] items-stretch border border-surface-200-800">
<Navigation layout="sidebar" className="grid grid-rows-[auto_1fr_auto] gap-4">
<Navigation.Header>
<a href="https://www.skeleton.dev" className="btn-icon btn-icon-lg preset-filled-primary-500">
<SkullIcon className="size-6" />
</a>
</Navigation.Header>
<Navigation.Content>
<Navigation.Group>
<Navigation.Menu>
<a href="/" className={anchorSidebar}>
<HouseIcon className="size-4" />
<span>Home</span>
</a>
</Navigation.Menu>
</Navigation.Group>
{Object.entries(linksSidebar).map(([category, links]) => (
<Navigation.Group key={category}>
<Navigation.Label className="capitalize pl-2">{category}</Navigation.Label>
<Navigation.Menu>
{links.map((link) => {
const Icon = link.icon;
return (
<a key={link.label} className={anchorSidebar} title={link.label} aria-label={link.label}>
<Icon className="size-4" />
<span>{link.label}</span>
</a>
);
})}
</Navigation.Menu>
</Navigation.Group>
))}
</Navigation.Content>
<Navigation.Footer>
<a href="/" className={anchorSidebar} title="Settings" aria-label="Settings">
<SettingsIcon className="size-4" />
<span>Settings</span>
</a>
</Navigation.Footer>
</Navigation>
<div className="flex justify-center items-center">
<p className="opacity-50">Contents</p>
</div>
</div>
);
}<script lang="ts">
import {
BedDoubleIcon,
BikeIcon,
BookIcon,
BubblesIcon,
HouseIcon,
MountainIcon,
PopcornIcon,
SailboatIcon,
SettingsIcon,
SkullIcon,
TreePalmIcon,
TvIcon,
} from '@lucide/svelte';
import { Navigation } from '@skeletonlabs/skeleton-svelte';
const linksSidebar = {
entertainment: [
{ label: 'Books', href: '#', icon: BookIcon },
{ label: 'Movies', href: '#', icon: PopcornIcon },
{ label: 'Television', href: '#', icon: TvIcon },
],
recreation: [
{ label: 'Biking', href: '#', icon: BikeIcon },
{ label: 'Sailing', href: '#', icon: SailboatIcon },
{ label: 'Hiking', href: '#', icon: MountainIcon },
],
relaxation: [
{ label: 'Lounge', href: '#', icon: TreePalmIcon },
{ label: 'Spa', href: '#', icon: BubblesIcon },
{ label: 'Sleep', href: '#', icon: BedDoubleIcon },
],
};
let anchorSidebar = 'btn hover:preset-tonal justify-start px-2 w-full';
</script>
<div class="w-full h-[728px] grid grid-cols-[auto_1fr] items-stretch border border-surface-200-800">
<!-- --- -->
<Navigation layout="sidebar" class="grid grid-rows-[auto_1fr_auto] gap-4">
<Navigation.Header>
<a href="https://www.skeleton.dev" class="btn-icon btn-icon-lg preset-filled-primary-500">
<SkullIcon class="size-6" />
</a>
</Navigation.Header>
<Navigation.Content>
<Navigation.Group>
<Navigation.Menu>
<a href="/" class={anchorSidebar}>
<HouseIcon class="size-4" />
<span>Home</span>
</a>
</Navigation.Menu>
</Navigation.Group>
{#each Object.entries(linksSidebar) as [category, links]}
<Navigation.Group>
<Navigation.Label class="capitalize pl-2">{category}</Navigation.Label>
<Navigation.Menu>
{#each links as link (link)}
{@const Icon = link.icon}
<a href={link.href} class={anchorSidebar} title={link.label} aria-label={link.label}>
<Icon class="size-4" />
<span>{link.label}</span>
</a>
{/each}
</Navigation.Menu>
</Navigation.Group>
{/each}
</Navigation.Content>
<Navigation.Footer>
<a href="/" class={anchorSidebar} title="Settings" aria-label="Settings">
<SettingsIcon class="size-4" />
<span>Settings</span>
</a>
</Navigation.Footer>
</Navigation>
<!-- --- -->
<div class="flex justify-center items-center">
<p class="opacity-50">Contents</p>
</div>
</div>- Recommended for large sized screens (ex: desktop).
- Ideal for horizontal screen layouts.
- Should be fixed to the left or right of the viewport.
- Supports multiple groups of links for deep navigation.
- Supports a label field per each group.
- Can scroll vertically if contents extend beyond the viewport height.
Toggle Layout
Using reactive state we can dynamically switch between multiple layouts. Tap the double arrow icon to toggle.
Contents
import { Navigation } from '@skeletonlabs/skeleton-react';
import { BookIcon } from 'lucide-react';
import { HouseIcon } from 'lucide-react';
import { PopcornIcon } from 'lucide-react';
import { TvIcon } from 'lucide-react';
import { ArrowLeftRightIcon } from 'lucide-react';
import { useState } from 'react';
export default function Default() {
const links = [
{ label: 'Home', href: '#', icon: HouseIcon },
{ label: 'Books', href: '#', icon: BookIcon },
{ label: 'Movies', href: '#', icon: PopcornIcon },
{ label: 'Television', href: '#', icon: TvIcon },
];
const buttonClasses = 'btn hover:preset-tonal';
let anchorRail = `${buttonClasses} aspect-square w-full max-w-[84px] flex flex-col items-center gap-0.5`;
let anchorSidebar = `${buttonClasses} justify-start px-2 w-full`;
let [layoutRail, setLayoutRail] = useState(true);
function toggleLayout() {
setLayoutRail(!layoutRail);
}
return (
<div className="w-full h-[728px] grid grid-cols-[auto_1fr] items-stretch border border-surface-200-800">
<Navigation layout={layoutRail ? 'rail' : 'sidebar'} className={layoutRail ? '' : 'grid grid-rows-[1fr_auto] gap-4'}>
<Navigation.Content>
<Navigation.Header>
<button type="button" className={layoutRail ? anchorRail : anchorSidebar} onClick={toggleLayout}>
<ArrowLeftRightIcon className={layoutRail ? 'size-5' : 'size-4'} />
{!layoutRail ? <span>Resize</span> : ''}
</button>
</Navigation.Header>
<Navigation.Menu>
{links.map((link) => {
const Icon = link.icon;
return (
<a key={link.label} className={layoutRail ? anchorRail : anchorSidebar}>
<Icon className={layoutRail ? 'size-5' : 'size-4'} />
<span className={layoutRail ? 'text-[10px]' : ''}>{link.label}</span>
</a>
);
})}
</Navigation.Menu>
</Navigation.Content>
</Navigation>
<div className="flex justify-center items-center">
<p className="opacity-50">Contents</p>
</div>
</div>
);
}Layout: Rail
<script lang="ts">
import { ArrowLeftRightIcon, BikeIcon, BookIcon, HouseIcon, TreePalmIcon } from '@lucide/svelte';
import { Navigation } from '@skeletonlabs/skeleton-svelte';
const links = [
{ label: 'Home', href: '#', icon: HouseIcon },
{ label: 'Entertainment', href: '#', icon: BookIcon },
{ label: 'Recreation', href: '#', icon: BikeIcon },
{ label: 'Relaxation', href: '#', icon: TreePalmIcon },
];
const buttonClasses = 'btn hover:preset-tonal';
let anchorRail = `${buttonClasses} aspect-square w-full max-w-[84px] flex flex-col items-center gap-0.5`;
let anchorSidebar = `${buttonClasses} justify-start px-2 w-full`;
let layoutRail = $state(true);
function toggleLayout() {
layoutRail = !layoutRail;
}
</script>
<div class="w-full h-[728px] grid grid-cols-[auto_1fr] items-stretch border border-surface-200-800">
<!-- --- -->
<Navigation layout={layoutRail ? 'rail' : 'sidebar'} class={layoutRail ? '' : 'grid grid-rows-[1fr_auto] gap-4'}>
<Navigation.Content>
<Navigation.Header>
<button type="button" class={layoutRail ? anchorRail : anchorSidebar} onclick={toggleLayout}>
<ArrowLeftRightIcon class={layoutRail ? 'size-5' : 'size-4'} />
{#if !layoutRail}<span>Resize</span>{/if}
</button>
</Navigation.Header>
<Navigation.Menu>
{#each links as link (link)}
{@const Icon = link.icon}
<a href={link.href} class={layoutRail ? anchorRail : anchorSidebar}>
<Icon class={layoutRail ? 'size-5' : 'size-4'} />
<span class={layoutRail ? 'text-[10px]' : ''}>{link.label}</span>
</a>
{/each}
</Navigation.Menu>
</Navigation.Content>
</Navigation>
<!-- --- -->
<div class="flex justify-center items-center">
<pre class="pre">Layout: {layoutRail ? 'Rail' : 'Sidebar'}</pre>
</div>
</div>Anatomy
Here’s an overview of how the Navigation component is structured in code:
import { Navigation } from '@skeletonlabs/skeleton-react';
export default function Anatomy() {
return (
<Navigation>
<Navigation.Header />
<Navigation.Content>
<Navigation.Group>
<Navigation.Label />
<Navigation.Menu />
</Navigation.Group>
</Navigation.Content>
<Navigation.Footer />
</Navigation>
);
}<script lang="ts">
import { Navigation } from '@skeletonlabs/skeleton-svelte';
</script>
<Navigation>
<Navigation.Header />
<Navigation.Content>
<Navigation.Group>
<Navigation.Label />
<Navigation.Menu />
</Navigation.Group>
</Navigation.Content>
<Navigation.Footer />
</Navigation>API Reference
Unable to load component information for react/navigation
Unable to load component information for svelte/navigation