libra/docs/stories/story-9.8-rtl-ltr-layout-pe...

7.8 KiB

Story 9.8: RTL/LTR Layout Perfection

Epic Reference

Epic 9: Design & Branding Implementation

Story Dependencies

  • Story 9.1 (Color System) - Must be complete; RTL audit needs final color variables
  • Story 9.4 (Button Styling) - Buttons must use logical properties
  • Story 9.5 (Form Styling) - Forms require RTL label/error positioning
  • Story 9.6 (Cards & Containers) - Cards need directional border handling
  • Story 9.7 (Navigation & Footer) - Navigation mirroring depends on this work

User Story

As a user, I want perfect RTL layout for Arabic and LTR for English, So that the content is natural to read in my language.

Background Context

Current State (from codebase analysis)

The application already has partial RTL support:

  • app()->getLocale() sets lang attribute on <html>
  • Some logical properties already in use: border-e, me-5, rtl:space-x-reverse
  • Missing: dir attribute is NOT set on <html> element
  • Missing: Systematic RTL audit of all components

PRD Requirements (Section 4.2)

  • Primary Language: Arabic (default) with RTL layout
  • Secondary Language: English with LTR layout
  • Full site language toggle
  • All UI elements in both languages

Acceptance Criteria

RTL (Arabic)

  • dir="rtl" dynamically set on <html> when locale is ar
  • Text aligns right naturally
  • Navigation mirrors (sidebar on right for RTL)
  • Form labels on right side of inputs
  • Icons/arrows flip appropriately (chevrons, arrows)
  • Margins/paddings swap using logical properties

LTR (English)

  • dir="ltr" set on <html> when locale is en
  • Standard left-to-right layout
  • Proper text alignment

Transitions

  • Seamless language toggle without page reload issues
  • No layout breaks on switch
  • No flash of wrong direction on page load

Component Support

  • Calendar component RTL support (date picker)
  • Tables RTL support (horizontal scroll direction)
  • Dropdowns open in correct direction
  • Modals position correctly
  • All Flux UI components tested in both modes

Technical Implementation

Key Files to Modify

1. Layout Files (Add dir attribute)

resources/views/components/layouts/app/sidebar.blade.php
resources/views/components/layouts/auth/simple.blade.php
resources/views/components/layouts/auth/card.blade.php
resources/views/components/layouts/auth/split.blade.php

Change: Update <html> tag in each layout:

<html
    lang="{{ str_replace('_', '-', app()->getLocale()) }}"
    dir="{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}"
    class="dark"
>

2. CSS Configuration

resources/css/app.css

Add RTL utilities in @theme or @layer:

/* RTL-aware icon flipping */
[dir="rtl"] .flip-rtl {
    transform: scaleX(-1);
}

/* Force LTR for numbers/code */
.ltr-content {
    direction: ltr;
    unicode-bidi: embed;
}

3. Navigation Component

resources/views/components/layouts/app/sidebar.blade.php

Audit and update:

  • Sidebar position (currently uses border-e - good)
  • Logo placement
  • Menu item icons
  • Dropdown positions

4. Form Components (Flux UI overrides if needed)

resources/views/livewire/auth/*.blade.php
resources/views/livewire/settings/*.blade.php

Ensure all forms use:

  • text-start instead of text-left
  • ms-* / me-* instead of ml-* / mr-*
  • ps-* / pe-* instead of pl-* / pr-*
  • start-* / end-* instead of left-* / right-*

Tailwind CSS 4 RTL Approach

Tailwind CSS 4 supports logical properties natively. Do NOT install a separate RTL plugin.

Logical Property Mapping:

Physical Logical (Use This)
left-* start-*
right-* end-*
ml-* ms-*
mr-* me-*
pl-* ps-*
pr-* pe-*
text-left text-start
text-right text-end
border-l-* border-s-*
border-r-* border-e-*
rounded-l-* rounded-s-*
rounded-r-* rounded-e-*

For directional icons that must flip:

<flux:icon
    name="chevron-right"
    class="{{ app()->getLocale() === 'ar' ? 'flip-rtl' : '' }}"
/>

Better: Use bidirectional-aware icons when available:

  • Use chevron-end concept or flip via CSS

Edge Cases to Handle

Numbers in RTL

Numbers should remain LTR even in Arabic context:

<span class="ltr-content">{{ $consultation->id }}</span>

Mixed Content (Arabic with English)

Wrap English phrases in LTR spans when embedded in Arabic:

<p>{{ __('Contact us at') }} <span class="ltr-content">info@libra.ps</span></p>

Form Validation Errors

Ensure error messages appear on the correct side:

<!-- Flux handles this, but verify -->
<flux:field>
    <flux:label>{{ __('Email') }}</flux:label>
    <flux:input type="email" wire:model="email" />
    <flux:error name="email" /> <!-- Should align with field direction -->
</flux:field>

Toast Notifications

Verify toast position respects direction:

  • LTR: Appear from right
  • RTL: Appear from left (or respect start/end)

Tables with Horizontal Scroll

<div class="overflow-x-auto" dir="ltr"> <!-- Force LTR scroll -->
    <table>
        <!-- Table content inherits document direction for text -->
    </table>
</div>

Testing Checklist

Manual Visual Testing (Required)

Test each in both Arabic and English:

  • Navigation layout

    • Sidebar appears on correct side
    • Logo position correct
    • Menu items align properly
    • Dropdown menus open correct direction
  • Form layouts

    • Labels align correctly
    • Input text direction correct
    • Error messages position correctly
    • Submit buttons align properly
  • Card layouts

    • Content aligns correctly
    • Border highlights on correct side
    • Action buttons position correctly
  • Table layouts

    • Headers align correctly
    • Cell content respects direction
    • Horizontal scroll works
  • Modal layouts

    • Close button position correct
    • Content alignment correct
    • Action buttons order correct (Cancel/Confirm)
  • Dropdown menus

    • Open in correct direction
    • Items align correctly
  • Pagination

    • Previous/Next arrows correct
    • Page numbers display correctly

Create Pest browser tests for critical RTL scenarios:

// tests/Browser/RtlLayoutTest.php
it('displays RTL layout for Arabic locale', function () {
    // Set locale to Arabic
    // Visit dashboard
    // Assert dir="rtl" on html element
    // Assert sidebar is on right side
});

Browser Testing

Test in:

  • Chrome (Windows/Mac)
  • Firefox
  • Safari
  • Mobile Safari (iOS)
  • Chrome Mobile (Android)

Definition of Done

  • dir attribute dynamically set based on locale
  • RTL renders correctly in Arabic
  • LTR renders correctly in English
  • Language switch is seamless (no layout flash)
  • Icons flip correctly where appropriate
  • All components from Testing Checklist verified
  • No layout breaks on language switch
  • Numbers and emails display correctly (LTR in RTL context)
  • Code formatted with Pint
  • Tests pass

Dev Notes

Flux UI RTL Support

Flux UI components generally support RTL well when dir="rtl" is set on <html>. However, audit each component for:

  • Icon positions
  • Dropdown directions
  • Border placements

Avoid These Patterns

<!-- BAD: Physical properties -->
<div class="ml-4 text-left border-l-2">

<!-- GOOD: Logical properties -->
<div class="ms-4 text-start border-s-2">

Resources

  • Tailwind CSS Logical Properties: Check search-docs for latest Tailwind 4 docs
  • Flux UI RTL: Test each component, file issues if needed

Estimation

Complexity: High | Effort: 5-6 hours