Skip to content
Navigation

Dock

The macOS dock, in Material.

Walkthrough

1. Basic

Move the pointer along the bar: the tile under it swells, its neighbours less, and the name rises over it. On a touch screen the tiles stay put at a finger's size; from the keyboard the arrow keys walk them.

<script lang="ts">	import { Dock, DockItem, DockDivider } from 'omaris';	import Icon from '$lib/patterns/shell/icon.svelte';​	const APPS = [		{ name: 'Home', icon: 'home' },		{ name: 'Mail', icon: 'mail', badge: 3 },		{ name: 'Calendar', icon: 'calendar' },		{ name: 'Messages', icon: 'message' },		{ name: 'Music', icon: 'music' },		{ name: 'Settings', icon: 'settings' }	] as const;​	let current = $state('Home');</script>​<div class="flex w-full flex-1 items-end justify-center">	<Dock label="Apps">		{#each APPS as app (app.name)}			<DockItem				label={app.name}				active={current === app.name}				badge={'badge' in app ? app.badge : undefined}				onclick={() => (current = app.name)}			>				<Icon name={app.icon} />			</DockItem>		{/each}		<DockDivider />		<DockItem label="Trash"><Icon name="trash" /></DockItem>	</Dock></div>

2. Vertical

Down the side, the way a rail sits. Labels ride out beside the tiles.

<script lang="ts">	import { Dock, DockItem } from 'omaris';	import Icon from '$lib/patterns/shell/icon.svelte';​	const TOOLS = [		{ name: 'Select', icon: 'target' },		{ name: 'Draw', icon: 'edit' },		{ name: 'Crop', icon: 'crop' },		{ name: 'Adjust', icon: 'sliders' },		{ name: 'Magic', icon: 'wand' }	] as const;​	let tool = $state('Select');</script>​<div class="flex w-full flex-1 items-center">	<Dock orientation="vertical" label="Tools" variant="filled">		{#each TOOLS as item (item.name)}			<DockItem label={item.name} active={tool === item.name} onclick={() => (tool = item.name)}>				<Icon name={item.icon} />			</DockItem>		{/each}	</Dock></div>

3. Glass

variant="glass" sets the tiles on frosted glass: what is behind the bar blurs through it.

<script lang="ts">	import { Dock, DockItem } from 'omaris';	import Icon from '$lib/patterns/shell/icon.svelte';​	const APPS = [		{ name: 'Home', icon: 'home' },		{ name: 'Photos', icon: 'image' },		{ name: 'Camera', icon: 'camera' },		{ name: 'Maps', icon: 'navigation' },		{ name: 'Music', icon: 'music' },		{ name: 'Settings', icon: 'settings' }	] as const;</script>​<div	class="relative flex min-h-72 w-full items-end justify-center overflow-hidden rounded-shape-xl bg-linear-to-br from-primary via-tertiary to-warning p-6">	<div class="absolute inset-x-8 top-8 grid grid-cols-3 gap-3">		{#each Array.from({ length: 6 }, (_, i) => i) as cell (cell)}			<div class="h-12 rounded-shape-md bg-background/35"></div>		{/each}	</div>	<Dock variant="glass" label="Apps">		{#each APPS as app (app.name)}			<DockItem label={app.name} active={app.name === 'Home'}>				<Icon name={app.icon} />			</DockItem>		{/each}	</Dock></div>

5. Overridden

The overridden case: a bigger base tile, a square dark bar and tiles restyled through classes — the dock still owns their size, so only the look changes.

<script lang="ts">	import { Dock, DockItem } from 'omaris';	import Icon from '$lib/patterns/shell/icon.svelte';​	const APPS = [		{ name: 'Home', icon: 'home' },		{ name: 'Search', icon: 'search' },		{ name: 'Library', icon: 'layers' },		{ name: 'Profile', icon: 'user' }	] as const;</script>​<div class="flex w-full flex-1 items-end justify-center">	<Dock		size={56}		magnification={1.5}		distance={110}		label="Apps"		classes={{ surface: 'rounded-shape-lg bg-inverse-surface ring-0' }}	>		{#each APPS as app (app.name)}			<DockItem				label={app.name}				active={app.name === 'Home'}				classes={{					control:						'rounded-shape-md bg-inverse-surface text-inverse-surface-foreground ring-1 ring-inverse-surface-foreground/15 ring-inset',					dot: 'bg-inverse-surface-foreground'				}}			>				<Icon name={app.icon} />			</DockItem>		{/each}	</Dock></div>