312 lines
6.4 KiB
Markdown
312 lines
6.4 KiB
Markdown
# IGNY8 Design Guide
|
|
|
|
> **🔒 MANDATORY** - All frontend code MUST follow these standards
|
|
> **Version:** 1.8.3
|
|
> **Last Updated:** January 20, 2026
|
|
|
|
---
|
|
|
|
## Quick Reference
|
|
|
|
| Need | Use | Import From |
|
|
|------|-----|-------------|
|
|
| Button | `<Button>` | `components/ui/button/Button` |
|
|
| Icon button | `<IconButton>` | `components/ui/button/IconButton` |
|
|
| Text input | `<InputField>` | `components/form/input/InputField` |
|
|
| Dropdown | `<Select>` | `components/form/Select` |
|
|
| Checkbox | `<Checkbox>` | `components/form/input/Checkbox` |
|
|
| Toggle | `<Switch>` | `components/form/switch/Switch` |
|
|
| Status label | `<Badge>` | `components/ui/badge/Badge` |
|
|
| Card | `<Card>` | `components/ui/card/Card` |
|
|
| Modal | `<Modal>` | `components/ui/modal` |
|
|
| Toast | `useToast()` | `components/ui/toast/ToastContainer` |
|
|
| Table | `<Table>` | `components/tables/Table` |
|
|
|
|
**Full component docs:** [docs/30-FRONTEND/COMPONENT-SYSTEM.md](docs/30-FRONTEND/COMPONENT-SYSTEM.md)
|
|
|
|
---
|
|
|
|
## 🎨 Color System
|
|
|
|
### Only 6 Base Colors (No Exceptions!)
|
|
|
|
| Token | Hex | Usage |
|
|
|-------|-----|-------|
|
|
| `brand` | #0077B6 | Primary actions, links |
|
|
| `success` | #2CA18E | Success states |
|
|
| `warning` | #D9A12C | Warnings, alerts |
|
|
| `danger/error` | #A12C40 | Errors, destructive |
|
|
| `purple` | #2C40A1 | Premium features |
|
|
| `gray` | #667085 | Text, borders, neutrals |
|
|
|
|
### Tailwind Classes
|
|
|
|
```tsx
|
|
// ✅ CORRECT - Use semantic colors
|
|
<div className="bg-brand-500 text-white">Primary</div>
|
|
<div className="bg-success-100 text-success-700">Success</div>
|
|
<div className="bg-error-100 text-error-700">Error</div>
|
|
<div className="text-gray-700 bg-gray-50">Neutral</div>
|
|
|
|
// ❌ WRONG - Default Tailwind colors are DISABLED
|
|
<div className="bg-blue-500">...</div> // Will not work
|
|
<div className="bg-red-500">...</div> // Will not work
|
|
<div className="bg-[#ff0000]">...</div> // Hardcoded - forbidden
|
|
```
|
|
|
|
---
|
|
|
|
## Component Rules
|
|
|
|
### Rule 1: NEVER Use Raw HTML Elements
|
|
|
|
```tsx
|
|
// ❌ NEVER
|
|
<button onClick={...}>Click</button>
|
|
<input type="text" />
|
|
<select>...</select>
|
|
<textarea></textarea>
|
|
|
|
// ✅ ALWAYS
|
|
<Button onClick={...}>Click</Button>
|
|
<InputField type="text" label="Name" />
|
|
<Select options={options} />
|
|
<TextArea rows={4} />
|
|
```
|
|
|
|
### Rule 2: Icons from Central Location Only
|
|
|
|
```tsx
|
|
// ❌ NEVER
|
|
import { XIcon } from '@heroicons/react/24/outline';
|
|
import { Trash } from 'lucide-react';
|
|
|
|
// ✅ ALWAYS
|
|
import { CloseIcon, TrashBinIcon } from '../../icons';
|
|
```
|
|
|
|
### Rule 3: Consistent Icon Sizing
|
|
|
|
```tsx
|
|
// In buttons/badges
|
|
<Icon className="w-4 h-4" />
|
|
|
|
// Standalone
|
|
<Icon className="w-5 h-5" />
|
|
|
|
// Headers/large
|
|
<Icon className="w-6 h-6" />
|
|
```
|
|
|
|
---
|
|
|
|
## Button Variants
|
|
|
|
```tsx
|
|
// Primary action (main CTA)
|
|
<Button variant="primary">Save Changes</Button>
|
|
|
|
// Secondary action
|
|
<Button variant="secondary">Cancel</Button>
|
|
|
|
// Danger/destructive
|
|
<Button variant="danger">Delete</Button>
|
|
|
|
// Outline style
|
|
<Button variant="outline">Learn More</Button>
|
|
|
|
// Ghost (minimal)
|
|
<Button variant="ghost">Skip</Button>
|
|
|
|
// With icon
|
|
<Button variant="primary" leftIcon={<PlusIcon />}>Add Item</Button>
|
|
|
|
// Icon only
|
|
<IconButton icon={<SettingsIcon />} aria-label="Settings" />
|
|
```
|
|
|
|
---
|
|
|
|
## Form Patterns
|
|
|
|
### Input Fields
|
|
|
|
```tsx
|
|
<InputField
|
|
label="Email"
|
|
type="email"
|
|
placeholder="you@example.com"
|
|
error={errors.email}
|
|
required
|
|
/>
|
|
```
|
|
|
|
### Select Dropdowns
|
|
|
|
```tsx
|
|
<Select
|
|
label="Country"
|
|
options={[
|
|
{ value: 'us', label: 'United States' },
|
|
{ value: 'uk', label: 'United Kingdom' },
|
|
]}
|
|
value={country}
|
|
onChange={setCountry}
|
|
/>
|
|
```
|
|
|
|
### Checkboxes & Switches
|
|
|
|
```tsx
|
|
// Checkbox
|
|
<Checkbox
|
|
label="I agree to terms"
|
|
checked={agreed}
|
|
onChange={setAgreed}
|
|
/>
|
|
|
|
// Toggle switch
|
|
<Switch
|
|
label="Enable notifications"
|
|
checked={enabled}
|
|
onChange={setEnabled}
|
|
/>
|
|
```
|
|
|
|
---
|
|
|
|
## Badge Tones
|
|
|
|
```tsx
|
|
<Badge tone="default">Draft</Badge>
|
|
<Badge tone="success">Active</Badge>
|
|
<Badge tone="warning">Pending</Badge>
|
|
<Badge tone="error">Failed</Badge>
|
|
<Badge tone="info">New</Badge>
|
|
```
|
|
|
|
---
|
|
|
|
## Modal Pattern
|
|
|
|
```tsx
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
<Modal
|
|
isOpen={isOpen}
|
|
onClose={() => setIsOpen(false)}
|
|
title="Confirm Delete"
|
|
>
|
|
<p>Are you sure you want to delete this item?</p>
|
|
<div className="flex gap-3 mt-4">
|
|
<Button variant="secondary" onClick={() => setIsOpen(false)}>
|
|
Cancel
|
|
</Button>
|
|
<Button variant="danger" onClick={handleDelete}>
|
|
Delete
|
|
</Button>
|
|
</div>
|
|
</Modal>
|
|
```
|
|
|
|
---
|
|
|
|
## Toast Notifications
|
|
|
|
```tsx
|
|
import { useToast } from '../components/ui/toast/ToastContainer';
|
|
|
|
const { showToast } = useToast();
|
|
|
|
// Success
|
|
showToast('Changes saved successfully', 'success');
|
|
|
|
// Error
|
|
showToast('Failed to save changes', 'error');
|
|
|
|
// Warning
|
|
showToast('Your session is about to expire', 'warning');
|
|
|
|
// Info
|
|
showToast('New features available', 'info');
|
|
```
|
|
|
|
---
|
|
|
|
## Spacing & Layout
|
|
|
|
### Standard Spacing Scale
|
|
|
|
| Class | Size | Usage |
|
|
|-------|------|-------|
|
|
| `gap-2` | 8px | Tight grouping |
|
|
| `gap-3` | 12px | Default spacing |
|
|
| `gap-4` | 16px | Section spacing |
|
|
| `gap-6` | 24px | Major sections |
|
|
|
|
### Card Layout
|
|
|
|
```tsx
|
|
<Card>
|
|
<Card.Header>
|
|
<h3>Title</h3>
|
|
</Card.Header>
|
|
<Card.Body>
|
|
Content here
|
|
</Card.Body>
|
|
<Card.Footer>
|
|
<Button>Action</Button>
|
|
</Card.Footer>
|
|
</Card>
|
|
```
|
|
|
|
---
|
|
|
|
## Typography
|
|
|
|
```tsx
|
|
// Page titles
|
|
<h1 className="text-2xl font-semibold text-gray-900">Page Title</h1>
|
|
|
|
// Section headers
|
|
<h2 className="text-lg font-medium text-gray-900">Section</h2>
|
|
|
|
// Card titles
|
|
<h3 className="text-base font-medium text-gray-900">Card Title</h3>
|
|
|
|
// Body text
|
|
<p className="text-sm text-gray-700">Body content</p>
|
|
|
|
// Secondary/muted text
|
|
<span className="text-sm text-gray-500">Helper text</span>
|
|
```
|
|
|
|
---
|
|
|
|
## ESLint Enforcement
|
|
|
|
These rules are **enforced via ESLint**:
|
|
|
|
| Rule | Level | Enforces |
|
|
|------|-------|----------|
|
|
| `no-raw-button` | warn | Use `<Button>` component |
|
|
| `no-raw-input` | warn | Use `<InputField>` component |
|
|
| `no-raw-select` | warn | Use `<Select>` component |
|
|
| `no-raw-textarea` | warn | Use `<TextArea>` component |
|
|
| `design-system-colors` | error | Only semantic colors |
|
|
| `no-hardcoded-colors` | error | No hex codes in className |
|
|
|
|
---
|
|
|
|
## Live Demo
|
|
|
|
Visit `/ui-elements` in the app to see all components in action.
|
|
|
|
---
|
|
|
|
## Related Docs
|
|
|
|
- [COMPONENT-SYSTEM.md](docs/30-FRONTEND/COMPONENT-SYSTEM.md) - Full component API
|
|
- [DESIGN-TOKENS.md](docs/30-FRONTEND/DESIGN-TOKENS.md) - CSS variables
|
|
- [PAGES.md](docs/30-FRONTEND/PAGES.md) - Route structure
|