LoginSignup
44
40

Next.jsのApp Routerを学ぶ際、shadcn/uiが参考になったという話

Last updated at Posted at 2024-05-10

Next.jsのApp Routerを学ぶ際に、UIライブラリを探していたところ、shadcn/uiが参考になったので紹介します。

shadcn/uiは、フレームワークやライブラリではなく、コピペで利用できるReactコンポーネントのサンプル集という立ち位置になっています。Tailwind CSSでデザインされており、React Server Components(RSC)にも対応しています。
サンプルの実装方法が参考になる点も魅力の一つです。

簡単ですがつらつらと紹介していきたいと思います。

shadcn/uiとは

デモを見てるとフレームワークやライブラリなのかなと思いきやそうではなく、コピペで利用できるサンプル集という立ち位置になっています。基本的にはTailwind CSSでデザインされてるようです。
サンプルとはいえ、実装方法で参考になった箇所が結構あったのでそこも気に入ってるポイントです。

関連技術

  • Next.js@14
  • Radix UI
  • Tailwind CSS
  • React Server Components対応
  • class-variance-authorityを積極的に活用
  • ダークモード対応

Example

サンプルが色々あるので、使いたい機能に合わせてコピペして持ってこれそうです。

CleanShot 2024-05-10 at 17.28.24.png

導入方法

Next.jsにフォーカスして調べてはいたのですが、ViteやAstro等色々対応しているみたいです。

CleanShot 2024-05-10 at 17.30.16.png

セットアップ

今回はNext.jsのセットアップ方法を紹介します

% npx create-next-app@latest my-app --typescript --tailwind --eslint
% npx shadcn-ui@latest init

利用方法

ボタンのサンプルが欲しければ、こんな感じで持って来れます

% npx shadcn-ui@latest add button
import { Button } from "@/components/ui/button"
 
export default function Home() {
  return (
    <div>
      <Button>Click me</Button>
    </div>
  )
}

カスタマイズ

cvaでデザインのパターンが増やせる実装になっているので要件に合わせて、色やvariantを変更していくと良さそうです。具体的な実装例を貼っておきます。

components/ui/button.tsx
import * as React from "react"
import { VariantProps, cva } from "class-variance-authority"

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

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive:
          "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline:
          "border border-input hover:bg-accent hover:text-accent-foreground",
        secondary:
          "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "underline-offset-4 hover:underline text-primary",
      },
      size: {
        default: "h-10 py-2 px-4",
        sm: "h-9 px-3 rounded-md",
        lg: "h-11 px-8 rounded-md",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, ...props }, ref) => {
    return (
      <button
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    )
  }
)
Button.displayName = "Button"

export { Button, buttonVariants }

実装サンプル

Server Componentsの実装方法やライブラリの選定、デザインの管理方法などだいぶ参考になったのでこちらのサンプルも紹介します。

ソース

デモ

44
40
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
44
40