From b056469be1c01034b19d0bf6d9c4b58ff48a7fef Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 1 Jul 2026 10:15:30 +0000 Subject: [PATCH] host: block editor renders ANY composition node (no more "(unknown block)") MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The block editor assumed cards-as-objects leaves (ref/alt-with-refs/each-with-ref), so a hand-authored composition (the compose-demo: text/row/alt-with-text/each-with-inline) fell through to "(unknown block)" for every text/row node. Now every node kind gets a labelled row + preview + move/remove controls: card (✎ chip), text (its content), layout (row/grid + item count), field, group, and a graceful "other". Conditionals/repeaters display each branch via host/blog--node-display (a ref → ✎ chip, else the inline text/summary) instead of assuming a ref. host/blog--node-kind extended (text/layout/field/group); +node-display/+branch-display. TEST-FIRST: a mixed body (text + alt-with-text + row + each-with-inline) asserts the editor has NO "unknown block" and labels text/layout/for-each. RED before, GREEN after. blog 171/171. Co-Authored-By: Claude Opus 4.8 --- lib/host/blog.sx | 45 ++++++++++++++++++++++++++++++++---------- lib/host/tests/blog.sx | 15 ++++++++++++++ 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/lib/host/blog.sx b/lib/host/blog.sx index 24cae789..419a0588 100644 --- a/lib/host/blog.sx +++ b/lib/host/blog.sx @@ -776,8 +776,31 @@ (fn (node) (if (= (type-of node) "list") (let ((h (str (first node)))) - (cond ((= h "ref") "card") ((= h "alt") "cond") ((= h "each") "each") (else "other"))) + (cond + ((= h "ref") "card") ((= h "alt") "cond") ((= h "each") "each") + ((= h "text") "text") + ((or (= h "row") (= h "grid")) "layout") + ((or (= h "field") (= h "val")) "field") + ((= h "seq") "group") + (else "other"))) "other"))) +;; a short human display of ANY composition node — for the editor rows. A ref becomes a +;; ✎ edit-chip; text/field/val show their content; a container shows its item count. +(define host/blog--node-display + (fn (slug node) + (if (= (type-of node) "list") + (let ((h (str (first node)))) + (cond + ((= h "ref") (host/blog--ref-chip slug (str (first (rest node))))) + ((= h "text") (let ((t (str (first (rest node))))) (if (> (len t) 50) (str (substr t 0 50) "…") t))) + ((or (= h "field") (= h "val")) (str h " " (str (first (rest node))))) + ((or (= h "seq") (= h "row") (= h "grid")) (str h " (" (len (rest node)) ")")) + (else h))) + (str node)))) +;; the display of a conditional/repeater BRANCH — its last element (a ref, text, or group). +(define host/blog--branch-display + (fn (slug branch) + (host/blog--node-display slug (host/blog--nth branch (- (len branch) 1))))) ;; every ref slug a node (transitively) contains — for `contains`-edge cleanup on remove. (define host/blog--node-refs (fn (node) @@ -1587,27 +1610,29 @@ (let ((kind (host/blog--node-kind node)) (rs "display:flex;gap:0.5em;align-items:center;border:1px solid #ddd;padding:0.4em;margin:0.2em 0")) (cond - ((= kind "card") - (quasiquote (li :style (unquote rs) - (b :style "min-width:5em" "card") - (span :style "flex:1" (unquote (host/blog--ref-chip slug (str (first (rest node)))))) - (unquote (host/blog--block-ctrls slug idx))))) + ;; CONDITIONAL: the condition