{# filterable_table.html — pure Tailwind data table, ux-architect/components/data-table contract #} {% if table %} {%- set config_json = { "sortField": table.default_sort_field, "sortDir": table.default_sort_dir, "inlineEditable": table.inline_editable, "bulkActions": table.bulk_actions, "entityName": table.entity_name } | tojson -%}
{# ── Table header: title + actions ───────────────────────────────────────── #} {% block table_header %}

{{ table.title }}

{# Column visibility menu #} {% if table.columns | length > 3 %}
{# Column visibility dropdown #}
{% endif %} {# Create button #} {% if table.create_url %} New {{ table.entity_name | replace("_", " ") }} {% endif %}
{% endblock table_header %} {# ── Toolbar: search · filters · bulk actions ─────────────────────────────── #}
{# Search — left #} {% if table.search_enabled %} {% with endpoint=table.api_endpoint, target='#' + table.table_id + '-body' %} {% include 'fragments/search_input.html' with context %} {% endwith %} {% endif %} {# Filter chips — centre, flex-grow #} {%- set has_filters = table.columns | selectattr('filterable') | list | length > 0 -%} {% if has_filters %}
{% include 'fragments/filter_bar.html' with context %}
{% endif %} {# Bulk actions — right, visible when rows selected #} {% if table.bulk_actions %} {% with entity_name=table.entity_name, actions_endpoint=table.api_endpoint %} {% include 'fragments/bulk_actions.html' with context %} {% endwith %} {% endif %}
{# ── Table scroll + loading overlay container ─────────────────────────────── #}
{# Loading overlay — sits above the table, dimmed backdrop #} {# Horizontal scroll region #}
{# colgroup — one per visible column. Drives column-resize via pointer events. #} {% if table.bulk_actions %} {% endif %} {% for col in table.columns %} {% if not col.hidden %} {% endif %} {% endfor %} {# Actions column #} {# ── Sticky header ─────────────────────────────────────────────────── #} {# Select-all checkbox #} {% if table.bulk_actions %} {% endif %} {# Column headers #} {% for col in table.columns %} {% if not col.hidden %} {% endif %} {% endfor %} {# Actions column header #} {# ── Table body — loaded via HTMX ──────────────────────────────────── #} {% include 'fragments/table_rows.html' %}
{{ table.title }}
{% if col.sortable %} {# Sortable header button #} {% else %} {{ col.label }} {% endif %} {# Resize handle — 4px wide, right edge of th #} Actions
{# Empty state — visible when tbody has no data rows #}
{# /overflow-x-auto #}
{# /relative rounded border #} {# Screen-reader-only HTMX loading indicator (real indicator managed by Alpine loading flag above) #}
Loading…
{# ── Footer: pagination ───────────────────────────────────────────────────── #} {% if table.pagination_mode != "infinite" %}
{% include 'fragments/table_pagination.html' %}
{% endif %} {# Slide-over panel for detail views #} {% if table.slide_over %} {% include 'components/alpine/slide_over.html' %} {% endif %} {# Screen reader live region for Alpine announcements #}
{% endif %}