Parser: skip unit suffix when next ident is a comparison keyword (starts, ends, contains, matches, is, does, in, precedes, follows). Fixes "123 starts with '12'" returning "123starts" instead of true. eval-hs: use hs-compile directly instead of hs-to-sx-from-source with "return " prefix, which was causing the parser to consume the comparison as a string suffix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
139 lines
4.2 KiB
Plaintext
139 lines
4.2 KiB
Plaintext
;; htmx demo API handlers — return HTML fragments for hx-* demos
|
|
|
|
;; Click to load
|
|
(defhandler
|
|
ex-click
|
|
:path "/sx/(applications.(htmx.(api.click)))"
|
|
:method :get
|
|
:returns "element"
|
|
(&key)
|
|
(div
|
|
(~tw :tokens "space-y-2")
|
|
(p (~tw :tokens "text-stone-800 font-medium") "Content loaded!")
|
|
(p
|
|
(~tw :tokens "text-stone-500 text-sm")
|
|
"Fetched from the server via hx-get")))
|
|
|
|
;; Active search
|
|
(defhandler
|
|
ex-search
|
|
:path "/sx/(applications.(htmx.(api.search)))"
|
|
:method :get
|
|
:returns "element"
|
|
(&key q)
|
|
(let
|
|
((query (or q "")))
|
|
(let
|
|
((items (list {:desc "GET request" :name "hx-get"} {:desc "POST request" :name "hx-post"} {:desc "Swap strategy" :name "hx-swap"} {:desc "Target element" :name "hx-target"} {:desc "Event trigger" :name "hx-trigger"} {:desc "Confirm dialog" :name "hx-confirm"} {:desc "Progressive enhancement" :name "hx-boost"} {:desc "CSS selector filter" :name "hx-select"})))
|
|
(let
|
|
((filtered (if (= query "") (list) (filter (fn (item) (contains? (downcase (get item :name)) (downcase query))) items))))
|
|
(if
|
|
(empty? filtered)
|
|
(p
|
|
(~tw :tokens "text-gray-400 italic py-2")
|
|
(str "No results for \"" query "\""))
|
|
(ul
|
|
(~tw :tokens "divide-y divide-gray-100")
|
|
(map
|
|
(fn
|
|
(item)
|
|
(li
|
|
(~tw :tokens "py-2 px-1")
|
|
(span
|
|
(~tw :tokens "font-medium text-gray-800")
|
|
(get item :name))
|
|
(span
|
|
(~tw :tokens "text-sm text-gray-500 ml-2")
|
|
(get item :desc))))
|
|
filtered)))))))
|
|
|
|
;; Tabs
|
|
(defhandler
|
|
ex-tab
|
|
:path "/sx/(applications.(htmx.(api.tab)))"
|
|
:method :get
|
|
:returns "element"
|
|
(&key tab)
|
|
(let
|
|
((tab (or tab "overview")))
|
|
(cond
|
|
(= tab "overview")
|
|
(div
|
|
(~tw :tokens "p-4 space-y-2")
|
|
(h3 (~tw :tokens "font-semibold text-stone-800") "Overview")
|
|
(p
|
|
(~tw :tokens "text-stone-600 text-sm")
|
|
"htmx gives you access to AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes."))
|
|
(= tab "features")
|
|
(div
|
|
(~tw :tokens "p-4 space-y-2")
|
|
(h3 (~tw :tokens "font-semibold text-stone-800") "Features")
|
|
(ul
|
|
(~tw
|
|
:tokens "list-disc list-inside text-sm text-stone-600 space-y-1")
|
|
(li "Any element, any event")
|
|
(li "Multiple swap strategies")
|
|
(li "CSS transition support")
|
|
(li "Out-of-band swaps")))
|
|
(= tab "code")
|
|
(div
|
|
(~tw :tokens "p-4")
|
|
(pre
|
|
(~tw :tokens "text-sm bg-stone-100 rounded p-3")
|
|
(code "(button :hx-get \"/api\" :hx-target \"#out\"\n \"Load\")")))
|
|
true
|
|
(div (~tw :tokens "p-4 text-stone-400") "Unknown tab"))))
|
|
|
|
;; Delete item — returns empty fragment to remove the element
|
|
(defhandler
|
|
ex-delete
|
|
:path "/sx/(applications.(htmx.(api.delete)))"
|
|
:method :delete
|
|
:csrf false
|
|
:returns "element"
|
|
(&key)
|
|
(<>))
|
|
|
|
;; Form submission
|
|
(defhandler
|
|
ex-form
|
|
:path "/sx/(applications.(htmx.(api.form)))"
|
|
:method :post
|
|
:csrf false
|
|
:returns "element"
|
|
(&key name email)
|
|
(div
|
|
(~tw :tokens "p-4 bg-green-50 border border-green-200 rounded-lg")
|
|
(p
|
|
(~tw :tokens "text-green-800 font-medium")
|
|
(str "Hello, " (or name "stranger") "!"))
|
|
(p
|
|
(~tw :tokens "text-sm text-green-600 mt-1")
|
|
(str "Email: " (or email "not provided")))))
|
|
|
|
;; Slow endpoint for indicator demo
|
|
(defhandler
|
|
ex-slow
|
|
:path "/sx/(applications.(htmx.(api.slow)))"
|
|
:method :get
|
|
:returns "element"
|
|
(&key)
|
|
(div
|
|
(~tw :tokens "p-4 bg-amber-50 border border-amber-200 rounded-lg")
|
|
(p (~tw :tokens "text-amber-800 font-medium") "Slow response received")
|
|
(p
|
|
(~tw :tokens "text-sm text-amber-600 mt-1")
|
|
"This response was delayed")))
|
|
|
|
;; Append item (beforeend swap demo)
|
|
(defhandler
|
|
ex-append
|
|
:path "/sx/(applications.(htmx.(api.append)))"
|
|
:method :post
|
|
:csrf false
|
|
:returns "element"
|
|
(&key)
|
|
(div
|
|
(~tw :tokens "p-2 border-b border-gray-100 text-sm text-stone-700")
|
|
"New item appended"))
|