# Accessible Component Patterns This document provides code examples for creating accessible components in ThrillWiki. Follow these patterns to ensure WCAG 2.1 AA compliance. ## Button ### Standard Button ```django {% include 'components/ui/button.html' with text='Save Changes' variant='primary' type='submit' %} ``` ### Icon Button (REQUIRED: aria_label) ```django {% include 'components/ui/button.html' with icon=close_svg size='icon' aria_label='Close dialog' variant='ghost' %} ``` **Important**: Icon-only buttons MUST include `aria_label` for screen reader accessibility. ### Disabled Button ```django {% include 'components/ui/button.html' with text='Submit' disabled=True %} ``` ### Button with HTMX ```django {% include 'components/ui/button.html' with text='Load More' hx_get='/api/items?page=2' hx_target='#item-list' hx_swap='beforeend' %} ``` ## Form Field ### Standard Field ```django {% include 'forms/partials/form_field.html' with field=form.email %} ``` The form_field.html component automatically handles: - Label association via `for` attribute - Error message display with proper ARIA - Required field indication - Help text with `aria-describedby` ### Field with Help Text ```django {% include 'forms/partials/form_field.html' with field=form.password help_text='Must be at least 8 characters' %} ``` ### Field with HTMX Validation ```django {% include 'forms/partials/form_field.html' with field=form.username hx_validate=True hx_validate_url='/api/validate-username/' %} ``` ### Complete Form Example ```django
``` ## Modal ### Basic Modal ```django {% extends 'components/modals/modal_base.html' %} {% block modal_body %}Are you sure you want to delete this item?
{% endblock %} ``` ### Modal with Actions ```django {% extends 'components/modals/modal_base.html' %} {% block modal_body %}This action cannot be undone.
{% endblock %} {% block modal_footer %} {% include 'components/ui/button.html' with text='Delete' variant='destructive' x_on_click='confirmDelete()' %} {% endblock %} ``` The modal_inner.html component automatically provides: - `role="dialog"` and `aria-modal="true"` - `aria-labelledby` pointing to title - `aria-describedby` pointing to body (and subtitle if present) - Focus trap with Tab/Shift+Tab cycling - Home/End key support for first/last focusable element - Escape key to close (configurable) - Auto-focus on first focusable element ## Navigation Menu ### Dropdown Menu ```django