6.4 KiB
6.4 KiB
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
🎨 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
// ✅ 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
// ❌ 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
// ❌ NEVER
import { XIcon } from '@heroicons/react/24/outline';
import { Trash } from 'lucide-react';
// ✅ ALWAYS
import { CloseIcon, TrashBinIcon } from '../../icons';
Rule 3: Consistent Icon Sizing
// 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
// 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
<InputField
label="Email"
type="email"
placeholder="you@example.com"
error={errors.email}
required
/>
Select Dropdowns
<Select
label="Country"
options={[
{ value: 'us', label: 'United States' },
{ value: 'uk', label: 'United Kingdom' },
]}
value={country}
onChange={setCountry}
/>
Checkboxes & Switches
// Checkbox
<Checkbox
label="I agree to terms"
checked={agreed}
onChange={setAgreed}
/>
// Toggle switch
<Switch
label="Enable notifications"
checked={enabled}
onChange={setEnabled}
/>
Badge Tones
<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
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
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
<Card>
<Card.Header>
<h3>Title</h3>
</Card.Header>
<Card.Body>
Content here
</Card.Body>
<Card.Footer>
<Button>Action</Button>
</Card.Footer>
</Card>
Typography
// 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 - Full component API
- DESIGN-TOKENS.md - CSS variables
- PAGES.md - Route structure