From e38a943ce0bc41a090ab20ffecd27aa6e7fee2e2 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 1 Jul 2024 13:51:20 +0200 Subject: [PATCH 01/45] Move token-applied? to token ns --- .../ui/workspace/tokens/context_menu.cljs | 3 ++- .../app/main/ui/workspace/tokens/core.cljs | 20 +++---------------- .../app/main/ui/workspace/tokens/sidebar.cljs | 3 ++- .../app/main/ui/workspace/tokens/token.cljs | 14 +++++++++++++ 4 files changed, 21 insertions(+), 19 deletions(-) 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 0b90a0e504..6d4c0e073f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -22,6 +22,7 @@ [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.icons :as i] [app.main.ui.workspace.tokens.core :as wtc] + [app.main.ui.workspace.tokens.token :as wtt] [app.util.dom :as dom] [app.util.timers :as timers] [clojure.set :as set] @@ -212,7 +213,7 @@ (defn additional-actions [{:keys [token-id token-type selected-shapes] :as context-data}] (let [attributes->actions (fn [update-fn coll] (for [{:keys [attributes] :as item} coll] - (let [selected? (wtc/tokens-applied? {:id token-id} selected-shapes attributes)] + (let [selected? (wtt/tokens-applied? {:id token-id} selected-shapes attributes)] (assoc item :action #(update-fn context-data attributes) :selected? selected?))))] diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 682cefde40..b88adac6db 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -9,7 +9,6 @@ [app.common.data :as d :refer [ordered-map]] [app.common.types.shape.radius :as ctsr] [app.common.types.token :as ctt] - [app.libs.file-builder :as fb] [app.main.data.tokens :as dt] [app.main.data.workspace :as udw] [app.main.data.workspace.changes :as dch] @@ -18,6 +17,7 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.workspace.tokens.style-dictionary :as sd] + [app.main.ui.workspace.tokens.token :as wtt] [app.util.dom :as dom] [app.util.webapi :as wapi] [cuerdas.core :as str] @@ -25,20 +25,6 @@ ;; Helpers --------------------------------------------------------------------- -(defn token-applied? - "Test if `token` is applied to a `shape` with the given `token-attributes`." - [token shape token-attributes] - (let [{:keys [id]} token - applied-tokens (get shape :applied-tokens {})] - (some (fn [attr] - (= (get applied-tokens attr) id)) - token-attributes))) - -(defn tokens-applied? - "Test if `token` is applied to to any of `shapes` with the given `token-attributes`." - [token shapes token-attributes] - (some #(token-applied? token % token-attributes) shapes)) - (defn resolve-token-value [{:keys [value resolved-value] :as token}] (or resolved-value @@ -74,7 +60,7 @@ (->> (tokens-name-map tokens) (map (fn [[_k {:keys [name] :as item}]] (cond-> (assoc item :label name) - (token-applied? item shape (or selected-attributes attributes)) (assoc :selected? true)))))) + (wtt/token-applied? item shape (or selected-attributes attributes)) (assoc :selected? true)))))) ;; Update functions ------------------------------------------------------------ @@ -83,7 +69,7 @@ :or {on-apply dt/update-token-from-attributes}} token-type-props shape-ids (->> selected-shapes (eduction - (remove #(tokens-applied? token % attributes)) + (remove #(wtt/tokens-applied? token % attributes)) (map :id)))] (p/let [sd-tokens (sd/resolve-workspace-tokens+ {:debug? true})] (let [resolved-token (get sd-tokens (:id token)) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 3ab3519e01..3b25a7d78f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -16,6 +16,7 @@ [app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.tokens.core :as wtc] [app.main.ui.workspace.tokens.style-dictionary :as sd] + [app.main.ui.workspace.tokens.token :as wtt] [app.util.dom :as dom] [cuerdas.core :as str] [okulary.core :as l] @@ -121,7 +122,7 @@ [:& token-pill {:key (:id token) :token token - :highlighted? (wtc/tokens-applied? token selected-shapes attributes) + :highlighted? (wtt/tokens-applied? token selected-shapes attributes) :on-click #(on-token-pill-click % token) :on-context-menu #(on-context-menu % token)}])]])]])) diff --git a/frontend/src/app/main/ui/workspace/tokens/token.cljs b/frontend/src/app/main/ui/workspace/tokens/token.cljs index ce288113d0..8a742b4d53 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token.cljs @@ -2,6 +2,20 @@ (:require [cuerdas.core :as str])) +(defn token-applied? + "Test if `token` is applied to a `shape` with the given `token-attributes`." + [token shape token-attributes] + (let [{:keys [id]} token + applied-tokens (get shape :applied-tokens {})] + (some (fn [attr] + (= (get applied-tokens attr) id)) + token-attributes))) + +(defn tokens-applied? + "Test if `token` is applied to to any of `shapes` with the given `token-attributes`." + [token shapes token-attributes] + (some #(token-applied? token % token-attributes) shapes)) + (defn token-name->path "Splits token-name into a path vector split by `.` characters. From cf07de3bcfe4ff4e5f583e4287ed622e12c119cf Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 1 Jul 2024 14:05:06 +0200 Subject: [PATCH 02/45] Add tests for token-applied? --- frontend/test/token_tests/token_test.cljs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/frontend/test/token_tests/token_test.cljs b/frontend/test/token_tests/token_test.cljs index 618dc9a218..2767bf3359 100644 --- a/frontend/test/token_tests/token_test.cljs +++ b/frontend/test/token_tests/token_test.cljs @@ -9,6 +9,29 @@ [app.main.ui.workspace.tokens.token :as wtt] [cljs.test :as t :include-macros true])) +(t/deftest token-applied-test + (t/testing "matches passed token with `:token-attributes`" + (t/is (true? (wtt/token-applied? {:id :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/testing "does't match passed token `:id`" + (t/is (nil? (wtt/token-applied? {:id :b} {:applied-tokens {:x :a}} #{:x})))) + (t/testing "doesn't match passed `:token-attributes`" + (t/is (nil? (wtt/token-applied? {:id :a} {:applied-tokens {:x :a}} #{:y}))))) + +(t/deftest tokens-applied-test + (t/testing "is true when single shape matches the token and attributes" + (t/is (true? (wtt/tokens-applied? {:id :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/tokens-applied? {:id :a} [{:applied-tokens {:x :b}} + {:applied-tokens {:x :b}}] + #{:x}))) + (t/is (nil? (wtt/tokens-applied? {:id :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"))) From 5cef23267c2ce443046c0080325de6ec55536e45 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Mon, 1 Jul 2024 14:14:36 +0200 Subject: [PATCH 03/45] Move to tokens ns, add test --- .../src/app/main/ui/workspace/tokens/core.cljs | 18 +----------------- .../app/main/ui/workspace/tokens/token.cljs | 8 ++++++++ frontend/test/token_tests/token_test.cljs | 7 +++++++ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index b88adac6db..b4e0c13f20 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -39,25 +39,9 @@ (->> (vals tokens) (group-by :type))) -(defn tokens-name-map - "Convert tokens into a map with their `:name` as the key. - - E.g.: {\"sm\" {:token-type :border-radius :id #uuid \"000\" ...}}" - [tokens] - (->> (map (fn [{:keys [name] :as token}] [name token]) tokens) - (into {}))) - -(defn tokens-name-map-for-type - "Convert tokens with `token-type` into a map with their `:name` as the key. - - E.g.: {\"sm\" {:token-type :border-radius :id #uuid \"000\" ...}}" - [token-type tokens] - (-> (group-tokens-by-type tokens) - (get token-type []) - (tokens-name-map))) (defn tokens-name-map->select-options [{:keys [shape tokens attributes selected-attributes]}] - (->> (tokens-name-map tokens) + (->> (wtt/token-names-map tokens) (map (fn [[_k {:keys [name] :as item}]] (cond-> (assoc item :label name) (wtt/token-applied? item shape (or selected-attributes attributes)) (assoc :selected? true)))))) diff --git a/frontend/src/app/main/ui/workspace/tokens/token.cljs b/frontend/src/app/main/ui/workspace/tokens/token.cljs index 8a742b4d53..1750db9f36 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token.cljs @@ -35,6 +35,14 @@ {:path (seq path) :selector selector})) +(defn token-names-map + "Convert tokens into a map with their `:name` as the key. + + E.g.: {\"sm\" {:token-type :border-radius :id #uuid \"000\" ...}}" + [tokens] + (->> (map (fn [{:keys [name] :as token}] [name token]) tokens) + (into {}))) + (defn token-names-tree "Convert tokens into a nested tree with their `:name` as the path." [tokens] diff --git a/frontend/test/token_tests/token_test.cljs b/frontend/test/token_tests/token_test.cljs index 2767bf3359..3486bed83c 100644 --- a/frontend/test/token_tests/token_test.cljs +++ b/frontend/test/token_tests/token_test.cljs @@ -37,6 +37,13 @@ (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/deftest tokens-name-map-test + (t/testing "creates a a names map from tokens" + (t/is (= {"border-radius.sm" {:name "border-radius.sm", :value "10"} + "border-radius.md" {:name "border-radius.md", :value "20"}} + (wtt/token-names-map [{:name "border-radius.sm" :value "10"} + {:name "border-radius.md" :value "20"}]))))) + (t/deftest tokens-name-tree-test (t/is (= {"foo" {"bar" From f2358b98273cb767f2e0b9b17b381fd3f8e9435a Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 2 Jul 2024 08:22:27 +0200 Subject: [PATCH 04/45] Use toggle function --- .../ui/workspace/tokens/context_menu.cljs | 2 +- .../app/main/ui/workspace/tokens/core.cljs | 43 ++++++++++++++++++- .../app/main/ui/workspace/tokens/sidebar.cljs | 8 ++-- .../app/main/ui/workspace/tokens/token.cljs | 2 +- frontend/test/token_tests/token_test.cljs | 6 +-- 5 files changed, 50 insertions(+), 11 deletions(-) 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 6d4c0e073f..352268480c 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -213,7 +213,7 @@ (defn additional-actions [{:keys [token-id token-type selected-shapes] :as context-data}] (let [attributes->actions (fn [update-fn coll] (for [{:keys [attributes] :as item} coll] - (let [selected? (wtt/tokens-applied? {:id token-id} selected-shapes attributes)] + (let [selected? (wtt/shapes-token-applied? {:id token-id} selected-shapes attributes)] (assoc item :action #(update-fn context-data attributes) :selected? selected?))))] diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index b4e0c13f20..b375109dae 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -21,7 +21,8 @@ [app.util.dom :as dom] [app.util.webapi :as wapi] [cuerdas.core :as str] - [promesa.core :as p])) + [promesa.core :as p] + [clojure.set :as set])) ;; Helpers --------------------------------------------------------------------- @@ -48,13 +49,51 @@ ;; Update functions ------------------------------------------------------------ +(defn apply-tokens? + [{:keys [attributes token shapes] :as _props}] + (let [{:keys [with-token without-token]} (group-by + (fn [shape] + (if (wtt/shapes-token-applied? token shape attributes) + :with-token + :without-token)) + shapes)] + (and (empty? with-token) (seq without-token)))) + +(defn on-add-token [{:keys [token-type-props token shapes] :as _props}] + (p/let [sd-tokens (sd/resolve-workspace-tokens+)] + (let [{:keys [attributes on-update-shape]} token-type-props + shape-ids (map :id shapes) + resolved-value (-> (get sd-tokens (:id token)) + (resolve-token-value)) + tokenized-attributes (->> (map (fn [attr] {attr (:id token)}) attributes) + (into {}))] + (st/emit! + (dch/update-shapes shape-ids (fn [shape] (update shape :applied-tokens merge tokenized-attributes)))) + (on-update-shape resolved-value shape-ids attributes)))) + +(def remove-keys #(apply dissoc %1 %2)) + +(defn on-remove-token [{:keys [token-type-props shapes] :as _props}] + (st/emit! + (dch/update-shapes (map :id shapes) + (fn [shape] + (update shape :applied-tokens remove-keys (:attributes token-type-props)))))) + +(defn on-toggle-token + [{:keys [token-type-props token shapes] :as props}] + (let [remove-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props))] + (if remove-tokens? + (on-remove-token props) + (on-add-token props)))) + (defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}] (let [{:keys [attributes on-apply on-update-shape] :or {on-apply dt/update-token-from-attributes}} token-type-props shape-ids (->> selected-shapes (eduction - (remove #(wtt/tokens-applied? token % attributes)) + (remove #(wtt/shapes-token-applied? token % attributes)) (map :id)))] + (p/let [sd-tokens (sd/resolve-workspace-tokens+ {:debug? true})] (let [resolved-token (get sd-tokens (:id token)) resolved-token-value (resolve-token-value resolved-token)] diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 3b25a7d78f..0addb4fad9 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -99,9 +99,9 @@ (mf/deps selected-shapes token-type-props) (fn [event token] (dom/stop-propagation event) - (wtc/on-apply-token {:token token - :token-type-props token-type-props - :selected-shapes selected-shapes}))) + (wtc/on-toggle-token {:token token + :shapes selected-shapes + :token-type-props token-type-props}))) tokens-count (count tokens)] [:div {:on-click on-toggle-open-click} [:& cmm/asset-section {:icon (mf/fnc icon-wrapper [_] @@ -122,7 +122,7 @@ [:& token-pill {:key (:id token) :token token - :highlighted? (wtt/tokens-applied? token selected-shapes attributes) + :highlighted? (wtt/shapes-token-applied? token selected-shapes attributes) :on-click #(on-token-pill-click % token) :on-context-menu #(on-context-menu % token)}])]])]])) diff --git a/frontend/src/app/main/ui/workspace/tokens/token.cljs b/frontend/src/app/main/ui/workspace/tokens/token.cljs index 1750db9f36..e52079f8f8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token.cljs @@ -11,7 +11,7 @@ (= (get applied-tokens attr) id)) token-attributes))) -(defn tokens-applied? +(defn shapes-token-applied? "Test if `token` is applied to to any of `shapes` with the given `token-attributes`." [token shapes token-attributes] (some #(token-applied? token % token-attributes) shapes)) diff --git a/frontend/test/token_tests/token_test.cljs b/frontend/test/token_tests/token_test.cljs index 3486bed83c..deea17fc0a 100644 --- a/frontend/test/token_tests/token_test.cljs +++ b/frontend/test/token_tests/token_test.cljs @@ -21,14 +21,14 @@ (t/deftest tokens-applied-test (t/testing "is true when single shape matches the token and attributes" - (t/is (true? (wtt/tokens-applied? {:id :a} [{:applied-tokens {:x :a}} + (t/is (true? (wtt/shapes-token-applied? {:id :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/tokens-applied? {:id :a} [{:applied-tokens {:x :b}} + (t/is (nil? (wtt/shapes-token-applied? {:id :a} [{:applied-tokens {:x :b}} {:applied-tokens {:x :b}}] #{:x}))) - (t/is (nil? (wtt/tokens-applied? {:id :a} [{:applied-tokens {:x :a}} + (t/is (nil? (wtt/shapes-token-applied? {:id :a} [{:applied-tokens {:x :a}} {:applied-tokens {:x :a}}] #{:y}))))) From c486ea81f457f2a4c905e68dfb1e111a9b00f83b Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 2 Jul 2024 15:03:04 +0200 Subject: [PATCH 05/45] Cleanup --- frontend/test/token_tests/token_test.cljs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/test/token_tests/token_test.cljs b/frontend/test/token_tests/token_test.cljs index deea17fc0a..c999c74cae 100644 --- a/frontend/test/token_tests/token_test.cljs +++ b/frontend/test/token_tests/token_test.cljs @@ -22,14 +22,14 @@ (t/deftest tokens-applied-test (t/testing "is true when single shape matches the token and attributes" (t/is (true? (wtt/shapes-token-applied? {:id :a} [{:applied-tokens {:x :a}} - {:applied-tokens {:x :b}}] + {:applied-tokens {:x :b}}] #{:x})))) (t/testing "is false when no shape matches the token or attributes" (t/is (nil? (wtt/shapes-token-applied? {:id :a} [{:applied-tokens {:x :b}} - {:applied-tokens {:x :b}}] + {:applied-tokens {:x :b}}] #{:x}))) (t/is (nil? (wtt/shapes-token-applied? {:id :a} [{:applied-tokens {:x :a}} - {:applied-tokens {:x :a}}] + {:applied-tokens {:x :a}}] #{:y}))))) (t/deftest name->path-test From 10d92f598c1b14ee0f9e27115a2b59ab39e50813 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 2 Jul 2024 15:03:09 +0200 Subject: [PATCH 06/45] Add nodemon watcher --- frontend/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/package.json b/frontend/package.json index c4b5b3c950..a561708646 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,6 +29,7 @@ "token-test:compile": "clojure -M:dev:shadow-cljs compile test-esm --config-merge '{:autorun false}'", "token-test:run": "bun target/tests-esm.cjs", "token-test:watch": "clojure -M:dev:shadow-cljs watch test-esm", + "token-test:nodemon": "nodemon --watch ./target/tests-esm.cjs --exec 'bun run token-test:run'", "token-test": "yarn run token-test:compile && yarn run token-test:run", "translations:validate": "node ./scripts/validate-translations.js", "translations:find-unused": "node ./scripts/find-unused-translations.js", From 3e5126251c194a4cf98e9b7f1b0dca69495c65ef Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 2 Jul 2024 15:19:31 +0200 Subject: [PATCH 07/45] Add failing logic test --- .../app/main/ui/workspace/tokens/core.cljs | 5 +- .../token_tests/logic/token_actions_test.cljs | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 frontend/test/token_tests/logic/token_actions_test.cljs diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index b375109dae..9a025362dd 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -59,10 +59,9 @@ shapes)] (and (empty? with-token) (seq without-token)))) -(defn on-add-token [{:keys [token-type-props token shapes] :as _props}] +(defn on-add-token [{:keys [token-type-props token shape-ids] :as _props}] (p/let [sd-tokens (sd/resolve-workspace-tokens+)] (let [{:keys [attributes on-update-shape]} token-type-props - shape-ids (map :id shapes) resolved-value (-> (get sd-tokens (:id token)) (resolve-token-value)) tokenized-attributes (->> (map (fn [attr] {attr (:id token)}) attributes) @@ -84,7 +83,7 @@ (let [remove-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props))] (if remove-tokens? (on-remove-token props) - (on-add-token props)))) + (on-add-token (assoc props :shape-ids (map :id shapes)))))) (defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}] (let [{:keys [attributes on-apply on-update-shape] diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs new file mode 100644 index 0000000000..18711cb39e --- /dev/null +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -0,0 +1,72 @@ +(ns token-tests.logic.token-actions-test + (:require + [app.common.test-helpers.compositions :as ctho] + [app.common.test-helpers.files :as cthf] + [app.common.test-helpers.ids-map :as cthi] + [app.main.ui.workspace.tokens.core :as wtc] + [cljs.test :as t :include-macros true] + [frontend-tests.helpers.pages :as thp] + [frontend-tests.helpers.state :as ths])) + +(t/use-fixtures :each + {:before thp/reset-idmap!}) + +(defn- setup-file + [] + (-> (cthf/sample-file :file-1) + (ctho/add-rect :file-1 :rect-1 {}) + (ctho/add-rect :file-1 :rect-2 {}) + (ctho/add-rect :file-1 :rect-3 {}))) + +(t/deftest test-update-shape + (t/async + done + (let [;; ==== Setup + file (setup-file) + store (ths/setup-store file) + + ;; ==== Action + events [(wtc/on-add-token {:token-type-props {:attributes {:rx :ry} + :on-update-shape #(fn [& _])} + :token {:id (random-uuid)}})]] + (ths/run-store + store done events + (fn [new-state] + (let [;; ==== Get + shape1' (get-in new-state [:workspace-data + :pages-index + (cthi/id :page1) + :objects + (cthi/id :shape1)]) + fills' (:fills shape1') + fill' (first fills')] + + ;; ==== Check + (t/is (some? shape1')) + (t/is (= (count fills') 1)) + (t/is (= (:fill-color fill') "#fabada")) + (t/is (= (:fill-opacity fill') 1)))))))) + + + +(comment + (defn make-printable + "Convert records that are not printable by cider inspect into regular maps." + [coll] + (letfn [(stringifyable? [x] + (not (or (map? x) + (sequential? x) + (keyword? x) + (number? x) + (uuid? x))))] + (clojure.walk/postwalk #(cond->> % + (record? %) (into {}) + (stringifyable? %) str) + coll))) + + (-> (cthf/sample-file :file-1) + (assoc :tokens {}) + (make-printable)) + + (make-printable (setup-file)) + nil) From 50635ae879cb04ab1fdee708d34f308e2020bde4 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Tue, 2 Jul 2024 16:06:41 +0200 Subject: [PATCH 08/45] Found error in handler logic, need rx streams --- .../token_tests/logic/token_actions_test.cljs | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 18711cb39e..e4679130a4 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -2,7 +2,9 @@ (:require [app.common.test-helpers.compositions :as ctho] [app.common.test-helpers.files :as cthf] - [app.common.test-helpers.ids-map :as cthi] + [app.common.test-helpers.shapes :as cths] + [app.main.data.workspace.changes :as dch] + [app.main.data.workspace.selection :as dws] [app.main.ui.workspace.tokens.core :as wtc] [cljs.test :as t :include-macros true] [frontend-tests.helpers.pages :as thp] @@ -11,45 +13,55 @@ (t/use-fixtures :each {:before thp/reset-idmap!}) + (defn- setup-file [] - (-> (cthf/sample-file :file-1) - (ctho/add-rect :file-1 :rect-1 {}) - (ctho/add-rect :file-1 :rect-2 {}) - (ctho/add-rect :file-1 :rect-3 {}))) + (let [token-id (random-uuid)] + (-> (cthf/sample-file :file-1 :page-label :page-1) + (ctho/add-rect :rect-1 {}) + (ctho/add-rect :rect-2 {}) + (ctho/add-rect :rect-3 {}) + (assoc-in [:data :tokens] {token-id {:id token-id + :value "12" + :name "sm" + :type :border-radius}})))) (t/deftest test-update-shape (t/async done (let [;; ==== Setup - file (setup-file) - store (ths/setup-store file) + file (setup-file) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) ;; ==== Action - events [(wtc/on-add-token {:token-type-props {:attributes {:rx :ry} - :on-update-shape #(fn [& _])} - :token {:id (random-uuid)}})]] + events [(dws/select-shape (:id rect-1)) + (dch/update-shapes [(:id rect-1)] (fn [shape] (assoc shape :applied-tokens {:rx (random-uuid)}))) + #_(wtc/on-add-token {:token-type-props {:attributes {:rx :ry} + :on-update-shape #(fn [& _])} + :shape-ids [(:id rect-1)] + :token {:id (random-uuid)}})]] (ths/run-store store done events (fn [new-state] - (let [;; ==== Get - shape1' (get-in new-state [:workspace-data - :pages-index - (cthi/id :page1) - :objects - (cthi/id :shape1)]) - fills' (:fills shape1') - fill' (first fills')] + (let [file' (ths/get-file-from-store new-state) + page' (cthf/current-page file') + rect-1' (cths/get-shape file' :rect-1) + ;; ==== Get + #_#_rect-1' (get-in new-state [:workspace-data + :pages-index + (cthi/id :page-1) + :objects + (cthi/id :rect-1)])] + + ;; ==== Check + (t/is (some? (:applied-tokens rect-1'))))))))) - ;; ==== Check - (t/is (some? shape1')) - (t/is (= (count fills') 1)) - (t/is (= (:fill-color fill') "#fabada")) - (t/is (= (:fill-opacity fill') 1)))))))) (comment + (t/run-tests) (defn make-printable "Convert records that are not printable by cider inspect into regular maps." [coll] From 97db3c29ca88959e6bd469783dfe242ca95ceafe Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 3 Jul 2024 09:50:54 +0200 Subject: [PATCH 09/45] Trying to convert to rx structure --- .../app/main/ui/workspace/tokens/core.cljs | 58 +++++++++---------- .../app/main/ui/workspace/tokens/sidebar.cljs | 7 ++- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 9a025362dd..f150e2c08e 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -20,9 +20,10 @@ [app.main.ui.workspace.tokens.token :as wtt] [app.util.dom :as dom] [app.util.webapi :as wapi] + [beicon.v2.core :as rx] [cuerdas.core :as str] - [promesa.core :as p] - [clojure.set :as set])) + [potok.v2.core :as ptk] + [promesa.core :as p])) ;; Helpers --------------------------------------------------------------------- @@ -59,31 +60,29 @@ shapes)] (and (empty? with-token) (seq without-token)))) + + + + + (defn on-add-token [{:keys [token-type-props token shape-ids] :as _props}] - (p/let [sd-tokens (sd/resolve-workspace-tokens+)] - (let [{:keys [attributes on-update-shape]} token-type-props - resolved-value (-> (get sd-tokens (:id token)) - (resolve-token-value)) - tokenized-attributes (->> (map (fn [attr] {attr (:id token)}) attributes) - (into {}))] - (st/emit! - (dch/update-shapes shape-ids (fn [shape] (update shape :applied-tokens merge tokenized-attributes)))) - (on-update-shape resolved-value shape-ids attributes)))) - -(def remove-keys #(apply dissoc %1 %2)) - -(defn on-remove-token [{:keys [token-type-props shapes] :as _props}] - (st/emit! - (dch/update-shapes (map :id shapes) - (fn [shape] - (update shape :applied-tokens remove-keys (:attributes token-type-props)))))) + (ptk/reify ::on-add-token + ptk/WatchEvent + (watch [_ _ _] + (rx/of + (p/resolved 1) + (dch/update-shapes shape-ids (fn [shape] (assoc shape :applied-tokens {:rx (:id token)}))))))) (defn on-toggle-token [{:keys [token-type-props token shapes] :as props}] - (let [remove-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props))] - (if remove-tokens? - (on-remove-token props) - (on-add-token (assoc props :shape-ids (map :id shapes)))))) + (ptk/reify ::on-toggle-token + ptk/WatchEvent + (watch [it state _] + (let [remove-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props)) + shape-ids (map :id shapes)] + (if remove-tokens? + (rx/of (dch/update-shapes shape-ids (fn [shape] (assoc shape :applied-tokens {})))) + (rx/of (on-add-token (assoc props :shape-ids shape-ids)))))))) (defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}] (let [{:keys [attributes on-apply on-update-shape] @@ -103,13 +102,12 @@ (on-update-shape resolved-token-value shape-ids attributes)))))) (defn update-shape-radius [value shape-ids] - (st/emit! - (dch/update-shapes shape-ids - (fn [shape] - (when (ctsr/has-radius? shape) - (ctsr/set-radius-1 shape value))) - {:reg-objects? true - :attrs ctt/border-radius-keys}))) + (dch/update-shapes shape-ids + (fn [shape] + (when (ctsr/has-radius? shape) + (ctsr/set-radius-1 shape value))) + {:reg-objects? true + :attrs ctt/border-radius-keys})) (defn update-shape-dimensions [value shape-ids] (st/emit! diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 0addb4fad9..1d58637800 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -99,9 +99,10 @@ (mf/deps selected-shapes token-type-props) (fn [event token] (dom/stop-propagation event) - (wtc/on-toggle-token {:token token - :shapes selected-shapes - :token-type-props token-type-props}))) + (st/emit! + (wtc/on-toggle-token {:token token + :shapes selected-shapes + :token-type-props token-type-props})))) tokens-count (count tokens)] [:div {:on-click on-toggle-open-click} [:& cmm/asset-section {:icon (mf/fnc icon-wrapper [_] From 1e70a4d714b543b409f1ffb7530286ecf2965b35 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 3 Jul 2024 11:09:50 +0200 Subject: [PATCH 10/45] Implement using rx observables instead of side-effects --- .../app/main/ui/workspace/tokens/core.cljs | 50 +++++++++++++++---- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index f150e2c08e..6974b35c4d 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -60,29 +60,59 @@ shapes)] (and (empty? with-token) (seq without-token)))) +(defn apply-token + "Applies `attributes` to `token` for `shapes-ids`. + When a `on-shape-update` function is passed, use this to update the shape attributes as well." + [{:keys [attributes token shape-ids on-update-shape] :as _props}] + (ptk/reify ::apply-token + ptk/WatchEvent + (watch [_ _ _] + (->> (rx/from (sd/resolve-workspace-tokens+)) + (rx/mapcat + (fn [sd-tokens] + (let [resolved-value (-> (get sd-tokens (:id token)) + (resolve-token-value)) + tokenized-attributes (->> (map (fn [attr] {attr (:id token)}) attributes) + (into {}))] + (rx/of + (dch/update-shapes shape-ids (fn [shape] (update shape :applied-tokens merge tokenized-attributes))) + (when on-update-shape + (on-update-shape resolved-value shape-ids attributes)))))))))) +(def remove-keys #(apply dissoc %1 %2)) +(defn unapply-token + "Removes `attributes` that match `token` for `shape-ids`. - -(defn on-add-token [{:keys [token-type-props token shape-ids] :as _props}] - (ptk/reify ::on-add-token + Doesn't update shape attributes." + [{:keys [attributes shape-ids] :as _props}] + (ptk/reify ::unapply-token ptk/WatchEvent (watch [_ _ _] (rx/of - (p/resolved 1) - (dch/update-shapes shape-ids (fn [shape] (assoc shape :applied-tokens {:rx (:id token)}))))))) + (dch/update-shapes + shape-ids + (fn [shape] + (update shape :applied-tokens remove-keys attributes))))))) (defn on-toggle-token - [{:keys [token-type-props token shapes] :as props}] + [{:keys [token-type-props token shapes] :as _props}] (ptk/reify ::on-toggle-token ptk/WatchEvent - (watch [it state _] - (let [remove-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props)) + (watch [_ _ _] + (let [{:keys [attributes on-update-shape]} token-type-props + remove-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props)) shape-ids (map :id shapes)] (if remove-tokens? - (rx/of (dch/update-shapes shape-ids (fn [shape] (assoc shape :applied-tokens {})))) - (rx/of (on-add-token (assoc props :shape-ids shape-ids)))))))) + (rx/of + (unapply-token {:attributes attributes + :shape-ids shape-ids})) + (rx/of + (apply-token {:attributes attributes + :token token + :shape-ids shape-ids + :on-update-shape on-update-shape}))))))) (defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}] (let [{:keys [attributes on-apply on-update-shape] From e203646085b33c009abf0adc3e3ea8d61e47a491 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 3 Jul 2024 11:16:16 +0200 Subject: [PATCH 11/45] Naming --- frontend/src/app/main/ui/workspace/tokens/core.cljs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 6974b35c4d..e4b6988175 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -102,9 +102,9 @@ ptk/WatchEvent (watch [_ _ _] (let [{:keys [attributes on-update-shape]} token-type-props - remove-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props)) + unapply-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props)) shape-ids (map :id shapes)] - (if remove-tokens? + (if unapply-tokens? (rx/of (unapply-token {:attributes attributes :shape-ids shape-ids})) From ed7aad6c4e28ed1f6ee131a25a9bda0cdf4ddf01 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 3 Jul 2024 16:11:39 +0200 Subject: [PATCH 12/45] Async token event tests working --- .../app/main/ui/workspace/tokens/core.cljs | 25 +++++--- .../ui/workspace/tokens/style_dictionary.cljs | 12 ++-- frontend/test/token_tests/helpers/state.cljs | 38 +++++++++++ .../token_tests/logic/token_actions_test.cljs | 64 +++++++++---------- 4 files changed, 90 insertions(+), 49 deletions(-) create mode 100644 frontend/test/token_tests/helpers/state.cljs diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index e4b6988175..ddeab24242 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -60,15 +60,19 @@ shapes)] (and (empty? with-token) (seq without-token)))) -(defn apply-token - "Applies `attributes` to `token` for `shapes-ids`. - - When a `on-shape-update` function is passed, use this to update the shape attributes as well." - [{:keys [attributes token shape-ids on-update-shape] :as _props}] - (ptk/reify ::apply-token +(defn done + [] + (ptk/reify ::done ptk/WatchEvent (watch [_ _ _] - (->> (rx/from (sd/resolve-workspace-tokens+)) + (rx/from (p/resolved true))))) + +(defn apply-token + [{:keys [attributes shape-ids token on-update-shape cb] :as _props}] + (ptk/reify ::apply-token + ptk/WatchEvent + (watch [_ state _] + (->> (rx/from (sd/resolve-tokens+ (get-in state [:workspace-data :tokens]))) (rx/mapcat (fn [sd-tokens] (let [resolved-value (-> (get sd-tokens (:id token)) @@ -77,8 +81,13 @@ (into {}))] (rx/of (dch/update-shapes shape-ids (fn [shape] (update shape :applied-tokens merge tokenized-attributes))) + (when cb + (cb)) (when on-update-shape - (on-update-shape resolved-value shape-ids attributes)))))))))) + (on-update-shape resolved-value shape-ids attributes)))) + #_(rx/of + (dch/update-shapes shape-ids #(assoc % :applied-tokens {:found 1}))))))))) + (def remove-keys #(apply dissoc %1 %2)) diff --git a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs index 73e68ad4cc..e4e965df72 100644 --- a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs @@ -53,7 +53,7 @@ "Resolves references and math expressions using StyleDictionary. Returns a promise with the resolved dictionary." [tokens & {:keys [debug?] :as config}] - (let [performance-start (js/window.performance.now) + (let [#_#_performance-start (js/window.performance.now) sd (tokens->style-dictionary+ tokens config)] (when debug? (js/console.log "StyleDictionary" sd)) @@ -61,12 +61,12 @@ (.buildAllPlatforms "json") (.catch js/console.error) (.then (fn [^js resp] - (let [performance-end (js/window.performance.now) - duration-ms (- performance-end performance-start) + (let [#_#_performance-end (js/window.performance.now) + #_#_duration-ms (- performance-end performance-start) resolved-tokens (.-allTokens resp)] - (when debug? - (js/console.log "Time elapsed" duration-ms "ms") - (js/console.log "Resolved tokens" resolved-tokens)) + #_(when debug? + (js/console.log "Time elapsed" duration-ms "ms") + (js/console.log "Resolved tokens" resolved-tokens)) resolved-tokens)))))) (defn humanize-errors [{:keys [errors value] :as _token}] diff --git a/frontend/test/token_tests/helpers/state.cljs b/frontend/test/token_tests/helpers/state.cljs new file mode 100644 index 0000000000..07d9fe0bf3 --- /dev/null +++ b/frontend/test/token_tests/helpers/state.cljs @@ -0,0 +1,38 @@ +(ns token-tests.helpers.state + (:require + [beicon.v2.core :as rx] + [potok.v2.core :as ptk])) + +(defn stop-on + "Helper function to be used with async version of run-store. + + Will stop the execution after event with `event-type` has completed." + [event-type] + (fn [stream] + (->> stream + (rx/tap #(prn (ptk/type %))) + (rx/filter #(ptk/type? event-type %))))) + +;; Support for async events in tests +;; https://chat.kaleidos.net/penpot-partners/pl/tz1yoes3w3fr9qanxqpuhoz3ch +(defn run-store + "Async version of `frontend-tests.helpers.state/run-store`." + ([store done events completed-cb] + (run-store store done events completed-cb nil)) + ([store done events completed-cb stopper] + (let [stream (ptk/input-stream store)] + (->> stream + (rx/take-until (if stopper + (stopper stream) + (rx/filter #(= :the/end %) stream))) + (rx/last) + (rx/tap (fn [] + (completed-cb @store))) + (rx/subs! (fn [_] (done)) + (fn [cause] + (js/console.log "[error]:" cause)) + (fn [_] + (js/console.log "[complete]")))) + (doall (for [event events] + (ptk/emit! store event))) + (ptk/emit! store :the/end)))) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index e4679130a4..0256dd9b85 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -4,11 +4,12 @@ [app.common.test-helpers.files :as cthf] [app.common.test-helpers.shapes :as cths] [app.main.data.workspace.changes :as dch] - [app.main.data.workspace.selection :as dws] [app.main.ui.workspace.tokens.core :as wtc] + [beicon.v2.core :as rx] [cljs.test :as t :include-macros true] [frontend-tests.helpers.pages :as thp] - [frontend-tests.helpers.state :as ths])) + [frontend-tests.helpers.state :as ths] + [potok.v2.core :as ptk])) (t/use-fixtures :each {:before thp/reset-idmap!}) @@ -21,43 +22,36 @@ (ctho/add-rect :rect-1 {}) (ctho/add-rect :rect-2 {}) (ctho/add-rect :rect-3 {}) - (assoc-in [:data :tokens] {token-id {:id token-id - :value "12" - :name "sm" - :type :border-radius}})))) + (assoc-in [:data :tokens] {#uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1" + {:id #uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1" + :value "12" + :name "sm" + :type :border-radius}})))) -(t/deftest test-update-shape +(t/deftest test-apply-token (t/async - done - (let [;; ==== Setup - file (setup-file) - store (ths/setup-store file) - rect-1 (cths/get-shape file :rect-1) - - ;; ==== Action - events [(dws/select-shape (:id rect-1)) - (dch/update-shapes [(:id rect-1)] (fn [shape] (assoc shape :applied-tokens {:rx (random-uuid)}))) - #_(wtc/on-add-token {:token-type-props {:attributes {:rx :ry} - :on-update-shape #(fn [& _])} - :shape-ids [(:id rect-1)] - :token {:id (random-uuid)}})]] - (ths/run-store - store done events - (fn [new-state] - (let [file' (ths/get-file-from-store new-state) - page' (cthf/current-page file') - rect-1' (cths/get-shape file' :rect-1) - ;; ==== Get - #_#_rect-1' (get-in new-state [:workspace-data - :pages-index - (cthi/id :page-1) - :objects - (cthi/id :rect-1)])] - - ;; ==== Check - (t/is (some? (:applied-tokens rect-1'))))))))) + done + (let [file (setup-file) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + events [(wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:rx :ry} + :token {:id #uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1"} + :on-update-shape wtc/update-shape-radius})]] + (ths/run-store + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + rect-1' (cths/get-shape file' :rect-1)] + (t/is (some? (:applied-tokens rect-1'))) + (t/is (= (:rx (:applied-tokens rect-1')) #uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1")) + (t/is (= (:rx rect-1') 12)))) + (fn [stream] + (->> stream + ;; (rx/tap #(prn (ptk/type %))) + (rx/filter #(ptk/type? :app.main.data.workspace.changes/send-update-indices %)))))))) (comment From a7e735bd816e09f336b2f503bbda730fee67dca2 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 3 Jul 2024 17:04:47 +0200 Subject: [PATCH 13/45] Add helper for asnc stores --- frontend/test/token_tests/helpers/state.cljs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/frontend/test/token_tests/helpers/state.cljs b/frontend/test/token_tests/helpers/state.cljs index 07d9fe0bf3..40fee3c492 100644 --- a/frontend/test/token_tests/helpers/state.cljs +++ b/frontend/test/token_tests/helpers/state.cljs @@ -10,9 +10,13 @@ [event-type] (fn [stream] (->> stream - (rx/tap #(prn (ptk/type %))) + #_(rx/tap #(prn (ptk/type %))) (rx/filter #(ptk/type? event-type %))))) +(def stop-on-send-update-indices + "Stops on `send-update-indices` function being called, which should be the last function of an event chain." + (stop-on :app.main.data.workspace.changes/send-update-indices)) + ;; Support for async events in tests ;; https://chat.kaleidos.net/penpot-partners/pl/tz1yoes3w3fr9qanxqpuhoz3ch (defn run-store @@ -36,3 +40,10 @@ (doall (for [event events] (ptk/emit! store event))) (ptk/emit! store :the/end)))) + +(defn run-store-async + "Helper version of `run-store` that automatically stops on the `send-update-indices` event" + ([store done events completed-cb] + (run-store store done events completed-cb stop-on-send-update-indices)) + ([store done events completed-cb stop-on] + (run-store store done events completed-cb stop-on))) From 219d184e6c530fa7f81660e7a333463e78a0a73b Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 3 Jul 2024 17:06:08 +0200 Subject: [PATCH 14/45] Add multiple tokens for tests --- .../token_tests/logic/token_actions_test.cljs | 55 ++++++++++++------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 0256dd9b85..69abfee67d 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -6,6 +6,7 @@ [app.main.data.workspace.changes :as dch] [app.main.ui.workspace.tokens.core :as wtc] [beicon.v2.core :as rx] + [token-tests.helpers.state :as tohs] [cljs.test :as t :include-macros true] [frontend-tests.helpers.pages :as thp] [frontend-tests.helpers.state :as ths] @@ -15,18 +16,30 @@ {:before thp/reset-idmap!}) +(def radius-token + {:id #uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1" + :value "12" + :name "sm" + :type :border-radius}) + +(def radius-ref-token + {:id #uuid "4c2bf84d-3a98-47a2-8e3c-e7fb037a615c" + :value "{sm} * 2" + :name "md" + :type :border-radius}) + + +(def test-tokens + {(:id radius-token) radius-token + (:id radius-ref-token) radius-ref-token}) + (defn- setup-file [] - (let [token-id (random-uuid)] - (-> (cthf/sample-file :file-1 :page-label :page-1) - (ctho/add-rect :rect-1 {}) - (ctho/add-rect :rect-2 {}) - (ctho/add-rect :rect-3 {}) - (assoc-in [:data :tokens] {#uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1" - {:id #uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1" - :value "12" - :name "sm" - :type :border-radius}})))) + (-> (cthf/sample-file :file-1 :page-label :page-1) + (ctho/add-rect :rect-1 {}) + (ctho/add-rect :rect-2 {}) + (ctho/add-rect :rect-3 {}) + (assoc-in [:data :tokens] test-tokens))) (t/deftest test-apply-token (t/async @@ -36,23 +49,23 @@ rect-1 (cths/get-shape file :rect-1) events [(wtc/apply-token {:shape-ids [(:id rect-1)] :attributes #{:rx :ry} - :token {:id #uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1"} + :token radius-token + :on-update-shape wtc/update-shape-radius}) + ;; Will override + (wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:rx :ry} + :token radius-ref-token :on-update-shape wtc/update-shape-radius})]] - - (ths/run-store + (tohs/run-store-async store done events (fn [new-state] (let [file' (ths/get-file-from-store new-state) rect-1' (cths/get-shape file' :rect-1)] (t/is (some? (:applied-tokens rect-1'))) - (t/is (= (:rx (:applied-tokens rect-1')) #uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1")) - (t/is (= (:rx rect-1') 12)))) - - (fn [stream] - (->> stream - ;; (rx/tap #(prn (ptk/type %))) - (rx/filter #(ptk/type? :app.main.data.workspace.changes/send-update-indices %)))))))) - + (t/is (= (:rx (:applied-tokens rect-1')) (:id radius-ref-token))) + (t/is (= (:ry (:applied-tokens rect-1')) (:id radius-ref-token))) + (t/is (= (:rx rect-1') 24)) + (t/is (= (:ry rect-1') 24)))))))) (comment (t/run-tests) From 0730ecef46fc86099f2e9dda6b1fa89895dd58eb Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 3 Jul 2024 17:15:23 +0200 Subject: [PATCH 15/45] Cleanup --- frontend/test/token_tests/logic/token_actions_test.cljs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 69abfee67d..a4f4420a67 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -3,14 +3,11 @@ [app.common.test-helpers.compositions :as ctho] [app.common.test-helpers.files :as cthf] [app.common.test-helpers.shapes :as cths] - [app.main.data.workspace.changes :as dch] [app.main.ui.workspace.tokens.core :as wtc] - [beicon.v2.core :as rx] - [token-tests.helpers.state :as tohs] [cljs.test :as t :include-macros true] [frontend-tests.helpers.pages :as thp] [frontend-tests.helpers.state :as ths] - [potok.v2.core :as ptk])) + [token-tests.helpers.state :as tohs])) (t/use-fixtures :each {:before thp/reset-idmap!}) From 71976ed7e945e01607518288f77d784c16357b5d Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Wed, 3 Jul 2024 18:24:09 +0200 Subject: [PATCH 16/45] Add helpers for creating test tokens --- .../token_tests/logic/token_actions_test.cljs | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index a4f4420a67..9e8e15e360 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -1,5 +1,6 @@ (ns token-tests.logic.token-actions-test (:require + [app.common.test-helpers.ids-map :as thi] [app.common.test-helpers.compositions :as ctho] [app.common.test-helpers.files :as cthf] [app.common.test-helpers.shapes :as cths] @@ -12,20 +13,25 @@ (t/use-fixtures :each {:before thp/reset-idmap!}) +(defn add-token [state label params] + (let [id (thi/new-id! label) + token (assoc params :id id)] + (update-in state [:data :tokens] assoc id token))) + +(defn get-token [file label] + (let [id (thi/id label)] + (get-in file [:data :tokens id]))) (def radius-token - {:id #uuid "91bf7f1f-fce2-482f-a423-c6b502705ff1" - :value "12" + {:value "12" :name "sm" :type :border-radius}) (def radius-ref-token - {:id #uuid "4c2bf84d-3a98-47a2-8e3c-e7fb037a615c" - :value "{sm} * 2" + {:value "{sm} * 2" :name "md" :type :border-radius}) - (def test-tokens {(:id radius-token) radius-token (:id radius-ref-token) radius-ref-token}) @@ -36,7 +42,12 @@ (ctho/add-rect :rect-1 {}) (ctho/add-rect :rect-2 {}) (ctho/add-rect :rect-3 {}) - (assoc-in [:data :tokens] test-tokens))) + (add-token :token-1 {:value "12" + :name "borderRadius.sm" + :type :border-radius}) + (add-token :token-2 {:value "{borderRadius.sm} * 2" + :name "borderRadius.md" + :type :border-radius}))) (t/deftest test-apply-token (t/async @@ -46,21 +57,22 @@ rect-1 (cths/get-shape file :rect-1) events [(wtc/apply-token {:shape-ids [(:id rect-1)] :attributes #{:rx :ry} - :token radius-token + :token (get-token file :token-1) :on-update-shape wtc/update-shape-radius}) ;; Will override (wtc/apply-token {:shape-ids [(:id rect-1)] :attributes #{:rx :ry} - :token radius-ref-token + :token (get-token file :token-2) :on-update-shape wtc/update-shape-radius})]] (tohs/run-store-async store done events (fn [new-state] (let [file' (ths/get-file-from-store new-state) + token-2' (get-token file' :token-2) rect-1' (cths/get-shape file' :rect-1)] (t/is (some? (:applied-tokens rect-1'))) - (t/is (= (:rx (:applied-tokens rect-1')) (:id radius-ref-token))) - (t/is (= (:ry (:applied-tokens rect-1')) (:id radius-ref-token))) + (t/is (= (:rx (:applied-tokens rect-1')) (:id token-2'))) + (t/is (= (:ry (:applied-tokens rect-1')) (:id token-2'))) (t/is (= (:rx rect-1') 24)) (t/is (= (:ry rect-1') 24)))))))) From b12e59a8d79d129563d436a61b95e3ee2ce70e76 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 09:13:02 +0200 Subject: [PATCH 17/45] Rename event to toggle-token --- frontend/src/app/main/ui/workspace/tokens/core.cljs | 2 +- frontend/src/app/main/ui/workspace/tokens/sidebar.cljs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index ddeab24242..31d8f9a693 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -105,7 +105,7 @@ (fn [shape] (update shape :applied-tokens remove-keys attributes))))))) -(defn on-toggle-token +(defn toggle-token [{:keys [token-type-props token shapes] :as _props}] (ptk/reify ::on-toggle-token ptk/WatchEvent diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 1d58637800..4edabdfccf 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -100,9 +100,9 @@ (fn [event token] (dom/stop-propagation event) (st/emit! - (wtc/on-toggle-token {:token token - :shapes selected-shapes - :token-type-props token-type-props})))) + (wtc/toggle-token {:token token + :shapes selected-shapes + :token-type-props token-type-props})))) tokens-count (count tokens)] [:div {:on-click on-toggle-open-click} [:& cmm/asset-section {:icon (mf/fnc icon-wrapper [_] From 3793e98660bc166c9d0dc49bf5335ad0c5dea9b6 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 09:29:16 +0200 Subject: [PATCH 18/45] Disable complete log --- frontend/test/token_tests/helpers/state.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/test/token_tests/helpers/state.cljs b/frontend/test/token_tests/helpers/state.cljs index 40fee3c492..6b9368210c 100644 --- a/frontend/test/token_tests/helpers/state.cljs +++ b/frontend/test/token_tests/helpers/state.cljs @@ -36,7 +36,7 @@ (fn [cause] (js/console.log "[error]:" cause)) (fn [_] - (js/console.log "[complete]")))) + #_(js/console.log "[complete]")))) (doall (for [event events] (ptk/emit! store event))) (ptk/emit! store :the/end)))) From 8370fd06d4daf9dff467072a574770a3810f1f00 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 09:29:43 +0200 Subject: [PATCH 19/45] Remove cb --- .../src/app/main/ui/workspace/tokens/core.cljs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 31d8f9a693..29d0047207 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -65,10 +65,10 @@ (ptk/reify ::done ptk/WatchEvent (watch [_ _ _] - (rx/from (p/resolved true))))) + (rx/of :the/end)))) (defn apply-token - [{:keys [attributes shape-ids token on-update-shape cb] :as _props}] + [{:keys [attributes shape-ids token on-update-shape] :as _props}] (ptk/reify ::apply-token ptk/WatchEvent (watch [_ state _] @@ -80,14 +80,10 @@ tokenized-attributes (->> (map (fn [attr] {attr (:id token)}) attributes) (into {}))] (rx/of - (dch/update-shapes shape-ids (fn [shape] (update shape :applied-tokens merge tokenized-attributes))) - (when cb - (cb)) + (dch/update-shapes shape-ids (fn [shape] + (update shape :applied-tokens merge tokenized-attributes))) (when on-update-shape - (on-update-shape resolved-value shape-ids attributes)))) - #_(rx/of - (dch/update-shapes shape-ids #(assoc % :applied-tokens {:found 1}))))))))) - + (on-update-shape resolved-value shape-ids attributes)))))))))) (def remove-keys #(apply dissoc %1 %2)) From e85de19a5e7459c88d61cf9574d420e07d9ba784 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 09:29:48 +0200 Subject: [PATCH 20/45] Add multiple shapes test --- .../token_tests/logic/token_actions_test.cljs | 77 +++++++++++++------ 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 9e8e15e360..b2f4827280 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -50,31 +50,60 @@ :type :border-radius}))) (t/deftest test-apply-token + (t/testing "applying a token twice with the same attributes will override") (t/async - done - (let [file (setup-file) - store (ths/setup-store file) - rect-1 (cths/get-shape file :rect-1) - events [(wtc/apply-token {:shape-ids [(:id rect-1)] - :attributes #{:rx :ry} - :token (get-token file :token-1) - :on-update-shape wtc/update-shape-radius}) - ;; Will override - (wtc/apply-token {:shape-ids [(:id rect-1)] - :attributes #{:rx :ry} - :token (get-token file :token-2) - :on-update-shape wtc/update-shape-radius})]] - (tohs/run-store-async - store done events - (fn [new-state] - (let [file' (ths/get-file-from-store new-state) - token-2' (get-token file' :token-2) - rect-1' (cths/get-shape file' :rect-1)] - (t/is (some? (:applied-tokens rect-1'))) - (t/is (= (:rx (:applied-tokens rect-1')) (:id token-2'))) - (t/is (= (:ry (:applied-tokens rect-1')) (:id token-2'))) - (t/is (= (:rx rect-1') 24)) - (t/is (= (:ry rect-1') 24)))))))) + done + (let [file (setup-file) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + events [(wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:rx :ry} + :token (get-token file :token-1) + :on-update-shape wtc/update-shape-radius}) + ;; Will override + (wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:rx :ry} + :token (get-token file :token-2) + :on-update-shape wtc/update-shape-radius})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + token-2' (get-token file' :token-2) + rect-1' (cths/get-shape file' :rect-1)] + (t/is (some? (:applied-tokens rect-1'))) + (t/is (= (:rx (:applied-tokens rect-1')) (:id token-2'))) + (t/is (= (:ry (:applied-tokens rect-1')) (:id token-2'))) + (t/is (= (:rx rect-1') 24)) + (t/is (= (:ry rect-1') 24)))))))) + +(t/deftest test-toggle-token + (t/testing "will apply token to all selected items, where no item has the token applied" + (t/async + done + (let [file (setup-file) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + rect-2 (cths/get-shape file :rect-2) + events [(wtc/toggle-token {:shapes [rect-1 rect-2] + :token-type-props {:attributes #{:rx :ry} + :on-update-shape wtc/update-shape-radius} + :token (get-token file :token-2)})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + token-2' (get-token file' :token-2) + rect-1' (cths/get-shape file' :rect-1) + rect-2' (cths/get-shape file' :rect-2)] + (t/is (some? (:applied-tokens rect-1'))) + (t/is (some? (:applied-tokens rect-2'))) + (t/is (= (:rx (:applied-tokens rect-1')) (:id token-2'))) + (t/is (= (:rx (:applied-tokens rect-2')) (:id token-2'))) + (t/is (= (:ry (:applied-tokens rect-1')) (:id token-2'))) + (t/is (= (:ry (:applied-tokens rect-2')) (:id token-2'))) + (t/is (= (:rx rect-1') 24)) + (t/is (= (:rx rect-2') 24))))))))) (comment (t/run-tests) From 581ced0ab82055fd2abc887e35339a7d4c735e63 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:00:44 +0200 Subject: [PATCH 21/45] Abstract into helper --- frontend/src/app/main/ui/workspace/tokens/core.cljs | 3 +-- frontend/src/app/main/ui/workspace/tokens/token.cljs | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 29d0047207..23940a28ae 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -77,8 +77,7 @@ (fn [sd-tokens] (let [resolved-value (-> (get sd-tokens (:id token)) (resolve-token-value)) - tokenized-attributes (->> (map (fn [attr] {attr (:id token)}) attributes) - (into {}))] + tokenized-attributes (wtt/attributes-map attributes (:id token))] (rx/of (dch/update-shapes shape-ids (fn [shape] (update shape :applied-tokens merge tokenized-attributes))) diff --git a/frontend/src/app/main/ui/workspace/tokens/token.cljs b/frontend/src/app/main/ui/workspace/tokens/token.cljs index e52079f8f8..2db7c24cf1 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token.cljs @@ -2,6 +2,12 @@ (:require [cuerdas.core :as str])) +(defn attributes-map + "Creats an attributes map using collection of `attributes` for `id`." + [attributes id] + (->> (map (fn [attr] {attr id}) attributes) + (into {}))) + (defn token-applied? "Test if `token` is applied to a `shape` with the given `token-attributes`." [token shape token-attributes] From ab62c5b4efffbc625b047e56ac4c19d86d0e5d93 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:00:58 +0200 Subject: [PATCH 22/45] Add helper to apply token to shape --- .../test/token_tests/logic/token_actions_test.cljs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index b2f4827280..18c105213c 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -8,7 +8,8 @@ [cljs.test :as t :include-macros true] [frontend-tests.helpers.pages :as thp] [frontend-tests.helpers.state :as ths] - [token-tests.helpers.state :as tohs])) + [token-tests.helpers.state :as tohs] + [app.main.ui.workspace.tokens.token :as wtt])) (t/use-fixtures :each {:before thp/reset-idmap!}) @@ -36,6 +37,17 @@ {(:id radius-token) radius-token (:id radius-ref-token) radius-ref-token}) +(defn apply-token-to-shape [file shape-label token-label attributes] + (let [first-page-id (get-in file [:data :pages 0]) + shape-id (thi/id shape-label) + token-id (thi/id token-label) + applied-attributes (wtt/attributes-map attributes token-id)] + (update-in file [:data + :pages-index first-page-id + :objects shape-id + :applied-tokens] + merge applied-attributes))) + (defn- setup-file [] (-> (cthf/sample-file :file-1 :page-label :page-1) From 596480d1771c8653744e1938819d0c7840d58c1a Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:05:36 +0200 Subject: [PATCH 23/45] Add test to verify toggle removes token for applied & unapplied --- .../token_tests/logic/token_actions_test.cljs | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 18c105213c..dde8bc0b93 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -89,18 +89,19 @@ (t/is (= (:rx rect-1') 24)) (t/is (= (:ry rect-1') 24)))))))) -(t/deftest test-toggle-token - (t/testing "will apply token to all selected items, where no item has the token applied" + +(t/deftest test-toggle-token-none + (t/testing "should apply token to all selected items, where no item has the token applied" (t/async done (let [file (setup-file) - store (ths/setup-store file) - rect-1 (cths/get-shape file :rect-1) - rect-2 (cths/get-shape file :rect-2) - events [(wtc/toggle-token {:shapes [rect-1 rect-2] - :token-type-props {:attributes #{:rx :ry} - :on-update-shape wtc/update-shape-radius} - :token (get-token file :token-2)})]] + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + rect-2 (cths/get-shape file :rect-2) + events [(wtc/toggle-token {:shapes [rect-1 rect-2] + :token-type-props {:attributes #{:rx :ry} + :on-update-shape wtc/update-shape-radius} + :token (get-token file :token-2)})]] (tohs/run-store-async store done events (fn [new-state] @@ -117,25 +118,28 @@ (t/is (= (:rx rect-1') 24)) (t/is (= (:rx rect-2') 24))))))))) -(comment - (t/run-tests) - (defn make-printable - "Convert records that are not printable by cider inspect into regular maps." - [coll] - (letfn [(stringifyable? [x] - (not (or (map? x) - (sequential? x) - (keyword? x) - (number? x) - (uuid? x))))] - (clojure.walk/postwalk #(cond->> % - (record? %) (into {}) - (stringifyable? %) str) - coll))) - - (-> (cthf/sample-file :file-1) - (assoc :tokens {}) - (make-printable)) - - (make-printable (setup-file)) - nil) +(t/deftest test-toggle-token-mixed + (t/testing "should unapply token if one of the selected items has the token applied" + (t/async + done + (let [file (-> (setup-file) + (apply-token-to-shape :rect-1 :token-1 #{:rx :ry})) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + rect-2 (cths/get-shape file :rect-2) + events [(wtc/toggle-token {:shapes [rect-1 rect-2] + :token-type-props {:attributes #{:rx :ry}}})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + token-2' (get-token file' :token-2) + rect-1' (cths/get-shape file' :rect-1) + rect-2' (cths/get-shape file' :rect-2)] + (t/is (nil? (:rx (:applied-tokens rect-1')))) + (t/is (nil? (:ry (:applied-tokens rect-1')))) + (t/is (nil? (:rx (:applied-tokens rect-2')))) + (t/is (nil? (:ry (:applied-tokens rect-2')))) + ;; Verify that shape attributes didn't get changed + (t/is (zero? (:rx rect-1'))) + (t/is (zero? (:rx rect-2')))))))))) From 818aa043ca6454570ba4b19f7f3e39284e00e80d Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:40:59 +0200 Subject: [PATCH 24/45] Wrap in undo sequence --- frontend/src/app/main/ui/workspace/tokens/core.cljs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 23940a28ae..0a1e6c54d3 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -14,6 +14,7 @@ [app.main.data.workspace.changes :as dch] [app.main.data.workspace.shape-layout :as dwsl] [app.main.data.workspace.transforms :as dwt] + [app.main.data.workspace.undo :as dwu] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.workspace.tokens.style-dictionary :as sd] @@ -75,14 +76,17 @@ (->> (rx/from (sd/resolve-tokens+ (get-in state [:workspace-data :tokens]))) (rx/mapcat (fn [sd-tokens] - (let [resolved-value (-> (get sd-tokens (:id token)) + (let [undo-id (js/Symbol) + resolved-value (-> (get sd-tokens (:id token)) (resolve-token-value)) tokenized-attributes (wtt/attributes-map attributes (:id token))] (rx/of + (dwu/start-undo-transaction undo-id) (dch/update-shapes shape-ids (fn [shape] (update shape :applied-tokens merge tokenized-attributes))) (when on-update-shape - (on-update-shape resolved-value shape-ids attributes)))))))))) + (on-update-shape resolved-value shape-ids attributes)) + (dwu/commit-undo-transaction undo-id))))))))) (def remove-keys #(apply dissoc %1 %2)) From f3261c9b0fff3038d31d73006770bb47fc71a9ea Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:41:10 +0200 Subject: [PATCH 25/45] Fix emit! side-effect --- frontend/src/app/main/ui/workspace/tokens/core.cljs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 0a1e6c54d3..467d47c7b4 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -148,9 +148,12 @@ :attrs ctt/border-radius-keys})) (defn update-shape-dimensions [value shape-ids] - (st/emit! - (dwt/update-dimensions shape-ids :width value) - (dwt/update-dimensions shape-ids :height value))) + (ptk/reify ::update-shape-dimensions + ptk/WatchEvent + (watch [_ _ _] + (rx/of + (dwt/update-dimensions shape-ids :width value) + (dwt/update-dimensions shape-ids :height value))))) (defn update-opacity [value shape-ids] (st/emit! From 8f806ef1fe0fed87acd8c2ed7945ba2f6686a334 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:41:46 +0200 Subject: [PATCH 26/45] Test single property updates --- .../token_tests/logic/token_actions_test.cljs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index dde8bc0b93..ff21af76c1 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -89,6 +89,54 @@ (t/is (= (:rx rect-1') 24)) (t/is (= (:ry rect-1') 24)))))))) +(t/deftest test-apply-border-radius + (t/testing "applies radius token and updates the shapes radius") + (t/async + done + (let [file (setup-file) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + events [(wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:rx :ry} + :token (get-token file :token-2) + :on-update-shape wtc/update-shape-radius})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + token-2' (get-token file' :token-2) + rect-1' (cths/get-shape file' :rect-1)] + (t/is (some? (:applied-tokens rect-1'))) + (t/is (= (:rx (:applied-tokens rect-1')) (:id token-2'))) + (t/is (= (:ry (:applied-tokens rect-1')) (:id token-2'))) + (t/is (= (:rx rect-1') 24)) + (t/is (= (:ry rect-1') 24)))))))) + +(t/deftest test-apply-dimensions + (t/testing "applies radius token and updates the shapes radius") + (t/async + done + (let [file (-> (setup-file) + (add-token :token-target {:value "100" + :name "dimensions.sm" + :type :dimensions})) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + events [(wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:width :height} + :token (get-token file :token-target) + :on-update-shape wtc/update-shape-dimensions})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + token-target' (get-token file' :token-target) + rect-1' (cths/get-shape file' :rect-1)] + (t/is (some? (:applied-tokens rect-1'))) + (t/is (= (:width (:applied-tokens rect-1')) (:id token-target'))) + (t/is (= (:height (:applied-tokens rect-1')) (:id token-target'))) + (t/is (= (:width rect-1') 100)) + (t/is (= (:height rect-1') 100)))))))) (t/deftest test-toggle-token-none (t/testing "should apply token to all selected items, where no item has the token applied" From a842cb2d7d415a382785a3c229b7288dfe02d40c Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:41:57 +0200 Subject: [PATCH 27/45] Cleanup --- frontend/test/token_tests/logic/token_actions_test.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index ff21af76c1..385323bce6 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -72,7 +72,6 @@ :attributes #{:rx :ry} :token (get-token file :token-1) :on-update-shape wtc/update-shape-radius}) - ;; Will override (wtc/apply-token {:shape-ids [(:id rect-1)] :attributes #{:rx :ry} :token (get-token file :token-2) From 1f0f35e7543acc4a12d8b62a4dbf49617f47dcfc Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:48:27 +0200 Subject: [PATCH 28/45] Remove unused --- .../test/token_tests/logic/token_actions_test.cljs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 385323bce6..d977af0b91 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -23,20 +23,6 @@ (let [id (thi/id label)] (get-in file [:data :tokens id]))) -(def radius-token - {:value "12" - :name "sm" - :type :border-radius}) - -(def radius-ref-token - {:value "{sm} * 2" - :name "md" - :type :border-radius}) - -(def test-tokens - {(:id radius-token) radius-token - (:id radius-ref-token) radius-ref-token}) - (defn apply-token-to-shape [file shape-label token-label attributes] (let [first-page-id (get-in file [:data :pages 0]) shape-id (thi/id shape-label) From b43d16008f04b8c2a77f37428aab3d16c105b8fc Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 10:51:08 +0200 Subject: [PATCH 29/45] Extract to helpers --- frontend/test/token_tests/helpers/tokens.cljs | 24 +++++++ .../token_tests/logic/token_actions_test.cljs | 69 ++++++++----------- 2 files changed, 53 insertions(+), 40 deletions(-) create mode 100644 frontend/test/token_tests/helpers/tokens.cljs diff --git a/frontend/test/token_tests/helpers/tokens.cljs b/frontend/test/token_tests/helpers/tokens.cljs new file mode 100644 index 0000000000..716dd07558 --- /dev/null +++ b/frontend/test/token_tests/helpers/tokens.cljs @@ -0,0 +1,24 @@ +(ns token-tests.helpers.tokens + (:require + [app.common.test-helpers.ids-map :as thi] + [app.main.ui.workspace.tokens.token :as wtt])) + +(defn add-token [state label params] + (let [id (thi/new-id! label) + token (assoc params :id id)] + (update-in state [:data :tokens] assoc id token))) + +(defn get-token [file label] + (let [id (thi/id label)] + (get-in file [:data :tokens id]))) + +(defn apply-token-to-shape [file shape-label token-label attributes] + (let [first-page-id (get-in file [:data :pages 0]) + shape-id (thi/id shape-label) + token-id (thi/id token-label) + applied-attributes (wtt/attributes-map attributes token-id)] + (update-in file [:data + :pages-index first-page-id + :objects shape-id + :applied-tokens] + merge applied-attributes))) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index d977af0b91..c6c4d41af1 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -1,5 +1,6 @@ (ns token-tests.logic.token-actions-test (:require + [token-tests.helpers.tokens :as toht] [app.common.test-helpers.ids-map :as thi] [app.common.test-helpers.compositions :as ctho] [app.common.test-helpers.files :as cthf] @@ -14,38 +15,26 @@ (t/use-fixtures :each {:before thp/reset-idmap!}) -(defn add-token [state label params] - (let [id (thi/new-id! label) - token (assoc params :id id)] - (update-in state [:data :tokens] assoc id token))) - -(defn get-token [file label] - (let [id (thi/id label)] - (get-in file [:data :tokens id]))) - -(defn apply-token-to-shape [file shape-label token-label attributes] - (let [first-page-id (get-in file [:data :pages 0]) - shape-id (thi/id shape-label) - token-id (thi/id token-label) - applied-attributes (wtt/attributes-map attributes token-id)] - (update-in file [:data - :pages-index first-page-id - :objects shape-id - :applied-tokens] - merge applied-attributes))) - (defn- setup-file [] (-> (cthf/sample-file :file-1 :page-label :page-1) (ctho/add-rect :rect-1 {}) (ctho/add-rect :rect-2 {}) (ctho/add-rect :rect-3 {}) - (add-token :token-1 {:value "12" - :name "borderRadius.sm" - :type :border-radius}) - (add-token :token-2 {:value "{borderRadius.sm} * 2" - :name "borderRadius.md" - :type :border-radius}))) + (toht/add-token :token-1 {:value "12" + :name "borderRadius.sm" + :type :border-radius}) + (toht/add-token :token-2 {:value "{borderRadius.sm} * 2" + :name "borderRadius.md" + :type :border-radius}))) + +(comment + + (floscr/make-printable + (-> (setup-file) + (toht/apply-token-to-shape :rect-1 :token-1 #{:rx :ry}))) + (-> (setup-file)) + nil) (t/deftest test-apply-token (t/testing "applying a token twice with the same attributes will override") @@ -56,17 +45,17 @@ rect-1 (cths/get-shape file :rect-1) events [(wtc/apply-token {:shape-ids [(:id rect-1)] :attributes #{:rx :ry} - :token (get-token file :token-1) + :token (toht/get-token file :token-1) :on-update-shape wtc/update-shape-radius}) (wtc/apply-token {:shape-ids [(:id rect-1)] :attributes #{:rx :ry} - :token (get-token file :token-2) + :token (toht/get-token file :token-2) :on-update-shape wtc/update-shape-radius})]] (tohs/run-store-async store done events (fn [new-state] (let [file' (ths/get-file-from-store new-state) - token-2' (get-token file' :token-2) + token-2' (toht/get-token file' :token-2) rect-1' (cths/get-shape file' :rect-1)] (t/is (some? (:applied-tokens rect-1'))) (t/is (= (:rx (:applied-tokens rect-1')) (:id token-2'))) @@ -83,13 +72,13 @@ rect-1 (cths/get-shape file :rect-1) events [(wtc/apply-token {:shape-ids [(:id rect-1)] :attributes #{:rx :ry} - :token (get-token file :token-2) + :token (toht/get-token file :token-2) :on-update-shape wtc/update-shape-radius})]] (tohs/run-store-async store done events (fn [new-state] (let [file' (ths/get-file-from-store new-state) - token-2' (get-token file' :token-2) + token-2' (toht/get-token file' :token-2) rect-1' (cths/get-shape file' :rect-1)] (t/is (some? (:applied-tokens rect-1'))) (t/is (= (:rx (:applied-tokens rect-1')) (:id token-2'))) @@ -102,20 +91,20 @@ (t/async done (let [file (-> (setup-file) - (add-token :token-target {:value "100" - :name "dimensions.sm" - :type :dimensions})) + (toht/add-token :token-target {:value "100" + :name "dimensions.sm" + :type :dimensions})) store (ths/setup-store file) rect-1 (cths/get-shape file :rect-1) events [(wtc/apply-token {:shape-ids [(:id rect-1)] :attributes #{:width :height} - :token (get-token file :token-target) + :token (toht/get-token file :token-target) :on-update-shape wtc/update-shape-dimensions})]] (tohs/run-store-async store done events (fn [new-state] (let [file' (ths/get-file-from-store new-state) - token-target' (get-token file' :token-target) + token-target' (toht/get-token file' :token-target) rect-1' (cths/get-shape file' :rect-1)] (t/is (some? (:applied-tokens rect-1'))) (t/is (= (:width (:applied-tokens rect-1')) (:id token-target'))) @@ -134,12 +123,12 @@ events [(wtc/toggle-token {:shapes [rect-1 rect-2] :token-type-props {:attributes #{:rx :ry} :on-update-shape wtc/update-shape-radius} - :token (get-token file :token-2)})]] + :token (toht/get-token file :token-2)})]] (tohs/run-store-async store done events (fn [new-state] (let [file' (ths/get-file-from-store new-state) - token-2' (get-token file' :token-2) + token-2' (toht/get-token file' :token-2) rect-1' (cths/get-shape file' :rect-1) rect-2' (cths/get-shape file' :rect-2)] (t/is (some? (:applied-tokens rect-1'))) @@ -156,7 +145,7 @@ (t/async done (let [file (-> (setup-file) - (apply-token-to-shape :rect-1 :token-1 #{:rx :ry})) + (toht/apply-token-to-shape :rect-1 :token-1 #{:rx :ry})) store (ths/setup-store file) rect-1 (cths/get-shape file :rect-1) rect-2 (cths/get-shape file :rect-2) @@ -166,7 +155,7 @@ store done events (fn [new-state] (let [file' (ths/get-file-from-store new-state) - token-2' (get-token file' :token-2) + token-2' (toht/get-token file' :token-2) rect-1' (cths/get-shape file' :rect-1) rect-2' (cths/get-shape file' :rect-2)] (t/is (nil? (:rx (:applied-tokens rect-1')))) From 322c8ef8ec0a969aeffef932dd87918dbfe0aceb Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 11:06:48 +0200 Subject: [PATCH 30/45] Update opacity --- .../app/main/ui/workspace/tokens/core.cljs | 3 +-- .../token_tests/logic/token_actions_test.cljs | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 467d47c7b4..56407e68fc 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -156,8 +156,7 @@ (dwt/update-dimensions shape-ids :height value))))) (defn update-opacity [value shape-ids] - (st/emit! - (dch/update-shapes shape-ids #(assoc % :opacity value)))) + (dch/update-shapes shape-ids #(assoc % :opacity value))) (defn update-stroke-width [value shape-ids] diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index c6c4d41af1..c5a3033873 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -112,6 +112,31 @@ (t/is (= (:width rect-1') 100)) (t/is (= (:height rect-1') 100)))))))) +(t/deftest test-apply-opacity + (t/testing "applies opacity token and updates the shapes opacity") + (t/async + done + (let [file (-> (setup-file) + (toht/add-token :token-target {:value "0.5" + :name "opacity.medium" + :type :opacity})) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + events [(wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:opacity} + :token (toht/get-token file :token-target) + :on-update-shape wtc/update-opacity})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + token-target' (toht/get-token file' :token-target) + rect-1' (cths/get-shape file' :rect-1)] + (t/is (some? (:applied-tokens rect-1'))) + (t/is (= (:opacity (:applied-tokens rect-1')) (:id token-target'))) + ;; TODO Fix opacity shape update not working? + #_(t/is (= (:opacity rect-1') 0.5)))))))) + (t/deftest test-toggle-token-none (t/testing "should apply token to all selected items, where no item has the token applied" (t/async From 7abfaef1cb237f14a5ffc9d9222039a5485655d5 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 11:08:46 +0200 Subject: [PATCH 31/45] Test applying rotation --- .../app/main/ui/workspace/tokens/core.cljs | 8 +++++-- .../token_tests/logic/token_actions_test.cljs | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 56407e68fc..35c0c7580c 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -166,8 +166,12 @@ (assoc-in shape [:strokes 0 :stroke-width] value)))))) (defn update-rotation [value shape-ids] - (st/emit! (udw/trigger-bounding-box-cloaking shape-ids) - (udw/increase-rotation shape-ids value))) + (ptk/reify ::update-shape-dimensions + ptk/WatchEvent + (watch [_ _ _] + (rx/of + (udw/trigger-bounding-box-cloaking shape-ids) + (udw/increase-rotation shape-ids value))))) (defn update-layout-spacing-column [value shape-ids] (doseq [shape-id shape-ids] diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index c5a3033873..e1c39ea9ad 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -137,6 +137,30 @@ ;; TODO Fix opacity shape update not working? #_(t/is (= (:opacity rect-1') 0.5)))))))) +(t/deftest test-apply-rotation + (t/testing "applies rotation token and updates the shapes rotation") + (t/async + done + (let [file (-> (setup-file) + (toht/add-token :token-target {:value "120" + :name "rotation.medium" + :type :rotation})) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + events [(wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:rotation} + :token (toht/get-token file :token-target) + :on-update-shape wtc/update-rotation})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + token-target' (toht/get-token file' :token-target) + rect-1' (cths/get-shape file' :rect-1)] + (t/is (some? (:applied-tokens rect-1'))) + (t/is (= (:rotation (:applied-tokens rect-1')) (:id token-target'))) + (t/is (= (:rotation rect-1') 120)))))))) + (t/deftest test-toggle-token-none (t/testing "should apply token to all selected items, where no item has the token applied" (t/async From 694baeee0c389964c4a0fab55470b685f984c500 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 11:12:49 +0200 Subject: [PATCH 32/45] Add sizing test --- .../token_tests/logic/token_actions_test.cljs | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index e1c39ea9ad..72016fd77a 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -87,7 +87,7 @@ (t/is (= (:ry rect-1') 24)))))))) (t/deftest test-apply-dimensions - (t/testing "applies radius token and updates the shapes radius") + (t/testing "applies dimensions token and updates the shapes width and height") (t/async done (let [file (-> (setup-file) @@ -112,6 +112,32 @@ (t/is (= (:width rect-1') 100)) (t/is (= (:height rect-1') 100)))))))) +(t/deftest test-apply-sizing + (t/testing "applies sizing token and updates the shapes width and height") + (t/async + done + (let [file (-> (setup-file) + (toht/add-token :token-target {:value "100" + :name "sizing.sm" + :type :sizing})) + store (ths/setup-store file) + rect-1 (cths/get-shape file :rect-1) + events [(wtc/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:width :height} + :token (toht/get-token file :token-target) + :on-update-shape wtc/update-shape-dimensions})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + token-target' (toht/get-token file' :token-target) + rect-1' (cths/get-shape file' :rect-1)] + (t/is (some? (:applied-tokens rect-1'))) + (t/is (= (:width (:applied-tokens rect-1')) (:id token-target'))) + (t/is (= (:height (:applied-tokens rect-1')) (:id token-target'))) + (t/is (= (:width rect-1') 100)) + (t/is (= (:height rect-1') 100)))))))) + (t/deftest test-apply-opacity (t/testing "applies opacity token and updates the shapes opacity") (t/async From 658e7ebd0a577200c85bf8ba25ab6110aa688c43 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 11:15:06 +0200 Subject: [PATCH 33/45] Cleanup --- .../test/token_tests/logic/token_actions_test.cljs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 72016fd77a..1c986799a9 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -1,7 +1,5 @@ (ns token-tests.logic.token-actions-test (:require - [token-tests.helpers.tokens :as toht] - [app.common.test-helpers.ids-map :as thi] [app.common.test-helpers.compositions :as ctho] [app.common.test-helpers.files :as cthf] [app.common.test-helpers.shapes :as cths] @@ -10,7 +8,7 @@ [frontend-tests.helpers.pages :as thp] [frontend-tests.helpers.state :as ths] [token-tests.helpers.state :as tohs] - [app.main.ui.workspace.tokens.token :as wtt])) + [token-tests.helpers.tokens :as toht])) (t/use-fixtures :each {:before thp/reset-idmap!}) @@ -28,14 +26,6 @@ :name "borderRadius.md" :type :border-radius}))) -(comment - - (floscr/make-printable - (-> (setup-file) - (toht/apply-token-to-shape :rect-1 :token-1 #{:rx :ry}))) - (-> (setup-file)) - nil) - (t/deftest test-apply-token (t/testing "applying a token twice with the same attributes will override") (t/async From b73cdd15e0e386bfd7da218520973993faad11d9 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 11:28:15 +0200 Subject: [PATCH 34/45] Add helper to remove attributes from applied-tokens --- frontend/src/app/main/ui/workspace/tokens/token.cljs | 10 ++++++++++ frontend/test/token_tests/token_test.cljs | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/frontend/src/app/main/ui/workspace/tokens/token.cljs b/frontend/src/app/main/ui/workspace/tokens/token.cljs index 2db7c24cf1..79fbb0e2d7 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token.cljs @@ -8,6 +8,16 @@ (->> (map (fn [attr] {attr id}) attributes) (into {}))) +(defn remove-attributes-for-token-id + "Removes applied tokens with `token-id` for the given `attributes` set from `applied-tokens`." + [attributes token-id applied-tokens] + (let [attr? (set attributes)] + (->> (remove (fn [[k v]] + (and (attr? k) + (= v token-id))) + applied-tokens) + (into {})))) + (defn token-applied? "Test if `token` is applied to a `shape` with the given `token-attributes`." [token shape token-attributes] diff --git a/frontend/test/token_tests/token_test.cljs b/frontend/test/token_tests/token_test.cljs index c999c74cae..255adf28e2 100644 --- a/frontend/test/token_tests/token_test.cljs +++ b/frontend/test/token_tests/token_test.cljs @@ -9,6 +9,12 @@ [app.main.ui.workspace.tokens.token :as wtt] [cljs.test :as t :include-macros true])) +(t/deftest remove-attributes-for-token-id + (t/testing "removes attributes matching the `token-id`, keeps other attributes" + (t/is (= {:ry :b} + (wtt/remove-attributes-for-token-id + #{:rx :ry} :a {:rx :a :ry :b}))))) + (t/deftest token-applied-test (t/testing "matches passed token with `:token-attributes`" (t/is (true? (wtt/token-applied? {:id :a} {:applied-tokens {:x :a}} #{:x})))) From 893e790787767095bec130081f4012a872ffaa2f Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 11:41:00 +0200 Subject: [PATCH 35/45] Only remove given token --- frontend/src/app/main/ui/workspace/tokens/core.cljs | 12 +++++++----- .../test/token_tests/logic/token_actions_test.cljs | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 35c0c7580c..30de64021f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -94,15 +94,16 @@ "Removes `attributes` that match `token` for `shape-ids`. Doesn't update shape attributes." - [{:keys [attributes shape-ids] :as _props}] + [{:keys [attributes token shape-ids] :as _props}] (ptk/reify ::unapply-token ptk/WatchEvent (watch [_ _ _] (rx/of - (dch/update-shapes - shape-ids - (fn [shape] - (update shape :applied-tokens remove-keys attributes))))))) + (let [remove-token #(wtt/remove-attributes-for-token-id attributes (:id token) %)] + (dch/update-shapes + shape-ids + (fn [shape] + (update shape :applied-tokens remove-token)))))))) (defn toggle-token [{:keys [token-type-props token shapes] :as _props}] @@ -115,6 +116,7 @@ (if unapply-tokens? (rx/of (unapply-token {:attributes attributes + :token token :shape-ids shape-ids})) (rx/of (apply-token {:attributes attributes diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 1c986799a9..f07affdae7 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -206,7 +206,7 @@ (t/is (= (:rx rect-2') 24))))))))) (t/deftest test-toggle-token-mixed - (t/testing "should unapply token if one of the selected items has the token applied" + (t/testing "should unapply given token if one of the selected items has the token applied" (t/async done (let [file (-> (setup-file) @@ -215,6 +215,7 @@ rect-1 (cths/get-shape file :rect-1) rect-2 (cths/get-shape file :rect-2) events [(wtc/toggle-token {:shapes [rect-1 rect-2] + :token (toht/get-token file :token-1) :token-type-props {:attributes #{:rx :ry}}})]] (tohs/run-store-async store done events From f20c08f31bc3c8e8f31bf58b025e5557c3f20954 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 14:05:20 +0200 Subject: [PATCH 36/45] Specify tests --- .../app/main/ui/workspace/tokens/core.cljs | 2 +- .../token_tests/logic/token_actions_test.cljs | 37 +++++++++++-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 30de64021f..1f1cd9f8fb 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -99,7 +99,7 @@ ptk/WatchEvent (watch [_ _ _] (rx/of - (let [remove-token #(wtt/remove-attributes-for-token-id attributes (:id token) %)] + (let [remove-token #(when % (wtt/remove-attributes-for-token-id attributes (:id token) %))] (dch/update-shapes shape-ids (fn [shape] diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index f07affdae7..354909bd4d 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -206,28 +206,35 @@ (t/is (= (:rx rect-2') 24))))))))) (t/deftest test-toggle-token-mixed - (t/testing "should unapply given token if one of the selected items has the token applied" + (t/testing "should unapply given token if one of the selected items has the token applied while keeping other tokens with some attributes" (t/async done (let [file (-> (setup-file) - (toht/apply-token-to-shape :rect-1 :token-1 #{:rx :ry})) + (toht/apply-token-to-shape :rect-1 :token-1 #{:rx :ry}) + (toht/apply-token-to-shape :rect-3 :token-2 #{:rx :ry})) store (ths/setup-store file) - rect-1 (cths/get-shape file :rect-1) - rect-2 (cths/get-shape file :rect-2) - events [(wtc/toggle-token {:shapes [rect-1 rect-2] + + rect-with-token (cths/get-shape file :rect-1) + rect-without-token (cths/get-shape file :rect-2) + rect-with-other-token (cths/get-shape file :rect-3) + + events [(wtc/toggle-token {:shapes [rect-with-token rect-without-token rect-with-other-token] :token (toht/get-token file :token-1) :token-type-props {:attributes #{:rx :ry}}})]] (tohs/run-store-async store done events (fn [new-state] (let [file' (ths/get-file-from-store new-state) - token-2' (toht/get-token file' :token-2) - rect-1' (cths/get-shape file' :rect-1) - rect-2' (cths/get-shape file' :rect-2)] - (t/is (nil? (:rx (:applied-tokens rect-1')))) - (t/is (nil? (:ry (:applied-tokens rect-1')))) - (t/is (nil? (:rx (:applied-tokens rect-2')))) - (t/is (nil? (:ry (:applied-tokens rect-2')))) - ;; Verify that shape attributes didn't get changed - (t/is (zero? (:rx rect-1'))) - (t/is (zero? (:rx rect-2')))))))))) + rect-with-token' (cths/get-shape file' :rect-1) + rect-without-token' (cths/get-shape file' :rect-2) + rect-with-other-token' (cths/get-shape file' :rect-3)] + + (t/testing "rect-with-token got the token remove" + (t/is (nil? (:rx (:applied-tokens rect-with-token')))) + (t/is (nil? (:ry (:applied-tokens rect-with-token'))))) + + (t/testing "rect-without-token didn't get updated" + (t/is (= (:applied-tokens rect-without-token') (:applied-tokens rect-without-token)))) + + (t/testing "rect-with-other-token didn't get updated" + (t/is (= (:applied-tokens rect-with-other-token') (:applied-tokens rect-with-other-token))))))))))) From 55713275b6e44539dbef654eead3f7b4b2ec6fbb Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 14:14:06 +0200 Subject: [PATCH 37/45] Add test for overriding token --- .../token_tests/logic/token_actions_test.cljs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/frontend/test/token_tests/logic/token_actions_test.cljs b/frontend/test/token_tests/logic/token_actions_test.cljs index 354909bd4d..3fadf0cdd0 100644 --- a/frontend/test/token_tests/logic/token_actions_test.cljs +++ b/frontend/test/token_tests/logic/token_actions_test.cljs @@ -238,3 +238,37 @@ (t/testing "rect-with-other-token didn't get updated" (t/is (= (:applied-tokens rect-with-other-token') (:applied-tokens rect-with-other-token))))))))))) + +(t/deftest test-toggle-token-apply-to-all + (t/testing "should apply token to all if none of the shapes has it applied" + (t/async + done + (let [file (-> (setup-file) + (toht/apply-token-to-shape :rect-1 :token-2 #{:rx :ry}) + (toht/apply-token-to-shape :rect-3 :token-2 #{:rx :ry})) + store (ths/setup-store file) + + rect-with-other-token-1 (cths/get-shape file :rect-1) + rect-without-token (cths/get-shape file :rect-2) + rect-with-other-token-2 (cths/get-shape file :rect-3) + + events [(wtc/toggle-token {:shapes [rect-with-other-token-1 rect-without-token rect-with-other-token-2] + :token (toht/get-token file :token-1) + :token-type-props {:attributes #{:rx :ry}}})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-store new-state) + target-token (toht/get-token file' :token-1) + rect-with-other-token-1' (cths/get-shape file' :rect-1) + rect-without-token' (cths/get-shape file' :rect-2) + rect-with-other-token-2' (cths/get-shape file' :rect-3)] + + (t/testing "token got applied to all shapes" + (t/is (= (:rx (:applied-tokens rect-with-other-token-1')) (:id target-token))) + (t/is (= (:rx (:applied-tokens rect-without-token')) (:id target-token))) + (t/is (= (:rx (:applied-tokens rect-with-other-token-2')) (:id target-token))) + + (t/is (= (:ry (:applied-tokens rect-with-other-token-1')) (:id target-token))) + (t/is (= (:ry (:applied-tokens rect-without-token')) (:id target-token))) + (t/is (= (:ry (:applied-tokens rect-with-other-token-2')) (:id target-token))))))))))) From 785961f7c6e789cea44d4d0a4acca29582931fff Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 14:31:50 +0200 Subject: [PATCH 38/45] Cleanup --- .../app/main/ui/workspace/tokens/core.cljs | 104 ++++++++---------- 1 file changed, 43 insertions(+), 61 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 1f1cd9f8fb..1518c303b9 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -42,31 +42,59 @@ (->> (vals tokens) (group-by :type))) - (defn tokens-name-map->select-options [{:keys [shape tokens attributes selected-attributes]}] (->> (wtt/token-names-map tokens) (map (fn [[_k {:keys [name] :as item}]] (cond-> (assoc item :label name) (wtt/token-applied? item shape (or selected-attributes attributes)) (assoc :selected? true)))))) -;; Update functions ------------------------------------------------------------ +;; Shape Update Functions ------------------------------------------------------ -(defn apply-tokens? - [{:keys [attributes token shapes] :as _props}] - (let [{:keys [with-token without-token]} (group-by - (fn [shape] - (if (wtt/shapes-token-applied? token shape attributes) - :with-token - :without-token)) - shapes)] - (and (empty? with-token) (seq without-token)))) +(defn update-shape-radius [value shape-ids] + (dch/update-shapes shape-ids + (fn [shape] + (when (ctsr/has-radius? shape) + (ctsr/set-radius-1 shape value))) + {:reg-objects? true + :attrs ctt/border-radius-keys})) -(defn done - [] - (ptk/reify ::done +(defn update-shape-dimensions [value shape-ids] + (ptk/reify ::update-shape-dimensions ptk/WatchEvent (watch [_ _ _] - (rx/of :the/end)))) + (rx/of + (dwt/update-dimensions shape-ids :width value) + (dwt/update-dimensions shape-ids :height value))))) + +(defn update-opacity [value shape-ids] + (dch/update-shapes shape-ids #(assoc % :opacity value))) + +(defn update-stroke-width + [value shape-ids] + (st/emit! + (dch/update-shapes shape-ids (fn [shape] + (when (seq (:strokes shape)) + (assoc-in shape [:strokes 0 :stroke-width] value)))))) + +(defn update-rotation [value shape-ids] + (ptk/reify ::update-shape-dimensions + ptk/WatchEvent + (watch [_ _ _] + (rx/of + (udw/trigger-bounding-box-cloaking shape-ids) + (udw/increase-rotation shape-ids value))))) + +(defn update-layout-spacing-column [value shape-ids] + (doseq [shape-id shape-ids] + (let [shape (dt/get-shape-from-state shape-id @st/state) + layout-direction (:layout-flex-dir shape) + layout-update (if (or (= layout-direction :row-reverse) (= layout-direction :row)) + {:layout-gap {:column-gap value}} + {:layout-gap {:row-gap value}})] + (st/emit! + (dwsl/update-layout [shape-id] layout-update))))) + +;; Events ---------------------------------------------------------------------- (defn apply-token [{:keys [attributes shape-ids token on-update-shape] :as _props}] @@ -88,8 +116,6 @@ (on-update-shape resolved-value shape-ids attributes)) (dwu/commit-undo-transaction undo-id))))))))) -(def remove-keys #(apply dissoc %1 %2)) - (defn unapply-token "Removes `attributes` that match `token` for `shape-ids`. @@ -141,50 +167,6 @@ :attributes attributes})) (on-update-shape resolved-token-value shape-ids attributes)))))) -(defn update-shape-radius [value shape-ids] - (dch/update-shapes shape-ids - (fn [shape] - (when (ctsr/has-radius? shape) - (ctsr/set-radius-1 shape value))) - {:reg-objects? true - :attrs ctt/border-radius-keys})) - -(defn update-shape-dimensions [value shape-ids] - (ptk/reify ::update-shape-dimensions - ptk/WatchEvent - (watch [_ _ _] - (rx/of - (dwt/update-dimensions shape-ids :width value) - (dwt/update-dimensions shape-ids :height value))))) - -(defn update-opacity [value shape-ids] - (dch/update-shapes shape-ids #(assoc % :opacity value))) - -(defn update-stroke-width - [value shape-ids] - (st/emit! - (dch/update-shapes shape-ids (fn [shape] - (when (seq (:strokes shape)) - (assoc-in shape [:strokes 0 :stroke-width] value)))))) - -(defn update-rotation [value shape-ids] - (ptk/reify ::update-shape-dimensions - ptk/WatchEvent - (watch [_ _ _] - (rx/of - (udw/trigger-bounding-box-cloaking shape-ids) - (udw/increase-rotation shape-ids value))))) - -(defn update-layout-spacing-column [value shape-ids] - (doseq [shape-id shape-ids] - (let [shape (dt/get-shape-from-state shape-id @st/state) - layout-direction (:layout-flex-dir shape) - layout-update (if (or (= layout-direction :row-reverse) (= layout-direction :row)) - {:layout-gap {:column-gap value}} - {:layout-gap {:row-gap value}})] - (st/emit! - (dwsl/update-layout [shape-id] layout-update))))) - ;; JSON export functions ------------------------------------------------------- (defn encode-tokens From 828e3a719f4ca643d09e7501802720336a1f1111 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 15:29:42 +0200 Subject: [PATCH 39/45] Disable running tests from shadow-cljs directly --- frontend/package.json | 4 +--- frontend/shadow-cljs.edn | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index a561708646..877357e28e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,9 +5,7 @@ "author": "Kaleidos INC", "private": true, "packageManager": "yarn@4.2.2", - "browserslist": [ - "defaults" - ], + "browserslist": ["defaults"], "type": "module", "repository": { "type": "git", diff --git a/frontend/shadow-cljs.edn b/frontend/shadow-cljs.edn index 7201b1dcb7..d958aa70b9 100644 --- a/frontend/shadow-cljs.edn +++ b/frontend/shadow-cljs.edn @@ -163,7 +163,7 @@ :output-to "target/tests-esm.cjs" :output-dir "target/test-esm" :ns-regexp "^token-tests.*-test$" - :autorun true + :autorun false :compiler-options {:output-feature-set :es2020 From 4a329a6318a73af680df3df02a1fac8eea97c923 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 15:52:58 +0200 Subject: [PATCH 40/45] Override http server --- frontend/shadow-cljs.edn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/shadow-cljs.edn b/frontend/shadow-cljs.edn index d958aa70b9..813e319c16 100644 --- a/frontend/shadow-cljs.edn +++ b/frontend/shadow-cljs.edn @@ -165,6 +165,8 @@ :ns-regexp "^token-tests.*-test$" :autorun false + :devtools {:http-port 3460} + :compiler-options {:output-feature-set :es2020 :output-wrapper false From 4fc7efd3b7149e451dc8cd53542ca8c56b7b3c24 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Thu, 4 Jul 2024 16:03:32 +0200 Subject: [PATCH 41/45] Restore performance measuring lines --- .../main/ui/workspace/tokens/style_dictionary.cljs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs index e4e965df72..911fbafe99 100644 --- a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs @@ -53,7 +53,7 @@ "Resolves references and math expressions using StyleDictionary. Returns a promise with the resolved dictionary." [tokens & {:keys [debug?] :as config}] - (let [#_#_performance-start (js/window.performance.now) + (let [performance-start (js/performance.now) sd (tokens->style-dictionary+ tokens config)] (when debug? (js/console.log "StyleDictionary" sd)) @@ -61,12 +61,12 @@ (.buildAllPlatforms "json") (.catch js/console.error) (.then (fn [^js resp] - (let [#_#_performance-end (js/window.performance.now) - #_#_duration-ms (- performance-end performance-start) + (let [performance-end (js/performance.now) + duration-ms (- performance-end performance-start) resolved-tokens (.-allTokens resp)] - #_(when debug? - (js/console.log "Time elapsed" duration-ms "ms") - (js/console.log "Resolved tokens" resolved-tokens)) + (when debug? + (js/console.log "Time elapsed" duration-ms "ms") + (js/console.log "Resolved tokens" resolved-tokens)) resolved-tokens)))))) (defn humanize-errors [{:keys [errors value] :as _token}] From c70bb876b23724758174b1dc453ced1cef88ebed Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 5 Jul 2024 08:31:38 +0200 Subject: [PATCH 42/45] Add changelog --- .../src/app/main/ui/workspace/tokens/CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontend/src/app/main/ui/workspace/tokens/CHANGELOG.md b/frontend/src/app/main/ui/workspace/tokens/CHANGELOG.md index 35d40bdfbf..5574e332c0 100644 --- a/frontend/src/app/main/ui/workspace/tokens/CHANGELOG.md +++ b/frontend/src/app/main/ui/workspace/tokens/CHANGELOG.md @@ -18,6 +18,18 @@ If possible add video here from PR as well ## Changes +### 2024-07-05 - UX Improvements when applying tokens + +[Link to PR](https://github.com/tokens-studio/tokens-studio-for-penpot/compare/token-studio-develop...ux-improvements?body=&expand=1) + +- When unapplying tokens, the shape doesn't change anymore +- Multi Select behavior according to [Specs](https://github.com/tokens-studio/obsidian-docs/blob/31f0d7f98ff5ac922970f3009fe877cc02d6d0cd/Products/TS%20for%20Penpot/Specs/Token%20State%20Specs.md) +- Undo for applying tokens and change the shape is now one undo step + (before applying a token created multiple undo steps) + +[Video](https://github.com/tokens-studio/tokens-studio-for-penpot/assets/1898374/01d9d429-cab1-41cd-a3ff-495003edd3e8 +) + ### 2024-07-01 - Disallow creating tokens at existing paths Disallow creating tokens at an existing path. From c7a46c31b43c8b71d087ed220ae6406ead0e3953 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 5 Jul 2024 08:53:45 +0200 Subject: [PATCH 43/45] Convert layout spacing to function --- .../app/main/ui/workspace/tokens/core.cljs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index 1518c303b9..bea09eea78 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -85,14 +85,17 @@ (udw/increase-rotation shape-ids value))))) (defn update-layout-spacing-column [value shape-ids] - (doseq [shape-id shape-ids] - (let [shape (dt/get-shape-from-state shape-id @st/state) - layout-direction (:layout-flex-dir shape) - layout-update (if (or (= layout-direction :row-reverse) (= layout-direction :row)) - {:layout-gap {:column-gap value}} - {:layout-gap {:row-gap value}})] - (st/emit! - (dwsl/update-layout [shape-id] layout-update))))) + (ptk/reify ::update-layout-spacing-column + ptk/WatchEvent + (watch [_ state _] + (rx/concat + (for [shape-id shape-ids] + (let [shape (dt/get-shape-from-state shape-id state) + layout-direction (:layout-flex-dir shape) + layout-update (if (or (= layout-direction :row-reverse) (= layout-direction :row)) + {:layout-gap {:column-gap value}} + {:layout-gap {:row-gap value}})] + (dwsl/update-layout [shape-id] layout-update))))))) ;; Events ---------------------------------------------------------------------- From 0fad53ea6c10b59e48c4c36ed4d8d9e8a27ac62c Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 5 Jul 2024 08:55:01 +0200 Subject: [PATCH 44/45] Convert stroke to event --- frontend/src/app/main/ui/workspace/tokens/core.cljs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/core.cljs b/frontend/src/app/main/ui/workspace/tokens/core.cljs index bea09eea78..cb03a7a277 100644 --- a/frontend/src/app/main/ui/workspace/tokens/core.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/core.cljs @@ -71,10 +71,9 @@ (defn update-stroke-width [value shape-ids] - (st/emit! - (dch/update-shapes shape-ids (fn [shape] - (when (seq (:strokes shape)) - (assoc-in shape [:strokes 0 :stroke-width] value)))))) + (dch/update-shapes shape-ids (fn [shape] + (when (seq (:strokes shape)) + (assoc-in shape [:strokes 0 :stroke-width] value))))) (defn update-rotation [value shape-ids] (ptk/reify ::update-shape-dimensions From bc1f27eac9919fb557b99343641c5aac1c6acc7d Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Fri, 5 Jul 2024 09:18:36 +0200 Subject: [PATCH 45/45] Trigger Build