mirror of
https://github.com/penpot/penpot.git
synced 2025-01-21 06:02:32 -05:00
Move callback function to component
This commit is contained in:
parent
28f25da9e8
commit
c98162d0bf
3 changed files with 55 additions and 66 deletions
|
@ -14,6 +14,7 @@
|
|||
[cuerdas.core :as str]
|
||||
[malli.core :as m]
|
||||
[malli.error :as me]
|
||||
[promesa.core :as p]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
;; Schemas ---------------------------------------------------------------------
|
||||
|
@ -33,11 +34,6 @@
|
|||
[:string {:min 1 :max 255}]
|
||||
non-existing-token-schema])))
|
||||
|
||||
(comment
|
||||
(-> (m/explain (token-name-schema #{"foo"}) nil)
|
||||
(me/humanize))
|
||||
nil)
|
||||
|
||||
;; Helpers ---------------------------------------------------------------------
|
||||
|
||||
(defn finalize-name [name]
|
||||
|
@ -46,6 +42,57 @@
|
|||
(defn finalize-value [name]
|
||||
(str/trim name))
|
||||
|
||||
;; Component -------------------------------------------------------------------
|
||||
|
||||
(defn use-debonced-resolve-callback
|
||||
[name-ref token tokens callback & {:keys [cached timeout]
|
||||
:or {cached {}
|
||||
timeout 160}}]
|
||||
(let [timeout-id-ref (mf/use-ref nil)
|
||||
cache (mf/use-ref cached)
|
||||
debounced-resolver-callback
|
||||
(mf/use-callback
|
||||
(mf/deps token callback tokens)
|
||||
(fn [event]
|
||||
(let [input (dom/get-target-val event)
|
||||
timeout-id (js/Symbol)
|
||||
;; Dont execute callback when the timout-id-ref is outdated because this function got called again
|
||||
timeout-outdated-cb? #(not= (mf/ref-val timeout-id-ref) timeout-id)]
|
||||
(mf/set-ref-val! timeout-id-ref timeout-id)
|
||||
(js/setTimeout
|
||||
(fn []
|
||||
(when (not (timeout-outdated-cb?))
|
||||
(if-let [cached (get (mf/ref-val cache) tokens)]
|
||||
(callback cached)
|
||||
(let [token-references (sd/find-token-references input)
|
||||
;; When creating a new token we dont have a token name yet,
|
||||
;; so we use a temporary token name that hopefully doesn't clash with any of the users token names.
|
||||
token-name (if (empty? @name-ref) "__TOKEN_STUDIO_SYSTEM.TEMP" @name-ref)
|
||||
direct-self-reference? (get token-references token-name)
|
||||
empty-input? (empty? (str/trim input))]
|
||||
(cond
|
||||
empty-input? (callback nil)
|
||||
direct-self-reference? (callback :error/token-direct-self-reference)
|
||||
:else
|
||||
(let [token-id (or (:id token) (random-uuid))
|
||||
new-tokens (update tokens token-id merge {:id token-id
|
||||
:value input
|
||||
:name token-name})]
|
||||
(-> (sd/resolve-tokens+ new-tokens)
|
||||
(p/finally
|
||||
(fn [resolved-tokens _err]
|
||||
(when-not (timeout-outdated-cb?)
|
||||
(let [{:keys [errors resolved-value] :as resolved-token} (get resolved-tokens token-id)]
|
||||
(cond
|
||||
resolved-value (do
|
||||
(mf/set-ref-val! cache (assoc (mf/ref-val cache) input resolved-tokens))
|
||||
(callback resolved-token))
|
||||
(= #{:style-dictionary/missing-reference} errors) (callback :error/token-missing-reference)
|
||||
:else (callback :error/unknown-error)))))))))))))
|
||||
|
||||
timeout))))]
|
||||
debounced-resolver-callback))
|
||||
|
||||
(mf/defc form
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [token] :as _args}]
|
||||
|
@ -63,7 +110,6 @@
|
|||
:description ""}
|
||||
token))
|
||||
state @state*
|
||||
_ (js/console.log "render")
|
||||
|
||||
form-touched (mf/use-state nil)
|
||||
update-form-touched (mf/use-callback
|
||||
|
@ -90,11 +136,11 @@
|
|||
set-resolve-value (mf/use-callback
|
||||
(fn [token-or-err]
|
||||
(let [value (cond
|
||||
(= token-or-err :error/token-self-reference) :error/token-self-reference
|
||||
(= token-or-err :error/token-direct-self-reference) :error/token-self-reference
|
||||
(= token-or-err :error/token-missing-reference) :error/token-missing-reference
|
||||
(:resolved-value token-or-err) (:resolved-value token-or-err))]
|
||||
(reset! token-resolve-result value))))
|
||||
on-update-value (sd/use-debonced-resolve-callback name token tokens set-resolve-value)
|
||||
on-update-value (use-debonced-resolve-callback name token tokens set-resolve-value)
|
||||
value-error? (when (keyword? @token-resolve-result)
|
||||
(= (namespace @token-resolve-result) "error"))
|
||||
|
||||
|
@ -136,6 +182,7 @@
|
|||
(case @token-resolve-result
|
||||
:error/token-self-reference "Token has self reference"
|
||||
:error/token-missing-reference "Token has missing reference"
|
||||
:error/unknown-error ""
|
||||
nil "Enter token value"
|
||||
[:p @token-resolve-result])]
|
||||
[:& tokens.common/labeled-input {:label "Description"
|
||||
|
|
|
@ -30,10 +30,6 @@
|
|||
(map second)
|
||||
(into #{})))
|
||||
|
||||
(defn token-self-reference? [token-name value-string]
|
||||
(let [refs (find-token-references value-string)]
|
||||
(get refs token-name)))
|
||||
|
||||
(defn tokens->style-dictionary+
|
||||
"Resolves references and math expressions using StyleDictionary.
|
||||
Returns a promise with the resolved dictionary."
|
||||
|
@ -115,55 +111,6 @@
|
|||
|
||||
;; Hooks -----------------------------------------------------------------------
|
||||
|
||||
(def new-token-temp-name
|
||||
"TOKEN_STUDIO_SYSTEM.TEMP")
|
||||
|
||||
(defn use-debonced-resolve-callback
|
||||
[name-ref token tokens callback & {:keys [cached timeout]
|
||||
:or {cached {}
|
||||
timeout 160}}]
|
||||
(let [timeout-id-ref (mf/use-ref nil)
|
||||
cache (mf/use-ref cached)
|
||||
debounced-resolver-callback
|
||||
(mf/use-callback
|
||||
(mf/deps token callback tokens)
|
||||
(fn [event]
|
||||
(let [input (dom/get-target-val event)
|
||||
timeout-id (js/Symbol)]
|
||||
(mf/set-ref-val! timeout-id-ref timeout-id)
|
||||
(js/setTimeout
|
||||
(fn []
|
||||
(when (= (mf/ref-val timeout-id-ref) timeout-id)
|
||||
(let [cached (-> (mf/ref-val cache)
|
||||
(get tokens))
|
||||
token-name (if (empty? @name-ref) new-token-temp-name @name-ref)]
|
||||
(cond
|
||||
cached (callback cached)
|
||||
(token-self-reference? token-name input) (callback :error/token-self-reference)
|
||||
:else (let [token-id (or (:id token) (random-uuid))
|
||||
new-tokens (update tokens token-id merge {:id token-id
|
||||
:value input
|
||||
:name token-name})]
|
||||
(-> (resolve-tokens+ new-tokens)
|
||||
(p/finally
|
||||
(fn [resolved-tokens _err]
|
||||
(js/console.log "input" input (empty? (str/trim input)))
|
||||
(cond
|
||||
;; Ignore outdated callbacks because the user input changed since it tried to resolve
|
||||
(not= (mf/ref-val timeout-id-ref) timeout-id) nil
|
||||
(empty? (str/trim input)) (callback nil)
|
||||
:else (let [resolved-token (get resolved-tokens token-id)]
|
||||
(js/console.log "resolved-token" resolved-token)
|
||||
(if (:resolved-value resolved-token)
|
||||
(do
|
||||
(mf/set-ref-val! cache (assoc (mf/ref-val cache) input resolved-tokens))
|
||||
(callback resolved-token))
|
||||
(callback :error/token-missing-reference))))))))))))
|
||||
|
||||
|
||||
timeout))))]
|
||||
debounced-resolver-callback))
|
||||
|
||||
(defonce !tokens-cache (atom nil))
|
||||
|
||||
(defn use-resolved-tokens
|
||||
|
|
|
@ -18,8 +18,3 @@
|
|||
(t/is (nil? (wtsd/find-token-references "1 + 2")))
|
||||
;; Edge-case: Ignore unmatched closing parens
|
||||
(t/is (= #{"foo" "bar"} (wtsd/find-token-references "{foo}} + {bar}"))))
|
||||
|
||||
(t/deftest test-token-self-reference?
|
||||
(t/is (some? (wtsd/token-self-reference? "some.value" "{md} + {some.value}")))
|
||||
(t/is (nil? (wtsd/token-self-reference? "some.value" "some.value")))
|
||||
(t/is (nil? (wtsd/token-self-reference? "sm" "{md} + {lg}"))))
|
||||
|
|
Loading…
Add table
Reference in a new issue