1{% if toolbar.should_render() %}
2{% set items=toolbar.get_items() %}
3<script defer src="{{ asset('toolbar/toolbar.js') }}" nonce="{{ request.csp_nonce }}"></script>
4<div id="plaintoolbar"
5 data-collapsed="true"
6 data-expanded="false"
7 data-items-open="false"
8 data-position="left"
9 class="group data-[hidden]:hidden! print:hidden text-stone-300 fixed bottom-0 w-full z-50 flex flex-col">
10
11 {#
12 Details panel. Visibility is driven entirely by data attributes on the
13 wrapper (no JS class toggling): shown when data-expanded=true, but
14 force-hidden on desktop while the bar is a collapsed pill.
15 #}
16 <div id="plaintoolbar-details" class="hidden group-data-[expanded=true]:block sm:group-data-[collapsed=true]:hidden! relative text-sm border-white/5 shadow-xl border-t inset-shadow-xs inset-shadow-stone-800 rounded-t-xl bg-stone-950/95 backdrop-blur-sm">
17
18 <div class="flex border-b border-white/5 px-2">
19 {# Mobile: scrollable tabs #}
20 <div id="plaintoolbar-tabs" class="flex flex-grow overflow-x-auto scrollbar-none">
21 {% for item in items %}
22 {% if item.name and item.panel_template_name %}
23 <button {% if loop.first %}data-active="true"{% endif %} data-toolbar-tab="{{ item.name }}" class="data-active:border-yellow-500 px-3 sm:px-4 py-3 sm:py-2.5 -mb-px cursor-pointer border-b-2 border-transparent hover:border-yellow-600 whitespace-nowrap text-sm" type="button">{{ item.name }}</button>
24 {% endif %}
25 {% endfor %}
26 <button data-plaintoolbar-expand class="flex-grow cursor-pointer inline-flex h-full min-w-[2rem]" type="button"></button>
27 </div>
28 <div class="px-2 sm:px-4 flex items-center gap-3 flex-shrink-0">
29 <button title="Hide toolbar for 1 hour" class="cursor-pointer hover:text-white text-white/50" type="button" data-plaintoolbar-hideuntil>
30 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-4 h-4" viewBox="0 0 16 16">
31 <path d="M8.515 1.019A7 7 0 0 0 8 1V0a8 8 0 0 1 .589.022zm2.004.45a7 7 0 0 0-.985-.299l.219-.976q.576.129 1.126.342zm1.37.71a7 7 0 0 0-.439-.27l.493-.87a8 8 0 0 1 .979.654l-.615.789a7 7 0 0 0-.418-.302zm1.834 1.79a7 7 0 0 0-.653-.796l.724-.69q.406.429.747.91zm.744 1.352a7 7 0 0 0-.214-.468l.893-.45a8 8 0 0 1 .45 1.088l-.95.313a7 7 0 0 0-.179-.483m.53 2.507a7 7 0 0 0-.1-1.025l.985-.17q.1.58.116 1.17zm-.131 1.538q.05-.254.081-.51l.993.123a8 8 0 0 1-.23 1.155l-.964-.267q.069-.247.12-.501m-.952 2.379q.276-.436.486-.908l.914.405q-.24.54-.555 1.038zm-.964 1.205q.183-.183.35-.378l.758.653a8 8 0 0 1-.401.432z"/>
32 <path d="M8 1a7 7 0 1 0 4.95 11.95l.707.707A8.001 8.001 0 1 1 8 0z"/>
33 <path d="M7.5 3a.5.5 0 0 1 .5.5v5.21l3.248 1.856a.5.5 0 0 1-.496.868l-3.5-2A.5.5 0 0 1 7 9V3.5a.5.5 0 0 1 .5-.5"/>
34 </svg>
35 </button>
36 </div>
37 </div>
38
39 {# Resize handle - hidden on mobile (touch resize not supported) #}
40 <div data-resizer class="hidden sm:block cursor-grab w-20 h-1.5 bg-white/15 rounded-full absolute top-1 left-1/2 -translate-x-1/2"></div>
41
42 {# Panel content - taller on mobile for better usability #}
43 <div class="overflow-auto h-[50vh] sm:h-[30vh] flex flex-col">
44 {% for item in items %}
45 {% if item.name and item.panel_template_name %}
46 <div data-toolbar-tab="{{ item.name }}" class="h-full {% if not loop.first %}hidden{% endif %}">
47 {{ item.render_panel() }}
48 </div>
49 {% endif %}
50 {% endfor %}
51 </div>
52
53 </div>
54
55 {#
56 Bar layout:
57 - Mobile (always): floating pill at the chosen position
58 - Desktop collapsed pill: floating pill at the chosen position
59 - Desktop uncollapsed (group-data-[collapsed=false]): full-width bottom bar
60 #}
61 {#
62 The pill's three positions are pure CSS translateX off a fixed left-0
63 anchor, so resize needs no JS. data-animate (set by toolbar.js only for
64 a snap or cycle) gates the slide transition; drag/dock stay instant.
65 #}
66 <div
67 id="plaintoolbar-bar"
68 class="fixed bottom-3 left-0 z-50 w-fit rounded-full py-2.5 cursor-grab
69 group-data-[position=left]:[transform:translateX(0.75rem)]
70 group-data-[position=center]:[transform:translateX(calc(50vw_-_50%))]
71 group-data-[position=right]:[transform:translateX(calc(100vw_-_100%_-_0.75rem))]
72 data-[animate]:transition-transform data-[animate]:duration-200 data-[animate]:ease-out
73 border border-white/10
74 sm:group-data-[collapsed=false]:relative sm:group-data-[collapsed=false]:inset-auto sm:group-data-[collapsed=false]:z-auto
75 sm:group-data-[collapsed=false]:[transform:none]
76 sm:group-data-[collapsed=false]:w-auto sm:group-data-[collapsed=false]:rounded-none sm:group-data-[collapsed=false]:py-2
77 sm:group-data-[collapsed=false]:border-0 sm:group-data-[collapsed=false]:border-t sm:group-data-[collapsed=false]:border-white/5
78 sm:group-data-[collapsed=false]:cursor-default
79 flex px-3 text-xs gap-3
80 bg-stone-950 shadow-xl"
81 >
82 {# Version: tappable toggle on mobile / desktop pill #}
83 <button id="plaintoolbar-version" class="flex sm:group-data-[collapsed=false]:hidden items-center flex-shrink-0 cursor-pointer whitespace-nowrap" type="button">
84 {{ toolbar.version }}
85 </button>
86 {# Version: selectable, non-interactive text on the desktop full bar #}
87 <span class="hidden sm:group-data-[collapsed=false]:flex items-center flex-shrink-0 whitespace-nowrap select-all">{{ toolbar.version }}</span>
88
89 {# Filler that expands the panel - desktop full bar only #}
90 <button type="button" data-plaintoolbar-expand class="hidden sm:group-data-[collapsed=false]:block flex-grow cursor-pointer min-w-0" title="Toggle panel"></button>
91
92 {#
93 Items list:
94 - desktop full bar: always shown
95 - mobile: shown when data-items-open=true (toggled by the version button)
96 - desktop pill: hidden
97 #}
98 <div id="plaintoolbar-items" class="hidden max-sm:group-data-[items-open=true]:flex sm:group-data-[collapsed=false]:flex items-center min-w-0">
99 <div class="flex items-center gap-3 transition-all min-w-0 [&>button]:max-w-[200px] sm:[&>button]:max-w-none">
100
101 {% for item in items %}
102 {% if item.button_template_name %}
103 {{ item.render_button() }}
104 {% endif %}
105 {% endfor %}
106
107 {% include "toolbar/links.html" ignore missing %}
108
109 <button data-plaintoolbar-expand class="hidden sm:group-data-[collapsed=false]:inline-flex hover:text-white text-white/50 cursor-pointer" type="button" title="Toggle panel">
110 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-3.5 h-3.5 transition-transform group-data-[expanded=true]:rotate-180" viewBox="0 0 16 16">
111 <path fill-rule="evenodd" d="M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z"/>
112 </svg>
113 </button>
114
115 <button data-plaintoolbar-collapse class="hidden sm:group-data-[collapsed=false]:inline-flex hover:text-white text-white/50 cursor-pointer" type="button" title="Collapse to pill">
116 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-3.5 h-3.5" viewBox="0 0 16 16">
117 <path fill-rule="evenodd" d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8"/>
118 </svg>
119 </button>
120
121 <button data-plaintoolbar-hide class="hover:text-red-500 text-white/50 cursor-pointer" type="button" title="Hide toolbar">
122 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-4 h-4 sm:w-3.5 sm:h-3.5" viewBox="0 0 16 16">
123 <path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"/>
124 </svg>
125 </button>
126
127 </div>
128 </div>
129 </div>
130
131</div>
132{% endif %}