One column per year on a hairline, each stating the year as a figure with its published count beside it, a sentence on what that year was about, and the pieces that defined it.
One column per year on a hairline, each stating the year as a figure with its published count beside it, a sentence on what that year was about, and the pieces that defined it.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/feature274?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/feature274?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/feature274.tsx and the badge6 component it uses for the eyebrow (installed to components/beste/component/badge6.tsx).
The installed file exports feature274Demo alongside the block: the exact props behind the preview above. Spread it to get a working year index in one line.
import { Feature274, feature274Demo } from "@/components/beste/block/feature274";
export default function ArchivePage() {
return <Feature274 {...feature274Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Feature274 } from "@/components/beste/block/feature274";
export default function ArchivePage() {
return (
<Feature274
eyebrow="The archive"
heading="Four years, read backwards"
countLabel="pieces"
years={[
{
year: "2026",
count: "18",
summary: "The year we published our prices.",
posts: [
{ title: "The estimate is design work", href: "/essays/estimate" },
{ title: "The quote we lost on purpose", href: "/letters/042" },
],
},
]}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Badge6 label above the hairline rule |
heading | string | – | Section heading under the rule |
countLabel | string | – | Noun after each year's count, e.g. "pieces" |
years | YearColumn[] | [] | One column per year, newest first |
className | string | – | Extra classes for the outer section |
type YearColumn = {
year: string;
count: string;
summary: string;
posts: YearPost[];
};
type YearPost = {
title: string;
href: string;
};year and count are strings, not numbers, so a column can read "2023" or "Before 2023" without the block trying to do arithmetic on it.tabular-nums, which keeps the figures aligned across columns even in a proportional typeface.md and four at lg, each on its own hairline, so a year with one post does not stretch to match its neighbour.feature34
Two-column grid of numbered items (01, 02, etc.) with circular badges, titles, and descriptions. Perfect for why-choose-us sections, benefits lists, or key differentiators.
feature162
3-column grid of numbered steps with titles and descriptions. Ideal for onboarding flows, process overviews, and how-it-works sections.
feature254
Timeline where every ruled row lines up a year, a photograph from that moment and the explanation of what forced the change, headed by a pill CTA on the heading line and stacking to a readable block on mobile.
feature233
A header with a badge, heading, and description, followed by many compact items in a two-column grid — each a lucide icon in a rounded bg-muted tile beside a title and one-line description.