Update reference docs: fix event names, add demos, document sx-boost target
- Remove sx:afterSettle (not dispatched), rename sx:sendError → sx:requestError - Add sx:clientRoute event (Phase 3 client-side routing) - Add working demos for all 10 events (afterRequest, afterSwap, requestError, clientRoute, sseOpen, sseMessage, sseError were missing demos) - Update sx-boost docs: configurable target selector, client routing behavior - Remove app-specific nav logic from orchestration.sx, use sx:clientRoute event - Pass page content deps to sx_response for component loading after server fallback Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -424,7 +424,8 @@
|
||||
:class "text-violet-600 hover:text-violet-800 underline text-sm"
|
||||
"sx-target"))
|
||||
(p :class "text-xs text-stone-400"
|
||||
"These links use AJAX navigation via sx-boost — no sx-get needed on each link.")))
|
||||
"These links use AJAX navigation via sx-boost — no sx-get needed on each link. "
|
||||
"Set the value to a CSS selector (e.g. sx-boost=\"#main-panel\") to configure the default swap target for all descendants.")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; sx-preload
|
||||
@@ -727,19 +728,42 @@
|
||||
"Request is cancelled via preventDefault() if the input is empty.")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; sx:afterSettle event demo
|
||||
;; sx:afterRequest event demo
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~ref-event-after-settle-demo ()
|
||||
(defcomp ~ref-event-after-request-demo ()
|
||||
(div :class "space-y-3"
|
||||
(button
|
||||
:sx-get "/reference/api/time"
|
||||
:sx-target "#ref-evt-ar-result"
|
||||
:sx-swap "innerHTML"
|
||||
:sx-on:sx:afterRequest "document.getElementById('ref-evt-ar-log').textContent = 'Response status: ' + (event.detail ? event.detail.status : '?')"
|
||||
:class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
|
||||
"Load (logs after response)")
|
||||
(div :id "ref-evt-ar-log"
|
||||
:class "p-2 rounded bg-emerald-50 text-emerald-700 text-sm"
|
||||
"Event log will appear here.")
|
||||
(div :id "ref-evt-ar-result"
|
||||
:class "p-3 rounded bg-stone-100 text-stone-400 text-sm"
|
||||
"Click to load — afterRequest fires before the swap.")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; sx:afterSwap event demo
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~ref-event-after-swap-demo ()
|
||||
(div :class "space-y-3"
|
||||
(button
|
||||
:sx-get "/reference/api/swap-item"
|
||||
:sx-target "#ref-evt-settle-list"
|
||||
:sx-target "#ref-evt-as-list"
|
||||
:sx-swap "beforeend"
|
||||
:sx-on:sx:afterSettle "var items = document.querySelectorAll('#ref-evt-settle-list > div'); if (items.length) items[items.length-1].scrollIntoView({behavior:'smooth'})"
|
||||
:sx-on:sx:afterSwap "var items = document.querySelectorAll('#ref-evt-as-list > div'); if (items.length) items[items.length-1].scrollIntoView({behavior:'smooth'}); document.getElementById('ref-evt-as-count').textContent = items.length + ' items'"
|
||||
:class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
|
||||
"Add item (scrolls after settle)")
|
||||
(div :id "ref-evt-settle-list"
|
||||
"Add item (scrolls after swap)")
|
||||
(div :id "ref-evt-as-count"
|
||||
:class "text-sm text-emerald-700"
|
||||
"1 items")
|
||||
(div :id "ref-evt-as-list"
|
||||
:class "p-3 rounded border border-stone-200 space-y-1 max-h-32 overflow-y-auto"
|
||||
(div :class "text-sm text-stone-500" "Items will be appended and scrolled into view."))))
|
||||
|
||||
@@ -791,3 +815,102 @@
|
||||
(div :id "ref-evt-vf-result"
|
||||
:class "p-3 rounded bg-stone-100 text-stone-400 text-sm"
|
||||
"Submit with empty/invalid email to trigger the event.")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; sx:requestError event demo
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~ref-event-request-error-demo ()
|
||||
(div :class "space-y-3"
|
||||
(button
|
||||
:sx-get "https://this-domain-does-not-exist.invalid/api"
|
||||
:sx-target "#ref-evt-re-result"
|
||||
:sx-swap "innerHTML"
|
||||
:sx-on:sx:requestError "document.getElementById('ref-evt-re-status').style.display = 'block'; document.getElementById('ref-evt-re-status').textContent = 'Network error — request never reached a server'"
|
||||
:class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
|
||||
"Request invalid domain")
|
||||
(div :id "ref-evt-re-status"
|
||||
:class "p-2 rounded bg-red-50 text-red-600 text-sm"
|
||||
:style "display: none"
|
||||
"")
|
||||
(div :id "ref-evt-re-result"
|
||||
:class "p-3 rounded bg-stone-100 text-stone-400 text-sm"
|
||||
"Click to trigger a network error — sx:requestError fires.")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; sx:clientRoute event demo
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~ref-event-client-route-demo ()
|
||||
(div :class "space-y-3"
|
||||
(p :class "text-sm text-stone-600"
|
||||
"Open DevTools console, then navigate to a pure page (no :data expression). "
|
||||
"You'll see \"sx:route client /path\" in the console — no network request is made.")
|
||||
(div :class "flex gap-2 flex-wrap"
|
||||
(a :href "/essays/"
|
||||
:class "px-3 py-1 bg-violet-100 text-violet-700 rounded text-sm no-underline hover:bg-violet-200"
|
||||
"Essays")
|
||||
(a :href "/plans/"
|
||||
:class "px-3 py-1 bg-violet-100 text-violet-700 rounded text-sm no-underline hover:bg-violet-200"
|
||||
"Plans")
|
||||
(a :href "/protocols/"
|
||||
:class "px-3 py-1 bg-violet-100 text-violet-700 rounded text-sm no-underline hover:bg-violet-200"
|
||||
"Protocols"))
|
||||
(p :class "text-xs text-stone-400"
|
||||
"The sx:clientRoute event fires on the swap target and bubbles to document.body. "
|
||||
"Apps use it to update nav selection, analytics, or other post-navigation state.")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; sx:sseOpen event demo
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~ref-event-sse-open-demo ()
|
||||
(div :class "space-y-3"
|
||||
(div :sx-sse "/reference/api/sse-time"
|
||||
:sx-sse-swap "time"
|
||||
:sx-swap "innerHTML"
|
||||
:sx-on:sx:sseOpen "document.getElementById('ref-evt-sseopen-status').textContent = 'Connected'; document.getElementById('ref-evt-sseopen-status').className = 'inline-block px-2 py-0.5 rounded text-xs bg-emerald-100 text-emerald-700'"
|
||||
(div :class "flex items-center gap-3"
|
||||
(span :id "ref-evt-sseopen-status"
|
||||
:class "inline-block px-2 py-0.5 rounded text-xs bg-amber-100 text-amber-700"
|
||||
"Connecting...")
|
||||
(span :class "text-sm text-stone-500" "SSE stream")))
|
||||
(p :class "text-xs text-stone-400"
|
||||
"The status badge turns green when the SSE connection opens.")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; sx:sseMessage event demo
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~ref-event-sse-message-demo ()
|
||||
(div :class "space-y-3"
|
||||
(div :sx-sse "/reference/api/sse-time"
|
||||
:sx-sse-swap "time"
|
||||
:sx-swap "innerHTML"
|
||||
:sx-on:sx:sseMessage "var c = parseInt(document.getElementById('ref-evt-ssemsg-count').dataset.count || '0') + 1; document.getElementById('ref-evt-ssemsg-count').dataset.count = c; document.getElementById('ref-evt-ssemsg-count').textContent = c + ' messages received'"
|
||||
(div :id "ref-evt-ssemsg-output"
|
||||
:class "p-3 rounded bg-stone-100 text-stone-600 text-sm font-mono"
|
||||
"Waiting for SSE messages..."))
|
||||
(div :id "ref-evt-ssemsg-count"
|
||||
:class "text-sm text-emerald-700"
|
||||
:data-count "0"
|
||||
"0 messages received")))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; sx:sseError event demo
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
(defcomp ~ref-event-sse-error-demo ()
|
||||
(div :class "space-y-3"
|
||||
(div :sx-sse "/reference/api/sse-time"
|
||||
:sx-sse-swap "time"
|
||||
:sx-swap "innerHTML"
|
||||
:sx-on:sx:sseError "document.getElementById('ref-evt-sseerr-status').textContent = 'Disconnected'; document.getElementById('ref-evt-sseerr-status').className = 'inline-block px-2 py-0.5 rounded text-xs bg-red-100 text-red-700'"
|
||||
:sx-on:sx:sseOpen "document.getElementById('ref-evt-sseerr-status').textContent = 'Connected'; document.getElementById('ref-evt-sseerr-status').className = 'inline-block px-2 py-0.5 rounded text-xs bg-emerald-100 text-emerald-700'"
|
||||
(div :class "flex items-center gap-3"
|
||||
(span :id "ref-evt-sseerr-status"
|
||||
:class "inline-block px-2 py-0.5 rounded text-xs bg-amber-100 text-amber-700"
|
||||
"Connecting...")
|
||||
(span :class "text-sm text-stone-500" "SSE stream")))
|
||||
(p :class "text-xs text-stone-400"
|
||||
"If the SSE connection drops, the badge turns red via sx:sseError.")))
|
||||
|
||||
Reference in New Issue
Block a user