docs(ui): drop sidebar saved-state — server defaults already ARE the standard docs behavior
Simplification per spec: the menu tracks state through the URL alone. Land on /docs: fully closed, headers only (an explicit home rule now overrides the contains-URL rule, since the root overview doc lives in Getting Started and would otherwise auto-open it). Land on any doc page: its containing section + group render open at first paint, current link bold — no JS, no jump, arrows consistent. Navigate elsewhere: old closes, new opens. Deleted: docs_nav cookie const/parse, ApplyNavOverrides, cookie write + collect/persist helpers in web/src/docs.ts, data-key attributes in the sidebar templ, and the first-section-open fallback (docs home used to force-open the first section — spec'd as closed). toggleCollapsible remains for in-page peeking; purely ephemeral. The [data-collapsed=true] CSS from the previous round stays — it is what makes the server-rendered state actually hide sections at paint (the original bug was that this CSS never existed). Tests: TestBuildNavigationNothingCurrent now asserts zero sections open on unmatched paths; TestBuildNavigation asserts Getting Started closed on a device page (no site-wide pin). make test green; 146 vitests; live verified: home 0 expanded, doc pages exactly 2 (section+group).
This commit is contained in:
1 parent
a8f8c4def9
commit
73e8cdef4b
6 files changed
+155
-272
No files matched your search
@@ -2,10 +2,8 @@ package docs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"bookhoard/internal/database"
|
||||
@@ -48,37 +46,10 @@ func (h *HTTPHandler) currentUser(c *echo.Context) templates.User {
|
||||
return templates.User{Theme: "tokyo-night"}
|
||||
}
|
||||
|
||||
// docsNavCookie is the browser-saved collapse state of the docs sidebar
|
||||
// (set by web/src/docs.ts on every toggle). Strictly-necessary UI state:
|
||||
// first-party, no identifiers, lets the server render the sidebar in the
|
||||
// visitor's chosen state so there is no post-paint jump.
|
||||
const docsNavCookie = "docs_nav"
|
||||
|
||||
// docsNavOverrides reads the saved collapse state from the cookie.
|
||||
// Keys are the sidebar's data-key values ("Section", "Section / Group");
|
||||
// values are the collapsed flag. Malformed cookies are ignored — the
|
||||
// server-rendered defaults win.
|
||||
func docsNavOverrides(c *echo.Context) map[string]bool {
|
||||
cookie, err := c.Cookie(docsNavCookie)
|
||||
if err != nil || cookie.Value == "" {
|
||||
return nil
|
||||
}
|
||||
raw, err := url.QueryUnescape(cookie.Value)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var overrides map[string]bool
|
||||
if err := json.Unmarshal([]byte(raw), &overrides); err != nil {
|
||||
return nil
|
||||
}
|
||||
return overrides
|
||||
}
|
||||
|
||||
// renderDocPage renders a document inside the docs layout.
|
||||
func (h *HTTPHandler) renderDocPage(c *echo.Context, doc *templates.Document) error {
|
||||
currentPath := c.Request().URL.Path
|
||||
nav := h.docs.BuildNavigation(currentPath)
|
||||
ApplyNavOverrides(nav, docsNavOverrides(c))
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := templates.DocsLayout(*nav, *doc, h.currentUser(c), currentPath).Render(c.Request().Context(), &buf); err != nil {
|
||||
|
||||
Reference in new issue
Block a user