diff --git a/frontend/src/app/main/ui/workspace/tokens/token.cljs b/common/src/app/common/files/tokens.cljc similarity index 90% rename from frontend/src/app/main/ui/workspace/tokens/token.cljs rename to common/src/app/common/files/tokens.cljc index 850dadf507..eb09914456 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token.cljs +++ b/common/src/app/common/files/tokens.cljc @@ -1,8 +1,7 @@ -(ns app.main.ui.workspace.tokens.token +(ns app.common.files.tokens (:require [app.common.data :as d] [app.common.data.macros :as dm] - [app.main.data.tinycolor :as tinycolor] [clojure.set :as set] [cuerdas.core :as str])) @@ -128,18 +127,6 @@ (defn color-token? [token] (= (:type token) :color)) - ;; FIXME: this should be precalculated ? (defn is-reference? [token] (str/includes? (:value token) "{")) - -(defn color-bullet-color [token-color-value] - (when-let [tc (tinycolor/valid-color token-color-value)] - (if (tinycolor/alpha tc) - {:color (tinycolor/->hex-string tc) - :opacity (tinycolor/alpha tc)} - (tinycolor/->hex-string tc)))) - -(defn resolved-token-bullet-color [{:keys [resolved-value] :as token}] - (when (and resolved-value (color-token? token)) - (color-bullet-color resolved-value))) diff --git a/frontend/test/frontend_tests/tokens/token_test.cljs b/common/test/common_tests/files/tokens_test.cljc similarity index 65% rename from frontend/test/frontend_tests/tokens/token_test.cljs rename to common/test/common_tests/files/tokens_test.cljc index 0124d58404..a16b625c88 100644 --- a/frontend/test/frontend_tests/tokens/token_test.cljs +++ b/common/test/common_tests/files/tokens_test.cljc @@ -4,36 +4,36 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns frontend-tests.tokens.token-test +(ns common-tests.files.tokens-test (:require - [app.main.ui.workspace.tokens.token :as wtt] - [cljs.test :as t :include-macros true])) + [app.common.files.tokens :as cft] + [clojure.test :as t])) (t/deftest test-parse-token-value (t/testing "parses double from a token value" - (t/is (= {:value 100.1 :unit nil} (wtt/parse-token-value "100.1"))) - (t/is (= {:value -9 :unit nil} (wtt/parse-token-value "-9")))) + (t/is (= {:value 100.1 :unit nil} (cft/parse-token-value "100.1"))) + (t/is (= {:value -9.0 :unit nil} (cft/parse-token-value "-9")))) (t/testing "trims white-space" - (t/is (= {:value -1.3 :unit nil} (wtt/parse-token-value " -1.3 ")))) + (t/is (= {:value -1.3 :unit nil} (cft/parse-token-value " -1.3 ")))) (t/testing "parses unit: px" - (t/is (= {:value 70.3 :unit "px"} (wtt/parse-token-value " 70.3px ")))) + (t/is (= {:value 70.3 :unit "px"} (cft/parse-token-value " 70.3px ")))) (t/testing "parses unit: %" - (t/is (= {:value -10 :unit "%"} (wtt/parse-token-value "-10%")))) + (t/is (= {:value -10.0 :unit "%"} (cft/parse-token-value "-10%")))) (t/testing "parses unit: px") (t/testing "returns nil for any invalid characters" - (t/is (nil? (wtt/parse-token-value " -1.3a ")))) + (t/is (nil? (cft/parse-token-value " -1.3a ")))) (t/testing "doesnt accept invalid double" - (t/is (nil? (wtt/parse-token-value ".3"))))) + (t/is (nil? (cft/parse-token-value ".3"))))) (t/deftest token-applied-test (t/testing "matches passed token with `:token-attributes`" - (t/is (true? (wtt/token-applied? {:name "a"} {:applied-tokens {:x "a"}} #{:x})))) + (t/is (true? (cft/token-applied? {:name "a"} {:applied-tokens {:x "a"}} #{:x})))) (t/testing "doesn't match empty token" - (t/is (nil? (wtt/token-applied? {} {:applied-tokens {:x "a"}} #{:x})))) + (t/is (nil? (cft/token-applied? {} {:applied-tokens {:x "a"}} #{:x})))) (t/testing "does't match passed token `:id`" - (t/is (nil? (wtt/token-applied? {:name "b"} {:applied-tokens {:x "a"}} #{:x})))) + (t/is (nil? (cft/token-applied? {:name "b"} {:applied-tokens {:x "a"}} #{:x})))) (t/testing "doesn't match passed `:token-attributes`" - (t/is (nil? (wtt/token-applied? {:name "a"} {:applied-tokens {:x "a"}} #{:y}))))) + (t/is (nil? (cft/token-applied? {:name "a"} {:applied-tokens {:x "a"}} #{:y}))))) (t/deftest shapes-ids-by-applied-attributes (t/testing "Returns set of matched attributes that fit the applied token" @@ -54,7 +54,7 @@ shape-applied-x-y shape-applied-all shape-applied-none] - expected (wtt/shapes-ids-by-applied-attributes {:name "1"} shapes attributes)] + expected (cft/shapes-ids-by-applied-attributes {:name "1"} shapes attributes)] (t/is (= (:x expected) (shape-ids shape-applied-x shape-applied-x-y shape-applied-all))) @@ -62,34 +62,34 @@ shape-applied-x-y shape-applied-all))) (t/is (= (:z expected) (shape-ids shape-applied-all))) - (t/is (true? (wtt/shapes-applied-all? expected (shape-ids shape-applied-all) attributes))) - (t/is (false? (wtt/shapes-applied-all? expected (apply shape-ids shapes) attributes))) + (t/is (true? (cft/shapes-applied-all? expected (shape-ids shape-applied-all) attributes))) + (t/is (false? (cft/shapes-applied-all? expected (apply shape-ids shapes) attributes))) (shape-ids shape-applied-x shape-applied-x-y shape-applied-all)))) (t/deftest tokens-applied-test (t/testing "is true when single shape matches the token and attributes" - (t/is (true? (wtt/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "a"}} + (t/is (true? (cft/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "a"}} {:applied-tokens {:x "b"}}] #{:x})))) (t/testing "is false when no shape matches the token or attributes" - (t/is (nil? (wtt/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "b"}} + (t/is (nil? (cft/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "b"}} {:applied-tokens {:x "b"}}] #{:x}))) - (t/is (nil? (wtt/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "a"}} + (t/is (nil? (cft/shapes-token-applied? {:name "a"} [{:applied-tokens {:x "a"}} {:applied-tokens {:x "a"}}] #{:y}))))) (t/deftest name->path-test - (t/is (= ["foo" "bar" "baz"] (wtt/token-name->path "foo.bar.baz"))) - (t/is (= ["foo" "bar" "baz"] (wtt/token-name->path "foo..bar.baz"))) - (t/is (= ["foo" "bar" "baz"] (wtt/token-name->path "foo..bar.baz....")))) + (t/is (= ["foo" "bar" "baz"] (cft/token-name->path "foo.bar.baz"))) + (t/is (= ["foo" "bar" "baz"] (cft/token-name->path "foo..bar.baz"))) + (t/is (= ["foo" "bar" "baz"] (cft/token-name->path "foo..bar.baz....")))) (t/deftest token-name-path-exists?-test - (t/is (true? (wtt/token-name-path-exists? "border-radius" {"border-radius" {"sm" {:name "sm"}}}))) - (t/is (true? (wtt/token-name-path-exists? "border-radius" {"border-radius" {:name "sm"}}))) - (t/is (true? (wtt/token-name-path-exists? "border-radius.sm" {"border-radius" {:name "sm"}}))) - (t/is (true? (wtt/token-name-path-exists? "border-radius.sm.x" {"border-radius" {:name "sm"}}))) - (t/is (false? (wtt/token-name-path-exists? "other" {"border-radius" {:name "sm"}}))) - (t/is (false? (wtt/token-name-path-exists? "dark.border-radius.md" {"dark" {"border-radius" {"sm" {:name "sm"}}}})))) + (t/is (true? (cft/token-name-path-exists? "border-radius" {"border-radius" {"sm" {:name "sm"}}}))) + (t/is (true? (cft/token-name-path-exists? "border-radius" {"border-radius" {:name "sm"}}))) + (t/is (true? (cft/token-name-path-exists? "border-radius.sm" {"border-radius" {:name "sm"}}))) + (t/is (true? (cft/token-name-path-exists? "border-radius.sm.x" {"border-radius" {:name "sm"}}))) + (t/is (false? (cft/token-name-path-exists? "other" {"border-radius" {:name "sm"}}))) + (t/is (false? (cft/token-name-path-exists? "dark.border-radius.md" {"dark" {"border-radius" {"sm" {:name "sm"}}}})))) diff --git a/frontend/src/app/main/data/style_dictionary.cljs b/frontend/src/app/main/data/style_dictionary.cljs index 5960e77119..58f43e6e4e 100644 --- a/frontend/src/app/main/data/style_dictionary.cljs +++ b/frontend/src/app/main/data/style_dictionary.cljs @@ -2,13 +2,13 @@ (:require ["@tokens-studio/sd-transforms" :as sd-transforms] ["style-dictionary$default" :as sd] + [app.common.files.tokens :as cft] [app.common.logging :as l] [app.common.schema :as sm] [app.common.transit :as t] [app.common.types.tokens-lib :as ctob] [app.main.data.tinycolor :as tinycolor] [app.main.ui.workspace.tokens.errors :as wte] - [app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.warnings :as wtw] [app.util.time :as dt] [beicon.v2.core :as rx] @@ -54,7 +54,7 @@ "Parses `value` of a numeric `sd-token` into a map like `{:value 1 :unit \"px\"}`. If the `value` is not parseable and/or has missing references returns a map with `:errors`." [value] - (let [parsed-value (wtt/parse-token-value value) + (let [parsed-value (cft/parse-token-value value) out-of-bounds (or (>= (:value parsed-value) sm/max-safe-int) (<= (:value parsed-value) sm/min-safe-int))] (if (and parsed-value (not out-of-bounds)) @@ -72,7 +72,7 @@ If the `value` is parseable but is out of range returns a map with `warnings`." [value has-references?] - (let [parsed-value (wtt/parse-token-value value) + (let [parsed-value (cft/parse-token-value value) out-of-scope (not (<= 0 (:value parsed-value) 1)) references (seq (ctob/find-token-value-references value))] (cond @@ -98,7 +98,7 @@ If the `value` is parseable but is out of range returns a map with `warnings`." [value has-references?] - (let [parsed-value (wtt/parse-token-value value) + (let [parsed-value (cft/parse-token-value value) out-of-scope (< (:value parsed-value) 0) references (seq (ctob/find-token-value-references value))] (cond diff --git a/frontend/src/app/main/data/workspace/tokens/application.cljs b/frontend/src/app/main/data/workspace/tokens/application.cljs index 1b6ce54049..16f5ff28e6 100644 --- a/frontend/src/app/main/data/workspace/tokens/application.cljs +++ b/frontend/src/app/main/data/workspace/tokens/application.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.files.tokens :as cft] [app.common.types.shape.layout :as ctsl] [app.common.types.shape.radius :as ctsr] [app.common.types.token :as ctt] @@ -23,7 +24,6 @@ [app.main.data.workspace.transforms :as dwt] [app.main.data.workspace.undo :as dwu] [app.main.store :as st] - [app.main.ui.workspace.tokens.token :as wtt] [beicon.v2.core :as rx] [clojure.set :as set] [potok.v2.core :as ptk])) @@ -56,8 +56,8 @@ (keys)) []) - resolved-value (get-in resolved-tokens [(wtt/token-identifier token) :resolved-value]) - tokenized-attributes (wtt/attributes-map attributes token)] + resolved-value (get-in resolved-tokens [(cft/token-identifier token) :resolved-value]) + tokenized-attributes (cft/attributes-map attributes token)] (rx/of (st/emit! (ptk/event ::ev/event {::ev/name "apply-tokens"})) (dwu/start-undo-transaction undo-id) @@ -80,7 +80,7 @@ ptk/WatchEvent (watch [_ _ _] (rx/of - (let [remove-token #(when % (wtt/remove-attributes-for-token attributes token %))] + (let [remove-token #(when % (cft/remove-attributes-for-token attributes token %))] (dwsh/update-shapes shape-ids (fn [shape] @@ -95,7 +95,7 @@ (get token-properties (:type token)) unapply-tokens? - (wtt/shapes-token-applied? token shapes (or all-attributes attributes)) + (cft/shapes-token-applied? token shapes (or all-attributes attributes)) shape-ids (map :id shapes)] (if unapply-tokens? diff --git a/frontend/src/app/main/data/workspace/tokens/color.cljs b/frontend/src/app/main/data/workspace/tokens/color.cljs new file mode 100644 index 0000000000..828a1ca4cd --- /dev/null +++ b/frontend/src/app/main/data/workspace/tokens/color.cljs @@ -0,0 +1,21 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.data.workspace.tokens.color + (:require + [app.common.files.tokens :as cft] + [app.main.data.tinycolor :as tinycolor])) + +(defn color-bullet-color [token-color-value] + (when-let [tc (tinycolor/valid-color token-color-value)] + (if (tinycolor/alpha tc) + {:color (tinycolor/->hex-string tc) + :opacity (tinycolor/alpha tc)} + (tinycolor/->hex-string tc)))) + +(defn resolved-token-bullet-color [{:keys [resolved-value] :as token}] + (when (and resolved-value (cft/color-token? token)) + (color-bullet-color resolved-value))) \ No newline at end of file diff --git a/frontend/src/app/main/ui/workspace/tokens/components/controls/input_token_color_bullet.cljs b/frontend/src/app/main/ui/workspace/tokens/components/controls/input_token_color_bullet.cljs index 581c7114f3..715f7699c5 100644 --- a/frontend/src/app/main/ui/workspace/tokens/components/controls/input_token_color_bullet.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/components/controls/input_token_color_bullet.cljs @@ -7,8 +7,8 @@ (ns app.main.ui.workspace.tokens.components.controls.input-token-color-bullet (:require-macros [app.main.style :as stl]) (:require + [app.main.data.workspace.tokens.color :as dwtc] [app.main.ui.components.color-bullet :refer [color-bullet]] - [app.main.ui.workspace.tokens.token :as wtt] [rumext.v2 :as mf])) (def ^:private schema::input-token-color-bullet @@ -23,6 +23,6 @@ [:div {:data-testid "token-form-color-bullet" :class (stl/css :input-token-color-bullet) :on-click on-click} - (if-let [color' (wtt/color-bullet-color color)] + (if-let [color' (dwtc/color-bullet-color color)] [:> color-bullet {:color color' :mini true}] [:div {:class (stl/css :input-token-color-bullet-placeholder)}])]) diff --git a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs index d5c0e0abd4..678f9a6b96 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -9,6 +9,7 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.files.tokens :as cft] [app.common.types.tokens-lib :as ctob] [app.main.data.modal :as modal] [app.main.data.workspace.shape-layout :as dwsl] @@ -18,7 +19,6 @@ [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.ds.foundations.assets.icon :refer [icon*]] - [app.main.ui.workspace.tokens.token :as wtt] [app.util.dom :as dom] [app.util.i18n :refer [tr]] [app.util.timers :as timers] @@ -30,9 +30,9 @@ ;; Actions --------------------------------------------------------------------- (defn attribute-actions [token selected-shapes attributes] - (let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes) + (let [ids-by-attributes (cft/shapes-ids-by-applied-attributes token selected-shapes attributes) shape-ids (into #{} (map :id selected-shapes))] - {:all-selected? (wtt/shapes-applied-all? ids-by-attributes shape-ids attributes) + {:all-selected? (cft/shapes-applied-all? ids-by-attributes shape-ids attributes) :shape-ids shape-ids :selected-pred #(seq (% ids-by-attributes))})) diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs index 58768169b9..8a698ecda8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs @@ -10,6 +10,7 @@ [app.common.colors :as c] [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.files.tokens :as cft] [app.common.types.tokens-lib :as ctob] [app.main.data.modal :as modal] [app.main.data.style-dictionary :as sd] @@ -28,7 +29,6 @@ [app.main.ui.workspace.tokens.components.controls.input-token-color-bullet :refer [input-token-color-bullet*]] [app.main.ui.workspace.tokens.components.controls.input-tokens :refer [input-tokens*]] [app.main.ui.workspace.tokens.errors :as wte] - [app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.update :as wtu] [app.main.ui.workspace.tokens.warnings :as wtw] [app.util.dom :as dom] @@ -64,7 +64,7 @@ (let [path-exists-schema (m/-simple-schema {:type :token/name-exists - :pred #(not (wtt/token-name-path-exists? % tokens-tree)) + :pred #(not (cft/token-name-path-exists? % tokens-tree)) :type-properties {:error/fn #(str "A token already exists at the path: " (:value %))}})] (m/schema [:and @@ -240,7 +240,7 @@ (let [create? (not (instance? ctob/Token token)) token (or token {:type token-type}) token-properties (dwta/get-token-properties token) - color? (wtt/color-token? token) + color? (cft/color-token? token) selected-set-tokens (mf/deref refs/workspace-selected-token-set-tokens) active-theme-tokens (cond-> (mf/deref refs/workspace-active-theme-sets-tokens) @@ -254,7 +254,7 @@ :interactive? true}) token-path (mf/use-memo (mf/deps (:name token)) - #(wtt/token-name->path (:name token))) + #(cft/token-name->path (:name token))) selected-set-tokens-tree (mf/use-memo (mf/deps token-path selected-set-tokens) @@ -329,7 +329,7 @@ value-input-ref (mf/use-ref nil) value-ref (mf/use-var (:value token)) - token-resolve-result* (mf/use-state (get resolved-tokens (wtt/token-identifier token))) + token-resolve-result* (mf/use-state (get resolved-tokens (cft/token-identifier token))) token-resolve-result (deref token-resolve-result*) set-resolve-value diff --git a/frontend/src/app/main/ui/workspace/tokens/token_pill.cljs b/frontend/src/app/main/ui/workspace/tokens/token_pill.cljs index e4654686c7..2e5e5180d5 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token_pill.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token_pill.cljs @@ -11,12 +11,13 @@ (:require [app.common.data :as d] [app.common.files.helpers :as cfh] + [app.common.files.tokens :as cft] [app.main.data.workspace.tokens.application :as dwta] + [app.main.data.workspace.tokens.color :as dwtc] [app.main.refs :as refs] [app.main.ui.components.color-bullet :refer [color-bullet]] [app.main.ui.ds.foundations.assets.icon :refer [icon*]] [app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]] - [app.main.ui.workspace.tokens.token :as wtt] [app.util.dom :as dom] [app.util.i18n :refer [tr]] [cuerdas.core :as str] @@ -80,6 +81,7 @@ :y "Y"}) ;; Helper functions + (defn partially-applied-attr "Translates partially applied attributes based on the dictionary." [app-token-keys is-applied {:keys [attributes all-attributes]}] @@ -156,9 +158,9 @@ (defn- applied-all-attributes? [token selected-shapes attributes] - (let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes) + (let [ids-by-attributes (cft/shapes-ids-by-applied-attributes token selected-shapes attributes) shape-ids (into #{} xf:map-id selected-shapes)] - (wtt/shapes-applied-all? ids-by-attributes shape-ids attributes))) + (cft/shapes-applied-all? ids-by-attributes shape-ids attributes))) (mf/defc token-pill* {::mf/wrap [mf/memo]} @@ -166,7 +168,7 @@ (let [{:keys [name value errors]} token has-selected? (pos? (count selected-shapes)) - is-reference? (wtt/is-reference? token) + is-reference? (cft/is-reference? token) contains-path? (str/includes? name ".") {:keys [attributes all-attributes]} @@ -179,7 +181,7 @@ applied? (if has-selected? - (wtt/shapes-token-applied? token selected-shapes (d/nilv all-attributes attributes)) + (cft/shapes-token-applied? token selected-shapes (d/nilv all-attributes attributes)) false) half-applied? @@ -201,10 +203,10 @@ no-valid-value) color - (when (wtt/color-token? token) + (when (cft/color-token? token) (let [theme-token (get active-theme-tokens (:name token))] - (or (wtt/resolved-token-bullet-color theme-token) - (wtt/resolved-token-bullet-color token)))) + (or (dwtc/resolved-token-bullet-color theme-token) + (dwtc/resolved-token-bullet-color token)))) on-click (mf/use-fn diff --git a/frontend/test/frontend_tests/runner.cljs b/frontend/test/frontend_tests/runner.cljs index 49936ee769..9799fb6aa6 100644 --- a/frontend/test/frontend_tests/runner.cljs +++ b/frontend/test/frontend_tests/runner.cljs @@ -13,7 +13,6 @@ [frontend-tests.tokens.logic.token-data-test] [frontend-tests.tokens.style-dictionary-test] [frontend-tests.tokens.token-form-test] - [frontend-tests.tokens.token-test] [frontend-tests.util-range-tree-test] [frontend-tests.util-simple-math-test] [frontend-tests.util-snap-data-test])) @@ -42,5 +41,4 @@ 'frontend-tests.tokens.logic.token-actions-test 'frontend-tests.tokens.logic.token-data-test 'frontend-tests.tokens.style-dictionary-test - 'frontend-tests.tokens.token-test 'frontend-tests.tokens.token-form-test)) diff --git a/frontend/test/frontend_tests/tokens/helpers/tokens.cljs b/frontend/test/frontend_tests/tokens/helpers/tokens.cljs index fa621df96c..f9f97f7ef3 100644 --- a/frontend/test/frontend_tests/tokens/helpers/tokens.cljs +++ b/frontend/test/frontend_tests/tokens/helpers/tokens.cljs @@ -1,8 +1,8 @@ (ns frontend-tests.tokens.helpers.tokens (:require + [app.common.files.tokens :as cft] [app.common.test-helpers.ids-map :as thi] - [app.common.types.tokens-lib :as ctob] - [app.main.ui.workspace.tokens.token :as wtt])) + [app.common.types.tokens-lib :as ctob])) (defn get-token [file name] (some-> (get-in file [:data :tokens-lib]) @@ -14,7 +14,7 @@ (let [first-page-id (get-in file [:data :pages 0]) shape-id (thi/id shape-label) token (get-token file token-label) - applied-attributes (wtt/attributes-map attributes token)] + applied-attributes (cft/attributes-map attributes token)] (update-in file [:data :pages-index first-page-id :objects shape-id