feat(docs): standalone docs site chrome + category/subcategory navigation
Docs pages no longer embed the app Header (whose hx-post login form silently degraded to a native GET, leaking credentials into the URL — this page never loaded htmx). New docs-owned topbar: search, theme picker, Open App; anonymous visitors get a plain /login link. Optional-auth middleware (hand-rolled — echojwt's ErrorHandler return ends the chain, producing empty 200s) populates the user for signed-in visitors. Navigation rebuilt from the docs directory tree: 6 sections, subcategory groups, server-rendered expansion and active states. Search results are a templ partial (/docs/search/partial); code highlighting is server-side chroma (previously dead hljs CSS); prose is theme-aware via typography DEFAULT vars (prose-invert painted unreadable text under light themes). /docs renders the index directly; standalone 404 without the tailwind CDN. Tests: navigation routing/expansion (internal/docs), render pins asserting no login form/password field/app sidebar ever return on docs pages. lint-rendering: exempt *.test.ts fixtures (jsdom DOM building); docs.ts baseline 5 -> 1.
This commit is contained in:
1 parent
9d0ae2bcc4
commit
84cd6328f4
19 files changed
+2030
-1097
No files matched your search
+30
-1
@@ -6,9 +6,9 @@ import (
|
||||
"bookhoard/internal/utils"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -33,6 +33,35 @@ func navItemClass(current, target string) string {
|
||||
return base + "text-content-muted hover:text-content hover:bg-surface-hover"
|
||||
}
|
||||
|
||||
// docsNavClass returns classes for docs sidebar links (server-rendered active
|
||||
// state — there is no client-side highlighter). indent sets the left padding,
|
||||
// deeper for subcategory group items.
|
||||
func docsNavClass(current, target, indent string) string {
|
||||
base := "nav-item flex items-center " + indent + " pr-4 mr-2 py-1.5 rounded-lg text-sm transition-colors "
|
||||
if strings.TrimRight(current, "/") == strings.TrimRight(target, "/") {
|
||||
return base + "bg-brand/15 text-brand font-medium"
|
||||
}
|
||||
return base + "text-content-muted hover:text-content hover:bg-surface-hover"
|
||||
}
|
||||
|
||||
// collapsibleState renders the data-collapsed attribute value for a docs nav
|
||||
// items container; web/src/docs.ts toggles it on click.
|
||||
func collapsibleState(collapsed bool) string {
|
||||
if collapsed {
|
||||
return "true"
|
||||
}
|
||||
return "false"
|
||||
}
|
||||
|
||||
// chevronStyle pre-rotates a docs nav section/group chevron when collapsed
|
||||
// (quote-free value: templ double-escapes quotes in style attributes).
|
||||
func chevronStyle(collapsed bool) string {
|
||||
if collapsed {
|
||||
return "transform: rotate(-90deg);"
|
||||
}
|
||||
return "transform: rotate(0deg);"
|
||||
}
|
||||
|
||||
// themeCheckClass returns the class suffix for a theme option's checkmark
|
||||
// wrapper: empty for the active theme (visible), " hidden" otherwise. The
|
||||
// check element is always rendered so updateThemeIndicators() can move it
|
||||
|
||||
Reference in new issue
Block a user