Files
orion/app/templates/shared/macros/tabs.html
Samir Boulahtit 1bc608ef6b refactor: use tabs macro for settings page with mobile support
- Replace custom sidebar/icon nav with standard tabs_nav macro
- Add horizontal scroll for mobile (overflow-x-auto)
- Reduce tab spacing on mobile (space-x-4 vs space-x-8 on desktop)
- Content panels now take full width below tabs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 13:00:58 +01:00

79 lines
2.8 KiB
HTML

{# app/templates/shared/macros/tabs.html #}
{# Tab navigation components for consistent UI across admin pages #}
{#
Tab navigation wrapper (standalone)
Usage:
{% call tabs_nav() %}
{{ tab_button('tab1', 'Tab 1', icon='home') }}
{{ tab_button('tab2', 'Tab 2', icon='cog') }}
{% endcall %}
#}
{% macro tabs_nav(tab_var='activeTab', class='') %}
<div class="mb-6 {{ class }}">
<div class="border-b border-gray-200 dark:border-gray-700">
<nav class="-mb-px flex space-x-4 md:space-x-8 overflow-x-auto">
{{ caller() }}
</nav>
</div>
</div>
{% endmacro %}
{#
Tab navigation wrapper (inline, for use inside cards/flex containers)
Usage:
<div class="flex justify-between">
{% call tabs_inline() %}
{{ tab_button('all', 'All', count_var='items.length') }}
{% endcall %}
<!-- other content like search -->
</div>
#}
{% macro tabs_inline(tab_var='activeTab') %}
<div class="flex space-x-2 border-b border-gray-200 dark:border-gray-700">
{{ caller() }}
</div>
{% endmacro %}
{#
Individual tab button
Args:
id: Tab identifier (used for activeTab comparison)
label: Display text
tab_var: Alpine.js variable name for active tab (default: 'activeTab')
icon: Optional icon name (uses $icon helper)
count_var: Optional Alpine.js variable for count badge
onclick: Optional custom click handler (overrides default tab switching)
#}
{% macro tab_button(id, label, tab_var='activeTab', icon=none, count_var=none, onclick=none) %}
<button
@click="{{ onclick if onclick else (tab_var ~ " = '" ~ id ~ "'") }}"
:class="{{ tab_var }} === '{{ id }}' ? 'border-purple-500 text-purple-600 dark:text-purple-400' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300'"
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm transition-colors"
>
{%- if icon %}<span x-html="$icon('{{ icon }}', 'inline w-5 h-5 mr-2')"></span>{% endif -%}
{{ label }}
{%- if count_var %}<span class="ml-2 px-2 py-0.5 text-xs rounded-full bg-gray-100 dark:bg-gray-700" x-text="{{ count_var }}"></span>{% endif -%}
</button>
{% endmacro %}
{#
Tab panel wrapper (for content that shows/hides based on active tab)
Usage:
{{ tab_panel('tab1') }}
<div>Tab 1 content</div>
{{ endtab_panel() }}
Or simply use x-show directly:
<div x-show="activeTab === 'tab1'" x-transition>
Content
</div>
#}
{% macro tab_panel(id, tab_var='activeTab', transition=true) %}
<div x-show="{{ tab_var }} === '{{ id }}'"{% if transition %} x-transition{% endif %}>
{% endmacro %}
{% macro endtab_panel() %}
</div>
{% endmacro %}