289 lines
6.6 KiB
Markdown
289 lines
6.6 KiB
Markdown
# Component Guide - Dish Planner
|
|
|
|
This guide documents the standardized UI components in the Dish Planner application. All components use Tailwind CSS with our custom color variables from the design system.
|
|
|
|
## Design System
|
|
|
|
### Colors
|
|
|
|
Our color palette is defined in `src/styles/theme/colors/root.css` and integrated into Tailwind via `tailwind.config.ts`:
|
|
|
|
- **Primary (Rose)**: `bg-primary`, `text-primary`, `border-primary` with shades 50-950
|
|
- **Secondary (Deluge)**: `bg-secondary`, `text-secondary`, `border-secondary` with shades 50-950
|
|
- **Accent (Malibu Blue)**: `bg-accent`, `text-accent`, `border-accent` with shades 50-950
|
|
- **Yellow (Gamboge)**: `bg-yellow`, `text-yellow`, `border-yellow` with shades 50-950
|
|
- **Gray (Ebony Clay)**: `bg-gray`, `text-gray`, `border-gray` with shades 100-950
|
|
- **Semantic Colors**:
|
|
- Danger (Alizarin Crimson): `bg-danger`, `text-danger`, `border-danger`
|
|
- Success (Spring Green): `bg-success`, `text-success`, `border-success`
|
|
- Warning (Burning Orange): `bg-warning`, `text-warning`, `border-warning`
|
|
|
|
## Components
|
|
|
|
### Button (`src/components/ui/Button.tsx`)
|
|
|
|
Unified button component supporting multiple variants, appearances, and states.
|
|
|
|
#### Props
|
|
|
|
```typescript
|
|
interface ButtonProps {
|
|
appearance?: 'solid' | 'outline' | 'text'; // Default: 'solid'
|
|
variant?: 'primary' | 'secondary' | 'accent' | 'danger'; // Default: 'primary'
|
|
size?: 'small' | 'medium' | 'large'; // Default: 'medium'
|
|
type?: 'button' | 'submit' | 'reset'; // Default: 'button'
|
|
href?: string; // For link buttons
|
|
icon?: ReactNode;
|
|
disabled?: boolean;
|
|
onClick?: () => void;
|
|
className?: string;
|
|
children: ReactNode;
|
|
}
|
|
```
|
|
|
|
#### Examples
|
|
|
|
```tsx
|
|
// Solid primary button
|
|
<Button variant="primary" appearance="solid">
|
|
Save
|
|
</Button>
|
|
|
|
// Outline accent button with icon
|
|
<Button variant="accent" appearance="outline" icon={<PlusIcon />}>
|
|
Add Item
|
|
</Button>
|
|
|
|
// Text danger button
|
|
<Button variant="danger" appearance="text" size="small">
|
|
Delete
|
|
</Button>
|
|
|
|
// Link button
|
|
<Button href="/dishes" appearance="outline" icon={<ChevronLeftIcon />}>
|
|
Back to Dishes
|
|
</Button>
|
|
```
|
|
|
|
### Input (`src/components/ui/Input.tsx`)
|
|
|
|
Standardized text input component with label, error, and helper text support.
|
|
|
|
#### Props
|
|
|
|
```typescript
|
|
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
label?: string;
|
|
error?: string;
|
|
helperText?: string;
|
|
fullWidth?: boolean; // Default: true
|
|
}
|
|
```
|
|
|
|
#### Examples
|
|
|
|
```tsx
|
|
// Basic input with label
|
|
<Input
|
|
label="Email"
|
|
type="email"
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
required
|
|
/>
|
|
|
|
// Input with error
|
|
<Input
|
|
label="Name"
|
|
value={name}
|
|
error="Name is required"
|
|
/>
|
|
|
|
// Input with helper text
|
|
<Input
|
|
label="Password"
|
|
type="password"
|
|
helperText="Must be at least 8 characters"
|
|
/>
|
|
```
|
|
|
|
### Select (`src/components/ui/Select.tsx`)
|
|
|
|
Standardized select dropdown component.
|
|
|
|
#### Props
|
|
|
|
```typescript
|
|
interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
|
|
label?: string;
|
|
error?: string;
|
|
helperText?: string;
|
|
fullWidth?: boolean; // Default: true
|
|
options: Array<{ value: string | number; label: string }>;
|
|
}
|
|
```
|
|
|
|
#### Example
|
|
|
|
```tsx
|
|
<Select
|
|
label="Recurrence"
|
|
value={recurrence}
|
|
onChange={(e) => setRecurrence(e.target.value)}
|
|
options={[
|
|
{ value: 7, label: 'Weekly' },
|
|
{ value: 30, label: 'Monthly' },
|
|
{ value: 365, label: 'Yearly' }
|
|
]}
|
|
/>
|
|
```
|
|
|
|
### Checkbox (`src/components/ui/Checkbox.tsx`)
|
|
|
|
Standardized checkbox component with label support.
|
|
|
|
#### Props
|
|
|
|
```typescript
|
|
interface CheckboxProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
label?: string;
|
|
error?: string;
|
|
helperText?: string;
|
|
}
|
|
```
|
|
|
|
#### Example
|
|
|
|
```tsx
|
|
<Checkbox
|
|
label="Enable notifications"
|
|
checked={enabled}
|
|
onChange={(e) => setEnabled(e.target.checked)}
|
|
/>
|
|
```
|
|
|
|
### Toggle (`src/components/ui/Toggle.tsx`)
|
|
|
|
Enhanced toggle switch component.
|
|
|
|
#### Props
|
|
|
|
```typescript
|
|
interface ToggleProps {
|
|
checked: boolean;
|
|
onChange: (checked: boolean) => void;
|
|
label?: string;
|
|
disabled?: boolean;
|
|
helperText?: string;
|
|
}
|
|
```
|
|
|
|
#### Example
|
|
|
|
```tsx
|
|
<Toggle
|
|
checked={isActive}
|
|
onChange={setIsActive}
|
|
label="Active"
|
|
helperText="Enable this feature"
|
|
/>
|
|
```
|
|
|
|
### Alert (`src/components/ui/Alert.tsx`)
|
|
|
|
Standardized alert component for displaying messages.
|
|
|
|
#### Props
|
|
|
|
```typescript
|
|
interface AlertProps {
|
|
type: 'error' | 'warning' | 'info' | 'success';
|
|
children: ReactNode;
|
|
className?: string;
|
|
}
|
|
```
|
|
|
|
#### Examples
|
|
|
|
```tsx
|
|
// Error alert
|
|
<Alert type="error">
|
|
An error occurred while saving.
|
|
</Alert>
|
|
|
|
// Success alert
|
|
<Alert type="success">
|
|
User created successfully!
|
|
</Alert>
|
|
|
|
// Warning alert
|
|
<Alert type="warning">
|
|
This action cannot be undone.
|
|
</Alert>
|
|
```
|
|
|
|
### Card (`src/components/layout/Card.tsx`)
|
|
|
|
Standardized card container component.
|
|
|
|
#### Props
|
|
|
|
```typescript
|
|
interface CardProps {
|
|
children: ReactNode;
|
|
className?: string;
|
|
}
|
|
```
|
|
|
|
#### Example
|
|
|
|
```tsx
|
|
<Card>
|
|
<div className="flex-grow">
|
|
<h3>User Name</h3>
|
|
</div>
|
|
<div className="flex gap-2">
|
|
<Button size="small">Edit</Button>
|
|
<Button size="small" variant="danger">Delete</Button>
|
|
</div>
|
|
</Card>
|
|
```
|
|
|
|
## Migration Guide
|
|
|
|
### From Old Button Components
|
|
|
|
The old button components have been removed. Use the unified `Button` component instead:
|
|
|
|
- `SolidButton` → `Button` with `appearance="solid"`
|
|
- `OutlineButton` → `Button` with `appearance="outline"`
|
|
- `SolidLinkButton` → `Button` with `appearance="solid"` and `href` prop
|
|
- `OutlineLinkButton` → `Button` with `appearance="outline"` and `href` prop
|
|
|
|
### Custom CSS Classes to Tailwind
|
|
|
|
Replace custom CSS classes with Tailwind utilities:
|
|
|
|
- `background-red` → `bg-primary`
|
|
- `background-secondary` → `bg-secondary`
|
|
- `font-size-18` → `text-lg`
|
|
- `text-accent-blue` → `text-accent`
|
|
- `border-accent` → `border-accent`
|
|
|
|
## Best Practices
|
|
|
|
1. **Use semantic color names**: Prefer `text-primary`, `bg-danger` over hardcoded colors
|
|
2. **Consistent spacing**: Use Tailwind's spacing scale (p-2, p-4, etc.)
|
|
3. **Responsive design**: Consider mobile-first responsive classes
|
|
4. **Accessibility**: Use proper ARIA attributes and semantic HTML
|
|
5. **Component reusability**: Always use the standardized components instead of creating custom styled elements
|
|
|
|
## Future Enhancements
|
|
|
|
Potential areas for further improvement:
|
|
|
|
- Migrate remaining inline-styled inputs to use the `Input` component
|
|
- Add dark mode support
|
|
- Create compound components for common patterns (e.g., FormGroup)
|
|
- Add animation utilities for better UX
|
|
- Implement a comprehensive form validation system
|