clone

an offline map explorer where each world, from a game map to a city's open data, ships as one .atlas file

feat/atlas-next-horizon
atlas / internal / app / templates / grid-navigator.tmpl
grid-navigator.tmpl 3.4K
1{{/*2 grid-navigator — the cell system in play, the cell held, and the subgrid.34 What a cell system is and what a cell draws belong to the analysis lane5 (issue #5 §5.4); which one is chosen and which cell is held belong to the6 session. This region is the second half only, which is why it names a system7 and never computes one.8*/}}9{{define "grid-navigator"}}<div id="atlas-grid-navigator" class="grid-navigator"{{if not .Grid.Enabled}} hidden{{end}}>10 {{/*11 Escape and the arrow telescope out one level. At the root there is no12 level left, so the same press closes the grid -- which is what the title13 says rather than leaving a reader to find out.14 */}}15 <button type="button" id="grid-back" aria-label="Back one cell level"16 title="{{if .Grid.Cell}}Back one {{.Grid.System}} level{{else}}Close {{.Grid.System}} grid{{end}}"17 hx-post="/session/grid" hx-vals:append='{"cell":"{{.Grid.Cell}}","ascend":"1"}'>←</button>18 {{/*19 One small mark beside the field it qualifies, saying which system the20 hash is written in. Always there -- a hash without its system is half an21 address -- and a button only when this world offers another system to22 cycle to; a world that divides one way wears the mark inert.23 */}}24 <button type="button" class="grid-system" id="grid-system"{{if not .Grid.Cycles}} disabled{{end}}25 title="{{if .Grid.Cycles}}Dividing by {{.Grid.Name}} · ⌘G for {{.Grid.Next}}{{else}}Dividing by {{.Grid.Name}}{{end}}"26 aria-label="{{if .Grid.Cycles}}Cell system: {{.Grid.Name}}. Switch to {{.Grid.Next}}{{else}}Cell system: {{.Grid.Name}}{{end}}"27 hx-post="/session/grid" hx-vals:append='{"system":"cycle"}'>{{.Grid.Mark}}</button>28 {{/*29 NO `changed` ON THIS FIELD, and the reason is that the server writes into30 it. `changed` remembers the value the last event carried and refuses one31 that matches -- which is right for a search box nobody else touches, and32 wrong here: the field is re-rendered by every swap, so ascending out of33 "m" leaves an empty field beside a remembered "m", and a reader who types34 the same hash again is answered with nothing at all. The event this hangs35 on is `input`, which a browser raises only when the value actually moved36 under the reader's hands, so the modifier was buying nothing to begin37 with. The reference had no such memory either: one input listener, one38 address, every time (`frontend/src/events.js`).39 */}}40 <label>41 <input type="text" id="grid-input" name="cell" value="{{.Grid.Cell}}"{{if .Grid.Length}} maxlength="{{.Grid.Length}}"{{end}}42 inputmode="text" autocomplete="off" autocapitalize="none" spellcheck="false"43 aria-label="{{.Grid.Name}} cell"44 hx-post="/session/grid" hx-trigger="input delay:150ms">45 </label>46 <button type="button" class="subgrid-toggle" id="subgrid-toggle"47 aria-pressed="{{.Grid.Subgrid}}"48 aria-label="{{if .Grid.Subgrid}}Hide the subgrid{{else}}Show the subgrid{{end}}"49 title="Space · show or hide the subgrid"50 hx-post="/session/grid" hx-vals:append='{"subgrid":"{{if .Grid.Subgrid}}0{{else}}1{{end}}"}'>51 <svg viewBox="0 0 16 16" aria-hidden="true">52 <path d="M2.5 2.5h11v11h-11z"/>53 <path d="M6.2 2.5v11M9.8 2.5v11M2.5 6.2h11M2.5 9.8h11"/>54 <path class="subgrid-toggle-slash" d="m2.6 13.4 10.8-10.8"/>55 </svg>56 </button>57</div>58{{end}}