226 lines
6.0 KiB
Markdown
226 lines
6.0 KiB
Markdown
# Button Component Standardization - Complete
|
|
|
|
## Overview
|
|
Fixed Button component and all Sites pages to match IGNY8 global design standard:
|
|
- Secondary button color now uses `text-dim` (#64748b)
|
|
- Removed ALL `Link` component usage from buttons
|
|
- All buttons now use `onClick` navigation with `useNavigate()`
|
|
|
|
## Changes Made
|
|
|
|
### 1. Button Component (`/frontend/src/components/ui/button/Button.tsx`)
|
|
|
|
#### Removed Link/Anchor Support
|
|
- **Removed imports**: `Link` from react-router-dom
|
|
- **Removed props**: `as`, `href`, `to`, `target`, `rel`
|
|
- **Simplified component**: Always renders `<button>` element (no conditional rendering)
|
|
- **Result**: Button component ONLY supports `onClick` navigation
|
|
|
|
#### Fixed Secondary Color
|
|
Changed ALL secondary variants to use text-dim color (#64748b):
|
|
|
|
**Before (WRONG):**
|
|
```tsx
|
|
brand: {
|
|
secondary: "bg-brand-50 text-brand-600 hover:bg-brand-100"
|
|
}
|
|
success: {
|
|
secondary: "bg-success-50 text-success-600 hover:bg-success-100"
|
|
}
|
|
// etc...
|
|
```
|
|
|
|
**After (CORRECT):**
|
|
```tsx
|
|
brand: {
|
|
secondary: "bg-transparent text-[#64748b] hover:bg-gray-100 dark:hover:bg-white/[0.08]"
|
|
}
|
|
success: {
|
|
secondary: "bg-transparent text-[#64748b] hover:bg-gray-100 dark:hover:bg-white/[0.08]"
|
|
}
|
|
// etc...
|
|
```
|
|
|
|
**Affected tones:**
|
|
- ✅ brand
|
|
- ✅ success
|
|
- ✅ warning
|
|
- ✅ danger
|
|
- ✅ neutral (already correct)
|
|
|
|
### 2. Sites Pages - Removed All Link Usage
|
|
|
|
#### Dashboard.tsx (`/frontend/src/pages/Sites/Dashboard.tsx`)
|
|
- **Removed import**: `Link` from react-router-dom
|
|
- **Changed**: 5 Quick Action cards from `<Link to={...}>` to `<button onClick={() => navigate(...)}>>`
|
|
- **Actions updated**:
|
|
- Manage Pages
|
|
- Manage Content
|
|
- Integrations
|
|
- Sync Dashboard
|
|
- Deploy Site
|
|
|
|
**Before:**
|
|
```tsx
|
|
<Link to={`/sites/${siteId}/pages`} className="...">
|
|
{/* card content */}
|
|
</Link>
|
|
```
|
|
|
|
**After:**
|
|
```tsx
|
|
<button onClick={() => navigate(`/sites/${siteId}/pages`)} className="...">
|
|
{/* card content */}
|
|
</button>
|
|
```
|
|
|
|
#### List.tsx (`/frontend/src/pages/Sites/List.tsx`)
|
|
- **Removed import**: `Link` from react-router-dom
|
|
- **Changed**: Site card buttons from `Button as={Link} to={...}` to `Button onClick={() => navigate(...)}`
|
|
- **Buttons updated**:
|
|
- Dashboard (primary variant)
|
|
- Content (secondary variant)
|
|
- Pages (secondary variant)
|
|
- Settings (secondary variant)
|
|
|
|
**Before:**
|
|
```tsx
|
|
<Button
|
|
as={Link}
|
|
to={`/sites/${site.id}`}
|
|
variant="primary"
|
|
size="sm"
|
|
startIcon={<EyeIcon className="w-4 h-4" />}
|
|
>
|
|
Dashboard
|
|
</Button>
|
|
```
|
|
|
|
**After:**
|
|
```tsx
|
|
<Button
|
|
onClick={() => navigate(`/sites/${site.id}`)}
|
|
variant="primary"
|
|
size="sm"
|
|
startIcon={<EyeIcon className="w-4 h-4" />}
|
|
>
|
|
Dashboard
|
|
</Button>
|
|
```
|
|
|
|
#### Content.tsx (`/frontend/src/pages/Sites/Content.tsx`)
|
|
- **Removed import**: `Link` from react-router-dom
|
|
- **Changed**: 2 buttons from `Button as={Link}` to `Button onClick`
|
|
- **Buttons updated**:
|
|
- "New Post" button (top of page)
|
|
- "Create Your First Post" button (empty state)
|
|
|
|
#### Editor.tsx (`/frontend/src/pages/Sites/Editor.tsx`)
|
|
- **Removed import**: `Link` from react-router-dom (was imported but not yet used)
|
|
|
|
## Verification
|
|
|
|
### TypeScript Compilation
|
|
✅ No errors found in:
|
|
- `/frontend/src/components/ui/button/Button.tsx`
|
|
- `/frontend/src/pages/Sites/Dashboard.tsx`
|
|
- `/frontend/src/pages/Sites/List.tsx`
|
|
- `/frontend/src/pages/Sites/Content.tsx`
|
|
- `/frontend/src/pages/Sites/Editor.tsx`
|
|
|
|
### Code Search
|
|
✅ No remaining instances of:
|
|
- `<Button as={Link}` in Sites pages
|
|
- `Button.*as={Link}` anywhere in frontend
|
|
|
|
## Button Standard Summary
|
|
|
|
### Correct Usage (ONLY allowed format)
|
|
```tsx
|
|
import { Button } from '@/components/ui/button/Button';
|
|
import { useNavigate } from 'react-router-dom';
|
|
|
|
const navigate = useNavigate();
|
|
|
|
// Simple button
|
|
<Button onClick={() => navigate('/path')} variant="primary">
|
|
Click Me
|
|
</Button>
|
|
|
|
// Button with icon
|
|
<Button
|
|
onClick={() => navigate('/path')}
|
|
variant="secondary"
|
|
startIcon={<IconComponent className="w-4 h-4" />}
|
|
>
|
|
Action
|
|
</Button>
|
|
|
|
// Multiple buttons (primary + secondary)
|
|
<div className="flex gap-2">
|
|
<Button onClick={handlePrimary} variant="primary">
|
|
Primary Action
|
|
</Button>
|
|
<Button onClick={handleSecondary} variant="secondary">
|
|
Secondary Action
|
|
</Button>
|
|
</div>
|
|
```
|
|
|
|
### Variants
|
|
- **primary**: Brand color background (#0693e3), white text
|
|
- **secondary**: Text-dim color (#64748b), transparent background, gray hover
|
|
- **outline**: Colored text with ring border
|
|
- **ghost**: Colored text with subtle hover
|
|
- **gradient**: Gradient background with shadow
|
|
|
|
### Tones
|
|
- **brand**: Primary blue (#0693e3)
|
|
- **success**: Teal-green (#0bbf87)
|
|
- **warning**: Vivid orange (#ff7a00)
|
|
- **danger**: Red (#ef4444)
|
|
- **neutral**: Gray
|
|
|
|
### Sizes
|
|
- **xs**: h-7 px-2.5 text-xs
|
|
- **sm**: h-9 px-3 text-sm (most common)
|
|
- **md**: h-10 px-4 text-sm
|
|
- **lg**: h-12 px-5 text-base
|
|
|
|
## Color Reference
|
|
|
|
### Text-Dim Color
|
|
```css
|
|
/* tokens.css */
|
|
--color-text-dim: #64748b; /* Light mode */
|
|
|
|
.dark {
|
|
--color-text-dim: #9ca3af; /* Dark mode */
|
|
}
|
|
```
|
|
|
|
This is Tailwind's `slate-500` equivalent, used for:
|
|
- Secondary button text
|
|
- Subdued/helper text
|
|
- Less prominent UI elements
|
|
|
|
## What Was Wrong Before
|
|
|
|
1. **Secondary color mismatch**: Used tone-specific colors (brand-600, success-600, etc.) instead of universal text-dim
|
|
2. **Link component usage**: Button component had `as={Link}` prop support (accessibility anti-pattern for navigation buttons)
|
|
3. **Mixed patterns**: Some pages used `<Link>`, others used `Button as={Link}`, creating inconsistency
|
|
4. **Wrong variants**: Some buttons still used old "solid"/"soft" names
|
|
|
|
## Result
|
|
|
|
✅ **Consistent design**: All secondary buttons now have same text-dim color across all tones
|
|
✅ **Single pattern**: ALL buttons use `onClick` with `useNavigate()` - no Link components
|
|
✅ **Proper semantics**: Navigation uses button elements with click handlers (matches HTML standard)
|
|
✅ **Type safe**: Removed unnecessary props from Button component
|
|
✅ **Maintainable**: Single source of truth for button styles in Button.tsx
|
|
|
|
---
|
|
|
|
**Date**: 2024
|
|
**Status**: ✅ Complete - All Sites pages standardized
|