libra/docs/stories/story-9.4-component-styling...

6.8 KiB

Story 9.4: Component Styling - Buttons

Epic Reference

Epic 9: Design & Branding Implementation

Dependencies

  • Story 9.1: Color System Implementation - Must be complete (this story uses the color variables defined there)

User Story

As a user, I want consistent, professional button styling, So that interactive elements are clear and visually appealing.

Context

This story implements the button styling system that will be used throughout the application. Buttons appear in:

  • Forms (submit, cancel actions)
  • Modals (confirm, dismiss)
  • Navigation (CTAs)
  • Admin dashboards (CRUD operations)
  • Client booking flow

The implementation extends Flux UI's button component with brand colors rather than replacing it, ensuring we maintain Flux's built-in accessibility and functionality.

Acceptance Criteria

Primary Button

  • Background: Gold (bg-gold / #D4AF37)
  • Text: Dark Navy Blue (text-navy)
  • Hover: Light Gold (hover:bg-gold-light / #F4E4B8)
  • Border-radius: 6px (rounded-md)
  • Padding: 12px 24px (px-6 py-3)

Secondary Button

  • Background: Transparent
  • Border: 2px solid Gold (border-2 border-gold)
  • Text: Gold (text-gold)
  • Hover: Gold background, Navy text (hover:bg-gold hover:text-navy)

Disabled State

  • Background: #CCCCCC
  • Text: #666666
  • No hover effect
  • Cursor: not-allowed

Danger Button

  • Background: #E74C3C (bg-danger)
  • Text: White
  • Hover: Slightly darker (hover:bg-danger/90)

Button Sizes

  • Small: px-4 py-2 text-sm (for compact UI areas)
  • Default: px-6 py-3 text-base (standard usage)
  • Large: px-8 py-4 text-lg (hero CTAs)

Features

  • Loading states with Flux spinner component
  • Focus states: Gold outline ring for accessibility (focus:ring-2 focus:ring-gold focus:ring-offset-2)
  • Icon support: Buttons with leading/trailing icons
  • Full-width variant for mobile forms
  • Button groups with proper border-radius handling

Files to Create/Modify

File Action Purpose
resources/css/app.css Modify Add button variant styles in @theme or as Tailwind components

Technical Notes

Flux UI Integration Approach

Flux UI buttons accept a variant prop. We extend Flux by:

  1. Using Flux's <flux:button> component as-is for structure
  2. Applying brand colors via the variant prop or custom CSS classes
  3. NOT creating wrapper components unless absolutely necessary

Reference: Use search-docs tool with query "button" and package "livewire/flux" for current Flux button API.

CSS Implementation

/* resources/css/app.css - Add after @import "tailwindcss" and @theme block */

/* Primary button - Gold background */
.btn-primary {
  @apply bg-gold text-navy hover:bg-gold-light rounded-md px-6 py-3 font-semibold transition-colors;
  @apply focus:outline-none focus:ring-2 focus:ring-gold focus:ring-offset-2;
}

/* Secondary button - Outlined */
.btn-secondary {
  @apply bg-transparent border-2 border-gold text-gold rounded-md px-6 py-3 font-semibold transition-colors;
  @apply hover:bg-gold hover:text-navy;
  @apply focus:outline-none focus:ring-2 focus:ring-gold focus:ring-offset-2;
}

/* Danger button */
.btn-danger {
  @apply bg-danger text-white hover:bg-danger/90 rounded-md px-6 py-3 font-semibold transition-colors;
  @apply focus:outline-none focus:ring-2 focus:ring-danger focus:ring-offset-2;
}

/* Disabled state - applies to all variants */
.btn-disabled,
button:disabled,
[disabled] {
  @apply bg-gray-300 text-gray-500 cursor-not-allowed;
  @apply hover:bg-gray-300; /* Override hover */
}

/* Size variants */
.btn-sm { @apply px-4 py-2 text-sm; }
.btn-lg { @apply px-8 py-4 text-lg; }

/* Full width for mobile */
.btn-full { @apply w-full; }

/* Loading state */
.btn-loading {
  @apply relative pointer-events-none opacity-75;
}

/* Icon spacing within buttons */
.btn-icon-left { @apply flex items-center gap-2; }
.btn-icon-right { @apply flex items-center gap-2 flex-row-reverse; }

Usage Examples

{{-- Primary button with Flux --}}
<flux:button variant="primary" class="btn-primary">
    {{ __('Submit') }}
</flux:button>

{{-- Secondary button --}}
<flux:button variant="ghost" class="btn-secondary">
    {{ __('Cancel') }}
</flux:button>

{{-- Danger button --}}
<flux:button variant="danger" class="btn-danger">
    {{ __('Delete') }}
</flux:button>

{{-- Button with icon --}}
<flux:button class="btn-primary btn-icon-left">
    <flux:icon name="plus" class="w-4 h-4" />
    {{ __('Add New') }}
</flux:button>

{{-- Loading state --}}
<flux:button class="btn-primary" wire:loading.class="btn-loading">
    <span wire:loading.remove>{{ __('Save') }}</span>
    <span wire:loading>{{ __('Saving...') }}</span>
</flux:button>

{{-- Full width on mobile --}}
<flux:button class="btn-primary btn-full sm:w-auto">
    {{ __('Book Consultation') }}
</flux:button>

Edge Cases to Handle

  • Icon-only buttons: Ensure adequate touch target (44px minimum)
  • Long button text: Text should not overflow; consider truncation or wrapping
  • RTL layout: Icons should flip position appropriately (use logical start/end if needed)
  • Button groups: First/last buttons need adjusted border-radius

Testing Requirements

Test Approach

  • Visual testing: Verify all button states render correctly
  • Accessibility testing: Validate focus states and contrast ratios
  • RTL testing: Confirm buttons display correctly in Arabic mode

Test Scenarios

// tests/Feature/Components/ButtonStylingTest.php

test('primary button has correct styling classes', function () {
    $this->get('/')
        ->assertSee('btn-primary');
});

test('disabled button prevents interaction', function () {
    // Verify disabled state renders with correct cursor and no hover
});

test('buttons are keyboard accessible', function () {
    // Verify focus states are visible
});

test('buttons render correctly in RTL mode', function () {
    // Set locale to Arabic and verify button layout
});

Accessibility Checklist

  • Focus indicator visible (gold ring)
  • Color contrast meets WCAG AA (4.5:1 for text)
  • Touch targets minimum 44x44px on mobile
  • Disabled state communicated to screen readers

Definition of Done

  • Primary button styled per acceptance criteria
  • Secondary button styled per acceptance criteria
  • Danger button styled per acceptance criteria
  • Disabled states work correctly
  • Loading states work with Flux spinner
  • Focus states visible and accessible
  • Size variants (sm, default, lg) implemented
  • Icon buttons work correctly
  • Full-width variant works on mobile
  • RTL layout tested
  • Tests pass
  • Code formatted with Pint

Estimation

Complexity: Medium | Effort: 3 hours