Nav redesign: embedded breadcrumb navigation with recursive depth
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m25s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m25s
Replace menu bar navigation with in-page nav embedded in content area. Each page shows logo/tagline/copyright, then a sibling row per trail level (← prev | Current | next →), then children as button links. - resolve-nav-path: recursive walk with no depth limit - find-nav-index: rewritten with recursion (set! broken across closures) - Walk stops on exact href match (prevents /cssx/ drilling into Overview) - Unicode chars (©, ←, →) inline instead of \u escapes (SX parser doesn't support them) - All 38 defpages wrapped in (~sx-doc :path ...) for in-page nav - Layout returns only root header (nav moved out of blue menu bar) - Standalone layout variants for sx-web.org (return nil) - New plans: environment-images, runtime-slicing, typed-sx, nav-redesign, sx-web-platform Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -169,6 +169,14 @@
|
||||
:summary "Prefetch missing component definitions before the user clicks — hover a link, fetch its deps, navigate client-side.")
|
||||
(dict :label "Content-Addressed Components" :href "/plans/content-addressed-components"
|
||||
:summary "Components identified by CID, stored on IPFS, fetched from anywhere. Canonical serialization, content verification, federated sharing.")
|
||||
(dict :label "Environment Images" :href "/plans/environment-images"
|
||||
:summary "Serialize evaluated environments as content-addressed images. Spec CID → image CID → every endpoint is fully executable and verifiable.")
|
||||
(dict :label "Runtime Slicing" :href "/plans/runtime-slicing"
|
||||
:summary "Tier the client runtime by need: L0 hypermedia (~5KB), L1 DOM ops (~8KB), L2 islands (~15KB), L3 full eval (~44KB). Sliced by slice.sx, translated by js.sx.")
|
||||
(dict :label "Typed SX" :href "/plans/typed-sx"
|
||||
:summary "Gradual type system for SX. Optional annotations, checked at registration time, zero runtime cost. types.sx — specced, bootstrapped, catches composition errors.")
|
||||
(dict :label "Nav Redesign" :href "/plans/nav-redesign"
|
||||
:summary "Replace menu bars with vertical breadcrumb navigation. Logo → section → page, arrows for siblings, children below. No dropdowns, no hamburger, infinite depth.")
|
||||
(dict :label "Fragment Protocol" :href "/plans/fragment-protocol"
|
||||
:summary "Structured sexp request/response for cross-service component transfer.")
|
||||
(dict :label "Glue Decoupling" :href "/plans/glue-decoupling"
|
||||
@@ -178,7 +186,9 @@
|
||||
(dict :label "SX CI Pipeline" :href "/plans/sx-ci"
|
||||
:summary "Build, test, and deploy in s-expressions — CI pipelines as SX components.")
|
||||
(dict :label "Live Streaming" :href "/plans/live-streaming"
|
||||
:summary "SSE and WebSocket transports for re-resolving suspense slots after initial page load — live data, real-time collaboration.")))
|
||||
:summary "SSE and WebSocket transports for re-resolving suspense slots after initial page load — live data, real-time collaboration.")
|
||||
(dict :label "sx-web Platform" :href "/plans/sx-web-platform"
|
||||
:summary "sx-web.org as online development platform — embedded Claude Code, IPFS storage, sx-activity publishing, sx-ci testing. Author, stage, test, deploy from the browser.")))
|
||||
|
||||
(define reactive-islands-nav-items (list
|
||||
(dict :label "Overview" :href "/reactive-islands/"
|
||||
@@ -281,6 +291,7 @@
|
||||
|
||||
;; Generic section nav — builds nav links from a list of items.
|
||||
;; Replaces _nav_items_sx() and all section-specific nav builders in utils.py.
|
||||
;; KEPT for backward compat with other apps — SX docs uses ~nav-list instead.
|
||||
(defcomp ~section-nav (&key items current)
|
||||
(<> (map (fn (item)
|
||||
(~nav-link
|
||||
@@ -289,3 +300,88 @@
|
||||
:is-selected (when (= (get item "label") current) "true")
|
||||
:select-colours "aria-selected:bg-violet-200 aria-selected:text-violet-900"))
|
||||
items)))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Nav tree — hierarchical navigation for SX docs
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(define sx-nav-tree
|
||||
{:label "sx" :href "/"
|
||||
:children (list
|
||||
{:label "Docs" :href "/docs/" :children docs-nav-items}
|
||||
{:label "CSSX" :href "/cssx/" :children cssx-nav-items}
|
||||
{:label "Reference" :href "/reference/" :children reference-nav-items}
|
||||
{:label "Protocols" :href "/protocols/" :children protocols-nav-items}
|
||||
{:label "Examples" :href "/examples/" :children examples-nav-items}
|
||||
{:label "Essays" :href "/essays/" :children essays-nav-items}
|
||||
{:label "Philosophy" :href "/philosophy/" :children philosophy-nav-items}
|
||||
{:label "Specs" :href "/specs/" :children specs-nav-items}
|
||||
{:label "Bootstrappers" :href "/bootstrappers/" :children bootstrappers-nav-items}
|
||||
{:label "Testing" :href "/testing/" :children testing-nav-items}
|
||||
{:label "Isomorphism" :href "/isomorphism/" :children isomorphism-nav-items}
|
||||
{:label "Plans" :href "/plans/" :children plans-nav-items}
|
||||
{:label "Reactive Islands" :href "/reactive-islands/" :children reactive-islands-nav-items})})
|
||||
|
||||
;; Resolve a URL path to a nav trail + children.
|
||||
;; Returns {:trail [{:node N :siblings S} ...] :children [...] :depth N}
|
||||
;; Trail is from outermost selected ancestor to deepest.
|
||||
(define resolve-nav-path
|
||||
(fn (tree path)
|
||||
(let ((trail (list)))
|
||||
(define walk
|
||||
(fn (node)
|
||||
(let ((children (get node "children")))
|
||||
(when children
|
||||
(let ((match (find-nav-match children path)))
|
||||
(when match
|
||||
(append! trail {:node match :siblings children})
|
||||
;; Only recurse deeper if this wasn't an exact match
|
||||
;; (exact match = we found our target, stop)
|
||||
(when (not (= (get match "href") path))
|
||||
(walk match))))))))
|
||||
(walk tree)
|
||||
(let ((depth (len trail)))
|
||||
(if (= depth 0)
|
||||
{:trail trail :children (get tree "children") :depth 0}
|
||||
(let ((deepest (nth trail (- depth 1))))
|
||||
{:trail trail
|
||||
:children (get (get deepest "node") "children")
|
||||
:depth depth}))))))
|
||||
|
||||
;; Find a nav item whose href matches the given path (or path prefix).
|
||||
(define find-nav-match
|
||||
(fn (items path)
|
||||
;; Exact match first
|
||||
(or (some (fn (item)
|
||||
(when (= (get item "href") path) item))
|
||||
items)
|
||||
;; Prefix match: path starts with item href (for /plans/typed-sx matching /plans/)
|
||||
(some (fn (item)
|
||||
(let ((href (get item "href")))
|
||||
(when (and (ends-with? href "/")
|
||||
(starts-with? path href))
|
||||
item)))
|
||||
items)
|
||||
;; Path contains section: /plans/typed-sx matches section with /plans/ children
|
||||
(some (fn (item)
|
||||
(let ((children (get item "children")))
|
||||
(when children
|
||||
(when (some (fn (child)
|
||||
(= (get child "href") path))
|
||||
children)
|
||||
item))))
|
||||
items))))
|
||||
|
||||
;; Find the index of a nav item in a list by matching href.
|
||||
(define find-nav-index
|
||||
(fn (items node)
|
||||
(let ((target-href (get node "href"))
|
||||
(count (len items)))
|
||||
(define find-loop
|
||||
(fn (i)
|
||||
(if (>= i count)
|
||||
0
|
||||
(if (= (get (nth items i) "href") target-href)
|
||||
i
|
||||
(find-loop (+ i 1))))))
|
||||
(find-loop 0))))
|
||||
|
||||
Reference in New Issue
Block a user