tower / commit
refactor(ui): stop opening and closing sections automatically
decisions.md | 33 ++++++++++++++++++++++++++++----- index.html | 6 +++--- src/ui/app.ts | 33 --------------------------------- 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/decisions.md b/decisions.md index ad7c249..3d32941 100644 --- a/decisions.md +++ b/decisions.md @@ -944,11 +944,11 @@ property of a value here, not a category of setting. **Order follows scope.** *View* moved to the top: it changes the whole app, not one panel. *About* moved to the bottom, where the least-used thing belongs. -**One section open at a time.** Seven panels in a fixed column pushed the useful -ones off-screen. They are `<details>` elements now — native disclosure, keyboard and -screen-reader behaviour for free — with a toggle handler closing the others. The -Selected panel opens itself when the selection changes, or the accordion would hide -the very thing just clicked. +**Foldable sections.** Seven panels in a fixed column pushed the useful ones +off-screen. They are `<details>` elements now — native disclosure, keyboard and +screen-reader behaviour for free. *This first shipped as an accordion, one open at a +time, with the Selected panel opening itself on selection; both were removed — see +D-032.* **Mode gating moved from a CSS class to the `hidden` property**, since `<details>` already carries open/closed state and stacking a `.hidden` class on top of it was a @@ -959,3 +959,26 @@ with links to design.md and decisions.md. Those documents are the author's worki notes on an unpublished novel, not a public invitation, and the links went to a repo a reader may not have. Now it says what is true and no more: *Tower is the setting of a novel. This map is its companion piece.* + +--- + +## D-032 — No automatic opening or closing + +**Reverted at the author's request:** the accordion was annoying, and nothing should +open or close by itself. + +**The two behaviours were one mistake.** Exclusive opening meant that clicking a +place could collapse the panel about to describe it, so the Selected panel had to +open itself to compensate. Removing the accordion removed the need for the +compensation: sections the author opens stay open, so a selection simply appears in +a panel that is already there. A workaround that only exists to undo another +behaviour is a sign the first behaviour is wrong. + +**What remains is state, not behaviour.** View and World start open, and Selected +starts open but stays hidden until something is selected — so the first selection +shows without anything having moved. After that the panels are wherever the author +put them: closing the editor keeps it closed through every later selection. + +**The general rule this is worth remembering by:** an interface that rearranges +itself in response to a click costs the user their place. Prefer a sensible initial +state and then hold still. diff --git a/index.html b/index.html index 1c4622e..b040c28 100644 --- a/index.html +++ b/index.html @@ -50,19 +50,19 @@ <p class="hint" id="tool-hint">Click a marker to select. Drag to move. Shift-click two points to measure a sightline.</p> </details> - <details class="sec" id="world-section"> + <details class="sec" id="world-section" open> <summary>World <span id="counts" class="dim"></span></summary> <ul id="list" class="list"></ul> </details> - <details class="sec" id="detail" hidden> + <details class="sec" id="detail" hidden open> <summary>Selected</summary> <p id="d-name"></p> <p id="d-blurb" class="dim"></p> <p id="d-where" class="dim"></p> </details> - <details class="sec" id="editor" hidden> + <details class="sec" id="editor" hidden open> <summary>Selected</summary> <label>Name <input id="f-name" type="text" /></label> <label>Kind <select id="f-kind"></select></label> diff --git a/src/ui/app.ts b/src/ui/app.ts index 50e8873..7fd1f06 100644 --- a/src/ui/app.ts +++ b/src/ui/app.ts @@ -64,7 +64,6 @@ export class App { private readonly writer = !new URLSearchParams(location.search).has('reader') private tool: Tool = 'select' private selectedId: string | null = null - private lastShownId: string | null = null private draft: [number, number][] = [] private probeFrom: SurfacePoint | null = null @@ -74,7 +73,6 @@ export class App { onDragPlace: (id, p) => this.onDragPlace(id, p), onHover: (p) => this.onHover(p), }) - this.wireSections() this.buildViews() this.buildTools() this.buildKindSelect() @@ -98,28 +96,6 @@ export class App { void this.setView(this.initialView()) } - // -------------------------------------------------------------- sections - - /** - * Accordion: opening one section closes the rest. The sidebar carries seven - * panels and the map is the point of the page, so at most one should be eating - * vertical space at a time. - */ - private wireSections(): void { - const all = [...document.querySelectorAll<HTMLDetailsElement>('aside details.sec')] - for (const d of all) { - d.addEventListener('toggle', () => { - if (!d.open) return - for (const other of all) if (other !== d) other.open = false - }) - } - } - - private openSection(id: string): void { - const el = $<HTMLDetailsElement>(id) - if (!el.open) el.open = true - } - // ----------------------------------------------------------------- views /** @@ -623,15 +599,6 @@ export class App { const detail = $<HTMLDetailsElement>('detail') const p = this.selectedId ? this.store.get(this.selectedId) : undefined - // Reveal the panel when the selection changes, or the accordion hides the very - // thing that was just clicked. - if (p && p.id !== this.lastShownId) { - this.lastShownId = p.id - queueMicrotask(() => this.openSection(this.writer ? 'editor' : 'detail')) - } else if (!p) { - this.lastShownId = null - } - // Readers get a read-only card. Without this branch renderEditor would happily // un-hide the edit panel — including the private notes field — for everyone. if (!this.writer) {