Skip to content

Instantly share code, notes, and snippets.

@yuhan0
Last active May 2, 2025 11:02
Show Gist options
  • Select an option

  • Save yuhan0/5e3aaccbb1be1925ed4bf066a692d50a to your computer and use it in GitHub Desktop.

Select an option

Save yuhan0/5e3aaccbb1be1925ed4bf066a692d50a to your computer and use it in GitHub Desktop.
Datastar debounce / throttle repro
(ns app.repro
(:require [hyperlith.core :as h]
[clojure.string :as str]))
(defn render [_req]
(h/html
[:main#morph.main
[:div {:style {:display :grid
:grid-gap :1em
:justify-items :stretch
:grid-template-columns (repeat 4 "1fr")}}
[:style "code,input{width:100%;margin:auto 1em}"]
(for [[sig & tags] '[[t1] [t2 noleading] [t3 trail] [t4 noleading trail]
[d1] [d2 leading] [d3 notrail] [d4 leading notrail]]
:let [t? (= \t (first (name sig)))
label (str/join "."
(list* (if t? "throttle" "debounce") tags))
attr (keyword (str "data-on-keydown"
(str/join "."
(list* (if t? "__throttle" "__debounce") "500ms" tags))))
prop (format "evt.key==='Backspace' ? $%s = '' : evt.key!=='Tab' ? $%s += evt.key : null" sig sig)
init-attr (str "data-signals-" sig "__ifmissing")]]
[:div {init-attr "''"}
[:code label]
[:br]
[:div {:style {:display :flex :align-items :center}}
[:input {attr prop}]
[:code {:data-text (str "$" sig)}]]])]]))
(def router
(h/router
{[:get "/"] (h/shim-handler [:title {} "repro"])
[:post "/"] (h/render-handler #'render)}))
(defn -main [& _]
(h/start-app
{:router #'router
:ctx-start (fn [])
:ctx-stop (fn [_])
:max-refresh-ms 100
:csrf-secret (h/env :csrf-secret)}))
(h/refresh-all!)
(comment
(-main)
(clojure.java.browse/browse-url "http://localhost:8080/")
;; stop server
(((h/get-app) :stop))
,)
@yuhan0
Copy link
Author

yuhan0 commented May 2, 2025

There's actually zero server-side logic going on here, the above just compiles to the following html

<main id="morph" class="main">
  <div style="display: grid; grid-gap: 1em; justify-items: stretch; grid-template-columns: 1fr 1fr 1fr 1fr;">
    <style>code,input{width:100%;margin:auto 1em}</style>
    <div data-signals-t1__ifmissing="''">
      <code>throttle</code>
      <br>
      <div style="display: flex; align-items: center;">
        <input data-on-keydown__throttle.500ms="evt.key==='Backspace' ? $t1 = '' : evt.key!=='Tab' ? $t1 += evt.key : null">
        <code data-text="$t1"></code>
      </div>
    </div>
    <div data-signals-t2__ifmissing="''">
      <code>throttle.noleading</code>
      <br>
      <div style="display: flex; align-items: center;">
        <input data-on-keydown__throttle.500ms.noleading="evt.key==='Backspace' ? $t2 = '' : evt.key!=='Tab' ? $t2 += evt.key : null">
        <code data-text="$t2"></code>
      </div>
    </div>
    <div data-signals-t3__ifmissing="''">
      <code>throttle.trail</code>
      <br>
      <div style="display: flex; align-items: center;">
        <input data-on-keydown__throttle.500ms.trail="evt.key==='Backspace' ? $t3 = '' : evt.key!=='Tab' ? $t3 += evt.key : null">
        <code data-text="$t3"></code>
      </div>
    </div>
    <div data-signals-t4__ifmissing="''">
      <code>throttle.noleading.trail</code>
      <br>
      <div style="display: flex; align-items: center;">
        <input data-on-keydown__throttle.500ms.noleading.trail="evt.key==='Backspace' ? $t4 = '' : evt.key!=='Tab' ? $t4 += evt.key : null">
        <code data-text="$t4"></code>
      </div>
    </div>
    <div data-signals-d1__ifmissing="''">
      <code>debounce</code>
      <br>
      <div style="display: flex; align-items: center;">
        <input data-on-keydown__debounce.500ms="evt.key==='Backspace' ? $d1 = '' : evt.key!=='Tab' ? $d1 += evt.key : null">
        <code data-text="$d1"></code>
      </div>
    </div>
    <div data-signals-d2__ifmissing="''">
      <code>debounce.leading</code>
      <br>
      <div style="display: flex; align-items: center;">
        <input data-on-keydown__debounce.500ms.leading="evt.key==='Backspace' ? $d2 = '' : evt.key!=='Tab' ? $d2 += evt.key : null">
        <code data-text="$d2"></code>
      </div>
    </div>
    <div data-signals-d3__ifmissing="''">
      <code>debounce.notrail</code>
      <br>
      <div style="display: flex; align-items: center;">
        <input data-on-keydown__debounce.500ms.notrail="evt.key==='Backspace' ? $d3 = '' : evt.key!=='Tab' ? $d3 += evt.key : null">
        <code data-text="$d3"></code>
      </div>
    </div>
    <div data-signals-d4__ifmissing="''">
      <code>debounce.leading.notrail</code>
      <br>
      <div style="display: flex; align-items: center;">
        <input data-on-keydown__debounce.500ms.leading.notrail="evt.key==='Backspace' ? $d4 = '' : evt.key!=='Tab' ? $d4 += evt.key : null">
        <code data-text="$d4"></code>
      </div>
    </div>
  </div>
</main>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment