Skip to main content

Command Palette

Search for a command to run...

Trying out Shadcn/UI for the first time

Updated
3 min read
Trying out Shadcn/UI for the first time

I was frustrated when I saw a lot of Tailwind CSS classes in my JSX code. I love Tailwind CSS, but it can be a bit verbose. I recently learned about shadcn/ui, a collection of Tailwind CSS components that can be used to create your own component library. I was surprised to find that shadcn/ui is not a traditional component library. Instead, it provides a set of components and utilities that you can use to create your own components. This makes shadcn/ui a great choice for developers who want to create their own custom component libraries.

Here are some of the benefits of using shadcn/ui:

  • Versatility: shadcn/ui provides a wide range of components and utilities, so you can create a component library that meets your specific needs.

  • Flexibility: shadcn/ui is not a traditional component library, so you have complete control over the look and feel of your components.

  • Efficiency: shadcn/ui can help you to reduce the amount of Tailwind CSS code that you need to write, which can make your code more readable and maintainable.

If you are looking for a way to create your own custom component library, I highly recommend shadcn/ui. It is a powerful tool that can help you to create beautiful and efficient components.

Here is the simple Title component I have created with it.

import * as React from "react"
import { VariantProps, cva } from "class-variance-authority"

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

const titleVariants = cva(
  "text-3xl font-extrabold leading-tight tracking-tighter sm:text-3xl md:text-5xl lg:text-6xl",
  {
    variants: {
      variant: {
        default: "",
        h1: "", // Think Something for H1 specific design
        h2: "", // Think Something for H2 specific design
      },
      size: {
        default: "sm:text-3xl md:text-5xl lg:text-6xl",
        sm: "sm:text-2xl md:text-4xl lg:text-5xl",
        lg: "sm:text-4xl md:text-6xl lg:text-7xl",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

export interface TitleProps
  extends React.HTMLAttributes<HTMLHeadingElement>,
    VariantProps<typeof titleVariants> {}

function Title(props: TitleProps) {
  const { variant, size, className, ...rest } = props

  function H1() {
    return (
      <h1
        className={cn(titleVariants({ variant, size, className }))}
        {...rest}
      />
    )
  }
  function H2() {
    return (
      <h2
        className={cn(titleVariants({ variant, size, className }))}
        {...rest}
      />
    )
  }

  let titleComponentMap = {
    h1: <H1 />,
    h2: <H2 />,
    default: <H1 />,
  }

  type ComponentMapKey = keyof typeof titleComponentMap

  return titleComponentMap[variant as ComponentMapKey] || <H1 />
}

export { Title, titleVariants }

And its implementation in the page.tsx looks like

import Link from "next/link"

import { siteConfig } from "@/config/site"
import { buttonVariants } from "@/components/ui/button"
import { Title, titleVariants } from "@/components/ui/title"

export default function IndexPage() {
  return (
    <section className="container grid items-center gap-6 pb-8 pt-6 md:py-10">
      <div className="flex max-w-[980px] flex-col items-start gap-2">
        <Title size="default" variant="h1">
          Beautifully designed components <br className="hidden sm:inline" />
          built with Radix UI and Tailwind CSS.
        </Title>
        <h2 className={titleVariants({ variant: "h2", size: "sm" })}>
          This is H2
        </h2>
        <p className="max-w-[700px] text-lg text-muted-foreground sm:text-xl">
          Accessible and customizable components that you can copy and paste
          into your apps. Free. Open Source. And Next.js 13 Ready.
        </p>
      </div>

      <div className="flex gap-4">
        <Link
          href={siteConfig.links.docs}
          target="_blank"
          rel="noreferrer"
          className={buttonVariants({ size: "lg" })}
        >
          Documentation
        </Link>
        <Link
          target="_blank"
          rel="noreferrer"
          href={siteConfig.links.github}
          className={buttonVariants({ variant: "outline", size: "lg" })}
        >
          GitHub
        </Link>
      </div>
    </section>
  )
}

Have you noticed the following part in the page.tsx page:

        <Title size="default" variant="h1">
          Beautifully designed components <br className="hidden sm:inline" />
          built with Radix UI and Tailwind CSS.
        </Title>
        <h2 className={titleVariants({ variant: "h2", size: "sm" })}>
          This is H2
        </h2>

In the first example, we have used Title component with size and variant props, and in the second example, we have used titleVariants in the className property.

Thank you.

36 views
Trying out Shadcn/UI for the first time