Skip to content
LuoForge/Tungsten
Components/Cluster·Experimental

Cluster

since v2.1.0

Horizontal flex row with wrapping — enforces spacing-scale gap values.

Install

Add the package and import the component.

pnpm add @hey-mike/tungsten
pnpm add @hey-mike/tungsten
import { Cluster } from '@hey-mike/tungsten';
import { Cluster } from '@hey-mike/tungsten';

Preview

Same fixtures used by the visual-regression suite.

Usage

apps/docs/app/snapshots/cluster/page.tsx

import { Cluster } from '@hey-mike/tungsten';
import { HeroSpecimen } from '../_components/HeroSpecimen';

const TAGS = ['design', 'system', 'tokens', 'components', 'layout', 'motion', 'color', 'type'];

function Tag({ label }: { label: string }) {
  return (
    <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-1 font-mono text-xs text-ink-2">
      {label}
    </span>
  );
}

export default function ClusterSnapshot() {
  return (
    <main data-testid="snapshot-root" className="bg-page text-ink-1 min-h-screen py-8">
      <h1 className="text-ink-2 mb-8 px-8 font-mono text-sm uppercase tracking-widest">Cluster</h1>

      <dl className="flex flex-col gap-10 px-8">
        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=2</dt>
          <dd className="m-0">
            <Cluster gap={2}>
              {TAGS.map((t) => <Tag key={t} label={t} />)}
            </Cluster>
          </dd>
        </div>

        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=4 (default)</dt>
          <dd className="m-0">
            <Cluster gap={4}>
              {TAGS.map((t) => <Tag key={t} label={t} />)}
            </Cluster>
          </dd>
        </div>

        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=6 · align=center</dt>
          <dd className="m-0">
            <Cluster gap={6} align="center">
              <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-1 font-mono text-xs text-ink-2">small</span>
              <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-3 font-mono text-xs text-ink-2">tall</span>
              <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-1 font-mono text-xs text-ink-2">small</span>
              <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-3 font-mono text-xs text-ink-2">tall</span>
            </Cluster>
          </dd>
        </div>

        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=4 · justify=between</dt>
          <dd className="m-0">
            <Cluster gap={4} justify="between">
              {['left', 'center', 'right'].map((t) => <Tag key={t} label={t} />)}
            </Cluster>
          </dd>
        </div>

        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=3 · align=baseline · wrapping</dt>
          <dd className="m-0">
            <Cluster gap={3} align="baseline">
              {[...TAGS, 'accessibility', 'dark mode', 'spacing', 'icons'].map((t) => <Tag key={t} label={t} />)}
            </Cluster>
          </dd>
        </div>
      </dl>

      {/* Gallery thumbnail (`?hero`): a few pills wrap into two tidy rows.
          Hidden in the detail view; revealed by the hero CSS. */}
      <div data-hero-specimen className="hidden">
        <HeroSpecimen>
          <Cluster gap={2}>
            {['design', 'system', 'tokens', 'layout', 'motion'].map((t) => (
              <Tag key={t} label={t} />
            ))}
          </Cluster>
        </HeroSpecimen>
      </div>
    </main>
  );
}
import { Cluster } from '@hey-mike/tungsten';
import { HeroSpecimen } from '../_components/HeroSpecimen';

const TAGS = ['design', 'system', 'tokens', 'components', 'layout', 'motion', 'color', 'type'];

function Tag({ label }: { label: string }) {
  return (
    <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-1 font-mono text-xs text-ink-2">
      {label}
    </span>
  );
}

export default function ClusterSnapshot() {
  return (
    <main data-testid="snapshot-root" className="bg-page text-ink-1 min-h-screen py-8">
      <h1 className="text-ink-2 mb-8 px-8 font-mono text-sm uppercase tracking-widest">Cluster</h1>

      <dl className="flex flex-col gap-10 px-8">
        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=2</dt>
          <dd className="m-0">
            <Cluster gap={2}>
              {TAGS.map((t) => <Tag key={t} label={t} />)}
            </Cluster>
          </dd>
        </div>

        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=4 (default)</dt>
          <dd className="m-0">
            <Cluster gap={4}>
              {TAGS.map((t) => <Tag key={t} label={t} />)}
            </Cluster>
          </dd>
        </div>

        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=6 · align=center</dt>
          <dd className="m-0">
            <Cluster gap={6} align="center">
              <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-1 font-mono text-xs text-ink-2">small</span>
              <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-3 font-mono text-xs text-ink-2">tall</span>
              <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-1 font-mono text-xs text-ink-2">small</span>
              <span className="bg-brand-overlay-08 border border-brand-overlay-20 rounded-lg px-3 py-3 font-mono text-xs text-ink-2">tall</span>
            </Cluster>
          </dd>
        </div>

        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=4 · justify=between</dt>
          <dd className="m-0">
            <Cluster gap={4} justify="between">
              {['left', 'center', 'right'].map((t) => <Tag key={t} label={t} />)}
            </Cluster>
          </dd>
        </div>

        <div>
          <dt className="text-ink-3 mb-2 font-mono text-xs">gap=3 · align=baseline · wrapping</dt>
          <dd className="m-0">
            <Cluster gap={3} align="baseline">
              {[...TAGS, 'accessibility', 'dark mode', 'spacing', 'icons'].map((t) => <Tag key={t} label={t} />)}
            </Cluster>
          </dd>
        </div>
      </dl>

      {/* Gallery thumbnail (`?hero`): a few pills wrap into two tidy rows.
          Hidden in the detail view; revealed by the hero CSS. */}
      <div data-hero-specimen className="hidden">
        <HeroSpecimen>
          <Cluster gap={2}>
            {['design', 'system', 'tokens', 'layout', 'motion'].map((t) => (
              <Tag key={t} label={t} />
            ))}
          </Cluster>
        </HeroSpecimen>
      </div>
    </main>
  );
}

Props

Surface specific to <Cluster />.

PropTypeDefaultDescription
gap0 | 1 | 2 | 3 | 4 | 6 | 8 | 10 | 124
align"start" | "center" | "end" | "baseline"Cross-axis alignment. stretch is intentionally absent — use Stack for column layouts.
justify"start" | "center" | "end" | "between" | "around"

Source