From 919998be1c9c07a3f042257243e8c435958426ff Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 14 Mar 2026 11:11:49 +0000 Subject: [PATCH] Move SX app CSS and init behavior from Python to init.sx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Styles (indicator, jiggle animation) and nav aria-selected behavior were inline Python strings in sx/app.py. Now they live in sx/sx/init.sx as proper SX source — styles via collect! "cssx", nav via dom-listen. The shell's inline_css is empty; CSSX handles style injection on boot. Co-Authored-By: Claude Opus 4.6 (1M context) --- sx/app.py | 27 +++++++-------------------- sx/sx/init.sx | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 sx/sx/init.sx diff --git a/sx/app.py b/sx/app.py index fcbedc9..12cb008 100644 --- a/sx/app.py +++ b/sx/app.py @@ -69,30 +69,17 @@ def create_app() -> "Quart": # Minimal shell — no Prism, no SweetAlert, no body.js # sx docs uses custom highlight.py, not Prism; body.js is for legacy apps + # Load init SX from file — styles + nav behavior, no inline Python strings + import os as _os + _init_path = _os.path.join(_os.path.dirname(__file__), "sx", "init.sx") + with open(_init_path) as _f: + _init_sx = _f.read() app.config["SX_SHELL"] = { "head_scripts": [], # no CDN scripts "body_scripts": [], # no body.js "inline_head_js": "", # no pre-boot JS (hover-capable, close-details unused) - "inline_css": ( - ".sx-indicator{display:none}" - ".sx-request .sx-indicator{display:inline-flex}" - "@keyframes sxJiggle{0%,100%{transform:translateX(0)}" - "25%{transform:translateX(-.5px)}75%{transform:translateX(.5px)}}" - "a.sx-request{animation:sxJiggle .3s ease-in-out infinite}" - ), - # Nav link aria-selected update on client-side routing — pure SX - "init_sx": ( - '(dom-listen (dom-body) "sx:clientRoute"' - ' (fn (e)' - ' (let ((p (get (event-detail e) "pathname")))' - ' (when p' - ' (for-each' - ' (fn (a) (dom-set-attr a "aria-selected" "false"))' - ' (dom-query-all "nav a[aria-selected]"))' - ' (for-each' - ' (fn (a) (dom-set-attr a "aria-selected" "true"))' - ' (dom-query-all (str "nav a[href=\\"" p "\\"]")))))))' - ), + "inline_css": "", # styles injected via CSSX from init.sx + "init_sx": _init_sx, } app.url_map.strict_slashes = False diff --git a/sx/sx/init.sx b/sx/sx/init.sx new file mode 100644 index 0000000..6080ffa --- /dev/null +++ b/sx/sx/init.sx @@ -0,0 +1,24 @@ +;; --------------------------------------------------------------------------- +;; SX app boot — styles and behaviors injected on page load +;; +;; Replaces inline_css and init_sx from Python app config. +;; Called as a data-init script on every page. +;; --------------------------------------------------------------------------- + +;; Framework styles — request indicators + link jiggle +(collect! "cssx" ".sx-indicator{display:none}") +(collect! "cssx" ".sx-request .sx-indicator{display:inline-flex}") +(collect! "cssx" "@keyframes sxJiggle{0%,100%{transform:translateX(0)}25%{transform:translateX(-.5px)}75%{transform:translateX(.5px)}}") +(collect! "cssx" "a.sx-request{animation:sxJiggle .3s ease-in-out infinite}") + +;; Nav link aria-selected update on client-side routing +(dom-listen (dom-body) "sx:clientRoute" + (fn (e) + (let ((p (get (event-detail e) "pathname"))) + (when p + (for-each + (fn (a) (dom-set-attr a "aria-selected" "false")) + (dom-query-all "nav a[aria-selected]")) + (for-each + (fn (a) (dom-set-attr a "aria-selected" "true")) + (dom-query-all (str "nav a[href=\"" p "\"]")))))))