# UI Components & Styling Instructions
This file contains instructions for working with UI components, styling, and forms.
## Core UI Library
Import from `packages/ui/src/`:
```tsx
// Shadcn components
import { Button } from '@kit/ui/button';
import { Card } from '@kit/ui/card';
// Makerkit components
import { If } from '@kit/ui/if';
import { ProfileAvatar } from '@kit/ui/profile-avatar';
import { toast } from '@kit/ui/sonner';
import { Trans } from '@kit/ui/trans';
```
## Styling Guidelines
- Use **Tailwind CSS v4** with semantic classes
- Prefer Shadcn-ui classes like `bg-background`, `text-muted-foreground`
- Use `cn()` utility from `@kit/ui/utils` for class merging
```tsx
import { cn } from '@kit/ui/utils';
function MyComponent({ className }) {
return (
Content
);
}
```
### Conditional Rendering
Use the `If` component from `packages/ui/src/makerkit/if.tsx`:
```tsx
import { If } from '@kit/ui/if';
}>
// With type inference
{(err) => }
```
### Testing Attributes
```tsx
Profile
```
## Forms with React Hook Form & Zod
```typescript
// 1. Schema in separate file
export const CreateNoteSchema = z.object({
title: z.string().min(1),
content: z.string().min(1),
});
// 2. Client component with form
'use client';
const form = useForm({
resolver: zodResolver(CreateNoteSchema),
});
const onSubmit = (data) => {
startTransition(async () => {
await toast.promise(createNoteAction(data), {
loading: 'Creating...',
success: 'Created!',
error: 'Failed!',
}).unwrap();
});
};
```
### Guidelines
- Place Zod resolver outside so it can be reused with Server Actions
- Never add generics to `useForm`, use Zod resolver to infer types instead
- Never use `watch()` instead use hook `useWatch`
- Add `FormDescription` (optionally) and always add `FormMessage` to display errors
### Form Examples
- Contact form: `apps/web/app/(marketing)/contact/_components/contact-form.tsx`
- Verify OTP form: `packages/otp/src/components/verify-otp-form.tsx`
## Internationalization
Always use `Trans` component from `packages/ui/src/makerkit/trans.tsx`:
```tsx
import { Trans } from '@kit/ui/trans';
// With HTML elements
,
}}
/>
```
## Toast Notifications
Use the `toast` utility from `@kit/ui/sonner`:
```tsx
import { toast } from '@kit/ui/sonner';
// Simple toast
toast.success('Success message');
toast.error('Error message');
// Promise-based toast
await toast.promise(asyncFunction(), {
loading: 'Processing...',
success: 'Done!',
error: 'Failed!',
});
```
## Common Component Patterns
### Loading States
```tsx
import { Spinner } from '@kit/ui/spinner';
}>
```
### Error Handling
```tsx
import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
import { ExclamationTriangleIcon } from '@radix-ui/react-icons';
Error{error}
```
### Button Patterns
```tsx
import { Button } from '@kit/ui/button';
// Loading button
// Variants
```
### Card Layouts
```tsx
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@kit/ui/card';
Card TitleCard description
Card content goes here
```
## Form Components
### Input Fields
```tsx
import { Input } from '@kit/ui/input';
import { Label } from '@kit/ui/label';
import { FormField, FormItem, FormLabel, FormControl, FormMessage } from '@kit/ui/form';
(
Title
)}
/>
```
### Select Components
```tsx
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@kit/ui/select';
(
Category
)}
/>
```
## Accessibility Guidelines
- Always include proper ARIA labels
- Use semantic HTML elements
- Ensure proper keyboard navigation
```tsx
```
## Dark Mode Support
The UI components automatically support dark mode through CSS variables. Use semantic color classes:
```tsx
// Good - semantic colors