Chanhdai
blockblog-01source: ok · refreshed
Blog 01
A blog section with a grid layout.
npx shadcn add "https://chanhdai.com/r/blog-01.json"free
Where it goes
blog-list
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lighticonslucide-react
Registry dependencies
button
Files2 · source cached 10/2/2026, 12:39:16 AM
src/registry/blocks/blog-01/blog-01.tsx
import { ArrowRightIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import { ArticleItem } from "@/registry/blocks/blog-01/components/article-item"
export default function Blog01() {
return (
<div className="container mx-auto flex flex-col gap-8 px-4 py-8">
<h2 className="ml-4 font-heading text-4xl font-medium tracking-tight md:text-5xl">
Blog
</h2>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{articles.map((article) => (
<a key={article.id} className="block h-full" href="#">
<ArticleItem
title={article.title}
coverUrl={article.coverUrl}
createdAt={article.createdAt}
/>
</a>
))}
</div>
<div className="flex justify-center">
<Button
className="gap-2 pr-2.5 pl-3"
nativeButton={false}
render={<a href="#" />}
>
View All
<ArrowRightIcon />
</Button>
</div>
</div>
)
}
type Article = {
id: string
title: string
coverUrl: string
createdAt: string
}
const articles: Article[] = [
{
id: "1",
title:
"Apple unveils iPhone 17 Pro: Aluminum frame returns, new colors, upgraded camera",
coverUrl:
"https://assets.chanhdai.com/registry/images/blocks/blog-01/1.webp",
createdAt: "2025-09-13",
},
{
id: "2",
title:
'While the world is expecting AGI, François Chollet is showing just how "naive" AI can be',
coverUrl:
"https://assets.chanhdai.com/registry/images/blocks/blog-01/2.webp",
createdAt: "2025-04-21",
},
{
id: "3",
title:
"Apple introduces iPhone 16e: A powerful new model for the iPhone 16 lineup",
coverUrl:
"https://assets.chanhdai.com/registry/images/blocks/blog-01/3.webp",
createdAt: "2025-02-20",
},
{
id: "4",
title:
"Apple unveils MacBook Pro M4: Same design, base model now with 16GB RAM, priced from $1,599",
coverUrl:
"https://assets.chanhdai.com/registry/images/blocks/blog-01/4.webp",
createdAt: "2024-10-31",
},
{
id: "5",
title:
"Apple unveils new Mac mini M4: Smaller, 16GB RAM on the base model, priced from $599",
coverUrl:
"https://assets.chanhdai.com/registry/images/blocks/blog-01/5.webp",
createdAt: "2024-10-31",
},
{
id: "6",
title:
"Apple unveils iMac M4: Unchanged design, more powerful M4 chip, RAM starts at 16GB, priced from $1,299",
coverUrl:
"https://assets.chanhdai.com/registry/images/blocks/blog-01/6.webp",
createdAt: "2024-10-29",
},
]
src/registry/blocks/blog-01/components/article-item.tsx
import { format } from "date-fns"
export type ArticleItemProps = {
title: string
coverUrl: string
createdAt: string
}
export function ArticleItem({ title, coverUrl, createdAt }: ArticleItemProps) {
return (
<article className="h-full rounded-2xl bg-card text-card-foreground shadow-xs ring-1 ring-foreground/10 dark:ring-border">
<div className="p-1 pb-0">
<div className="relative aspect-video">
<img
className="size-full rounded-xl object-cover"
src={coverUrl}
alt={title}
/>
<div className="pointer-events-none absolute inset-0 rounded-xl inset-ring-1 inset-ring-black/10 dark:inset-ring-white/15" />
</div>
</div>
<div className="flex flex-col gap-2 px-4 pt-4 pb-6">
<time
className="block text-sm text-muted-foreground"
dateTime={new Date(createdAt).toISOString()}
>
{format(new Date(createdAt), "MMMM d, yyyy")}
</time>
<h3 className="text-lg/tight font-medium text-balance">{title}</h3>
</div>
</article>
)
}