Browse docsDock

Navigation

Glass Dock

A row of app icons on a glass shelf that name themselves on hover.

pnpm dlx shadcn@4.14.1 add @glassyui/glass-dock

Preview

Open an app.

Demos ready. Update 0.

Installation

First add the exact @glassyui mapping to components.json as shown in Getting Started. Then run the pinned item command:

Install Glass Dock

pnpm dlx shadcn@4.14.1 add @glassyui/glass-dock
What this installs10 files, 2 packages

Direct registry declarations

These values belong to @glassyui/glass-dock itself in registry.json.

Package dependencies

  • @radix-ui/react-slot
  • clsx

Registry dependencies

  • @glassyui/glass-surface

File targets

  • components/glassyui/glass-dock.tsx

Complete installed closure

This follows every namespaced registry dependency recursively and de-duplicates the packages and target files installed with this item.

Package dependencies

  • @radix-ui/react-slot
  • clsx

Installed files

  • components/glassyui/glass-dock.tsx
  • components/glassyui/glass-surface.tsx
  • components/glassyui/lib/merge-refs.ts
  • components/glassyui/lib/refraction-map.ts
  • components/glassyui/lib/use-refraction-filter.tsx
  • components/glassyui/lib/scene-context.ts
  • components/glassyui/glass-provider.tsx
  • components/glassyui/liquid-filters.tsx
  • components/glassyui/lib/preferences.ts
  • components/glassyui/styles/liquid.css

Usage

Save this as dock-example.tsx. It is the complete example shown above, including its artwork.

Usage

'use client';

import { useState, type CSSProperties } from 'react';
import { GlassDock, GlassDockItem } from '@/components/glassyui/glass-dock';

const apps = [
  { label: 'Inbox', color: '#2f6fd8', path: 'M14 18h36v28H14z M14 19l18 14 18-14' },
  { label: 'Chat', color: '#146c3c', path: 'M14 16h36v26H30l-11 8v-8h-5z M23 26h18 M23 33h12' },
  {
    label: 'Gallery',
    color: '#b36c13',
    path: 'M15 15h34v34H15z M15 40l10-10 9 9 6-6 9 10 M38 23h.1',
  },
  { label: 'Player', color: '#c9361a', path: 'M25 18v28l23-14z' },
  { label: 'Docs', color: '#756c66', path: 'M17 13h30v38H17z M24 23h16 M24 31h16 M24 39h11' },
];

const dockStyle: CSSProperties & { '--lg-dock-size': string; '--lg-dock-gap': string } = {
  '--lg-dock-size': 'clamp(24px, 12cqi, 44px)',
  '--lg-dock-gap': '6px',
};

type DockExampleProps = { onAction?: (message: string) => void };

export function DockExample({ onAction }: DockExampleProps) {
  const [running, setRunning] = useState(['Chat']);
  const [message, setMessage] = useState('Open an app.');

  return (
    <div
      style={{
        containerType: 'inline-size',
        display: 'grid',
        alignContent: 'center',
        justifyItems: 'center',
        gap: 26,
        width: '100%',
        minHeight: 220,
        borderRadius: 22,
        background:
          'radial-gradient(ellipse at 20% 120%, #a53722, transparent 65%), linear-gradient(135deg, #211c1a, #5c291c)',
      }}
    >
      <GlassDock aria-label="Dock" role="group" style={dockStyle}>
        {apps.map((app) => (
          <GlassDockItem
            active={running.includes(app.label)}
            key={app.label}
            label={app.label}
            onClick={() => {
              setRunning((current) =>
                current.includes(app.label) ? current : [...current, app.label],
              );
              const next = `${app.label} opened.`;
              setMessage(next);
              onAction?.(next);
            }}
          >
            <svg aria-hidden="true" viewBox="0 0 64 64">
              <rect fill={app.color} height="64" rx="14" width="64" />
              <path
                d={app.path}
                fill="none"
                stroke="#fff"
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth="3"
              />
            </svg>
          </GlassDockItem>
        ))}
      </GlassDock>
      <p
        role={onAction ? undefined : 'status'}
        style={{ margin: 0, color: '#fff8f2', fontSize: 13 }}
      >
        {message}
      </p>
    </div>
  );
}

After configuring the registry, install every component this example uses:

Install example components

pnpm dlx shadcn@4.14.1 add @glassyui/glass-dock

Examples

Render the copied example

import { DockExample } from "./dock-example";

export default function Page() {
  return <DockExample />;
}

API

GlassDock

Glass shelf under a row of items.

GlassDockItem

Icon button with a hover label and a running indicator.

label

Required accessible name, also shown above the icon on hover.

active

Shows the running dot under the icon.

asChild

Renders the single child, such as a link, as the item.

GlassDockSeparator

Vertical divider between item groups.

Notes

Input

Icons keep their size wherever the pointer is. Hover or keyboard focus shows the label, and focus also enlarges the icon.

Accessibility

Keep the Radix-backed semantics intact and preserve visible labels, focus states, and keyboard operation when copying the source.

Performance

Use provider quality preferences for dense app screens. Reserve strong refraction for hero or showcase surfaces.