masonix
Examples

Basic Layout

A clean starter masonry grid with responsive automatic columns.

Use this pattern for the first masonry surface in an app: simple data, stable keys, automatic columns, and a reusable card component.

ReleaseReady

Launch plan

Milestones, owners, and final QA notes for the public release.

DesignReview

Brand board

Palette, type scale, and image direction for campaign pages.

ResearchNew

Research notes

Five customer interviews summarized into product opportunities.

GrowthDone

Metrics review

Activation moved up after the onboarding card refresh.

ProductPlanning

Roadmap

Small bets that improve feed performance and editorial control.

SupportOpen

Support themes

Repeated tickets grouped by install, styling, and virtualization.

Example

import { clsx } from 'clsx';
import { Masonry } from 'masonix';

type Task = {
  id: string;
  title: string;
  detail: string;
  area: string;
  status: string;
  accent: string;
};

function TaskCard({ task }: { task: Task }) {
  return (
    <article
      className={clsx(
        'relative overflow-hidden',
        'p-4',
        'rounded-xl border shadow-sm',
        'border-zinc-200 bg-white text-zinc-950 shadow-zinc-950/5 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50',
      )}
    >
      <div
        className="absolute inset-y-0 left-0 w-1"
        style={{ background: task.accent }}
      />
      <div className="flex items-center justify-between gap-3 pl-2">
        <span className="text-xs font-medium text-zinc-500 dark:text-zinc-400">
          {task.area}
        </span>
        <span className="rounded-full bg-zinc-100 px-2 py-1 text-xs text-zinc-700 dark:bg-zinc-900 dark:text-zinc-300">
          {task.status}
        </span>
      </div>
      <div className="pl-2 pt-2">
        <h3 className="text-sm font-semibold">{task.title}</h3>
        <p className="mt-2 text-sm leading-6 text-zinc-600 dark:text-zinc-400">
          {task.detail}
        </p>
      </div>
    </article>
  );
}

export function TaskGrid({ tasks }: { tasks: Task[] }) {
  return (
    <Masonry
      items={tasks}
      columnWidth={190}
      maxColumns={3}
      gap={14}
      itemKey={(task) => task.id}
      render={({ data }) => <TaskCard task={data} />}
    />
  );
}

When to use

Use this for cards that are cheap to render and do not need shortest-column balancing. It is the best default for product tiles, settings panels, and simple content collections.

Notes

  • columnWidth keeps cards readable as the container grows.
  • maxColumns prevents dense, hard-to-scan layouts on wide screens.
  • itemKey keeps identity stable during filters and sorting.

On this page