Files
igny8/BUTTON_STANDARDIZATION_COMPLETE.md
IGNY8 VPS (Salman) 4fe68cc271 ui frotneedn fixes
2025-11-26 06:47:23 +00:00

6.0 KiB

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):

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):

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)

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:

<Link to={`/sites/${siteId}/pages`} className="...">
  {/* card content */}
</Link>

After:

<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:

<Button
  as={Link}
  to={`/sites/${site.id}`}
  variant="primary"
  size="sm"
  startIcon={<EyeIcon className="w-4 h-4" />}
>
  Dashboard
</Button>

After:

<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

No remaining instances of:

  • <Button as={Link} in Sites pages
  • Button.*as={Link} anywhere in frontend

Button Standard Summary

Correct Usage (ONLY allowed format)

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

/* 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