Add standardized HTMX conventions, interaction patterns, and migration guide for ThrillWiki UX

This commit is contained in:
pacnpal
2025-12-22 16:56:27 -05:00
parent 2e35f8c5d9
commit ae31e889d7
144 changed files with 25792 additions and 4440 deletions

View File

@@ -1,5 +1,94 @@
<div id="modal-container" class="modal" role="dialog" aria-modal="true" tabindex="-1">
<div class="modal-content">
{% block modal_content %}{% endblock %}
</div>
</div>
{% comment %}
Modal Base Component
====================
A flexible, accessible modal dialog component with Alpine.js integration.
Purpose:
Provides a base modal structure with backdrop, header, body, and footer
sections. Includes keyboard navigation (ESC to close), focus trapping,
and proper ARIA attributes for accessibility.
Usage Examples:
Basic modal:
{% include 'components/modals/modal_base.html' with modal_id='my-modal' title='Modal Title' %}
{% block modal_body %}
<p>Modal content here</p>
{% endblock %}
{% endinclude %}
Modal with footer:
<div x-data="{ showModal: false }">
<button @click="showModal = true">Open Modal</button>
{% include 'components/modals/modal_base.html' with modal_id='confirm-modal' title='Confirm Action' show_var='showModal' %}
{% block modal_body %}
<p>Are you sure?</p>
{% endblock %}
{% block modal_footer %}
<button @click="showModal = false" class="btn-secondary">Cancel</button>
<button @click="confirmAction(); showModal = false" class="btn-primary">Confirm</button>
{% endblock %}
{% endinclude %}
</div>
Different sizes:
{% include 'components/modals/modal_base.html' with modal_id='lg-modal' title='Large Modal' size='lg' %}
Parameters:
Required:
- modal_id: Unique identifier for the modal (used for ARIA and targeting)
Optional:
- title: Modal title text (if empty, header section is hidden)
- size: Size variant 'sm', 'md', 'lg', 'xl', 'full' (default: 'md')
- show_close_button: Show X button in header (default: True)
- show_var: Alpine.js variable name for show/hide state (default: 'show')
- close_on_backdrop: Close when clicking backdrop (default: True)
- close_on_escape: Close when pressing Escape (default: True)
- prevent_scroll: Prevent body scroll when open (default: True)
Blocks:
- modal_header: Custom header content (replaces default header)
- modal_body: Main modal content (required)
- modal_footer: Footer content (optional)
Dependencies:
- Alpine.js for interactivity
- Tailwind CSS for styling
- Font Awesome icons (for close button)
Accessibility:
- Uses dialog role with aria-modal="true"
- Focus is trapped within modal when open
- ESC key closes the modal
- aria-labelledby points to title
- aria-describedby available for body content
{% endcomment %}
{# Default values #}
{% with size=size|default:'md' show_close_button=show_close_button|default:True show_var=show_var|default:'show' close_on_backdrop=close_on_backdrop|default:True close_on_escape=close_on_escape|default:True prevent_scroll=prevent_scroll|default:True %}
{# Size classes mapping #}
{% if size == 'sm' %}
{% with size_class='max-w-sm' %}
{% include 'components/modals/modal_inner.html' %}
{% endwith %}
{% elif size == 'lg' %}
{% with size_class='max-w-2xl' %}
{% include 'components/modals/modal_inner.html' %}
{% endwith %}
{% elif size == 'xl' %}
{% with size_class='max-w-4xl' %}
{% include 'components/modals/modal_inner.html' %}
{% endwith %}
{% elif size == 'full' %}
{% with size_class='max-w-full mx-4' %}
{% include 'components/modals/modal_inner.html' %}
{% endwith %}
{% else %}
{% with size_class='max-w-lg' %}
{% include 'components/modals/modal_inner.html' %}
{% endwith %}
{% endif %}
{% endwith %}