feat: extract shared infrastructure from shared_lib
Phase 1-3 of decoupling plan: - Shared DB, models, infrastructure, browser, config, utils - Event infrastructure (domain_events outbox, bus, processor) - Structured logging - Generic container concept (container_type/container_id) - Alembic migrations for all schema changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
68
browser/templates/macros/scrolling_menu.html
Normal file
68
browser/templates/macros/scrolling_menu.html
Normal file
@@ -0,0 +1,68 @@
|
||||
{#
|
||||
Scrolling menu macro with arrow navigation
|
||||
|
||||
Creates a horizontally scrollable menu (desktop) or vertically scrollable (mobile)
|
||||
with arrow buttons that appear/hide based on content overflow.
|
||||
|
||||
Parameters:
|
||||
- container_id: Unique ID for the scroll container
|
||||
- items: List of items to iterate over
|
||||
- item_content: Caller block that renders each item (receives 'item' variable)
|
||||
- wrapper_class: Optional additional classes for outer wrapper
|
||||
- container_class: Optional additional classes for scroll container
|
||||
- item_class: Optional additional classes for each item wrapper
|
||||
#}
|
||||
|
||||
{% macro scrolling_menu(container_id, items, wrapper_class='', container_class='', item_class='') %}
|
||||
{% if items %}
|
||||
{# Left scroll arrow - desktop only #}
|
||||
<button
|
||||
class="scrolling-menu-arrow-{{ container_id }} hidden flex-shrink-0 p-2 hover:bg-stone-200 rounded"
|
||||
aria-label="Scroll left"
|
||||
_="on click
|
||||
set #{{ container_id }}.scrollLeft to #{{ container_id }}.scrollLeft - 200">
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
</button>
|
||||
|
||||
{# Scrollable container #}
|
||||
<div id="{{ container_id }}"
|
||||
class="overflow-y-auto sm:overflow-x-auto sm:overflow-y-visible scrollbar-hide max-h-[50vh] sm:max-h-none {{ container_class }}"
|
||||
style="scroll-behavior: smooth;"
|
||||
_="on load or scroll
|
||||
-- Show arrows if content overflows (desktop only)
|
||||
if window.innerWidth >= 640 and my.scrollWidth > my.clientWidth
|
||||
remove .hidden from .scrolling-menu-arrow-{{ container_id }}
|
||||
add .flex to .scrolling-menu-arrow-{{ container_id }}
|
||||
else
|
||||
add .hidden to .scrolling-menu-arrow-{{ container_id }}
|
||||
remove .flex from .scrolling-menu-arrow-{{ container_id }}
|
||||
end">
|
||||
<div class="flex flex-col sm:flex-row gap-1 {{ wrapper_class }}">
|
||||
{% for item in items %}
|
||||
<div class="{{ item_class }}">
|
||||
{{ caller(item) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.scrollbar-hide::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.scrollbar-hide {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
{# Right scroll arrow - desktop only #}
|
||||
<button
|
||||
class="scrolling-menu-arrow-{{ container_id }} hidden flex-shrink-0 p-2 hover:bg-stone-200 rounded"
|
||||
aria-label="Scroll right"
|
||||
_="on click
|
||||
set #{{ container_id }}.scrollLeft to #{{ container_id }}.scrollLeft + 200">
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
Reference in New Issue
Block a user