mirror of
https://github.com/penpot/penpot.git
synced 2025-06-06 09:31:38 +02:00
♻️ Refactor token set auto selection mechanism
This is a general purpose change that also allows perform a best effort on selection sets when the name is changed (per example by moving it into other group).
This commit is contained in:
parent
5446464d7e
commit
4a4cd9492a
6 changed files with 82 additions and 106 deletions
|
@ -252,71 +252,35 @@
|
||||||
set-name (add-set-prefix (last paths))]
|
set-name (add-set-prefix (last paths))]
|
||||||
(conj set-path set-name)))
|
(conj set-path set-name)))
|
||||||
|
|
||||||
(defn split-token-set-path [token-set-path]
|
(defn split-token-set-name
|
||||||
(split-path token-set-path set-separator))
|
[name]
|
||||||
|
(split-path name set-separator))
|
||||||
(defn split-token-set-name [token-set-name]
|
|
||||||
(-> (split-token-set-path token-set-name)
|
|
||||||
(add-token-set-paths-prefix)))
|
|
||||||
|
|
||||||
(defn get-token-set-path [token-set]
|
(defn get-token-set-path [token-set]
|
||||||
(let [path (get-path token-set set-separator)]
|
(let [path (get-path token-set set-separator)]
|
||||||
(add-token-set-paths-prefix path)))
|
(add-token-set-paths-prefix path)))
|
||||||
|
|
||||||
(defn set-name->set-path-string [set-name]
|
(defn get-token-set-final-name
|
||||||
(-> (split-token-set-name set-name)
|
[name]
|
||||||
(join-set-path)))
|
(-> (split-token-set-name name)
|
||||||
|
(peek)))
|
||||||
(defn set-path->set-name [set-path]
|
|
||||||
(->> (split-token-set-path set-path)
|
|
||||||
(map (fn [path-part]
|
|
||||||
(or (-> (split-set-prefix path-part)
|
|
||||||
(second))
|
|
||||||
path-part)))
|
|
||||||
(join-set-path)))
|
|
||||||
|
|
||||||
(defn get-token-set-final-name [path]
|
|
||||||
(-> (split-token-set-path path)
|
|
||||||
(last)))
|
|
||||||
|
|
||||||
(defn set-name->prefixed-full-path [name-str]
|
(defn set-name->prefixed-full-path [name-str]
|
||||||
(-> (split-token-set-path name-str)
|
(-> (split-token-set-name name-str)
|
||||||
(set-full-path->set-prefixed-full-path)))
|
(set-full-path->set-prefixed-full-path)))
|
||||||
|
|
||||||
(defn get-token-set-prefixed-path [token-set]
|
(defn get-token-set-prefixed-path [token-set]
|
||||||
(let [path (get-path token-set set-separator)]
|
(let [path (get-path token-set set-separator)]
|
||||||
(set-full-path->set-prefixed-full-path path)))
|
(set-full-path->set-prefixed-full-path path)))
|
||||||
|
|
||||||
(defn get-prefixed-token-set-final-prefix [prefixed-path-str]
|
(defn prefixed-set-path-string->set-name-string [path-str]
|
||||||
(some-> (get-token-set-final-name prefixed-path-str)
|
(->> (split-token-set-name 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)))
|
|
||||||
|
|
||||||
(defn prefixed-set-path-string->set-path [path-str]
|
|
||||||
(->> (split-token-set-path path-str)
|
|
||||||
(map (fn [path-part]
|
(map (fn [path-part]
|
||||||
(or (-> (split-set-str-path-prefix path-part)
|
(or (-> (split-set-str-path-prefix path-part)
|
||||||
(second))
|
(second))
|
||||||
path-part)))))
|
path-part)))
|
||||||
|
|
||||||
(defn prefixed-set-path-string->set-name-string [path-str]
|
|
||||||
(->> (prefixed-set-path-string->set-path path-str)
|
|
||||||
(join-set-path)))
|
(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 replace-last-path-name
|
(defn replace-last-path-name
|
||||||
"Replaces the last element in a `path` vector with `name`."
|
"Replaces the last element in a `path` vector with `name`."
|
||||||
[path name]
|
[path name]
|
||||||
|
@ -363,7 +327,7 @@
|
||||||
(defrecord TokenSet [name description modified-at tokens]
|
(defrecord TokenSet [name description modified-at tokens]
|
||||||
ITokenSet
|
ITokenSet
|
||||||
(update-name [_ set-name]
|
(update-name [_ set-name]
|
||||||
(TokenSet. (-> (split-token-set-path name)
|
(TokenSet. (-> (split-token-set-name name)
|
||||||
(drop-last)
|
(drop-last)
|
||||||
(concat [set-name])
|
(concat [set-name])
|
||||||
(join-set-path))
|
(join-set-path))
|
||||||
|
@ -406,7 +370,8 @@
|
||||||
(vals tokens))
|
(vals tokens))
|
||||||
|
|
||||||
(get-set-prefixed-path-string [_]
|
(get-set-prefixed-path-string [_]
|
||||||
(set-name-string->prefixed-set-path-string name))
|
(-> (set-name->prefixed-full-path name)
|
||||||
|
(join-set-path)))
|
||||||
|
|
||||||
(get-tokens-tree [_]
|
(get-tokens-tree [_]
|
||||||
(tokens-tree tokens))
|
(tokens-tree tokens))
|
||||||
|
@ -754,7 +719,7 @@ used for managing active sets without a user created theme.")
|
||||||
;; Set
|
;; Set
|
||||||
(and v (instance? TokenSet v))
|
(and v (instance? TokenSet v))
|
||||||
[{:group? false
|
[{:group? false
|
||||||
:path (split-token-set-path (:name v))
|
:path (split-token-set-name (:name v))
|
||||||
:parent-path parent
|
:parent-path parent
|
||||||
:depth depth
|
:depth depth
|
||||||
:set v}]
|
:set v}]
|
||||||
|
@ -880,7 +845,7 @@ Will return a value that matches this schema:
|
||||||
this)))
|
this)))
|
||||||
|
|
||||||
(delete-set-path [_ prefixed-set-name]
|
(delete-set-path [_ prefixed-set-name]
|
||||||
(let [prefixed-set-path (split-token-set-path prefixed-set-name)
|
(let [prefixed-set-path (split-token-set-name prefixed-set-name)
|
||||||
set-node (get-in sets prefixed-set-path)
|
set-node (get-in sets prefixed-set-path)
|
||||||
set-group? (not (instance? TokenSet set-node))
|
set-group? (not (instance? TokenSet set-node))
|
||||||
set-name-string (prefixed-set-path-string->set-name-string prefixed-set-name)]
|
set-name-string (prefixed-set-path-string->set-name-string prefixed-set-name)]
|
||||||
|
@ -988,13 +953,13 @@ Will return a value that matches this schema:
|
||||||
(->> (tree-seq d/ordered-map? vals sets)
|
(->> (tree-seq d/ordered-map? vals sets)
|
||||||
(filter (partial instance? TokenSet))))
|
(filter (partial instance? TokenSet))))
|
||||||
|
|
||||||
(get-path-sets [_ path]
|
(get-path-sets [_ name]
|
||||||
(some->> (get-in sets (split-token-set-path path))
|
(some->> (get-in sets (split-token-set-name name))
|
||||||
(tree-seq d/ordered-map? vals)
|
(tree-seq d/ordered-map? vals)
|
||||||
(filter (partial instance? TokenSet))))
|
(filter (partial instance? TokenSet))))
|
||||||
|
|
||||||
(get-sets-at-prefix-path [_ prefixed-path-str]
|
(get-sets-at-prefix-path [_ prefixed-path-str]
|
||||||
(some->> (get-in sets (split-token-set-path prefixed-path-str))
|
(some->> (get-in sets (split-token-set-name prefixed-path-str))
|
||||||
(tree-seq d/ordered-map? vals)
|
(tree-seq d/ordered-map? vals)
|
||||||
(filter (partial instance? TokenSet))))
|
(filter (partial instance? TokenSet))))
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,8 @@
|
||||||
(dch/commit-changes changes)
|
(dch/commit-changes changes)
|
||||||
(wtu/update-workspace-tokens))))))
|
(wtu/update-workspace-tokens))))))
|
||||||
|
|
||||||
|
(declare set-selected-token-set-name)
|
||||||
|
|
||||||
(defn create-token-set [set-name token-set]
|
(defn create-token-set [set-name token-set]
|
||||||
(let [new-token-set (-> token-set
|
(let [new-token-set (-> token-set
|
||||||
(update :name #(if (empty? %) set-name (ctob/join-set-path [% set-name]))))]
|
(update :name #(if (empty? %) set-name (ctob/join-set-path [% set-name]))))]
|
||||||
|
@ -117,7 +119,7 @@
|
||||||
(let [changes (-> (pcb/empty-changes it)
|
(let [changes (-> (pcb/empty-changes it)
|
||||||
(pcb/add-token-set new-token-set))]
|
(pcb/add-token-set new-token-set))]
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwts/set-selected-token-set-name (:name new-token-set))
|
(set-selected-token-set-name (:name new-token-set))
|
||||||
(dch/commit-changes changes)))))))
|
(dch/commit-changes changes)))))))
|
||||||
|
|
||||||
(defn rename-token-set-group [set-group-path set-group-fname]
|
(defn rename-token-set-group [set-group-path set-group-fname]
|
||||||
|
@ -138,7 +140,7 @@
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/update-token-set token-set prev-token-set))]
|
(pcb/update-token-set token-set prev-token-set))]
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwts/set-selected-token-set-name (:name token-set))
|
(set-selected-token-set-name (:name token-set))
|
||||||
(dch/commit-changes changes))))))
|
(dch/commit-changes changes))))))
|
||||||
|
|
||||||
(defn toggle-token-set [{:keys [token-set-name]}]
|
(defn toggle-token-set [{:keys [token-set-name]}]
|
||||||
|
@ -164,18 +166,11 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (dsh/lookup-file-data state)
|
(let [data (dsh/lookup-file-data state)
|
||||||
update-token-set-change (some-> lib
|
|
||||||
(ctob/get-sets)
|
|
||||||
(first)
|
|
||||||
(:name)
|
|
||||||
(dwts/set-selected-token-set-name))
|
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/set-tokens-lib lib))]
|
(pcb/set-tokens-lib lib))]
|
||||||
(rx/of
|
(rx/of (dch/commit-changes changes)
|
||||||
(dch/commit-changes changes)
|
(wtu/update-workspace-tokens))))))
|
||||||
update-token-set-change
|
|
||||||
(wtu/update-workspace-tokens))))))
|
|
||||||
|
|
||||||
(defn delete-token-set-path [group? path]
|
(defn delete-token-set-path [group? path]
|
||||||
(ptk/reify ::delete-token-set-path
|
(ptk/reify ::delete-token-set-path
|
||||||
|
@ -221,20 +216,13 @@
|
||||||
(ptk/reify ::drop-token-set
|
(ptk/reify ::drop-token-set
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [undo-id (js/Symbol)]
|
(try
|
||||||
(try
|
(when-let [changes (clt/generate-move-token-set (pcb/empty-changes it) (get-tokens-lib state) drop-opts)]
|
||||||
(when-let [changes (clt/generate-move-token-set (pcb/empty-changes it) (get-tokens-lib state) drop-opts)]
|
(rx/of (dch/commit-changes changes)
|
||||||
(rx/of
|
(wtu/update-workspace-tokens)))
|
||||||
(dwu/start-undo-transaction undo-id)
|
(catch js/Error e
|
||||||
(dch/commit-changes changes)
|
(rx/of
|
||||||
(some-> (get-in changes [:redo-changes 0 :to-path])
|
(drop-error (ex-data e))))))))
|
||||||
(ctob/join-set-path)
|
|
||||||
(dwts/set-selected-token-set-name))
|
|
||||||
(wtu/update-workspace-tokens)
|
|
||||||
(dwu/commit-undo-transaction undo-id)))
|
|
||||||
(catch js/Error e
|
|
||||||
(rx/of
|
|
||||||
(drop-error (ex-data e)))))))))
|
|
||||||
|
|
||||||
(defn update-create-token
|
(defn update-create-token
|
||||||
[{:keys [token prev-token-name]}]
|
[{:keys [token prev-token-name]}]
|
||||||
|
@ -267,7 +255,7 @@
|
||||||
(pcb/set-token set-name (or prev-token-name (:name token)) token)))]
|
(pcb/set-token set-name (or prev-token-name (:name token)) token)))]
|
||||||
|
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwts/set-selected-token-set-name set-name)
|
(set-selected-token-set-name set-name)
|
||||||
(when-not prev-token-name
|
(when-not prev-token-name
|
||||||
(ptk/event ::ev/event {::ev/name "create-tokens"}))
|
(ptk/event ::ev/event {::ev/name "create-tokens"}))
|
||||||
(dch/commit-changes changes))))))
|
(dch/commit-changes changes))))))
|
||||||
|
@ -345,3 +333,11 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc-in state [:workspace-local :token-set-context-menu] nil))))
|
(assoc-in state [:workspace-local :token-set-context-menu] nil))))
|
||||||
|
|
||||||
|
(defn set-selected-token-set-name
|
||||||
|
[name]
|
||||||
|
(ptk/reify ::set-selected-token-set-name
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :workspace-local assoc :selected-token-set-name name))))
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
Will default to the first set."
|
Will default to the first set."
|
||||||
(:require
|
(:require
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.main.data.helpers :as dsh]
|
[app.main.data.helpers :as dsh]))
|
||||||
[potok.v2.core :as ptk]))
|
|
||||||
|
|
||||||
(defn get-selected-token-set-name [state]
|
(defn get-selected-token-set-name [state]
|
||||||
(or (get-in state [:workspace-local :selected-token-set-name])
|
(or (get-in state [:workspace-local :selected-token-set-name])
|
||||||
|
@ -33,10 +32,3 @@
|
||||||
(defn get-selected-token-set-tokens [state]
|
(defn get-selected-token-set-tokens [state]
|
||||||
(some-> (get-selected-token-set state)
|
(some-> (get-selected-token-set state)
|
||||||
:tokens))
|
:tokens))
|
||||||
|
|
||||||
(defn set-selected-token-set-name
|
|
||||||
[name]
|
|
||||||
(ptk/reify ::set-selected-token-set-path-from-name
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(update state :workspace-local assoc :selected-token-set-name name))))
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.tokens :as wdt]
|
[app.main.data.tokens :as wdt]
|
||||||
[app.main.data.workspace.tokens.selected-set :as dwts]
|
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||||
|
@ -34,7 +33,7 @@
|
||||||
(st/emit! (wdt/toggle-token-set-group group-path)))
|
(st/emit! (wdt/toggle-token-set-group group-path)))
|
||||||
|
|
||||||
(defn on-select-token-set-click [set-name]
|
(defn on-select-token-set-click [set-name]
|
||||||
(st/emit! (dwts/set-selected-token-set-name set-name)))
|
(st/emit! (wdt/set-selected-token-set-name set-name)))
|
||||||
|
|
||||||
(defn on-update-token-set [set-name token-set]
|
(defn on-update-token-set [set-name token-set]
|
||||||
(st/emit! (wdt/update-token-set (:name token-set) (ctob/update-name token-set set-name))))
|
(st/emit! (wdt/update-token-set (:name token-set) (ctob/update-name token-set set-name))))
|
||||||
|
@ -449,7 +448,7 @@
|
||||||
[{:keys [tokens-lib selected-token-set-name]}]
|
[{:keys [tokens-lib selected-token-set-name]}]
|
||||||
|
|
||||||
(let [token-sets
|
(let [token-sets
|
||||||
(ctob/get-set-tree tokens-lib)
|
(some-> tokens-lib (ctob/get-set-tree))
|
||||||
|
|
||||||
token-set-selected?
|
token-set-selected?
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
|
|
@ -240,17 +240,17 @@
|
||||||
(mf/defc theme-sets-list*
|
(mf/defc theme-sets-list*
|
||||||
{::mf/private true}
|
{::mf/private true}
|
||||||
[{:keys [tokens-lib]}]
|
[{:keys [tokens-lib]}]
|
||||||
(let [token-sets
|
(let [;; FIXME: This is an inneficient operation just for being
|
||||||
(ctob/get-sets tokens-lib)
|
;; ability to check if there are some sets and lookup the
|
||||||
|
;; first one when no set is selected, should be REFACTORED; is
|
||||||
|
;; inneficient because instead of return the sets as-is (tree)
|
||||||
|
;; it firstly makes it a plain seq from tree.
|
||||||
|
token-sets
|
||||||
|
(some-> tokens-lib (ctob/get-sets))
|
||||||
|
|
||||||
selected-token-set-name
|
selected-token-set-name
|
||||||
(mf/deref refs/selected-token-set-name)
|
(mf/deref refs/selected-token-set-name)
|
||||||
|
|
||||||
selected-token-set-name
|
|
||||||
(if selected-token-set-name
|
|
||||||
selected-token-set-name
|
|
||||||
(-> token-sets first :name))
|
|
||||||
|
|
||||||
{:keys [new-path] :as ctx}
|
{:keys [new-path] :as ctx}
|
||||||
(sets-context/use-context)]
|
(sets-context/use-context)]
|
||||||
|
|
||||||
|
@ -309,15 +309,15 @@
|
||||||
selected-token-set-name
|
selected-token-set-name
|
||||||
(mf/deref refs/selected-token-set-name)
|
(mf/deref refs/selected-token-set-name)
|
||||||
|
|
||||||
|
selected-token-set
|
||||||
|
(when selected-token-set-name
|
||||||
|
(some-> tokens-lib (ctob/get-set selected-token-set-name)))
|
||||||
|
|
||||||
;; If we have not selected any set explicitly we just
|
;; If we have not selected any set explicitly we just
|
||||||
;; select the first one from the list of sets
|
;; select the first one from the list of sets
|
||||||
selected-token-set-tokens
|
selected-token-set-tokens
|
||||||
(if selected-token-set-name
|
(when selected-token-set
|
||||||
(-> (ctob/get-set tokens-lib selected-token-set-name)
|
(get selected-token-set :tokens))
|
||||||
(get :tokens))
|
|
||||||
(-> (ctob/get-sets tokens-lib)
|
|
||||||
(first)
|
|
||||||
(get :tokens)))
|
|
||||||
|
|
||||||
tokens
|
tokens
|
||||||
(mf/with-memo [active-theme-tokens selected-token-set-tokens]
|
(mf/with-memo [active-theme-tokens selected-token-set-tokens]
|
||||||
|
@ -340,6 +340,31 @@
|
||||||
(mf/with-memo [tokens-by-type]
|
(mf/with-memo [tokens-by-type]
|
||||||
(get-sorted-token-groups tokens-by-type))]
|
(get-sorted-token-groups tokens-by-type))]
|
||||||
|
|
||||||
|
(mf/with-effect [tokens-lib selected-token-set-name]
|
||||||
|
(when tokens-lib
|
||||||
|
(if selected-token-set-name
|
||||||
|
;; WORKAROUND: because we don't have a stable reference (by
|
||||||
|
;; ID per example) to token sets, when a set is moved the
|
||||||
|
;; name/path of the set changes and now can point to not
|
||||||
|
;; existing object; on this cases we perform a best effort
|
||||||
|
;; search around all existing sets that matches the
|
||||||
|
;; name (and not the path) and select it if it is found
|
||||||
|
(when-not (ctob/get-set tokens-lib selected-token-set-name)
|
||||||
|
(let [selected-name (ctob/get-token-set-final-name selected-token-set-name)
|
||||||
|
match (->> (ctob/get-sets tokens-lib)
|
||||||
|
(map :name)
|
||||||
|
(filter (fn [name]
|
||||||
|
(let [path (ctob/split-token-set-name name)]
|
||||||
|
(= (peek path) selected-name))))
|
||||||
|
(first))]
|
||||||
|
(when match
|
||||||
|
(st/emit! (dt/set-selected-token-set-name match)))))
|
||||||
|
|
||||||
|
(let [match (->> (ctob/get-sets tokens-lib)
|
||||||
|
(first)
|
||||||
|
(:name))]
|
||||||
|
(st/emit! (dt/set-selected-token-set-name match))))))
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
[:& token-context-menu]
|
[:& token-context-menu]
|
||||||
[:& title-bar {:all-clickable true
|
[:& title-bar {:all-clickable true
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
[app.common.transit :as t]
|
[app.common.transit :as t]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.main.refs :as refs]
|
|
||||||
[app.main.ui.workspace.tokens.errors :as wte]
|
[app.main.ui.workspace.tokens.errors :as wte]
|
||||||
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
|
[app.main.ui.workspace.tokens.tinycolor :as tinycolor]
|
||||||
[app.main.ui.workspace.tokens.token :as wtt]
|
[app.main.ui.workspace.tokens.token :as wtt]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue