diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 5574d8f9c..1df9c698c 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -215,6 +215,10 @@ (defn split-token-set-path [path] (split-path path set-separator)) +(defn get-token-set-final-name [path] + (-> (split-token-set-path path) + (last))) + (defn set-name->prefixed-full-path [name-str] (-> (split-token-set-path name-str) (set-full-path->set-prefixed-full-path))) @@ -223,6 +227,11 @@ (let [path (get-path token-set set-separator)] (set-full-path->set-prefixed-full-path path))) +(defn get-prefixed-token-set-final-prefix [prefixed-path-str] + (some-> (get-token-set-final-name prefixed-path-str) + (split-set-str-path-prefix) + (first))) + (defn set-name-string->prefixed-set-path-string [name-str] (-> (set-name->prefixed-full-path name-str) (join-set-path))) @@ -235,6 +244,16 @@ path-part))) (join-set-path))) +(defn prefixed-set-path-final-group? + "Predicate if the given prefixed path string ends with a group." + [prefixed-path-str] + (= (get-prefixed-token-set-final-prefix prefixed-path-str) set-group-prefix)) + +(defn prefixed-set-path-final-set? + "Predicate if the given prefixed path string ends with a set." + [prefixed-path-str] + (= (get-prefixed-token-set-final-prefix prefixed-path-str) set-prefix)) + (defn tokens-tree "Convert tokens into a nested tree with their `:name` as the path. Optionally use `update-token-fn` option to transform the token." diff --git a/common/src/app/common/types/tokens_list.cljc b/common/src/app/common/types/tokens_list.cljc deleted file mode 100644 index b31262d4d..000000000 --- a/common/src/app/common/types/tokens_list.cljc +++ /dev/null @@ -1,49 +0,0 @@ -;; This Source Code Form is subject to the terms of the Mozilla Public -;; License, v. 2.0. If a copy of the MPL was not distributed with this -;; file, You can obtain one at http://mozilla.org/MPL/2.0/. -;; -;; Copyright (c) KALEIDOS INC - -(ns app.common.types.tokens-list - (:require - [app.common.data :as d] - [app.common.time :as dt])) - -(defn tokens-seq - "Returns a sequence of all tokens within the file data." - [file-data] - (vals (:tokens file-data))) - -(defn- touch - "Updates the `modified-at` timestamp of a token." - [token] - (assoc token :modified-at (dt/now))) - -(defn add-token - "Adds a new token to the file data, setting its `modified-at` timestamp." - [file-data token-set-id token] - (-> file-data - (update :tokens assoc (:id token) (touch token)) - (d/update-in-when [:token-sets-index token-set-id] #(-> - (update % :tokens conj (:id token)) - (touch))))) - -(defn get-token - "Retrieves a token by its ID from the file data." - [file-data token-id] - (get-in file-data [:tokens token-id])) - -(defn set-token - "Sets or updates a token in the file data, updating its `modified-at` timestamp." - [file-data token] - (d/assoc-in-when file-data [:tokens (:id token)] (touch token))) - -(defn update-token - "Applies a function to update a token in the file data, then touches it." - [file-data token-id f & args] - (d/update-in-when file-data [:tokens token-id] #(-> (apply f % args) (touch)))) - -(defn delete-token - "Removes a token from the file data by its ID." - [file-data token-id] - (update file-data :tokens dissoc token-id)) diff --git a/common/src/app/common/types/tokens_theme_list.cljc b/common/src/app/common/types/tokens_theme_list.cljc deleted file mode 100644 index 971c96946..000000000 --- a/common/src/app/common/types/tokens_theme_list.cljc +++ /dev/null @@ -1,79 +0,0 @@ -;; This Source Code Form is subject to the terms of the Mozilla Public -;; License, v. 2.0. If a copy of the MPL was not distributed with this -;; file, You can obtain one at http://mozilla.org/MPL/2.0/. -;; -;; Copyright (c) KALEIDOS INC - -(ns app.common.types.tokens-theme-list - (:require - [app.common.data :as d] - [app.common.time :as dt])) - -(defn- touch - "Updates the `modified-at` timestamp of a token set." - [token-set] - (assoc token-set :modified-at (dt/now))) - -(defn assoc-active-token-themes - [file-data theme-ids] - (assoc file-data :token-active-themes theme-ids)) - -(defn add-temporary-token-theme - [file-data {:keys [id name] :as token-theme}] - (-> file-data - (d/dissoc-in [:token-themes-index (:token-theme-temporary-id file-data)]) - (assoc :token-theme-temporary-id id) - (assoc :token-theme-temporary-name name) - (update :token-themes-index assoc id token-theme))) - -(defn delete-temporary-token-theme - [file-data token-theme-id] - (cond-> file-data - (= (:token-theme-temporary-id file-data) token-theme-id) (dissoc :token-theme-temporary-id :token-theme-temporary-name) - :always (d/dissoc-in [:token-themes-index (:token-theme-temporary-id file-data)]))) - -(defn add-token-theme - [file-data {:keys [index id] :as token-theme}] - (-> file-data - (update :token-themes - (fn [token-themes] - (let [exists? (some (partial = id) token-themes)] - (cond - exists? token-themes - (nil? index) (conj (or token-themes []) id) - :else (d/insert-at-index token-themes index [id]))))) - (update :token-themes-index assoc id token-theme))) - -(defn update-token-theme - [file-data token-theme-id f & args] - (d/update-in-when file-data [:token-themes-index token-theme-id] #(-> (apply f % args) (touch)))) - -(defn delete-token-theme - [file-data theme-id] - (-> file-data - (update :token-themes (fn [ids] (d/removev #(= % theme-id) ids))) - (update :token-themes-index dissoc theme-id) - (update :token-active-themes disj theme-id))) - -(defn add-token-set - [file-data {:keys [index id] :as token-set}] - (-> file-data - (update :token-set-groups - (fn [token-set-groups] - (let [exists? (some (partial = id) token-set-groups)] - (cond - exists? token-set-groups - (nil? index) (conj (or token-set-groups []) id) - :else (d/insert-at-index token-set-groups index [id]))))) - (update :token-sets-index assoc id token-set))) - -(defn update-token-set - [file-data token-set-id f & args] - (d/update-in-when file-data [:token-sets-index token-set-id] #(-> (apply f % args) (touch)))) - -(defn delete-token-set - [file-data token-set-id] - (-> file-data - (update :token-set-groups (fn [xs] (into [] (remove #(= (:id %) token-set-id) xs)))) - (update :token-sets-index dissoc token-set-id) - (update :token-themes-index (fn [xs] (update-vals xs #(update % :sets disj token-set-id)))))) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index c2d54a11e..16ebf7a76 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -493,9 +493,6 @@ (def workspace-selected-token-set-path (l/derived wtts/get-selected-token-set-path st/state)) -(def workspace-token-set-group-selected? - (l/derived wtts/token-group-selected? st/state)) - (def workspace-ordered-token-sets (l/derived #(or (some-> % ctob/get-sets) []) tokens-lib)) diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 7682e22c3..476156b61 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -271,6 +271,11 @@ (mf/deps theme-state) (fn [set-name] (swap! theme-state #(ctob/toggle-set % set-name)))) + on-click-token-set (mf/use-callback + (mf/deps on-toggle-token-set) + (fn [prefixed-set-path-str] + (let [set-name (ctob/prefixed-set-path-string->set-name-string prefixed-set-path-str)] + (on-toggle-token-set set-name)))) on-change-field (fn [field value] (swap! theme-state #(assoc % field value))) on-save-form (mf/use-callback @@ -322,7 +327,7 @@ {:token-sets token-sets :token-set-selected? (constantly false) :token-set-active? token-set-active? - :on-select on-toggle-token-set + :on-select on-click-token-set :on-toggle-token-set on-toggle-token-set :origin "theme-modal" :context sets-context/static-context}]] diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index bf7f42c8c..145cd2f95 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -60,16 +60,8 @@ :default-value default-value}])) (mf/defc sets-tree-set-group - [{:keys [label tree-depth tree-path selected? collapsed? on-select editing? on-edit on-edit-reset on-edit-submit]}] + [{:keys [label tree-depth tree-path selected? collapsed? editing? on-edit on-edit-reset on-edit-submit]}] (let [editing?' (editing? tree-path) - on-click - (mf/use-fn - (mf/deps editing? tree-path) - (fn [event] - (dom/stop-propagation event) - (when-not (editing? tree-path) - (on-select tree-path)))) - on-context-menu (mf/use-fn (mf/deps editing? tree-path) @@ -80,33 +72,34 @@ (st/emit! (wdt/show-token-set-context-menu {:position (dom/get-client-position event) - :tree-path tree-path})))))] - [:div {;; :ref dref - :role "button" + :prefixed-set-path tree-path}))))) + on-click (mf/use-fn + (fn [event] + (dom/stop-propagation event) + (swap! collapsed? not)))] + [:div {:role "button" :data-testid "tokens-set-group-item" :style {"--tree-depth" tree-depth} :class (stl/css-case :set-item-container true + :set-item-group true :selected-set selected?) - :on-click on-click - :on-context-menu on-context-menu - :on-double-click #(on-edit tree-path)} + :on-context-menu on-context-menu} [:> icon-button* - {:on-click (fn [event] - (.stopPropagation event) - (swap! collapsed? not)) + {:class (stl/css :set-item-group-collapse-button) + :on-click on-click :aria-label (tr "labels.collapse") :icon (if @collapsed? "arrow-right" "arrow-down") :variant "action"}] - [:> icon* - {:id "group" - :class (stl/css :icon)}] (if editing?' [:& editing-label {:default-value label :on-cancel on-edit-reset :on-create on-edit-reset - :on-submit #(on-edit-submit)}] - [:div {:class (stl/css :set-name)} label])])) + ;; TODO Implement set group renaming + :on-submit (constantly nil)}] + [:div {:class (stl/css :set-name) + :on-double-click #(on-edit tree-path)} + label])])) (mf/defc sets-tree-set [{:keys [set label tree-depth tree-path selected? on-select active? on-toggle editing? on-edit on-edit-reset on-edit-submit]}] @@ -119,9 +112,7 @@ (fn [event] (dom/stop-propagation event) (when-not editing?' - (on-toggle set-name) (on-select tree-path)))) - on-context-menu (mf/use-fn (mf/deps editing?' tree-path) @@ -132,16 +123,17 @@ (st/emit! (wdt/show-token-set-context-menu {:position (dom/get-client-position event) - :tree-path tree-path})))))] - - [:div {;; :ref dref - :role "button" + :prefixed-set-path tree-path}))))) + on-checkbox-click (mf/use-fn + (fn [event] + (dom/stop-propagation event) + (on-toggle set-name)))] + [:div {:role "button" :data-testid "tokens-set-item" :style {"--tree-depth" tree-depth} :class (stl/css-case :set-item-container true :selected-set selected?) :on-click on-click - :on-double-click #(on-edit tree-path) :on-context-menu on-context-menu :aria-checked active?'} [:> icon* @@ -155,9 +147,11 @@ :on-create on-edit-reset :on-submit #(on-edit-submit set-name (ctob/update-name set %))}] [:* - [:div {:class (stl/css :set-name)} label] - [:button {:on-click on-click - :type "button" + [:div {:class (stl/css :set-name) + :on-double-click #(on-edit tree-path)} + label] + [:button {:type "button" + :on-click on-checkbox-click :class (stl/css-case :checkbox-style true :checkbox-checked-style active?')} (when active?' @@ -170,9 +164,9 @@ [{:keys [set-path set-node tree-depth tree-path on-select selected? on-toggle active? editing? on-edit on-edit-reset on-edit-submit] :or {tree-depth 0} :as props}] - (let [[set-prefix set-path'] (some-> set-path (ctob/split-set-str-path-prefix)) + (let [[set-path-prefix set-fname] (some-> set-path (ctob/split-set-str-path-prefix)) set? (instance? ctob/TokenSet set-node) - set-group? (= ctob/set-group-prefix set-prefix) + set-group? (= ctob/set-group-prefix set-path-prefix) root? (= tree-depth 0) collapsed? (mf/use-state false) children? (and @@ -187,7 +181,7 @@ :active? active? :selected? (selected? tree-path) :on-select on-select - :label set-path' + :label set-fname :tree-path (or tree-path set-path) :tree-depth tree-depth :editing? editing? @@ -199,7 +193,7 @@ [:& sets-tree-set-group {:selected? (selected? tree-path) :on-select on-select - :label set-path' + :label set-fname :collapsed? collapsed? :tree-path (or tree-path set-path) :tree-depth tree-depth diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.scss b/frontend/src/app/main/ui/workspace/tokens/sets.scss index 10c7c83f0..a0a84192f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.scss +++ b/frontend/src/app/main/ui/workspace/tokens/sets.scss @@ -34,6 +34,14 @@ } } +.set-item-group { + cursor: unset; +} + +.set-item-group-collapse-button { + cursor: pointer; +} + .set-name { @include textEllipsis; flex-grow: 1; diff --git a/frontend/src/app/main/ui/workspace/tokens/sets_context_menu.cljs b/frontend/src/app/main/ui/workspace/tokens/sets_context_menu.cljs index 4fb37428a..cf3c1c412 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets_context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets_context_menu.cljs @@ -7,6 +7,7 @@ (ns app.main.ui.workspace.tokens.sets-context-menu (:require-macros [app.main.style :as stl]) (:require + [app.common.types.tokens-lib :as ctob] [app.main.data.tokens :as wdt] [app.main.refs :as refs] [app.main.store :as st] @@ -35,11 +36,13 @@ [:span {:class (stl/css :title)} title]]) (mf/defc menu - [{:keys [tree-path]}] + [{:keys [prefixed-set-path]}] (let [{:keys [on-edit]} (sets-context/use-context) - edit-name (mf/use-fn #(on-edit tree-path)) - delete-set (mf/use-fn #(st/emit! (wdt/delete-token-set-path tree-path)))] + edit-name (mf/use-fn #(on-edit prefixed-set-path)) + delete-set (mf/use-fn #(st/emit! (wdt/delete-token-set-path prefixed-set-path)))] [:ul {:class (stl/css :context-list)} + (when (ctob/prefixed-set-path-final-group? prefixed-set-path) + [:& menu-entry {:title "Add set to this group" :on-click js/console.log}]) [:& menu-entry {:title (tr "labels.rename") :on-click edit-name}] [:& menu-entry {:title (tr "labels.delete") :on-click delete-set}]])) @@ -61,4 +64,4 @@ :ref dropdown-ref :style {:top top :left left} :on-context-menu prevent-default} - [:& menu {:tree-path (:tree-path mdata)}]]])) + [:& menu {:prefixed-set-path (:prefixed-set-path mdata)}]]])) diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 4818ff879..be90c259f 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -245,11 +245,7 @@ [:div {:class (stl/css :sets-sidebar)} [:& themes-header] [:div {:class (stl/css :sidebar-header)} - [:& title-bar {:collapsable true - :collapsed (not @open?) - :all-clickable true - :title (tr "labels.sets") - :on-collapsed #(swap! open? not)} + [:& title-bar {:title (tr "labels.sets")} [:& add-set-button {:on-open on-open :style "header"}]]] [:& theme-sets-list {:on-open on-open}]]]]))