mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-23 07:31:08 -05:00
Add standardized HTMX conventions, interaction patterns, and migration guide for ThrillWiki UX
This commit is contained in:
156
backend/templates/components/pagination_inner.html
Normal file
156
backend/templates/components/pagination_inner.html
Normal file
@@ -0,0 +1,156 @@
|
||||
{# Inner pagination template - do not use directly, use pagination.html instead #}
|
||||
<nav class="bg-white dark:bg-gray-800 px-4 py-3 flex items-center justify-between border-t border-gray-200 dark:border-gray-700 sm:px-6 rounded-b-lg"
|
||||
aria-label="Pagination"
|
||||
role="navigation">
|
||||
|
||||
{# Results info - Hidden on mobile #}
|
||||
{% if show_info %}
|
||||
<div class="hidden sm:block">
|
||||
<p class="{{ info_class }} text-gray-700 dark:text-gray-300">
|
||||
Showing
|
||||
<span class="font-medium">{{ page_obj.start_index }}</span>
|
||||
to
|
||||
<span class="font-medium">{{ page_obj.end_index }}</span>
|
||||
of
|
||||
<span class="font-medium">{{ page_obj.paginator.count }}</span>
|
||||
results
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="flex-1 flex justify-between sm:justify-end gap-2">
|
||||
{# Previous Button #}
|
||||
{% if page_obj.has_previous %}
|
||||
{% if use_htmx %}
|
||||
<button type="button"
|
||||
hx-get="{{ base_url|default:request.path }}?{% if request.GET.urlencode %}{{ request.GET.urlencode }}&{% endif %}page={{ page_obj.previous_page_number }}"
|
||||
hx-target="{{ hx_target }}"
|
||||
hx-swap="{{ hx_swap }}"
|
||||
hx-push-url="{{ hx_push_url|default:'true' }}"
|
||||
class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors"
|
||||
aria-label="Go to previous page">
|
||||
<svg class="mr-2 h-5 w-5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Previous
|
||||
</button>
|
||||
{% else %}
|
||||
<a href="?{% if request.GET.urlencode %}{{ request.GET.urlencode }}&{% endif %}page={{ page_obj.previous_page_number }}"
|
||||
class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors"
|
||||
aria-label="Go to previous page">
|
||||
<svg class="mr-2 h-5 w-5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Previous
|
||||
</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 font-medium rounded-md text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 cursor-not-allowed"
|
||||
aria-disabled="true">
|
||||
<svg class="mr-2 h-5 w-5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Previous
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{# Page numbers - Hidden on mobile, visible on medium+ screens #}
|
||||
<div class="hidden md:flex items-center gap-1">
|
||||
{% for num in page_obj.paginator.page_range %}
|
||||
{% if num == page_obj.number %}
|
||||
{# Current page #}
|
||||
<span class="relative inline-flex items-center {{ btn_padding }} border border-blue-500 bg-blue-50 dark:bg-blue-900/30 font-medium text-blue-600 dark:text-blue-400 rounded-md"
|
||||
aria-current="page">
|
||||
{{ num }}
|
||||
</span>
|
||||
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
||||
{# Pages near current #}
|
||||
{% if use_htmx %}
|
||||
<button type="button"
|
||||
hx-get="{{ base_url|default:request.path }}?{% if request.GET.urlencode %}{{ request.GET.urlencode }}&{% endif %}page={{ num }}"
|
||||
hx-target="{{ hx_target }}"
|
||||
hx-swap="{{ hx_swap }}"
|
||||
hx-push-url="{{ hx_push_url|default:'true' }}"
|
||||
class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 rounded-md transition-colors"
|
||||
aria-label="Go to page {{ num }}">
|
||||
{{ num }}
|
||||
</button>
|
||||
{% else %}
|
||||
<a href="?{% if request.GET.urlencode %}{{ request.GET.urlencode }}&{% endif %}page={{ num }}"
|
||||
class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 rounded-md transition-colors"
|
||||
aria-label="Go to page {{ num }}">
|
||||
{{ num }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% elif num == 1 or num == page_obj.paginator.num_pages %}
|
||||
{# First and last page always visible #}
|
||||
{% if use_htmx %}
|
||||
<button type="button"
|
||||
hx-get="{{ base_url|default:request.path }}?{% if request.GET.urlencode %}{{ request.GET.urlencode }}&{% endif %}page={{ num }}"
|
||||
hx-target="{{ hx_target }}"
|
||||
hx-swap="{{ hx_swap }}"
|
||||
hx-push-url="{{ hx_push_url|default:'true' }}"
|
||||
class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 rounded-md transition-colors"
|
||||
aria-label="Go to page {{ num }}">
|
||||
{{ num }}
|
||||
</button>
|
||||
{% else %}
|
||||
<a href="?{% if request.GET.urlencode %}{{ request.GET.urlencode }}&{% endif %}page={{ num }}"
|
||||
class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 rounded-md transition-colors"
|
||||
aria-label="Go to page {{ num }}">
|
||||
{{ num }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% elif num == page_obj.number|add:'-4' or num == page_obj.number|add:'4' %}
|
||||
{# Ellipsis #}
|
||||
<span class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 font-medium text-gray-500 dark:text-gray-400 rounded-md"
|
||||
aria-hidden="true">
|
||||
…
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{# Mobile page indicator #}
|
||||
<div class="flex md:hidden items-center">
|
||||
<span class="{{ info_class }} text-gray-700 dark:text-gray-300">
|
||||
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{# Next Button #}
|
||||
{% if page_obj.has_next %}
|
||||
{% if use_htmx %}
|
||||
<button type="button"
|
||||
hx-get="{{ base_url|default:request.path }}?{% if request.GET.urlencode %}{{ request.GET.urlencode }}&{% endif %}page={{ page_obj.next_page_number }}"
|
||||
hx-target="{{ hx_target }}"
|
||||
hx-swap="{{ hx_swap }}"
|
||||
hx-push-url="{{ hx_push_url|default:'true' }}"
|
||||
class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors"
|
||||
aria-label="Go to next page">
|
||||
Next
|
||||
<svg class="ml-2 h-5 w-5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
{% else %}
|
||||
<a href="?{% if request.GET.urlencode %}{{ request.GET.urlencode }}&{% endif %}page={{ page_obj.next_page_number }}"
|
||||
class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 font-medium rounded-md text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors"
|
||||
aria-label="Go to next page">
|
||||
Next
|
||||
<svg class="ml-2 h-5 w-5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="relative inline-flex items-center {{ btn_padding }} border border-gray-300 dark:border-gray-600 font-medium rounded-md text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 cursor-not-allowed"
|
||||
aria-disabled="true">
|
||||
Next
|
||||
<svg class="ml-2 h-5 w-5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
Reference in New Issue
Block a user