mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-23 12:51:09 -05:00
Add standardized HTMX conventions, interaction patterns, and migration guide for ThrillWiki UX
This commit is contained in:
227
backend/templates/components/ui/icon.html
Normal file
227
backend/templates/components/ui/icon.html
Normal file
@@ -0,0 +1,227 @@
|
||||
{% comment %}
|
||||
Icon Component - SVG Icon Wrapper
|
||||
|
||||
A component for rendering SVG icons consistently. Provides a library of common icons
|
||||
and supports custom SVG content. Replaces Font Awesome with inline SVGs for better
|
||||
customization and smaller bundle size.
|
||||
|
||||
Usage Examples:
|
||||
Named icon:
|
||||
{% include 'components/ui/icon.html' with name='search' %}
|
||||
|
||||
With size:
|
||||
{% include 'components/ui/icon.html' with name='menu' size='lg' %}
|
||||
|
||||
With custom class:
|
||||
{% include 'components/ui/icon.html' with name='user' class='text-primary' %}
|
||||
|
||||
Custom SVG content:
|
||||
{% include 'components/ui/icon.html' with svg='<path d="..."/>' %}
|
||||
|
||||
Parameters:
|
||||
- name: Icon name from the built-in library
|
||||
- size: 'xs', 'sm', 'md', 'lg', 'xl' (default: 'md')
|
||||
- class: Additional CSS classes
|
||||
- svg: Custom SVG path content (for icons not in the library)
|
||||
- stroke_width: SVG stroke width (default: 2)
|
||||
- aria_label: Accessibility label (required for meaningful icons)
|
||||
- aria_hidden: Set to 'false' for meaningful icons (default: 'true' for decorative)
|
||||
|
||||
Available Icons:
|
||||
Navigation: menu, close, chevron-down, chevron-up, chevron-left, chevron-right,
|
||||
arrow-left, arrow-right, arrow-up, arrow-down, external-link
|
||||
Actions: search, plus, minus, edit, trash, download, upload, copy, share, refresh
|
||||
User: user, users, settings, logout, login
|
||||
Status: check, x, info, warning, error, question
|
||||
Media: image, video, music, file, folder
|
||||
Communication: mail, phone, message, bell, send
|
||||
Social: heart, star, bookmark, thumbs-up, thumbs-down
|
||||
Misc: home, calendar, clock, map-pin, globe, sun, moon, eye, eye-off, lock, unlock
|
||||
{% endcomment %}
|
||||
|
||||
{% with icon_size=size|default:'md' %}
|
||||
|
||||
<svg
|
||||
class="icon icon-{{ name }}
|
||||
{% if icon_size == 'xs' %}w-3 h-3
|
||||
{% elif icon_size == 'sm' %}w-4 h-4
|
||||
{% elif icon_size == 'lg' %}w-6 h-6
|
||||
{% elif icon_size == 'xl' %}w-8 h-8
|
||||
{% else %}w-5 h-5{% endif %}
|
||||
{{ class|default:'' }}"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="{{ stroke_width|default:'2' }}"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
{% if aria_label %}aria-label="{{ aria_label }}" role="img"{% else %}aria-hidden="{{ aria_hidden|default:'true' }}"{% endif %}>
|
||||
|
||||
{% if svg %}
|
||||
{{ svg|safe }}
|
||||
{% elif name == 'search' %}
|
||||
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
|
||||
{% elif name == 'menu' %}
|
||||
<path d="M4 6h16M4 12h16M4 18h16"/>
|
||||
{% elif name == 'close' or name == 'x' %}
|
||||
<path d="M6 18L18 6M6 6l12 12"/>
|
||||
{% elif name == 'chevron-down' %}
|
||||
<path d="M19 9l-7 7-7-7"/>
|
||||
{% elif name == 'chevron-up' %}
|
||||
<path d="M5 15l7-7 7 7"/>
|
||||
{% elif name == 'chevron-left' %}
|
||||
<path d="M15 19l-7-7 7-7"/>
|
||||
{% elif name == 'chevron-right' %}
|
||||
<path d="M9 5l7 7-7 7"/>
|
||||
{% elif name == 'arrow-left' %}
|
||||
<path d="M19 12H5M12 19l-7-7 7-7"/>
|
||||
{% elif name == 'arrow-right' %}
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
{% elif name == 'arrow-up' %}
|
||||
<path d="M12 19V5M5 12l7-7 7 7"/>
|
||||
{% elif name == 'arrow-down' %}
|
||||
<path d="M12 5v14M19 12l-7 7-7-7"/>
|
||||
{% elif name == 'external-link' %}
|
||||
<path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6M15 3h6v6M10 14L21 3"/>
|
||||
{% elif name == 'plus' %}
|
||||
<path d="M12 5v14M5 12h14"/>
|
||||
{% elif name == 'minus' %}
|
||||
<path d="M5 12h14"/>
|
||||
{% elif name == 'edit' or name == 'pencil' %}
|
||||
<path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/>
|
||||
<path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
||||
{% elif name == 'trash' or name == 'delete' %}
|
||||
<path d="M3 6h18M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/>
|
||||
<path d="M10 11v6M14 11v6"/>
|
||||
{% elif name == 'download' %}
|
||||
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/>
|
||||
{% elif name == 'upload' %}
|
||||
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12"/>
|
||||
{% elif name == 'copy' %}
|
||||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
|
||||
<path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/>
|
||||
{% elif name == 'share' %}
|
||||
<circle cx="18" cy="5" r="3"/>
|
||||
<circle cx="6" cy="12" r="3"/>
|
||||
<circle cx="18" cy="19" r="3"/>
|
||||
<path d="M8.59 13.51l6.83 3.98M15.41 6.51l-6.82 3.98"/>
|
||||
{% elif name == 'refresh' %}
|
||||
<path d="M23 4v6h-6M1 20v-6h6"/>
|
||||
<path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
|
||||
{% elif name == 'user' %}
|
||||
<path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/>
|
||||
<circle cx="12" cy="7" r="4"/>
|
||||
{% elif name == 'users' %}
|
||||
<path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/>
|
||||
<path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/>
|
||||
{% elif name == 'settings' or name == 'cog' %}
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z"/>
|
||||
{% elif name == 'logout' or name == 'sign-out' %}
|
||||
<path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4M16 17l5-5-5-5M21 12H9"/>
|
||||
{% elif name == 'login' or name == 'sign-in' %}
|
||||
<path d="M15 3h4a2 2 0 012 2v14a2 2 0 01-2 2h-4M10 17l5-5-5-5M15 12H3"/>
|
||||
{% elif name == 'check' %}
|
||||
<path d="M20 6L9 17l-5-5"/>
|
||||
{% elif name == 'info' %}
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M12 16v-4M12 8h.01"/>
|
||||
{% elif name == 'warning' or name == 'alert-triangle' %}
|
||||
<path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0zM12 9v4M12 17h.01"/>
|
||||
{% elif name == 'error' or name == 'alert-circle' %}
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M12 8v4M12 16h.01"/>
|
||||
{% elif name == 'question' or name == 'help-circle' %}
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01"/>
|
||||
{% elif name == 'image' %}
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
|
||||
<circle cx="8.5" cy="8.5" r="1.5"/>
|
||||
<path d="M21 15l-5-5L5 21"/>
|
||||
{% elif name == 'file' %}
|
||||
<path d="M13 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V9z"/>
|
||||
<path d="M13 2v7h7"/>
|
||||
{% elif name == 'folder' %}
|
||||
<path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"/>
|
||||
{% elif name == 'mail' or name == 'email' %}
|
||||
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
|
||||
<path d="M22 6l-10 7L2 6"/>
|
||||
{% elif name == 'phone' %}
|
||||
<path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72 12.84 12.84 0 00.7 2.81 2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45 12.84 12.84 0 002.81.7A2 2 0 0122 16.92z"/>
|
||||
{% elif name == 'message' or name == 'chat' %}
|
||||
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
|
||||
{% elif name == 'bell' %}
|
||||
<path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 01-3.46 0"/>
|
||||
{% elif name == 'send' %}
|
||||
<path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/>
|
||||
{% elif name == 'heart' %}
|
||||
<path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"/>
|
||||
{% elif name == 'star' %}
|
||||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
||||
{% elif name == 'bookmark' %}
|
||||
<path d="M19 21l-7-5-7 5V5a2 2 0 012-2h10a2 2 0 012 2z"/>
|
||||
{% elif name == 'thumbs-up' %}
|
||||
<path d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3zM7 22H4a2 2 0 01-2-2v-7a2 2 0 012-2h3"/>
|
||||
{% elif name == 'thumbs-down' %}
|
||||
<path d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3zm7-13h2.67A2.31 2.31 0 0122 4v7a2.31 2.31 0 01-2.33 2H17"/>
|
||||
{% elif name == 'home' %}
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/>
|
||||
<path d="M9 22V12h6v10"/>
|
||||
{% elif name == 'calendar' %}
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/>
|
||||
<path d="M16 2v4M8 2v4M3 10h18"/>
|
||||
{% elif name == 'clock' %}
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M12 6v6l4 2"/>
|
||||
{% elif name == 'map-pin' or name == 'location' %}
|
||||
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0118 0z"/>
|
||||
<circle cx="12" cy="10" r="3"/>
|
||||
{% elif name == 'globe' %}
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M2 12h20M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z"/>
|
||||
{% elif name == 'sun' %}
|
||||
<circle cx="12" cy="12" r="5"/>
|
||||
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
|
||||
{% elif name == 'moon' %}
|
||||
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
|
||||
{% elif name == 'eye' %}
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
{% elif name == 'eye-off' %}
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24M1 1l22 22"/>
|
||||
{% elif name == 'lock' %}
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
|
||||
<path d="M7 11V7a5 5 0 0110 0v4"/>
|
||||
{% elif name == 'unlock' %}
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
|
||||
<path d="M7 11V7a5 5 0 019.9-1"/>
|
||||
{% elif name == 'filter' %}
|
||||
<path d="M22 3H2l8 9.46V19l4 2v-8.54L22 3z"/>
|
||||
{% elif name == 'sort' %}
|
||||
<path d="M3 6h18M6 12h12M9 18h6"/>
|
||||
{% elif name == 'grid' %}
|
||||
<rect x="3" y="3" width="7" height="7"/>
|
||||
<rect x="14" y="3" width="7" height="7"/>
|
||||
<rect x="14" y="14" width="7" height="7"/>
|
||||
<rect x="3" y="14" width="7" height="7"/>
|
||||
{% elif name == 'list' %}
|
||||
<path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/>
|
||||
{% elif name == 'more-horizontal' or name == 'dots' %}
|
||||
<circle cx="12" cy="12" r="1"/>
|
||||
<circle cx="19" cy="12" r="1"/>
|
||||
<circle cx="5" cy="12" r="1"/>
|
||||
{% elif name == 'more-vertical' %}
|
||||
<circle cx="12" cy="12" r="1"/>
|
||||
<circle cx="12" cy="5" r="1"/>
|
||||
<circle cx="12" cy="19" r="1"/>
|
||||
{% elif name == 'loader' or name == 'spinner' %}
|
||||
<path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/>
|
||||
{% else %}
|
||||
{# Default: question mark icon for unknown names #}
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01"/>
|
||||
{% endif %}
|
||||
</svg>
|
||||
|
||||
{% endwith %}
|
||||
Reference in New Issue
Block a user