Skip to main content

php-laravel-blade-accessibility

Builds accessible server-rendered PHP/Laravel applications using Blade templates with accessible form patterns, Livewire integration, aria attributes, error announcements with alerts, and tools lens-for-laravel and laravel-blade-ally.

معلومات المصدر

المستودع
paulpas/agent-skill-router
آخر نشاط في المصدر
٢٣ سبتمبر ٢٠٢٦ في ١٧:١٧
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٧
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
php-laravel-blade-accessibility
description
Builds accessible server-rendered PHP/Laravel applications using Blade templates with accessible form patterns, Livewire integration, aria attributes, error announcements with alerts, and tools lens-for-laravel and laravel-blade-ally.
license
MIT
compatibility
opencode
metadata
{"version":"1.0.0","domain":"coding","role":"implementation","scope":"implementation","output-format":"code","content-types":["code","patterns","examples"],"triggers":"PHP, Laravel, Blade, Livewire, accessible forms, aria attributes, lens-for-laravel, laravel-blade-ally","related-skills":"semantic-html-aria-accessibility-tree, automated-a11y-testing-axe-core","archetypes":["tactical","implementation"],"anti_triggers":["React framework","Vue framework","client-side rendering only","backend database"],"response_profile":{"verbosity":"low","directive_strength":"high","abstraction_level":"operational"}}
# Laravel Blade Accessibility: Forms & Livewire Builds accessible server-rendered PHP/Laravel applications using Blade templates with proper form patterns, ARIA attributes (aria-invalid, aria-describedby), form validation with error announcements (role="alert"), and Livewire reactive patterns. Integrates lens-for-laravel and laravel-blade-ally tools for accessibility audits. Load when building Laravel forms, implementing Livewire components with ARIA, or ensuring server-rendered HTML accessibility. ## TL;DR Checklist - [ ] Use Blade form components with proper label associations - [ ] Add `aria-invalid` and `aria-describedby` to form inputs - [ ] Display validation errors with `role="alert"` for screen reader announcements - [ ] Use Livewire `wire:loading` with `aria-live="polite"` for loading states - [ ] Associate labels: `<label for="field-id">` - [ ] Group related fields with `<fieldset>` and `<legend>` - [ ] Use `lens-for-laravel` for accessibility analysis - [ ] Run `php artisan ally:analyze` (laravel-blade-ally) in CI/CD - [ ] Test forms with jest-axe for blade templates --- ## When to Use Use this skill when: - Building accessible forms in Laravel Blade - Implementing Livewire reactive components with form validation - Ensuring server-rendered HTML meets WCAG 2.1 AA - Adding ARIA attributes to form fields - Setting up accessibility testing for Laravel projects - Building validation feedback with screen reader support --- ## When NOT to Use Avoid this skill for: - React/Vue client-side rendering (use framework-specific skills) - Database design or backend logic (use data skills) - Laravel routing or controller logic beyond accessibility - CSS/styling concerns (use CSS skills) - Blade templating syntax (use Laravel docs) --- ## Core Workflow 1. **Create Form Component** — Build reusable Blade form components with labels 2. **Add ARIA Attributes** — Use aria-invalid, aria-describedby on inputs 3. **Implement Validation** — Show errors with role="alert" for announcements 4. **Integrate Livewire** — Add wire:loading, wire:target, aria-live 5. **Add Descriptions** — Link help text with aria-describedby 6. **Test with Tools** — Use lens-for-laravel and laravel-blade-ally 7. **Verify with axe** — Run automated testing on Blade output 8. **Screen Reader Test** — Manual test with VoiceOver/NVDA --- ## Implementation Patterns ### Pattern 1: Accessible Form Field Component ```blade {{-- resources/views/components/form/field.blade.php --}} @props([ 'name' => '', 'label' => '', 'type' => 'text', 'required' => false, 'error' => null, 'description' => null, 'value' => '', 'placeholder' => '', ]) @php $errorId = $name . '-error'; $descriptionId = $name . '-description'; $hasError = $error !== null; $describedBy = []; if ($description) { $describedBy[] = $descriptionId; } if ($hasError) { $describedBy[] = $errorId; } $ariaDescribedBy = count($describedBy) > 0 ? implode(' ', $describedBy) : null; @endphp <div class="form-field {{ $hasError ? 'form-field--error' : '' }}"> {{-- Label --}} <label for="{{ $name }}" class="form-field__label"> {{ $label }} @if ($required) <span aria-label="required" class="required-mark"> *</span> @endif </label> {{-- Input --}} <input id="{{ $name }}" name="{{ $name }}" type="{{ $type }}" value="{{ old($name, $value) }}" placeholder="{{ $placeholder }}" @required($required) aria-required="{{ $required ? 'true' : 'false' }}" aria-invalid="{{ $hasError ? 'true' : 'false' }}" @if ($ariaDescribedBy) aria-describedby="{{ $ariaDescribedBy }}" @endif class="form-field__input {{ $hasError ? 'form-field__input--error' : '' }}" /> {{-- Description --}} @if ($description) <p id="{{ $descriptionId }}" class="form-field__description"> {{ $description }} </p> @endif {{-- Error Message --}} @if ($hasError) <p id="{{ $errorId }}" class="form-field__error" role="alert"> {{ $error }} </p> @endif </div> ``` **Usage:** ```blade <form method="POST" action="/contact"> @csrf <x-form.field name="email" label="Email Address" type="email" required :error="$errors->first('email')" description="We'll never share your email with anyone else." /> <x-form.field name="message" label="Message" type="textarea" required :error="$errors->first('message')" /> <button type="submit">Send</button> </form> ``` ### Pattern 2: Form with Validation ```blade {{-- resources/views/contact.blade.php --}} <form method="POST" action="/contact" novalidate> @csrf {{-- Email Field --}} <div class="form-group"> <label for="email" class="form-label"> Email Address <span aria-label="required">*</span> </label> <input id="email" name="email" type="email" value="{{ old('email') }}" required aria-required="true" aria-invalid="{{ $errors->has('email') ? 'true' : 'false' }}" aria-describedby="{{ $errors->has('email') ? 'email-error' : null }}" class="form-input {{ $errors->has('email') ? 'form-input--error' : '' }}" /> @if ($errors->has('email')) <p id="email-error" class="form-error" role="alert"> {{ $errors->first('email') }} </p> @endif </div> {{-- Message Field --}} <div class="form-group"> <label for="message" class="form-label"> Message <span aria-label="required">*</span> </label> <textarea id="message" name="message" required aria-required="true" aria-invalid="{{ $errors->has('message') ? 'true' : 'false' }}" aria-describedby="{{ $errors->has('message') ? 'message-error message-hint' : 'message-hint' }}" class="form-textarea {{ $errors->has('message') ? 'form-textarea--error' : '' }}" >{{ old('message') }}</textarea> <p id="message-hint" class="form-hint"> Maximum 1000 characters </p> @if ($errors->has('message')) <p id="message-error" class="form-error" role="alert"> {{ $errors->first('message') }} </p> @endif </div> {{-- Checkbox Field --}} <div class="form-group"> <input id="terms" name="terms" type="checkbox" required aria-required="true" aria-invalid="{{ $errors->has('terms') ? 'true' : 'false' }}" aria-describedby="{{ $errors->has('terms') ? 'terms-error' : null }}" /> <label for="terms" class="form-label"> I agree to the <a href="/terms" target="_blank">terms of service</a> </label> @if ($errors->has('terms')) <p id="terms-error" class="form-error" role="alert"> {{ $errors->first('terms') }} </p> @endif </div> <button type="submit" class="btn btn-primary"> Submit </button> </form> ``` ### Pattern 3: Livewire Form Component with ARIA ```php // app/Livewire/ContactForm.php namespace App\Livewire; use Livewire\Component; class ContactForm extends Component { public string $email = ''; public string $message = ''; protected array $rules = [ 'email' => 'required|email', 'message' => 'required|min:10|max:1000', ]; protected array $messages = [ 'email.required' => 'Please enter your email address.', 'email.email' => 'Please enter a valid email address.', 'message.required' => 'Please enter a message.', 'message.min' => 'Message must be at least 10 characters.', 'message.max' => 'Message must not exceed 1000 characters.', ]; public function submit() { $this->validate(); // Send email or save to database session()->flash('success', 'Your message has been sent!'); $this->reset(); } public function render() { return view('livewire.contact-form'); } } ``` ```blade {{-- resources/views/livewire/contact-form.blade.php --}} <form wire:submit="submit" novalidate> {{-- Status Message --}} @if (session('success')) <div class="alert alert-success" role="alert" aria-live="assertive"> {{ session('success') }} </div> @endif {{-- Email Field --}} <div class="form-group"> <label for="email" class="form-label"> Email Address <span aria-label="required">*</span> </label> <input id="email" wire:model="email" type="email" required aria-required="true" aria-invalid="{{ $errors->has('email') ? 'true' : 'false' }}" aria-describedby="{{ $errors->has('email') ? 'email-error' : null }}" class="form-input {{ $errors->has('email') ? 'form-input--error' : '' }}" /> @error('email') <p id="email-error" class="form-error" role="alert"> {{ $message }} </p> @enderror </div> {{-- Message Field --}} <div class="form-group"> <label for="message" class="form-label"> Message <span aria-label="required">*</span> </label> <textarea id="message" wire:model="message" required aria-required="true"
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub