# Blog 02

> A blog section with a lined grid layout.

A shadcn/ui block from the [@ncdai](https://chanhdai.com/components) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/ncdai/blog-02).

- Page, with a live preview: https://shadcn.exchange/r/ncdai/blog-02
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/ncdai/blog-02-light-78240a6664263d17.png
- Registry item: https://chanhdai.com/r/blog-02.json
- Categories: marketing
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://chanhdai.com/r/blog-02.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `date-fns`, `lucide-react`
- Registry items: `button`, `https://chanhdai.com/r/style.json`

## Files

### `src/registry/blocks/blog-02/blog-02.tsx`

```tsx
import { ArrowRightIcon } from "lucide-react"

import { Button } from "@/components/ui/button"
import { ArticleItem } from "@/registry/blocks/blog-02/components/article-item"

export function Blog02() {
  return (
    <div className="max-w-screen overflow-x-clip">
      <div className="container mx-auto px-4">
        <div className="border-x border-line py-8">
          <h2 className="screen-line-top screen-line-bottom ml-4 font-heading text-3xl font-medium tracking-tight">
            Blog
          </h2>

          <p className="p-4 text-base text-balance text-muted-foreground">
            A collection of articles on development, design, ideas, and tech
            news.
          </p>

          <div className="screen-line-top relative py-4">
            <div className="pointer-events-none absolute inset-0 -z-1 grid grid-cols-1 gap-4 max-sm:hidden sm:grid-cols-2 md:grid-cols-3">
              <div className="border-r border-line" />
              <div className="border-l border-line md:border-x" />
              <div className="border-l border-line max-md:hidden" />
            </div>

            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3">
              {articles.map((article) => (
                <ArticleItem
                  key={article.id}
                  url="#"
                  title={article.title}
                  coverUrl={article.coverUrl}
                  createdAt={article.createdAt}
                />
              ))}
            </div>
          </div>

          <div className="screen-line-top screen-line-bottom flex justify-center py-2">
            <Button
              className="gap-2 pr-2.5 pl-3"
              nativeButton={false}
              render={<a href="#" />}
            >
              View All
              <ArrowRightIcon />
            </Button>
          </div>
        </div>
      </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-02/components/article-item.tsx`

```tsx
import { format } from "date-fns"

import { cn } from "@/lib/utils"

export type ArticleItemProps = {
  url: string
  title: string
  coverUrl: string
  createdAt: string
}

export function ArticleItem({
  url,
  title,
  coverUrl,
  createdAt,
}: ArticleItemProps) {
  return (
    <a
      href={url}
      className={cn(
        "flex flex-col gap-2 p-2 transition-[background-color] ease-out hover:bg-accent/30",
        "max-sm:screen-line-top max-sm:screen-line-bottom",
        "sm:max-md:nth-[2n+1]:screen-line-top sm:max-md:nth-[2n+1]:screen-line-bottom",
        "md:nth-[3n+1]:screen-line-top md:nth-[3n+1]:screen-line-bottom"
      )}
    >
      <div className="relative aspect-video">
        <img
          src={coverUrl}
          alt={title}
          className="size-full rounded-xl object-cover"
        />
        <div className="pointer-events-none absolute inset-0 rounded-xl inset-ring-1 inset-ring-black/10 dark:inset-ring-white/10" />
      </div>

      <div className="flex flex-col gap-2 p-2">
        <h3 className="text-lg/tight font-medium text-balance">{title}</h3>

        <dl>
          <dt className="sr-only">Published on</dt>
          <dd className="text-sm text-muted-foreground">
            <time dateTime={new Date(createdAt).toISOString()}>
              {format(new Date(createdAt), "MMMM d, yyyy")}
            </time>
          </dd>
        </dl>
      </div>
    </a>
  )
}
```
