reviewed epic 9 stories
This commit is contained in:
@@ -8,45 +8,82 @@ As a **user**,
|
||||
I want **consistent, accessible form styling**,
|
||||
So that **data entry is intuitive and error states are clear**.
|
||||
|
||||
## Dependencies
|
||||
- **Story 9.1 (Color System)** - Must be completed first; provides Tailwind color aliases used below
|
||||
- **Story 9.2 (Typography System)** - Font weights for labels
|
||||
|
||||
## Color Reference (from Story 9.1)
|
||||
For quick reference, this story uses these colors defined in the Tailwind theme:
|
||||
- `gold` (#D4AF37) - Focus states, checkbox accents
|
||||
- `charcoal` (#2C3E50) - Default borders, label text
|
||||
- `danger` (#E74C3C) - Error states
|
||||
- `cream` (#F9F7F4) - Input backgrounds (if needed)
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Input Fields
|
||||
- [ ] Border: Charcoal Gray
|
||||
- [ ] Focus: Gold border
|
||||
- [ ] Border-radius: 6px
|
||||
- [ ] Padding: 12px 16px
|
||||
- [ ] Border: Charcoal Gray (`border-charcoal/30`)
|
||||
- [ ] Focus: Gold border with subtle ring (`focus:border-gold focus:ring-gold/20`)
|
||||
- [ ] Border-radius: 6px (`rounded-md`)
|
||||
- [ ] Padding: 12px 16px (`px-4 py-3`)
|
||||
|
||||
### Textareas
|
||||
- [ ] Same styling as inputs
|
||||
- [ ] Minimum height: 120px
|
||||
- [ ] Minimum height: 120px (`min-h-[120px]`)
|
||||
|
||||
### Select Dropdowns
|
||||
- [ ] Custom styled (not native)
|
||||
- [ ] Consistent with inputs
|
||||
- [ ] Custom styled using Flux UI (not native browser)
|
||||
- [ ] Consistent border/focus styling with inputs
|
||||
|
||||
### Checkboxes & Radios
|
||||
- [ ] Custom styled with gold accent
|
||||
- [ ] Clear checked state
|
||||
- [ ] Custom styled with gold accent when checked
|
||||
- [ ] Clear visual distinction between checked/unchecked states
|
||||
|
||||
### Labels
|
||||
- [ ] SemiBold weight
|
||||
- [ ] Required indicator (*)
|
||||
- [ ] SemiBold weight (`font-semibold`)
|
||||
- [ ] Required indicator (*) in danger color
|
||||
|
||||
### Error States
|
||||
- [ ] Red border
|
||||
- [ ] Error message below field
|
||||
- [ ] Red border (`border-danger`)
|
||||
- [ ] Error message displayed below field
|
||||
- [ ] Error ring on focus (`focus:ring-danger/20`)
|
||||
|
||||
### RTL Support
|
||||
- [ ] All fields align correctly in RTL
|
||||
- [ ] Labels align to the right in RTL mode
|
||||
- [ ] Input text direction follows locale
|
||||
- [ ] Error messages align correctly
|
||||
- [ ] Padding swaps appropriately (use `ps-4 pe-4` instead of `px-4` if needed)
|
||||
|
||||
## Technical Notes
|
||||
## Files to Create/Modify
|
||||
|
||||
### Primary Files
|
||||
- `resources/css/app.css` - Add form component utility classes
|
||||
|
||||
### Flux UI Integration
|
||||
Flux UI Free includes these form components that need styling customization:
|
||||
- `flux:input` - Text inputs
|
||||
- `flux:textarea` - Multiline text
|
||||
- `flux:select` - Dropdown selects
|
||||
- `flux:checkbox` - Checkboxes
|
||||
- `flux:radio` - Radio buttons
|
||||
- `flux:field` - Field wrapper with label/error support
|
||||
|
||||
### Existing Forms to Audit
|
||||
Review and update existing forms in:
|
||||
- `resources/views/livewire/` - Any Volt components with forms
|
||||
- Authentication views (login, register, password reset)
|
||||
- Contact/booking forms
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### CSS Classes (add to `resources/css/app.css`)
|
||||
|
||||
```css
|
||||
/* Form field styling */
|
||||
.input-field {
|
||||
@apply w-full border border-charcoal/30 rounded-md px-4 py-3
|
||||
focus:border-gold focus:ring-2 focus:ring-gold/20
|
||||
transition-colors outline-none;
|
||||
transition-colors outline-none bg-white;
|
||||
}
|
||||
|
||||
.input-error {
|
||||
@@ -66,21 +103,158 @@ So that **data entry is intuitive and error states are clear**.
|
||||
@apply text-sm text-danger mt-1;
|
||||
}
|
||||
|
||||
/* Textarea specific */
|
||||
.textarea-field {
|
||||
@apply input-field min-h-[120px] resize-y;
|
||||
}
|
||||
|
||||
/* Custom checkbox */
|
||||
.checkbox-custom {
|
||||
@apply w-5 h-5 rounded border-charcoal/30 text-gold
|
||||
focus:ring-gold focus:ring-offset-0;
|
||||
}
|
||||
|
||||
/* Custom radio */
|
||||
.radio-custom {
|
||||
@apply w-5 h-5 border-charcoal/30 text-gold
|
||||
focus:ring-gold focus:ring-offset-0;
|
||||
}
|
||||
```
|
||||
|
||||
### Flux UI Component Usage Examples
|
||||
|
||||
```blade
|
||||
{{-- Basic input with label --}}
|
||||
<flux:field>
|
||||
<flux:label class="form-label">Email</flux:label>
|
||||
<flux:input type="email" wire:model="email" class="input-field" />
|
||||
</flux:field>
|
||||
|
||||
{{-- Required field with error --}}
|
||||
<flux:field>
|
||||
<flux:label class="form-label form-label-required">Name</flux:label>
|
||||
<flux:input
|
||||
wire:model="name"
|
||||
class="input-field @error('name') input-error @enderror"
|
||||
/>
|
||||
@error('name')
|
||||
<span class="error-message">{{ $message }}</span>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
{{-- Textarea --}}
|
||||
<flux:field>
|
||||
<flux:label class="form-label">Message</flux:label>
|
||||
<flux:textarea wire:model="message" class="textarea-field" />
|
||||
</flux:field>
|
||||
|
||||
{{-- Select dropdown --}}
|
||||
<flux:field>
|
||||
<flux:label class="form-label">Category</flux:label>
|
||||
<flux:select wire:model="category" class="input-field">
|
||||
<flux:select.option value="">Select...</flux:select.option>
|
||||
<flux:select.option value="legal">Legal</flux:select.option>
|
||||
<flux:select.option value="general">General</flux:select.option>
|
||||
</flux:select>
|
||||
</flux:field>
|
||||
|
||||
{{-- Checkbox with gold accent --}}
|
||||
<flux:field>
|
||||
<flux:checkbox wire:model="agree" class="checkbox-custom" />
|
||||
<flux:label class="form-label inline ms-2">I agree to the terms</flux:label>
|
||||
</flux:field>
|
||||
|
||||
{{-- Radio group --}}
|
||||
<flux:field>
|
||||
<flux:label class="form-label form-label-required">Preferred Contact</flux:label>
|
||||
<div class="flex gap-4 mt-2">
|
||||
<label class="flex items-center gap-2">
|
||||
<flux:radio wire:model="contact" value="email" class="radio-custom" />
|
||||
<span>Email</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2">
|
||||
<flux:radio wire:model="contact" value="phone" class="radio-custom" />
|
||||
<span>Phone</span>
|
||||
</label>
|
||||
</div>
|
||||
</flux:field>
|
||||
```
|
||||
|
||||
### RTL Considerations
|
||||
- Use logical properties where possible (`ps-`, `pe-`, `ms-`, `me-` instead of `pl-`, `pr-`, `ml-`, `mr-`)
|
||||
- Flux components should handle RTL automatically with `dir="rtl"` on the HTML element
|
||||
- Test label positioning in Arabic locale
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
### Manual Testing Checklist
|
||||
1. **Visual Inspection (both locales)**
|
||||
- [ ] Switch to Arabic - verify RTL alignment
|
||||
- [ ] Switch to English - verify LTR alignment
|
||||
- [ ] All form elements match design specs
|
||||
|
||||
2. **Interactive States**
|
||||
- [ ] Click into each field type - verify gold focus ring appears
|
||||
- [ ] Tab through form - verify focus order is logical
|
||||
- [ ] Submit with errors - verify error styling appears
|
||||
|
||||
3. **Accessibility**
|
||||
- [ ] Labels are associated with inputs (clicking label focuses input)
|
||||
- [ ] Error messages are announced to screen readers
|
||||
- [ ] Focus indicators are clearly visible
|
||||
|
||||
### Automated Tests
|
||||
Create feature test for form styling verification:
|
||||
|
||||
```php
|
||||
// tests/Feature/FormStylingTest.php
|
||||
test('form fields render with correct classes', function () {
|
||||
// Test that forms include the expected CSS classes
|
||||
$this->get('/contact')
|
||||
->assertSee('input-field')
|
||||
->assertSee('form-label');
|
||||
});
|
||||
|
||||
test('form error states display correctly', function () {
|
||||
// Submit form with invalid data and check error styling
|
||||
Livewire::test('contact-form')
|
||||
->set('email', 'invalid')
|
||||
->call('submit')
|
||||
->assertSee('input-error')
|
||||
->assertSee('error-message');
|
||||
});
|
||||
```
|
||||
|
||||
### Browser Testing (RTL Verification)
|
||||
```php
|
||||
// tests/Browser/FormRtlTest.php
|
||||
it('displays form labels on the right in RTL mode', function () {
|
||||
visit('/ar/contact')
|
||||
->assertPresent('[dir="rtl"]')
|
||||
->assertVisible('.form-label');
|
||||
// Visual inspection for alignment
|
||||
});
|
||||
```
|
||||
|
||||
## Definition of Done
|
||||
- [ ] Input styling consistent
|
||||
- [ ] Textarea styling consistent
|
||||
- [ ] Select styling works
|
||||
- [ ] Checkbox/radio styled
|
||||
- [ ] Error states clear
|
||||
- [ ] RTL alignment correct
|
||||
- [ ] Tests pass
|
||||
- [ ] CSS classes added to `resources/css/app.css`
|
||||
- [ ] Input styling matches specs (border, focus, padding, radius)
|
||||
- [ ] Textarea styling consistent with inputs, min-height 120px
|
||||
- [ ] Select dropdowns styled consistently (not native)
|
||||
- [ ] Checkboxes show gold accent when checked
|
||||
- [ ] Radio buttons show gold accent when selected
|
||||
- [ ] Labels are semibold with required indicator working
|
||||
- [ ] Error states show red border and message below
|
||||
- [ ] RTL alignment verified in Arabic locale
|
||||
- [ ] LTR alignment verified in English locale
|
||||
- [ ] Existing forms updated to use new classes
|
||||
- [ ] Feature tests pass
|
||||
- [ ] Code formatted with Pint
|
||||
|
||||
## Estimation
|
||||
**Complexity:** Medium | **Effort:** 3-4 hours
|
||||
|
||||
## Dev Notes
|
||||
- Check Flux UI docs for any built-in theming options before adding custom CSS
|
||||
- If Flux components don't accept className props well, may need to use CSS selectors targeting Flux's rendered HTML
|
||||
- Run `npm run build` after CSS changes to see updates
|
||||
|
||||
Reference in New Issue
Block a user