♻️ Extract token value validation to source resolve function

This commit is contained in:
Xavier Julian 2026-04-23 12:35:53 +02:00
parent 9067dd3d04
commit a21b6198c3
4 changed files with 32 additions and 30 deletions

View File

@ -29,7 +29,6 @@
[app.util.i18n :refer [tr]]
[app.util.object :as obj]
[beicon.v2.core :as rx]
[cljs.pprint :as pp]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
@ -39,6 +38,10 @@
(and (string? token-name)
(re-matches cto/token-name-validation-regex token-name))
valid-token-ref?
(or (str/blank? value)
(re-matches cto/token-ref-validation-regex value))
token
{:value value
:name (if (or (not valid-token-name?) (str/blank? token-name))
@ -50,18 +53,21 @@
(dissoc (:name prev-token))
(update (:name token) #(ctob/make-token (merge % prev-token token))))]
(->> (if (contains? cf/flags :tokenscript)
(rx/of (ts/resolve-tokens tokens))
(sd/resolve-tokens-interactive tokens))
(rx/mapcat
(fn [resolved-tokens]
(let [{:keys [errors resolved-value] :as resolved-token} (get resolved-tokens (:name token))
resolved-value (if (contains? cf/flags :tokenscript)
(ts/tokenscript-symbols->penpot-unit resolved-value)
resolved-value)]
(if resolved-value
(rx/of {:value resolved-value})
(rx/of {:error (first errors)}))))))))
(if-not valid-token-ref?
(rx/of {:error {:error/fn #(str (tr "workspace.tokens.invalid-value" %))
:error/value value}})
(->> (if (contains? cf/flags :tokenscript)
(rx/of (ts/resolve-tokens tokens))
(sd/resolve-tokens-interactive tokens))
(rx/mapcat
(fn [resolved-tokens]
(let [{:keys [errors resolved-value] :as resolved-token} (get resolved-tokens (:name token))
resolved-value (if (contains? cf/flags :tokenscript)
(ts/tokenscript-symbols->penpot-unit resolved-value)
resolved-value)]
(if resolved-value
(rx/of {:value resolved-value})
(rx/of {:error (first errors)})))))))))
(mf/defc value-combobox*
[{:keys [name tokens token token-type empty-to-end ref] :rest props}]
@ -106,7 +112,6 @@
(mf/with-memo [raw-tokens-by-type token-type]
(csu/filter-tokens-for-input raw-tokens-by-type token-type))
visible-options
(mf/with-memo [filtered-tokens-by-type token]
(if token
@ -280,21 +285,15 @@
(fn [error]
((:error/fn error) (:error/value error))))))
(rx/subs! (fn [{:keys [error value]}]
(let [touched? (get-in @form [:touched name])
current-value (get-in @form [:data name] "")
valid-ref? (re-matches cto/token-ref-validation-regex current-value)]
(let [touched? (get-in @form [:touched name])]
(when touched?
(if error
(do
(swap! form assoc-in [:extra-errors name] {:message error})
(reset! hint* {:message error :type "error"}))
(if (and (not (str/blank? current-value)) (not valid-ref?))
(let [message (tr "workspace.tokens.invalid-value" (str current-value))]
(swap! form assoc-in [:extra-errors name] {:message message})
(reset! hint* {:message message :type "error"}))
(let [message (tr "workspace.tokens.resolved-value" value)]
(swap! form update :extra-errors dissoc name)
(reset! hint* {:message message :type "hint"})))))))))]
(let [message (tr "workspace.tokens.resolved-value" value)]
(swap! form update :extra-errors dissoc name)
(reset! hint* {:message message :type "hint"}))))))))]
(fn []
(rx/dispose! subs))))

View File

@ -35,11 +35,16 @@
(mf/with-memo [token-path tokens-in-selected-set]
(-> (ctob/tokens-tree tokens-in-selected-set)
(d/dissoc-in token-path)))
props
(mf/spread-props props {:token-type token-type
:tokens-tree-in-selected-set tokens-tree-in-selected-set
:token token
:input-component token.controls/value-combobox*})
(if (contains? cf/flags :token-combobox)
(mf/spread-props props {:token-type token-type
:tokens-tree-in-selected-set tokens-tree-in-selected-set
:token token
:input-component token.controls/value-combobox*})
(mf/spread-props props {:token-type token-type
:tokens-tree-in-selected-set tokens-tree-in-selected-set
:token token}))
text-case-props (if (contains? cf/flags :token-combobox)
(mf/spread-props props {:input-value-placeholder (tr "workspace.tokens.text-case-value-enter")
:input-component token.controls/value-combobox*})

View File

@ -69,7 +69,6 @@
(let [make-schema (or make-schema #(-> (cfo/make-token-schema % token-type)
(sm/dissoc-key :id)))
input-component (or input-component token.controls/input*)
_ (prn "Rendering generic form with input-component:" input-component)
validate-token (or validator default-validate-token)
active-tab* (mf/use-state #(if (cfo/is-reference? token) :reference :composite))

View File

@ -11,7 +11,6 @@
padding-block-end: var(--sp-s);
display: flex;
gap: var(--sp-s);
flex-wrap: wrap;
padding-inline-start: calc(var(--node-spacing));