An archive of essays with dates and reading times. Each title shows its cover image in a wide 3:2 frame.
@keyframeui
registry/demos/hover-preview-journal-demo.tsx
import { HoverPreview, HoverPreviewItem } from "@/components/ui/hover-preview";
const posts = [
{
title: "Designing for the second visit",
date: "Sep 18, 2026",
minutes: 6,
photo: "1497032628192-86f99bcd76bc",
},
{
title: "Motion is a material, not a garnish",
date: "Aug 29, 2026",
minutes: 9,
photo: "1557672172-298e090bd0f1",
},
{
title: "Shipping a design system in six weeks",
date: "Aug 04, 2026",
minutes: 12,
photo: "1519389950473-47ba0277781c",
},
{
title: "A reading list for product designers",
date: "Jul 15, 2026",
minutes: 4,
photo: "1481627834876-b7833e8f5570",
},
{
title: "How we price fixed-scope projects",
date: "Jun 30, 2026",
minutes: 7,
photo: "1499750310107-5fef28a66643",
},
{
title: "Notes on writing interface copy",
date: "Jun 02, 2026",
minutes: 5,
photo: "1455390582262-044cdead277a",
},
];
const photo = (id: string, width: number, height: number) =>
`https://images.unsplash.com/photo-${id}?auto=format&fit=crop&w=${width}&h=${height}&q=80`;
const slug = (title: string) => title.toLowerCase().replace(/[^a-z0-9]+/g, "-");
export function HoverPreviewJournalDemo() {
return (
<section className="w-full max-w-3xl">
<div className="mb-4 flex items-end justify-between gap-4">
<h3 className="text-2xl font-semibold tracking-tight text-zinc-900 dark:text-zinc-50">Journal</h3>
<p className="font-mono text-xs text-zinc-500 tabular-nums">{posts.length} essays</p>
</div>
<HoverPreview
previewClassName="aspect-[3/2] w-64 rounded-md sm:w-80"
className="border-t border-zinc-200 dark:border-zinc-800"
>
{posts.map((post) => (
<HoverPreviewItem
key={post.title}
href={`#${slug(post.title)}`}
image={photo(post.photo, 720, 480)}
thumbnail={photo(post.photo, 120, 120)}
className="items-baseline gap-6 border-b border-zinc-200 py-5 dark:border-zinc-800"
thumbnailClassName="self-center"
>
<time className="hidden w-24 shrink-0 font-mono text-xs text-zinc-500 tabular-nums sm:block">
{post.date}
</time>
<span className="flex-1 text-lg font-medium tracking-tight text-pretty text-zinc-900 sm:text-2xl dark:text-zinc-50">
{post.title}
</span>
<span className="shrink-0 font-mono text-xs text-zinc-500 tabular-nums">
{post.minutes} min
</span>
</HoverPreviewItem>
))}
</HoverPreview>
</section>
);
}
Live preview, examples and props: https://keyframeui.com/components/hover-preview#hover-preview-journal-demo






















