Add spread + collect primitives, rewrite ~cssx/tw as defcomp
New SX primitives for child-to-parent communication in the render tree: - spread type: make-spread, spread?, spread-attrs — child injects attrs onto parent element (class joins with space, style with semicolon) - collect!/collected/clear-collected! — render-time accumulation with dedup into named buckets ~cssx/tw is now a proper defcomp returning a spread value instead of a macro wrapping children. ~cssx/flush reads collected "cssx" rules and emits a single <style data-cssx> tag. All four render adapters (html, async, dom, aser) handle spread values. Both bootstraps (Python + JS) regenerated. Also fixes length→len in cssx.sx (length was never a registered primitive). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,9 @@
|
||||
;; Pre-rendered DOM node → pass through
|
||||
"dom-node" expr
|
||||
|
||||
;; Spread → pass through (parent element handles it)
|
||||
"spread" expr
|
||||
|
||||
;; Dict → empty
|
||||
"dict" (create-fragment)
|
||||
|
||||
@@ -221,10 +224,34 @@
|
||||
(dom-set-attr el attr-name (str attr-val)))))
|
||||
(assoc state "skip" true "i" (inc (get state "i"))))
|
||||
|
||||
;; Positional arg → child
|
||||
;; Positional arg → child (or spread → merge attrs onto element)
|
||||
(do
|
||||
(when (not (contains? VOID_ELEMENTS tag))
|
||||
(dom-append el (render-to-dom arg env new-ns)))
|
||||
(let ((child (render-to-dom arg env new-ns)))
|
||||
(if (spread? child)
|
||||
;; Spread: merge attrs onto parent element
|
||||
(for-each
|
||||
(fn ((key :as string))
|
||||
(let ((val (dict-get (spread-attrs child) key)))
|
||||
(if (= key "class")
|
||||
;; Class: append to existing
|
||||
(let ((existing (dom-get-attr el "class")))
|
||||
(dom-set-attr el "class"
|
||||
(if (and existing (not (= existing "")))
|
||||
(str existing " " val)
|
||||
val)))
|
||||
(if (= key "style")
|
||||
;; Style: append with semicolon
|
||||
(let ((existing (dom-get-attr el "style")))
|
||||
(dom-set-attr el "style"
|
||||
(if (and existing (not (= existing "")))
|
||||
(str existing ";" val)
|
||||
val)))
|
||||
;; Other attrs: overwrite
|
||||
(dom-set-attr el key (str val))))))
|
||||
(keys (spread-attrs child)))
|
||||
;; Normal child: append to element
|
||||
(dom-append el child))))
|
||||
(assoc state "i" (inc (get state "i"))))))))
|
||||
(dict "i" 0 "skip" false)
|
||||
args)
|
||||
|
||||
Reference in New Issue
Block a user