Fix stepper client-side [object Object] flash and missing CSSX styles
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m54s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m54s
Three issues in the stepper island's client-side rendering: 1. do-step used eval-expr with empty env for ~cssx/tw spreads — component not found, result leaked as [object Object]. Fixed: call ~cssx/tw directly (in scope from island env) with trampoline. 2. steps-to-preview excluded spreads — SSR preview had no styling. Fixed: include spreads in the tree so both SSR and client render with CSSX classes. 3. build-children used named let (let loop ...) which produces unresolved Thunks in render mode due to the named-let compiler desugaring interacting with the render/eval boundary. Fixed: rewrote as plain recursive function bc-loop avoiding named let. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -103,39 +103,38 @@
|
||||
(let ((pos (dict "i" 0))
|
||||
(max-i (min target (len all-steps))))
|
||||
(letrec
|
||||
((build-children (fn ()
|
||||
(let ((children (list)))
|
||||
(let loop ()
|
||||
(if (>= (get pos "i") max-i)
|
||||
children
|
||||
(let ((step (nth all-steps (get pos "i")))
|
||||
(stype (get step "type")))
|
||||
(cond
|
||||
(= stype "open")
|
||||
(do
|
||||
(dict-set! pos "i" (+ (get pos "i") 1))
|
||||
(let ((tag (get step "tag"))
|
||||
(attrs (or (get step "attrs") (list)))
|
||||
(spreads (or (get step "spreads") (list)))
|
||||
(inner (build-children)))
|
||||
(append! children
|
||||
(concat (list (make-symbol tag)) spreads attrs inner)))
|
||||
(loop))
|
||||
(= stype "close")
|
||||
(do (dict-set! pos "i" (+ (get pos "i") 1))
|
||||
children)
|
||||
(= stype "leaf")
|
||||
(do (dict-set! pos "i" (+ (get pos "i") 1))
|
||||
(append! children (get step "expr"))
|
||||
(loop))
|
||||
(= stype "expr")
|
||||
(do (dict-set! pos "i" (+ (get pos "i") 1))
|
||||
(append! children (get step "expr"))
|
||||
(loop))
|
||||
:else
|
||||
(do (dict-set! pos "i" (+ (get pos "i") 1))
|
||||
(loop))))))))))
|
||||
(let ((root (build-children)))
|
||||
((bc-loop (fn (children)
|
||||
(if (>= (get pos "i") max-i)
|
||||
children
|
||||
(let ((step (nth all-steps (get pos "i")))
|
||||
(stype (get step "type")))
|
||||
(cond
|
||||
(= stype "open")
|
||||
(do
|
||||
(dict-set! pos "i" (+ (get pos "i") 1))
|
||||
(let ((tag (get step "tag"))
|
||||
(attrs (or (get step "attrs") (list)))
|
||||
(spreads (or (get step "spreads") (list)))
|
||||
(inner (bc-loop (list))))
|
||||
(append! children
|
||||
(concat (list (make-symbol tag)) spreads attrs inner)))
|
||||
(bc-loop children))
|
||||
(= stype "close")
|
||||
(do (dict-set! pos "i" (+ (get pos "i") 1))
|
||||
children)
|
||||
(= stype "leaf")
|
||||
(do (dict-set! pos "i" (+ (get pos "i") 1))
|
||||
(append! children (get step "expr"))
|
||||
(bc-loop children))
|
||||
(= stype "expr")
|
||||
(do (dict-set! pos "i" (+ (get pos "i") 1))
|
||||
(append! children (get step "expr"))
|
||||
(bc-loop children))
|
||||
:else
|
||||
(do (dict-set! pos "i" (+ (get pos "i") 1))
|
||||
(bc-loop children))))))))
|
||||
|
||||
(let ((root (bc-loop (list))))
|
||||
(cond
|
||||
(= (len root) 1) (first root)
|
||||
(empty? root) nil
|
||||
@@ -194,16 +193,21 @@
|
||||
(when (< i (len attrs))
|
||||
(dom-set-attr el (keyword-name (nth attrs i)) (nth attrs (+ i 1)))
|
||||
(loop (+ i 2))))
|
||||
;; Evaluate spreads via ~cssx/tw (in scope from island env)
|
||||
(for-each (fn (sp)
|
||||
(let ((result (eval-expr sp (make-env))))
|
||||
(when (and result (spread? result))
|
||||
(let ((sattrs (spread-attrs result)))
|
||||
(for-each (fn (k)
|
||||
(if (= k "class")
|
||||
(dom-set-attr el "class"
|
||||
(str (or (dom-get-attr el "class") "") " " (get sattrs k)))
|
||||
(dom-set-attr el k (get sattrs k))))
|
||||
(keys sattrs))))))
|
||||
(when (and (list? sp) (>= (len sp) 3)
|
||||
(= (type-of (nth sp 1)) "keyword")
|
||||
(= (keyword-name (nth sp 1)) "tokens")
|
||||
(string? (nth sp 2)))
|
||||
(let ((result (trampoline (~cssx/tw :tokens (nth sp 2)))))
|
||||
(when (spread? result)
|
||||
(let ((sattrs (spread-attrs result)))
|
||||
(for-each (fn (k)
|
||||
(if (= k "class")
|
||||
(dom-set-attr el "class"
|
||||
(str (or (dom-get-attr el "class") "") " " (get sattrs k)))
|
||||
(dom-set-attr el k (get sattrs k))))
|
||||
(keys sattrs)))))))
|
||||
spreads)
|
||||
(when parent (dom-append parent el))
|
||||
(push-stack el))
|
||||
@@ -214,9 +218,8 @@
|
||||
(let ((val (get step "expr")))
|
||||
(dom-append parent (create-text-node (if (string? val) val (str val))))))
|
||||
(= step-type "expr")
|
||||
(let ((rendered (render-to-dom (get step "expr") (make-env) nil)))
|
||||
(when (and parent rendered)
|
||||
(dom-append parent rendered)))))
|
||||
;; Component expressions handled by lake's reactive render
|
||||
nil))
|
||||
(swap! step-idx inc)
|
||||
(update-code-highlight)
|
||||
(set-cookie "sx-home-stepper" (freeze-to-sx "home-stepper")))))
|
||||
@@ -255,10 +258,11 @@
|
||||
(build-code-dom)
|
||||
(let ((preview (get-preview)))
|
||||
(when preview (dom-set-prop preview "innerHTML" "")))
|
||||
(let ((target (deref step-idx)))
|
||||
(reset! step-idx 0)
|
||||
(set-stack (list (get-preview)))
|
||||
(for-each (fn (_) (do-step)) (slice (deref steps) 0 target)))
|
||||
(batch (fn ()
|
||||
(let ((target (deref step-idx)))
|
||||
(reset! step-idx 0)
|
||||
(set-stack (list (get-preview)))
|
||||
(for-each (fn (_) (do-step)) (slice (deref steps) 0 target)))))
|
||||
(update-code-highlight)
|
||||
(run-post-render-hooks)))))))
|
||||
(div :class "space-y-4"
|
||||
|
||||
Reference in New Issue
Block a user