# Component Standards - CareBridge
## Critical Rule: No Custom Components
**NEVER create custom UI components from scratch. ALWAYS use shadcn/ui.**
## Using shadcn/ui
### Adding Components
```bash
# List available components
npx shadcn@latest add
# Add a specific component
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add dialog
npx shadcn@latest add form
```
This adds components to `src/components/ui/` with proper TypeScript types and styling.
### Example: Adding a Button
```bash
npx shadcn@latest add button
```
Then use it:
```typescript
import { Button } from '@/components/ui/button'
export function MyComponent() {
return Click me
}
```
### Available Variants
shadcn components come with built-in variants. Check the component file for options:
```typescript
// Button variants
Default
Delete
Outline
Secondary
Ghost
Link
// Card components
Title
Description
Content here
Footer actions
```
## Component Organization
### Location
```
src/
├── components/
│ ├── ui/ # shadcn components (DON'T EDIT)
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ └── ...
│ ├── dashboard/ # Dashboard-specific components
│ ├── calendar/ # Calendar-specific components
│ ├── concierge/ # Concierge-specific components
│ └── nav-main.tsx # Global navigation components
```
### Naming Conventions
- UI components: `kebab-case.tsx` (button.tsx, card.tsx)
- Feature components: `PascalCase.tsx` (DashboardHeader.tsx, CaseList.tsx)
- Use descriptive names: `ConciergeBookingForm.tsx` not `Form.tsx`
## Styling Rules
### CSS Variables (READ-ONLY)
**NEVER create custom CSS variables. ONLY use existing ones from `globals.css`.**
Available CSS variables:
```css
/* From globals.css */
--background
--foreground
--card
--card-foreground
--popover
--popover-foreground
--primary
--primary-foreground
--secondary
--secondary-foreground
--muted
--muted-foreground
--accent
--accent-foreground
--destructive
--destructive-foreground
--border
--input
--ring
```
### Using CSS Variables
```typescript
// ✅ CORRECT - Use existing variables
Content
// ✅ CORRECT - Use Tailwind utility classes
Card content
// ❌ WRONG - Custom CSS variables
Content
// ❌ WRONG - Inline styles
Content
```
### Tailwind Classes
Use Tailwind utility classes for styling:
```typescript
// ✅ CORRECT
// ❌ WRONG - Custom CSS classes
Content
```
## Form Components
### Using React Hook Form + Zod
CareBridge uses React Hook Form with Zod validation:
```typescript
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
const formSchema = z.object({
name: z.string().min(1, 'Name is required'),
email: z.string().email('Invalid email'),
})
export function MyForm() {
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
name: '',
email: '',
},
})
const onSubmit = async (values: z.infer) => {
// Handle submission
}
return (
)
}
```
## Dialog/Modal Pattern
```typescript
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
export function MyDialog() {
return (
Open Dialog
Dialog Title
Dialog content here
)
}
```
## Empty States Pattern
Use the `EmptyState` component for "no data" scenarios:
```typescript
import { EmptyState } from '@/components/dashboard/empty-state'
import { Users } from 'lucide-react'
export function MyComponent({ data }) {
if (!data || data.length === 0) {
return (
)
}
return {/* Render data */}
}
```
## Loading States
```typescript
import { Skeleton } from '@/components/ui/skeleton'
export function LoadingState() {
return (
)
}
```
## Icons
Use Lucide React for icons:
```typescript
import { Calendar, User, Settings, CreditCard } from 'lucide-react'
export function MyComponent() {
return (
Calendar
)
}
```
## Common Component Patterns
### Card with Actions
```typescript
Title
Description
Content here
Cancel
Save
```
### List with Items
```typescript
{items.map((item) => (
{item.title}
{item.description}
View
))}
```
## Responsive Design
Use Tailwind responsive prefixes:
```typescript
{/* Responsive grid */}
{/* Stack vertically on mobile, horizontally on larger screens */}
```
## Common Mistakes
### ❌ Mistake #1: Creating custom components
```typescript
// WRONG - Don't create custom buttons
export function CustomButton({ children }) {
return (
{children}
)
}
// CORRECT - Use shadcn button
import { Button } from '@/components/ui/button'
{children}
```
### ❌ Mistake #2: Custom CSS variables
```typescript
// WRONG - Don't create custom variables
Content
// CORRECT - Use existing variables
Content
```
### ❌ Mistake #3: Inline styles
```typescript
// WRONG - Avoid inline styles
Content
// CORRECT - Use Tailwind classes
Content
```
### ❌ Mistake #4: Not using TypeScript types
```typescript
// WRONG - No types
export function MyComponent({ user }) {
return {user.name}
}
// CORRECT - Proper TypeScript types
type Props = {
user: {
name: string
email: string
}
}
export function MyComponent({ user }: Props) {
return {user.name}
}
```
## Component Checklist
Before creating a component:
- [ ] Is there a shadcn component for this? (Use `npx shadcn@latest add`)
- [ ] Am I using existing CSS variables?
- [ ] Am I using Tailwind classes instead of inline styles?
- [ ] Do I have proper TypeScript types?
- [ ] Is the component in the right directory?
- [ ] Am I preserving case context in navigation?