mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2026-01-05 00:58:50 +01:00
overhaul: migrated to tailwind css for css management, consolidated custom css, removed inline css, removed unneeded css, and otherwise improved page styling
This commit is contained in:
parent
f1e21873e7
commit
b994978f60
81 changed files with 15784 additions and 2936 deletions
399
code/web/templates/partials/_panels.html
Normal file
399
code/web/templates/partials/_panels.html
Normal file
|
|
@ -0,0 +1,399 @@
|
|||
{# Panel/Tile Component Library #}
|
||||
{# Usage: {{ import '_panels.html' }} then call panel macros #}
|
||||
|
||||
{#
|
||||
Panel Container Macro
|
||||
|
||||
Parameters:
|
||||
- title (str): Panel title (optional)
|
||||
- variant (str): 'default', 'alt', 'dark', 'bordered' (default: 'default')
|
||||
- padding (str): 'none', 'sm', 'md', 'lg' (default: 'md')
|
||||
- classes (str): Additional CSS classes
|
||||
- attrs (str): Additional HTML attributes
|
||||
|
||||
Content Block:
|
||||
- header: Optional custom header (overrides title)
|
||||
- body: Panel content (required)
|
||||
- footer: Optional footer content
|
||||
|
||||
Examples:
|
||||
{% call panel(title='Deck Stats') %}
|
||||
{% block body %}
|
||||
<p>Cards: 100</p>
|
||||
{% endblock %}
|
||||
{% endcall %}
|
||||
|
||||
{% call panel(variant='alt', padding='lg') %}
|
||||
{% block body %}
|
||||
<p>Content here</p>
|
||||
{% endblock %}
|
||||
{% endcall %}
|
||||
#}
|
||||
{% macro panel(title='', variant='default', padding='md', classes='', attrs='') %}
|
||||
{%- set variant_class = 'panel-' + variant if variant != 'default' else '' -%}
|
||||
{%- set padding_class = 'panel-padding-' + padding -%}
|
||||
{%- set all_classes = ['panel', variant_class, padding_class, classes]|select|join(' ') -%}
|
||||
|
||||
<div class="{{ all_classes }}" {{ attrs|safe }}>
|
||||
{% if caller.header is defined %}
|
||||
{{ caller.header() }}
|
||||
{% elif title %}
|
||||
<div class="panel-header">
|
||||
<h3 class="panel-title">{{ title }}</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="panel-body">
|
||||
{{ caller.body() }}
|
||||
</div>
|
||||
|
||||
{% if caller.footer is defined %}
|
||||
<div class="panel-footer">
|
||||
{{ caller.footer() }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{#
|
||||
Simple Panel Macro (no block structure)
|
||||
|
||||
Parameters: Same as panel() plus:
|
||||
- content (str): Body HTML content
|
||||
|
||||
Examples:
|
||||
{{ simple_panel(title='Welcome', content='<p>Hello, user!</p>') }}
|
||||
{{ simple_panel(content='<p>No title panel</p>', variant='alt') }}
|
||||
#}
|
||||
{% macro simple_panel(title='', content='', variant='default', padding='md', classes='', attrs='') %}
|
||||
{%- set variant_class = 'panel-' + variant if variant != 'default' else '' -%}
|
||||
{%- set padding_class = 'panel-padding-' + padding -%}
|
||||
{%- set all_classes = ['panel', variant_class, padding_class, classes]|select|join(' ') -%}
|
||||
|
||||
<div class="{{ all_classes }}" {{ attrs|safe }}>
|
||||
{% if title %}
|
||||
<div class="panel-header">
|
||||
<h3 class="panel-title">{{ title }}</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="panel-body">
|
||||
{{ content|safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{#
|
||||
Info Panel Macro (with icon and optional action)
|
||||
|
||||
Parameters:
|
||||
- icon (str): Icon HTML or character
|
||||
- title (str): Panel title (required)
|
||||
- content (str): Panel content (required)
|
||||
- type (str): 'info', 'success', 'warning', 'error' (default: 'info')
|
||||
- action_text (str): Optional action button text
|
||||
- action_href (str): Action button URL
|
||||
- action_onclick (str): Action button onclick handler
|
||||
- classes (str): Additional CSS classes
|
||||
|
||||
Examples:
|
||||
{{ info_panel(
|
||||
icon='ℹ️',
|
||||
title='Setup Required',
|
||||
content='Please run the setup process before building decks.',
|
||||
type='info',
|
||||
action_text='Run Setup',
|
||||
action_href='/setup'
|
||||
) }}
|
||||
#}
|
||||
{% macro info_panel(icon='', title='', content='', type='info', action_text='', action_href='', action_onclick='', classes='') %}
|
||||
{%- set type_class = 'panel-info-' + type -%}
|
||||
{%- set all_classes = ['panel', 'panel-info', type_class, classes]|select|join(' ') -%}
|
||||
|
||||
<div class="{{ all_classes }}">
|
||||
<div class="panel-info-content">
|
||||
{% if icon %}
|
||||
<div class="panel-info-icon">{{ icon|safe }}</div>
|
||||
{% endif %}
|
||||
<div class="panel-info-text">
|
||||
{% if title %}
|
||||
<h4 class="panel-info-title">{{ title }}</h4>
|
||||
{% endif %}
|
||||
<div class="panel-info-message">{{ content|safe }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if action_text %}
|
||||
<div class="panel-info-action">
|
||||
{% from '_buttons.html' import button %}
|
||||
{{ button(action_text, href=action_href, onclick=action_onclick, variant='primary', size='sm') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{#
|
||||
Stat Panel Macro (for displaying key metrics)
|
||||
|
||||
Parameters:
|
||||
- label (str): Stat label (required)
|
||||
- value (str or int): Stat value (required)
|
||||
- sublabel (str): Optional secondary label
|
||||
- icon (str): Optional icon
|
||||
- variant (str): 'default', 'primary', 'success', 'warning', 'error' (default: 'default')
|
||||
- classes (str): Additional CSS classes
|
||||
|
||||
Examples:
|
||||
{{ stat_panel('Total Cards', value=100) }}
|
||||
{{ stat_panel('Mana Value', value='3.2', sublabel='Average', icon='⚡') }}
|
||||
#}
|
||||
{% macro stat_panel(label, value, sublabel='', icon='', variant='default', classes='') %}
|
||||
{%- set variant_class = 'panel-stat-' + variant if variant != 'default' else '' -%}
|
||||
{%- set all_classes = ['panel', 'panel-stat', variant_class, classes]|select|join(' ') -%}
|
||||
|
||||
<div class="{{ all_classes }}">
|
||||
{% if icon %}
|
||||
<div class="panel-stat-icon">{{ icon|safe }}</div>
|
||||
{% endif %}
|
||||
<div class="panel-stat-content">
|
||||
<div class="panel-stat-value">{{ value }}</div>
|
||||
<div class="panel-stat-label">{{ label }}</div>
|
||||
{% if sublabel %}
|
||||
<div class="panel-stat-sublabel">{{ sublabel }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{#
|
||||
Collapsible Panel Macro
|
||||
|
||||
Parameters:
|
||||
- title (str): Panel title (required)
|
||||
- id (str): Panel HTML id (auto-generated if not provided)
|
||||
- expanded (bool): Initially expanded (default: False)
|
||||
- variant (str): Panel variant (default: 'default')
|
||||
- padding (str): Panel padding (default: 'md')
|
||||
- classes (str): Additional CSS classes
|
||||
|
||||
Content Block:
|
||||
- body: Panel content (required)
|
||||
|
||||
Examples:
|
||||
{% call collapsible_panel(title='Advanced Options', expanded=False) %}
|
||||
{% block body %}
|
||||
<p>Advanced settings here</p>
|
||||
{% endblock %}
|
||||
{% endcall %}
|
||||
#}
|
||||
{% macro collapsible_panel(title, id='', expanded=False, variant='default', padding='md', classes='') %}
|
||||
{%- set panel_id = id if id else 'panel-' + title|lower|replace(' ', '-') -%}
|
||||
{%- set content_id = panel_id + '-content' -%}
|
||||
{%- set variant_class = 'panel-' + variant if variant != 'default' else '' -%}
|
||||
{%- set padding_class = 'panel-padding-' + padding -%}
|
||||
{%- set expanded_class = 'panel-expanded' if expanded else 'panel-collapsed' -%}
|
||||
{%- set all_classes = ['panel', 'panel-collapsible', variant_class, padding_class, expanded_class, classes]|select|join(' ') -%}
|
||||
|
||||
<div class="{{ all_classes }}" id="{{ panel_id }}">
|
||||
<button type="button"
|
||||
class="panel-toggle"
|
||||
aria-expanded="{{ 'true' if expanded else 'false' }}"
|
||||
aria-controls="{{ content_id }}"
|
||||
onclick="togglePanel('{{ panel_id }}')">
|
||||
<span class="panel-toggle-icon"></span>
|
||||
<span class="panel-title">{{ title }}</span>
|
||||
</button>
|
||||
|
||||
<div class="panel-body panel-collapse-content"
|
||||
id="{{ content_id }}"
|
||||
{% if not expanded %}style="display:none;"{% endif %}>
|
||||
{{ caller.body() }}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{#
|
||||
Grid Container Macro (for laying out multiple panels)
|
||||
|
||||
Parameters:
|
||||
- columns (int or str): Number of columns (1, 2, 3, 4, 'auto') (default: 'auto')
|
||||
- gap (str): Grid gap (default: '1rem')
|
||||
- classes (str): Additional CSS classes
|
||||
|
||||
Content Block:
|
||||
- body: Grid items (panels or other content)
|
||||
|
||||
Examples:
|
||||
{% call grid_container(columns=3) %}
|
||||
{% block body %}
|
||||
{{ stat_panel('Stat 1', 100) }}
|
||||
{{ stat_panel('Stat 2', 200) }}
|
||||
{{ stat_panel('Stat 3', 300) }}
|
||||
{% endblock %}
|
||||
{% endcall %}
|
||||
#}
|
||||
{% macro grid_container(columns='auto', gap='1rem', classes='') %}
|
||||
{%- set columns_class = 'panel-grid-cols-' + (columns|string) -%}
|
||||
{%- set all_classes = ['panel-grid', columns_class, classes]|select|join(' ') -%}
|
||||
|
||||
<div class="{{ all_classes }}" style="gap: {{ gap }};">
|
||||
{{ caller.body() }}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{#
|
||||
Empty State Panel Macro
|
||||
|
||||
Parameters:
|
||||
- icon (str): Icon HTML or character
|
||||
- title (str): Empty state title (required)
|
||||
- message (str): Empty state message (required)
|
||||
- action_text (str): Optional action button text
|
||||
- action_href (str): Action button URL
|
||||
- action_onclick (str): Action button onclick handler
|
||||
- classes (str): Additional CSS classes
|
||||
|
||||
Examples:
|
||||
{{ empty_state_panel(
|
||||
icon='📋',
|
||||
title='No Decks Found',
|
||||
message='You haven\'t created any decks yet. Start building your first deck!',
|
||||
action_text='Build Deck',
|
||||
action_href='/build'
|
||||
) }}
|
||||
#}
|
||||
{% macro empty_state_panel(icon='', title='', message='', action_text='', action_href='', action_onclick='', classes='') %}
|
||||
{%- set all_classes = ['panel', 'panel-empty-state', classes]|select|join(' ') -%}
|
||||
|
||||
<div class="{{ all_classes }}">
|
||||
{% if icon %}
|
||||
<div class="panel-empty-icon">{{ icon|safe }}</div>
|
||||
{% endif %}
|
||||
{% if title %}
|
||||
<h3 class="panel-empty-title">{{ title }}</h3>
|
||||
{% endif %}
|
||||
{% if message %}
|
||||
<p class="panel-empty-message">{{ message }}</p>
|
||||
{% endif %}
|
||||
{% if action_text %}
|
||||
<div class="panel-empty-action">
|
||||
{% from '_buttons.html' import button %}
|
||||
{{ button(action_text, href=action_href, onclick=action_onclick, variant='primary') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{#
|
||||
Loading Panel Macro
|
||||
|
||||
Parameters:
|
||||
- message (str): Loading message (default: 'Loading...')
|
||||
- spinner (bool): Show spinner animation (default: True)
|
||||
- classes (str): Additional CSS classes
|
||||
|
||||
Examples:
|
||||
{{ loading_panel() }}
|
||||
{{ loading_panel(message='Building deck...', spinner=True) }}
|
||||
#}
|
||||
{% macro loading_panel(message='Loading...', spinner=True, classes='') %}
|
||||
{%- set all_classes = ['panel', 'panel-loading', classes]|select|join(' ') -%}
|
||||
|
||||
<div class="{{ all_classes }}">
|
||||
{% if spinner %}
|
||||
<div class="panel-loading-spinner" aria-hidden="true"></div>
|
||||
{% endif %}
|
||||
<div class="panel-loading-message">{{ message }}</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{# CSS Classes Reference #}
|
||||
{#
|
||||
Panel Base:
|
||||
- .panel (base panel class)
|
||||
|
||||
Panel Variants:
|
||||
- .panel-default (default background, var(--panel))
|
||||
- .panel-alt (alternate background, var(--panel-alt))
|
||||
- .panel-dark (dark background, #0f1115)
|
||||
- .panel-bordered (bordered, no background)
|
||||
|
||||
Panel Padding:
|
||||
- .panel-padding-none (no padding)
|
||||
- .panel-padding-sm (0.5rem)
|
||||
- .panel-padding-md (0.75rem, default)
|
||||
- .panel-padding-lg (1.5rem)
|
||||
|
||||
Panel Structure:
|
||||
- .panel-header (header section)
|
||||
- .panel-title (title text, h3)
|
||||
- .panel-body (content section)
|
||||
- .panel-footer (footer section)
|
||||
|
||||
Info Panel:
|
||||
- .panel-info (info panel container)
|
||||
- .panel-info-info (blue theme)
|
||||
- .panel-info-success (green theme)
|
||||
- .panel-info-warning (yellow theme)
|
||||
- .panel-info-error (red theme)
|
||||
- .panel-info-content (content wrapper)
|
||||
- .panel-info-icon (icon container)
|
||||
- .panel-info-text (text wrapper)
|
||||
- .panel-info-title (info title, h4)
|
||||
- .panel-info-message (info message)
|
||||
- .panel-info-action (action button wrapper)
|
||||
|
||||
Stat Panel:
|
||||
- .panel-stat (stat panel container)
|
||||
- .panel-stat-default, .panel-stat-primary, etc. (color variants)
|
||||
- .panel-stat-icon (stat icon)
|
||||
- .panel-stat-content (stat content wrapper)
|
||||
- .panel-stat-value (stat value, large)
|
||||
- .panel-stat-label (stat label)
|
||||
- .panel-stat-sublabel (optional secondary label)
|
||||
|
||||
Collapsible Panel:
|
||||
- .panel-collapsible (collapsible panel)
|
||||
- .panel-expanded (expanded state)
|
||||
- .panel-collapsed (collapsed state)
|
||||
- .panel-toggle (toggle button)
|
||||
- .panel-toggle-icon (chevron/arrow icon)
|
||||
- .panel-collapse-content (collapsible content)
|
||||
|
||||
Panel Grid:
|
||||
- .panel-grid (grid container)
|
||||
- .panel-grid-cols-auto (auto columns)
|
||||
- .panel-grid-cols-1, .panel-grid-cols-2, etc. (fixed columns)
|
||||
|
||||
Empty State:
|
||||
- .panel-empty-state (empty state container)
|
||||
- .panel-empty-icon (empty state icon)
|
||||
- .panel-empty-title (empty state title, h3)
|
||||
- .panel-empty-message (empty state message, p)
|
||||
- .panel-empty-action (action button wrapper)
|
||||
|
||||
Loading Panel:
|
||||
- .panel-loading (loading panel)
|
||||
- .panel-loading-spinner (spinner animation)
|
||||
- .panel-loading-message (loading message text)
|
||||
#}
|
||||
|
||||
{# JavaScript Helper Functions #}
|
||||
{#
|
||||
These functions should be included in a global JavaScript file or inline script:
|
||||
|
||||
// Toggle collapsible panel
|
||||
function togglePanel(panelId) {
|
||||
const panel = document.getElementById(panelId);
|
||||
if (!panel) return;
|
||||
|
||||
const button = panel.querySelector('.panel-toggle');
|
||||
const content = panel.querySelector('.panel-collapse-content');
|
||||
const isExpanded = button.getAttribute('aria-expanded') === 'true';
|
||||
|
||||
// Toggle state
|
||||
button.setAttribute('aria-expanded', !isExpanded);
|
||||
content.style.display = isExpanded ? 'none' : 'block';
|
||||
panel.classList.toggle('panel-expanded');
|
||||
panel.classList.toggle('panel-collapsed');
|
||||
}
|
||||
#}
|
||||
Loading…
Add table
Add a link
Reference in a new issue