)
}
```
### Example 4: Composing a Page from Components
```typescript
// src/components/Level2.tsx
import { useState } from 'react'
import { Button } from '@/components/atoms'
import { AppHeader, AppFooter, ProfileCard } from '@/components/molecules'
import {
UserProfileForm,
IRCWebchat,
CommentsList
} from '@/components/organisms'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
interface Level2Props {
user: User
onLogout: () => void
onNavigate: (level: number) => void
}
export function Level2({ user, onLogout, onNavigate }: Level2Props) {
const [activeTab, setActiveTab] = useState('profile')
return (
User Dashboard
Welcome back, {user.username}!
ProfileChatComments
)
}
export default Level2
```
## Decision Tree: Which Category?
### Is it a single UI element?
**→ Use an ATOM (from shadcn/ui)**
- Examples: Button, Input, Badge, Avatar
- Import from: `@/components/atoms` or `@/components/ui/*`
### Is it 2-5 atoms working together?
**→ Create a MOLECULE**
- Examples: FormField, SearchBar, CardHeader
- Put in: `src/components/molecules/`
- Export from: `@/components/molecules/index.ts`
### Is it a complex feature with business logic?
**→ Create an ORGANISM**
- Examples: UserManagement, SchemaEditor, Chat
- Put in: `src/components/organisms/`
- Export from: `@/components/organisms/index.ts`
### Is it a complete page/view?
**→ It's a PAGE**
- Examples: Level1, Level2, Level3
- Keep at: `src/components/`
## Best Practices
### 1. Keep Atoms Generic
```typescript
// ✅ Good - generic and reusable
export function StatusBadge({ status }: { status: string }) {
return {status}
}
// ❌ Bad - too specific
export function UserOnlineStatusBadgeForLevel2Dashboard({ status }: Props) {
return {status}
}
```
### 2. Molecules Should Be Self-Contained
```typescript
// ✅ Good - everything needed is inside
export function SearchBar({ onSearch }: { onSearch: (q: string) => void }) {
const [query, setQuery] = useState('')
return (
setQuery(e.target.value)} />
)
}
// ❌ Bad - state managed externally
export function SearchBar({ query, setQuery, onSearch }: Props) {
return (
setQuery(e.target.value)} />
)
}
```
### 3. Organisms Can Have Complex Logic
```typescript
// ✅ Good - organism handles complex state and business logic
export function UserManagement() {
const [users, setUsers] = useKV('users', [])
const [loading, setLoading] = useState(false)
const [filter, setFilter] = useState('')
const filteredUsers = users.filter(u =>
u.name.toLowerCase().includes(filter.toLowerCase())
)
const handleAddUser = async (userData: UserData) => {
setLoading(true)
// Complex user creation logic
await Database.addUser(userData)
setUsers(current => [...current, newUser])
setLoading(false)
}
return (
)
}
```
### 4. Use Composition
```typescript
// ✅ Good - compose from smaller parts
function SettingsPage() {
return (
)
}
```
### Pattern 2: Data Table (Organism)
```typescript
import { Button, Input } from '@/components/atoms'
import { Table } from '@/components/ui/table'
import { useState } from 'react'
export function UserTable({ data }: { data: User[] }) {
const [filter, setFilter] = useState('')
const [sortBy, setSortBy] = useState('name')
const filteredData = data
.filter(row => row.name.includes(filter))
.sort((a, b) => a[sortBy].localeCompare(b[sortBy]))
return (
setFilter(e.target.value)}
/>
{/* Table implementation */}
)
}
```
## Questions?
- **Where do I put a component?** Use the decision tree above
- **Can atoms import molecules?** No, never
- **Can organisms import other organisms?** Yes, that's fine
- **Do I have to move existing components?** No, exports make it virtual
- **Should I refactor everything now?** No, use atomic design for new code
## Summary
- **Atoms**: Basic UI elements (shadcn/ui)
- **Molecules**: 2-5 atoms working together
- **Organisms**: Complex features with logic
- **Pages**: Complete views
Import from `@/components/atoms`, `@/components/molecules`, or `@/components/organisms` for cleaner code!