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-authorityimport { 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:classNameaclasshelyett.