Learning
Tailwind CSS

Tailwind + React / Next.js

className, dinamikus class-ek, cn(), CVA, Server Components, ThemeToggle példa.

Tailwind + React / Next.js

className a JSX-ben

React-ban a class helyett className-t kell használni – ez nem Tailwind-specifikus, ez a React követelménye:

// ❌ HTML szintaxis (nem React)
<div class="flex items-center">

// ✅ JSX szintaxis
<div className="flex items-center">

Dinamikus class-ek – a helyes megközelítés

// 1. Egyszerű ternary
<div className={isActive ? 'bg-blue-500' : 'bg-gray-200'}>

// 2. Kondicionális class hozzáadás
<div className={`base-class ${condition ? 'extra-class' : ''}`}>

// 3. clsx (ajánlott)
import { clsx } from 'clsx';
<div className={clsx('base-class', condition && 'extra-class')}>

// 4. cn() – tailwind-merge-gel (legjobb megközelítés)
import { cn } from '@/lib/utils';
<div className={cn('base-class', condition && 'extra-class', className)}>

Variáns-alapú komponens (CVA minta)

A class-variance-authority (CVA) könyvtár Tailwind-del rendkívül elegáns komponenseket tesz lehetővé:

npm install class-variance-authority
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';

const buttonVariants = cva(
  'inline-flex items-center justify-center font-semibold rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none',
  {
    variants: {
      variant: {
        default: 'bg-blue-500 hover:bg-blue-600 text-white focus:ring-blue-500',
        secondary: 'bg-gray-100 hover:bg-gray-200 text-gray-900 focus:ring-gray-500',
        destructive: 'bg-red-500 hover:bg-red-600 text-white focus:ring-red-500',
        ghost: 'hover:bg-gray-100 text-gray-900 focus:ring-gray-500',
        link: 'text-blue-600 underline-offset-4 hover:underline focus:ring-blue-500',
      },
      size: {
        sm: 'h-9 px-3 text-sm',
        default: 'h-10 px-4',
        lg: 'h-11 px-6 text-lg',
        icon: 'h-10 w-10',
      },
    },
    defaultVariants: {
      variant: 'default',
      size: 'default',
    },
  }
);

interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  className?: string;
}

export function Button({ className, variant, size, ...props }: ButtonProps) {
  return (
    <button
      className={cn(buttonVariants({ variant, size }), className)}
      {...props}
    />
  );
}

Használat:

<Button>Alap gomb</Button>
<Button variant="secondary" size="sm">Kis másodlagos</Button>
<Button variant="destructive" size="lg">Nagy törlés</Button>
<Button variant="ghost" size="icon"><TrashIcon /></Button>

Next.js App Router + Server Components

A Tailwind tökéletesen működik Server Components-szel, mert a styling statikus class nevekkel történik – nincs JavaScript futásidei overhead:

// app/page.tsx – Server Component (alapértelmezett)
export default function HomePage() {
  return (
    <main className="min-h-screen bg-gray-50">
      <div className="container mx-auto px-4 py-16">
        <h1 className="text-4xl font-bold text-gray-900">Üdvözöllek!</h1>
      </div>
    </main>
  );
}

Client Component-re csak akkor van szükség, ha interaktivitás kell (pl. dark mode toggle, animált menü):

// components/ThemeToggle.tsx – Client Component
'use client';
import { useState } from 'react';

export function ThemeToggle() {
  const [isDark, setIsDark] = useState(false);
  
  return (
    <button
      className="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
      onClick={() => {
        setIsDark(!isDark);
        document.documentElement.classList.toggle('dark');
      }}
    >
      {isDark ? '☀️' : '🌙'}
    </button>
  );
}

Összefoglaló

React + Tailwind esetén a cn() helper a legfontosabb eszköz. A CVA minta a legelegánsabb megoldás variáns-alapú komponensekhez. Server Components-sel nincs különleges teendő – a Tailwind osztályok statikusak, így tökéletesen kompatibilisek. Az egyetlen "react-specifikus" szabály: className a class helyett.

On this page