Dock

A bottom navigation bar of icon+label items.

Colors (active item accent)

Real use · interactive bottom nav

Using Dock

Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.

Plain HTML — CSS classes

The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path is complete for Dock — it needs no JavaScript, so the classes below are the whole story.

/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";

Root class dock, with 11 modifiers:

  • .dock
  • .dock-accent
  • .dock-error
  • .dock-info
  • .dock-item
  • .dock-item-active
  • .dock-label
  • .dock-neutral
  • .dock-primary
  • .dock-secondary
  • .dock-success
  • .dock-warning

React

Typed components over those same classes, with behavior and accessibility from Base UI.

npm i @wizeworks/silicaui-react
import { Dock } from "@wizeworks/silicaui-react";

Props

DockProps
PropTypeRequiredDescription
colorDockColornoAccent color for the active item. Default primary.
DockItemProps
PropTypeRequiredDescription
activebooleannoHighlight this item as the current destination.

Source of the demo above

The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.

Show source
import { useState } from "react";
import { Dock, DockItem, DockLabel } from "@wizeworks/silicaui-react";
import { Section } from "../lib/Section";
import { COLORS } from "../lib/data";

function HomeIcon() {
    return (
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="m3 11 9-8 9 8M5 10v10h5v-6h4v6h5V10" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
    );
}
function SearchIcon() {
    return (
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <circle cx="11" cy="11" r="7" />
            <path d="m21 21-4.3-4.3" strokeLinecap="round" />
        </svg>
    );
}
function UserIcon() {
    return (
        <svg viewBox="0 0 24 24" fill="currentColor">
            <circle cx="12" cy="8" r="4" />
            <path d="M4 20c0-4.4 3.6-7 8-7s8 2.6 8 7Z" />
        </svg>
    );
}

export function DockDemo() {
    const [tab, setTab] = useState("home");

    return (
        <>
            <Section title="Colors (active item accent)">
                <div className="flex flex-col gap-4">
                    {COLORS.slice(0, 6).map((color) => (
                        <Dock key={color} color={color} className="max-w-xs rounded-box">
                            <DockItem active>
                                <HomeIcon />
                                <DockLabel>Home</DockLabel>
                            </DockItem>
                            <DockItem>
                                <SearchIcon />
                                <DockLabel>Search</DockLabel>
                            </DockItem>
                            <DockItem>
                                <UserIcon />
                                <DockLabel>Profile</DockLabel>
                            </DockItem>
                        </Dock>
                    ))}
                </div>
            </Section>

            <Section title="Real use · interactive bottom nav">
                <Dock color="primary" className="max-w-xs rounded-box">
                    <DockItem active={tab === "home"} onClick={() => setTab("home")}>
                        <HomeIcon />
                        <DockLabel>Home</DockLabel>
                    </DockItem>
                    <DockItem active={tab === "search"} onClick={() => setTab("search")}>
                        <SearchIcon />
                        <DockLabel>Search</DockLabel>
                    </DockItem>
                    <DockItem active={tab === "profile"} onClick={() => setTab("profile")}>
                        <UserIcon />
                        <DockLabel>Profile</DockLabel>
                    </DockItem>
                </Dock>
            </Section>
        </>
    );
}

Vanilla — node tree to HTML

Dock — lowers to <div>, holding its children. Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.

npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviors
import { atom, toHtml } from "@wizeworks/silicaui-html";

const node = atom("Dock", "dock", { /* props */ }, [/* children */]);
const markup = toHtml(node);

Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "dock dock-primary" rather than passing a colour as a prop.

Takes children
yes
Hydrated by
nothing — this one is static markup

The full API for Dock, on every path, is available through the Silica MCP server.