# Blog 2

> Blog

A shadcn/ui block from the [@cnippet-blocks](https://blocks.cnippet.dev/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/cnippet-blocks/blog-2).

- Page, with a live preview: https://shadcn.exchange/r/cnippet-blocks/blog-2
- Screenshot: https://shadcn.exchange/shot/cnippet-blocks/blog-2/light.png
- Registry item: https://blocks.cnippet.dev/r/blog-2.json
- Categories: blog
- Listed: 2026-11-01, source last changed 2026-11-01

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/cnippet-blocks/blog-2.json
```

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

## Dependencies

- Registry items: `@cnippet/badge`, `@cnippet/button`, `@cnippet/tabs`

## Files

### `registry/default/sections/blog-2.tsx`

```tsx
"use client";

import Image from "next/image";
import Link from "next/link";
import { useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Tabs, TabsList, TabsPanel, TabsTab } from "@/components/ui/tabs";

const categories = [
  { id: "all", label: "All" },
  { id: "robotics", label: "Robotics" },
  { id: "arduino", label: "Arduino" },
  { id: "microcontrollers", label: "Microcontrollers" },
  { id: "ai-ml", label: "AI & Machine Learning" },
];

const featuredPost = {
  category: "Robotics",
  categoryId: "robotics",
  excerpt:
    "Explore how artificial intelligence and advanced sensors are enabling robots to work alongside humans, from collaborative manufacturing to autonomous delivery.",
  image: "https://images.cnippet.dev/image/upload/v1770400411/h1.jpg",
  publishedDate: "March 20, 2025",
  readTime: "8 min read",
  title: "The Rise of Collaborative Robots: A New Era in Automation",
};

const posts = [
  {
    category: "Arduino",
    categoryId: "arduino",
    image: "https://images.cnippet.dev/image/upload/v1770400411/h2.jpg",
    publishedDate: "March 19, 2025",
    readTime: "6 min read",
    title: "Getting Started with Arduino: 5 Beginner Projects",
  },
  {
    category: "Microcontrollers",
    categoryId: "microcontrollers",
    image: "https://images.cnippet.dev/image/upload/v1770400411/h3.jpg",
    publishedDate: "March 18, 2025",
    readTime: "7 min read",
    title: "ESP32 vs Raspberry Pi Pico: Choosing the Right MCU",
  },
  {
    category: "AI & Machine Learning",
    categoryId: "ai-ml",
    image: "https://images.cnippet.dev/image/upload/v1770400411/h4.jpg",
    publishedDate: "March 17, 2025",
    readTime: "5 min read",
    title: "TinyML: Running Neural Networks on Microcontrollers",
  },
];

function CurvedCorner({ position }: { position: "left" | "bottom" }) {
  if (position === "left") {
    return (
      <div className="absolute top-0 right-auto bottom-auto -left-2 flex h-2 w-2 items-center justify-center">
        <svg
          fill="none"
          height="8"
          viewBox="0 0 8 8"
          width="8"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            clipRule="evenodd"
            d="M8 0H0C4.41828 0 8 3.58172 8 8V0Z"
            fill="white"
            fillRule="evenodd"
          />
        </svg>
      </div>
    );
  }
  return (
    <div className="absolute top-auto right-0 -bottom-2 left-auto flex h-2 w-2 items-center justify-center">
      <svg
        fill="none"
        height="8"
        viewBox="0 0 8 8"
        width="8"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          clipRule="evenodd"
          d="M8 0H0C4.41828 0 8 3.58172 8 8V0Z"
          fill="white"
          fillRule="evenodd"
        />
      </svg>
    </div>
  );
}

export default function BlogVariant2() {
  const [activeCategory, setActiveCategory] = useState("all");

  const filteredPosts =
    activeCategory === "all"
      ? posts
      : posts.filter((post) => post.categoryId === activeCategory);

  const showFeatured =
    activeCategory === "all" || featuredPost.categoryId === activeCategory;

  return (
    <section className="w-full bg-white py-12 sm:py-16 lg:py-20">
      <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
        <Badge className="mb-4 rounded-full px-2 py-0.5">Latest Articles</Badge>

        <h2 className="max-w-lg font-medium font-onest text-3xl text-gray-900 tracking-tight sm:text-4xl md:text-6xl">
          Explore the future of robotics
        </h2>

        <Tabs
          className="mt-8"
          onValueChange={setActiveCategory}
          value={activeCategory}
        >
          <TabsList className="flex flex-wrap gap-2 border-none bg-transparent p-0 shadow-none">
            {categories.map((category) => (
              <TabsTab
                className={`rounded-md border-none px-4 py-2 font-medium font-onest text-sm transition-colors focus-visible:ring-0 ${
                  activeCategory === category.id
                    ? "border-none bg-blue-600 outline-0 data-active:text-white"
                    : "text-black"
                }`}
                key={category.id}
                value={category.id}
              >
                {category.label}
              </TabsTab>
            ))}
          </TabsList>

          <TabsPanel className="mt-10" value={activeCategory}>
            {showFeatured && (
              <article className="grid grid-cols-1 gap-8 lg:grid-cols-12 lg:gap-12">
                <div className="relative col-span-4">
                  <div className="relative aspect-4/3 w-full overflow-hidden rounded-2xl lg:aspect-square">
                    <Image
                      alt={featuredPost.title}
                      className="object-cover"
                      fill
                      src={featuredPost.image}
                    />
                  </div>

                  <span className="absolute top-0 right-0 rounded-bl-lg bg-white px-3 py-1 font-medium text-gray-600 text-xs">
                    {featuredPost.readTime}
                    <CurvedCorner position="left" />
                    <CurvedCorner position="bottom" />
                  </span>
                </div>

                <div className="col-span-8 flex flex-col justify-center">
                  <Link
                    className="font-medium font-onest text-blue-600 text-sm hover:text-blue-700"
                    href="#"
                  >
                    {featuredPost.category}
                  </Link>

                  <h3 className="mt-2 font-medium font-onest text-3xl! text-gray-900 sm:text-5xl!">
                    {featuredPost.title}
                  </h3>

                  <p className="mt-4 font-onest text-base text-gray-600 leading-relaxed">
                    {featuredPost.excerpt}
                  </p>

                  <p className="mt-4 text-gray-500 text-sm">
                    Published on {featuredPost.publishedDate}
                  </p>

                  <div className="mt-6">
                    <Button
                      className="rounded-full border-none px-6 py-2 font-medium font-onest text-gray-700 text-sm"
                      render={<Link href="#" />}
                      variant="secondary"
                    >
                      Read more
                    </Button>
                  </div>
                </div>
              </article>
            )}

            <div
              className={`grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3 ${
                showFeatured ? "mt-12" : ""
              }`}
            >
              {filteredPosts.map((post) => (
                <article
                  className="group relative cursor-pointer"
                  key={post.title}
                >
                  <div className="relative">
                    <div className="relative h-52 w-full overflow-hidden rounded-2xl">
                      <Image
                        alt={post.title}
                        className="object-cover transition-transform duration-300 group-hover:scale-105"
                        fill
                        src={post.image}
                      />
                    </div>

                    <span className="absolute top-0 right-0 rounded-bl-lg bg-white px-3 py-1 font-medium text-gray-600 text-xs">
                      {post.readTime}
                      <CurvedCorner position="left" />
                      <CurvedCorner position="bottom" />
                    </span>
                  </div>

                  <div className="mt-4">
                    <Link
                      className="font-medium font-onest text-blue-600 text-sm hover:text-blue-700"
                      href="#"
                    >
                      <span className="absolute inset-0" />
                      {post.category}
                    </Link>

                    <h3 className="mt-2 font-medium font-onest text-gray-900 text-xl! leading-snug sm:text-2xl!">
                      {post.title}
                    </h3>

                    <p className="mt-2 text-gray-500 text-sm">
                      Published on {post.publishedDate}
                    </p>
                  </div>
                </article>
              ))}
            </div>

            {filteredPosts.length === 0 && !showFeatured && (
              <div className="py-12 text-center">
                <p className="font-onest text-gray-500">
                  No articles found in this category.
                </p>
              </div>
            )}
          </TabsPanel>
        </Tabs>
      </div>
    </section>
  );
}
```
