diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 573dac181d..5c392f2db9 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -485,17 +485,15 @@ (defn backtrace-tokens-tree "Convert tokens into a nested tree with their name as the path. - Generates a uuid per token to backtrace a token from an external source (StyleDictionary). + Uses the existing token :id to backtrace a token from an external source (StyleDictionary). The backtrace can't be the name as the name might not exist when the user is creating a token." [tokens] (reduce (fn [acc [_ token]] - (let [temp-id (random-uuid) - token (assoc token :temp/id temp-id) - path (get-token-path token)] + (let [path (get-token-path token)] (-> acc (assoc-in (concat [:tokens-tree] path) token) - (assoc-in [:ids temp-id] token)))) + (assoc-in [:ids (:id token)] token)))) {:tokens-tree {} :ids {}} tokens)) diff --git a/frontend/src/app/main/data/style_dictionary.cljs b/frontend/src/app/main/data/style_dictionary.cljs index 63a076f93f..48320fd9a0 100644 --- a/frontend/src/app/main/data/style_dictionary.cljs +++ b/frontend/src/app/main/data/style_dictionary.cljs @@ -551,7 +551,7 @@ (.. sd-token -original -name)) (defn sd-token-uuid [^js sd-token] - (uuid (.-uuid (.-id ^js sd-token)))) + (uuid (.-uuid (.. sd-token -original -id)))) (defn resolve-tokens [tokens] @@ -560,15 +560,23 @@ (defn resolve-tokens-interactive "Interactive check of resolving tokens. - Uses a ids map to backtrace the original token from the resolved StyleDictionary token. + Uses a ids map to backtrace the original token from the resolved + StyleDictionary token. - We have to pass in all tokens from all sets in the entire library to style dictionary - so we know if references are missing / to resolve them and possibly show interactive previews (in the tokens form) to the user. + We have to pass in all tokens from all sets in the entire library to + style dictionary so we know if references are missing / to resolve + them and possibly show interactive previews (in the tokens form) to + the user. - Since we're using the :name path as the identifier we might be throwing away or overriding tokens in the tree that we pass to StyleDictionary. + Since we're using the :name path as the identifier we might be + throwing away or overriding tokens in the tree that we pass to + StyleDictionary. - So to get back the original token from the resolved sd-token (see my updates for what an sd-token is) we include a temporary :id for the token that we pass to StyleDictionary, - this way after the resolving computation we can restore any token, even clashing ones with the same :name path by just looking up that :id in the ids map." + So to get back the original token from the resolved sd-token (see my + updates for what an sd-token is) we include a temporary :id for the + token that we pass to StyleDictionary, this way after the resolving + computation we can restore any token, even clashing ones with the + same :name path by just looking up that :id in the ids map." [tokens] (let [{:keys [tokens-tree ids]} (ctob/backtrace-tokens-tree tokens)] (resolve-tokens-tree tokens-tree #(get ids (sd-token-uuid %))))) @@ -584,10 +592,11 @@ (defonce !tokens-cache (atom nil)) (defn use-resolved-tokens - "The StyleDictionary process function is async, so we can't use resolved values directly. + "The StyleDictionary process function is async, so we can't use + resolved values directly. - This hook will return the unresolved tokens as state until they are processed, - then the state will be updated with the resolved tokens." + This hook will return the unresolved tokens as state until they are + processed, then the state will be updated with the resolved tokens." [tokens & {:keys [cache-atom interactive?] :or {cache-atom !tokens-cache} :as config}] diff --git a/frontend/test/frontend_tests/tokens/style_dictionary_test.cljs b/frontend/test/frontend_tests/tokens/style_dictionary_test.cljs index bf8aad0c35..1f1609f344 100644 --- a/frontend/test/frontend_tests/tokens/style_dictionary_test.cljs +++ b/frontend/test/frontend_tests/tokens/style_dictionary_test.cljs @@ -57,3 +57,29 @@ (t/is (= :error.token/number-too-large (get-in resolved-tokens ["borderRadius.largeFn" :errors 0 :error/code]))) (done)))))))) + +(t/deftest resolve-tokens-interactive-test + (t/async + done + (t/testing "resolves tokens interactively using backtrace ids map" + (let [tokens (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id (cthi/new-id! :core-set) + :name "core")) + (ctob/add-token (cthi/id :core-set) + (ctob/make-token {:name "borderRadius.sm" + :value "12px" + :type :border-radius})) + (ctob/add-token (cthi/id :core-set) + (ctob/make-token {:value "{borderRadius.sm} * 2" + :name "borderRadius.md" + :type :border-radius})) + (ctob/get-all-tokens-map))] + (-> (sd/resolve-tokens-interactive tokens) + (rx/sub! + (fn [resolved-tokens] + (t/is (= 12 (get-in resolved-tokens ["borderRadius.sm" :resolved-value]))) + (t/is (= "px" (get-in resolved-tokens ["borderRadius.sm" :unit]))) + (t/is (= 24 (get-in resolved-tokens ["borderRadius.md" :resolved-value]))) + (t/is (= "px" (get-in resolved-tokens ["borderRadius.md" :unit]))) + (done)))))))) +