Files
mono/market/sexp/detail.sexpr
giles f9d9697c67 Externalize sexp to .sexpr files + render() API
Replace all 676 inline sexp() string calls across 7 services with
render(component_name, **kwargs) calls backed by 46 external .sexpr
component definition files (587 defcomps total).

- Add render() function to shared/sexp/jinja_bridge.py
- Add load_service_components() helper and update load_sexp_dir() for *.sexpr
- Update parser keyword regex to support HTMX hx-on::event syntax
- Convert remaining inline HTML in route files to render() calls
- Add shared/sexp/templates/misc.sexp for cross-service utility components

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:14:58 +00:00

95 lines
4.1 KiB
Plaintext

;; Market product detail components
(defcomp ~market-detail-gallery-inner (&key like-html image alt labels-html brand)
(<> (raw! like-html)
(figure :class "inline-block"
(div :class "relative w-full aspect-square"
(img :data-main-img "" :src image :alt alt
:class "w-full h-full object-contain object-top" :loading "eager" :decoding "async")
(raw! labels-html))
(figcaption :class "mt-2 text-sm text-stone-600 text-center" brand))))
(defcomp ~market-detail-nav-buttons ()
(<>
(button :type "button" :data-prev ""
:class "absolute left-2 top-1/2 -translate-y-1/2 z-10 grid place-items-center w-12 h-12 md:w-14 md:h-14 rounded-full bg-white/90 hover:bg-white shadow-lg text-3xl md:text-4xl"
:title "Previous" "\u2039")
(button :type "button" :data-next ""
:class "absolute right-2 top-1/2 -translate-y-1/2 z-10 grid place-items-center w-12 h-12 md:w-14 md:h-14 rounded-full bg-white/90 hover:bg-white shadow-lg text-3xl md:text-4xl"
:title "Next" "\u203a")))
(defcomp ~market-detail-gallery (&key inner-html nav-html)
(div :class "relative rounded-xl overflow-hidden bg-stone-100"
(raw! inner-html) (raw! nav-html)))
(defcomp ~market-detail-thumb (&key title src alt)
(<> (button :type "button" :data-thumb ""
:class "shrink-0 rounded-lg overflow-hidden bg-stone-100 hover:opacity-90 ring-offset-2"
:title title
(img :src src :class "h-16 w-16 object-contain" :alt alt :loading "lazy" :decoding "async"))
(span :data-image-src src :class "hidden")))
(defcomp ~market-detail-thumbs (&key thumbs-html)
(div :class "flex flex-row justify-center"
(div :class "mt-3 flex gap-2 overflow-x-auto no-scrollbar" (raw! thumbs-html))))
(defcomp ~market-detail-no-image (&key like-html)
(div :class "relative aspect-square bg-stone-100 rounded-xl flex items-center justify-center text-stone-400"
(raw! like-html) "No image"))
(defcomp ~market-detail-sticker (&key src name)
(img :src src :alt name :class "w-10 h-10"))
(defcomp ~market-detail-stickers (&key items-html)
(div :class "p-2 flex flex-row justify-center gap-2" (raw! items-html)))
(defcomp ~market-detail-unit-price (&key price)
(div (str "Unit price: " price)))
(defcomp ~market-detail-case-size (&key size)
(div (str "Case size: " size)))
(defcomp ~market-detail-extras (&key inner-html)
(div :class "mt-2 space-y-1 text-sm text-stone-600" (raw! inner-html)))
(defcomp ~market-detail-desc-short (&key text)
(p :class "leading-relaxed text-lg" text))
(defcomp ~market-detail-desc-html (&key html)
(div :class "max-w-none text-sm leading-relaxed" (raw! html)))
(defcomp ~market-detail-desc-wrapper (&key inner-html)
(div :class "mt-4 text-stone-800 space-y-3" (raw! inner-html)))
(defcomp ~market-detail-section (&key title html)
(details :class "group rounded-xl border bg-white shadow-sm open:shadow p-0"
(summary :class "cursor-pointer select-none px-4 py-3 flex items-center justify-between"
(span :class "font-medium" title)
(span :class "ml-2 text-xl transition-transform group-open:rotate-180" "\u2304"))
(div :class "px-4 pb-4 max-w-none text-sm leading-relaxed" (raw! html))))
(defcomp ~market-detail-sections (&key items-html)
(div :class "mt-8 space-y-3" (raw! items-html)))
(defcomp ~market-detail-right-col (&key inner-html)
(div :class "md:col-span-3" (raw! inner-html)))
(defcomp ~market-detail-layout (&key gallery-html stickers-html details-html)
(<> (div :class "mt-3 grid grid-cols-1 md:grid-cols-5 gap-6" :data-gallery-root ""
(div :class "md:col-span-2" (raw! gallery-html) (raw! stickers-html))
(raw! details-html))
(div :class "pb-8")))
(defcomp ~market-landing-excerpt (&key text)
(div :class "w-full text-center italic text-3xl p-2" text))
(defcomp ~market-landing-image (&key src)
(div :class "mb-3 flex justify-center"
(img :src src :alt "" :class "rounded-lg w-full md:w-3/4 object-cover")))
(defcomp ~market-landing-html (&key html)
(div :class "blog-content p-2" (raw! html)))
(defcomp ~market-landing-content (&key inner-html)
(<> (article :class "relative w-full" (raw! inner-html)) (div :class "pb-8")))