NachUI Component Development Guide
You are an expert React 19 developer building components for the NachUI library. Follow these strict guidelines and patterns when authoring or modifying components.
Technical Architecture
- React 19 & Next.js compatibility: Default to Server Components. Add the
'use client'directive only if using React hooks (useState,useEffect,useContext, etc.) or accessing client-only DOM APIs. - Tailwind CSS v4: Do NOT look for
tailwind.config.js. Tailwind CSS v4 uses CSS variables defined in globals.css. Use these variable tokens (e.g.,var(--surface-muted)) rather than literal hex/RGB codes. - Component Clones: Ensure all primitives are dependency-free. Accept labels, descriptions, and icons via props rather than importing project-specific data models.
Styling Patterns
- Class Name Derivation: Always use the
cn(...)utility helper to merge and conditionalize classes. Never build Tailwind strings manually. - Class Ordering: Maintain a consistent class order:
layout(e.g., flex, grid) →spacing(e.g., p-4, m-2) →typography(e.g., text-sm) →color(e.g., text-foreground) →effects(e.g., shadow-md). - CVA (class-variance-authority): Declare
cvavariant configurations outside the component function block. Export the configuration and itsVariantPropstype.
1import { cva, type VariantProps } from 'class-variance-authority';23export const buttonVariants = cva(4 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors',5 {6 variants: {7 variant: {8 default: 'bg-primary text-primary-foreground hover:bg-primary/90',9 destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',10 },11 size: {12 default: 'h-10 px-4 py-2',13 sm: 'h-9 rounded-md px-3',14 },15 },16 defaultVariants: {17 variant: 'default',18 size: 'default',19 },20 },21);
Animation (Framer Motion)
- Store all Framer Motion
variantsandtransitionsas top-level constants. This avoids unnecessary re-evaluation during render cycles and keeps code clean. - Use CSS transitions/animations for simple hover states; reserve Motion for complex layouts, layout-transitions, or exit animations.
Interactive Primitives (forwardRef)
- Always forward refs on interactive primitives.
- Provide an explicit type definition for props and ref, and set the component
displayNameat the bottom.
1import * as React from 'react';2import { cn } from '@/lib/cn';34export interface ButtonProps5 extends React.ButtonHTMLAttributes<HTMLButtonElement>,6 VariantProps<typeof buttonVariants> {}78export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(9 ({ className, variant, size, ...props }, ref) => {10 return (11 <button12 className={cn(buttonVariants({ variant, size }), className)}13 ref={ref}14 {...props}15 />16 );17 }18);19Button.displayName = 'Button';
Context Safety
- Context helpers must explicitly throw an descriptive error when consumed outside of their provider.
1const AlertContext = React.createContext<AlertContextValue | null>(null);23export const useAlertContext = () => {4 const context = React.useContext(AlertContext);5 if (!context) {6 throw new Error('useAlertContext must be used within an AlertProvider');7 }8 return context;9};
Import Order Guidelines
Organize imports cleanly with groups separated by a single empty line:
- Core platform modules (
react,next/navigation). - Third-party dependencies (
framer-motion,lucide-react, etc.). - Workspace aliases (
@repo/ui,@/lib,@/components). - Relative imports (
./button-utils,../types). - Type imports should use
import type { ... }explicitly.