Files
rose-ash/shared/sx/templates/controls.sx
giles e8bc228c7f
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 11m37s
Rebrand sexp → sx across web platform (173 files)
Rename all sexp directories, files, identifiers, and references to sx.
artdag/ excluded (separate media processing DSL).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:06:57 +00:00

99 lines
5.3 KiB
Plaintext

(defcomp ~search-mobile (&key current-local-href search search-count hx-select search-headers-mobile)
(div :id "search-mobile-wrapper"
:class "flex flex-row gap-2 items-center flex-1 min-w-0 pr-2"
(input :id "search-mobile"
:type "text" :name "search" :aria-label "search"
:class "text-base md:text-sm col-span-5 rounded-md px-3 py-2 mb-2 w-full min-w-0 max-w-full border-2 border-stone-200 placeholder-shown:border-stone-200 [&:not(:placeholder-shown)]:border-yellow-200"
:sx-preserve true
:value (or search "")
:placeholder "search"
:sx-trigger "input changed delay:300ms"
:sx-target "#main-panel"
:sx-select (str (or hx-select "#main-panel") ", #search-mobile-wrapper, #search-desktop-wrapper")
:sx-get current-local-href
:sx-swap "outerHTML"
:sx-push-url "true"
:sx-headers search-headers-mobile
:sx-sync "this:replace"
:autocomplete "off")
(div :id "search-count-mobile" :aria-label "search count"
:class (if (not search-count) "text-xl text-red-500" "")
(when search (str search-count)))))
(defcomp ~search-desktop (&key current-local-href search search-count hx-select search-headers-desktop)
(div :id "search-desktop-wrapper"
:class "flex flex-row gap-2 items-center"
(input :id "search-desktop"
:type "text" :name "search" :aria-label "search"
:class "w-full mx-1 my-3 px-3 py-2 text-md rounded-xl border-2 shadow-sm border-white placeholder-shown:border-white [&:not(:placeholder-shown)]:border-yellow-200"
:sx-preserve true
:value (or search "")
:placeholder "search"
:sx-trigger "input changed delay:300ms"
:sx-target "#main-panel"
:sx-select (str (or hx-select "#main-panel") ", #search-mobile-wrapper, #search-desktop-wrapper")
:sx-get current-local-href
:sx-swap "outerHTML"
:sx-push-url "true"
:sx-headers search-headers-desktop
:sx-sync "this:replace"
:autocomplete "off")
(div :id "search-count-desktop" :aria-label "search count"
:class (if (not search-count) "text-xl text-red-500" "")
(when search (str search-count)))))
(defcomp ~mobile-filter (&key filter-summary action-buttons filter-details)
(details :class "group/filter p-2 md:hidden" :data-toggle-group "mobile-panels"
(summary :class "bg-white/90"
(div :class "flex flex-row items-start"
(div
(div :class "md:hidden mx-2 bg-stone-200 rounded"
(span :class "flex items-center justify-center text-stone-600 text-lg h-12 w-12 transition-transform group-open/filter:hidden self-start"
(i :class "fa-solid fa-filter"))
(span
(svg :aria-hidden "true" :viewBox "0 0 24 24"
:class "w-12 h-12 rotate-180 transition-transform group-open/filter:block hidden self-start"
(path :d "M6 9l6 6 6-6" :fill "currentColor")))))
(div :id "filter-summary-mobile"
:class "flex-1 md:hidden grid grid-cols-12 items-center gap-3"
(div :class "flex flex-col items-start gap-2"
(when filter-summary filter-summary)))))
(when action-buttons action-buttons)
(div :id "filter-details-mobile" :style "display:contents"
(when filter-details filter-details))))
(defcomp ~infinite-scroll (&key url page total-pages id-prefix colspan)
(if (< page total-pages)
(tr :id (str id-prefix "-sentinel-" page)
:sx-get url
:sx-trigger "intersect once delay:250ms"
:sx-swap "outerHTML"
:sx-retry "exponential:1000:30000"
:role "status" :aria-live "polite" :aria-hidden "true"
(td :colspan colspan :class "px-3 py-4"
(div :class "block md:hidden h-[60vh] js-mobile-sentinel"
(div :class "sx-indicator js-loading text-center text-xs text-stone-400"
(str "loading\u2026 " page " / " total-pages))
(div :class "js-neterr hidden flex h-full items-center justify-center"))
(div :class "hidden md:block h-[30vh] js-desktop-sentinel"
(div :class "sx-indicator js-loading text-center text-xs text-stone-400"
(str "loading\u2026 " page " / " total-pages))
(div :class "js-neterr hidden inset-0 grid place-items-center p-4"))))
(tr (td :colspan colspan :class "px-3 py-4 text-center text-xs text-stone-400"
"End of results"))))
(defcomp ~status-pill (&key status size)
(let* ((s (or status "pending"))
(lower (lower s))
(sz (or size "xs"))
(colours (cond
(= lower "paid") "border-emerald-300 bg-emerald-50 text-emerald-700"
(= lower "confirmed") "border-emerald-300 bg-emerald-50 text-emerald-700"
(= lower "checked_in") "border-blue-300 bg-blue-50 text-blue-700"
(or (= lower "failed") (= lower "cancelled")) "border-rose-300 bg-rose-50 text-rose-700"
(= lower "provisional") "border-amber-300 bg-amber-50 text-amber-700"
(= lower "ordered") "border-blue-300 bg-blue-50 text-blue-700"
true "border-stone-300 bg-stone-50 text-stone-700")))
(span :class (str "inline-flex items-center rounded-full border px-2 py-0.5 text-" sz " font-medium " colours)
s)))