Merge pull request #6075 from penpot/niwinz-develop-token-fixes-1

 Add several fixes and improvements to tokens
This commit is contained in:
Andrey Antukh 2025-03-17 14:47:21 +01:00 committed by GitHub
commit c1c22dc6c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 1480 additions and 1447 deletions

View file

@ -376,18 +376,12 @@
[:type [:= :update-active-token-themes]] [:type [:= :update-active-token-themes]]
[:theme-ids [:set :string]]]] [:theme-ids [:set :string]]]]
[:add-token-sets
[:map {:title "AddTokenSetsChange"}
[:type [:= :add-token-sets]]
[:token-sets [:sequential ::ctot/token-set]]]]
[:rename-token-set-group [:rename-token-set-group
[:map {:title "RenameTokenSetGroup"} [:map {:title "RenameTokenSetGroup"}
[:type [:= :rename-token-set-group]] [:type [:= :rename-token-set-group]]
[:set-group-path [:vector :string]] [:set-group-path [:vector :string]]
[:set-group-fname :string]]] [:set-group-fname :string]]]
[:move-token-set-before [:move-token-set-before
[:map {:title "MoveTokenSetBefore"} [:map {:title "MoveTokenSetBefore"}
[:type [:= :move-token-set-before]] [:type [:= :move-token-set-before]]
@ -1050,12 +1044,6 @@
(update data :tokens-lib #(-> % (ctob/ensure-tokens-lib) (update data :tokens-lib #(-> % (ctob/ensure-tokens-lib)
(ctob/set-active-themes theme-ids)))) (ctob/set-active-themes theme-ids))))
(defmethod process-change :add-token-sets
[data {:keys [token-sets]}]
(update data :tokens-lib #(-> %
(ctob/ensure-tokens-lib)
(ctob/add-sets (map ctob/make-token-set token-sets)))))
(defmethod process-change :rename-token-set-group (defmethod process-change :rename-token-set-group
[data {:keys [set-group-path set-group-fname]}] [data {:keys [set-group-path set-group-fname]}]
(update data :tokens-lib (fn [lib] (update data :tokens-lib (fn [lib]

View file

@ -875,9 +875,28 @@
:token nil})) :token nil}))
(apply-changes-local)))) (apply-changes-local))))
(defn set-token-set [changes set-name group? token-set] (defn rename-token-set
[changes name new-name]
(assert-library! changes) (assert-library! changes)
(let [library-data (::library-data (meta changes)) (let [library-data (::library-data (meta changes))
prev-token-set (some-> (get library-data :tokens-lib)
(ctob/get-set name))]
(-> changes
(update :redo-changes conj {:type :set-token-set
:set-name name
:token-set (assoc prev-token-set :name new-name)
:group? false})
(update :undo-changes conj {:type :set-token-set
:set-name new-name
:token-set prev-token-set
:group? false})
(apply-changes-local))))
(defn set-token-set
[changes set-name group? token-set]
(assert-library! changes)
(let [library-data (::library-data (meta changes))
prev-token-set (some-> (get library-data :tokens-lib) prev-token-set (some-> (get library-data :tokens-lib)
(ctob/get-set set-name))] (ctob/get-set set-name))]
(-> changes (-> changes

View file

@ -44,7 +44,7 @@
(defn vec-starts-with? [v1 v2] (defn vec-starts-with? [v1 v2]
(= (subvec v1 0 (min (count v1) (count v2))) v2)) (= (subvec v1 0 (min (count v1) (count v2))) v2))
(defn calculate-move-token-set-or-set-group (defn- calculate-move-token-set-or-set-group
[tokens-lib {:keys [from-index to-index position collapsed-paths] [tokens-lib {:keys [from-index to-index position collapsed-paths]
:or {collapsed-paths #{}}}] :or {collapsed-paths #{}}}]
(let [tree (-> (ctob/get-set-tree tokens-lib) (let [tree (-> (ctob/get-set-tree tokens-lib)

View file

@ -27,14 +27,17 @@
(def valid-groupable-item? (def valid-groupable-item?
(sm/validator schema:groupable-item)) (sm/validator schema:groupable-item))
(def xf-map-trim
(comp
(map str/trim)
(remove str/empty?)))
(defn split-path (defn split-path
"Decompose a string in the form 'one.two.three' into a vector of strings, removing spaces." "Decompose a string in the form 'one.two.three' into a vector of strings, removing spaces."
[path separator] [path separator]
(let [xf (comp (map str/trim) (->> (str/split path separator)
(remove str/empty?))] (into [] xf-map-trim)
(->> (str/split path separator) (not-empty)))
(into [] xf))))
(defn split-path-name [s separator] (defn split-path-name [s separator]
(let [[path name] (str/split s (re-pattern (str "\\" separator)) 2)] (let [[path name] (str/split s (re-pattern (str "\\" separator)) 2)]
@ -61,10 +64,12 @@
(join-path separator)))) (join-path separator))))
(defn get-path (defn get-path
"Get the groups part of the name as a vector. E.g. group.subgroup.name -> ['group' 'subgroup']" "Get the path of object by specified separator (E.g. with '.'
separator, the 'group.subgroup.name' -> ['group' 'subgroup'])"
[item separator] [item separator]
(assert (valid-groupable-item? item) "expected groupable item") (assert (valid-groupable-item? item) "expected groupable item")
(split-path (:name item) separator)) (->> (split-path (:name item) separator)
(not-empty)))
(defn get-groups-str (defn get-groups-str
"Get the groups part of the name. E.g. group.subgroup.name -> group.subgroup" "Get the groups part of the name. E.g. group.subgroup.name -> group.subgroup"
@ -97,14 +102,9 @@
(def token-separator ".") (def token-separator ".")
(defn get-token-path [path] (defn get-token-path
(get-path path token-separator)) [token]
(get-path token token-separator))
;; FIXME: misleading name, we are spliting name into path, not
;; spliting path into path
(defn split-token-path
[path]
(split-path path token-separator))
(defrecord Token [name type value description modified-at]) (defrecord Token [name type value description modified-at])
@ -247,22 +247,33 @@
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 get-token-set-path
[token-set]
(get-path token-set set-separator))
(defn split-token-set-name (defn split-token-set-name
[name] [name]
(split-path name set-separator)) (split-path name set-separator))
(defn get-token-set-path [token-set] (defn normalize-set-name
(let [path (get-path token-set set-separator)] "Normalize a set name.
(add-token-set-paths-prefix path)))
If `relative-to` is provided, the normalized name will preserve the
same group prefix as reference name"
([name]
(->> (split-token-set-name name)
(str/join set-separator)))
([name relative-to]
(->> (concat (butlast (split-token-set-name relative-to))
(split-token-set-name name))
(str/join set-separator))))
;; FIXME: revisit
(defn get-token-set-final-name (defn get-token-set-final-name
[name] [name]
(-> (split-token-set-name name) (-> (split-token-set-name name)
(peek))) (peek)))
(defn split-token-set-path [token-set-path]
(split-path token-set-path set-separator))
(defn set-name->prefixed-full-path [name-str] (defn set-name->prefixed-full-path [name-str]
(-> (split-token-set-name name-str) (-> (split-token-set-name name-str)
(set-full-path->set-prefixed-full-path))) (set-full-path->set-prefixed-full-path)))
@ -291,7 +302,7 @@
[tokens & {:keys [update-token-fn] [tokens & {:keys [update-token-fn]
:or {update-token-fn identity}}] :or {update-token-fn identity}}]
(reduce-kv (fn [acc _ token] (reduce-kv (fn [acc _ token]
(let [path (split-token-path (:name token))] (let [path (get-token-path token)]
(assoc-in acc path (update-token-fn token)))) (assoc-in acc path (update-token-fn token))))
{} tokens)) {} tokens))
@ -303,8 +314,8 @@
(reduce (reduce
(fn [acc [_ token]] (fn [acc [_ token]]
(let [temp-id (random-uuid) (let [temp-id (random-uuid)
token (assoc token :temp/id temp-id) token (assoc token :temp/id temp-id)
path (split-token-path (:name token))] path (get-token-path token)]
(-> acc (-> acc
(assoc-in (concat [:tokens-tree] path) token) (assoc-in (concat [:tokens-tree] path) token)
(assoc-in [:ids temp-id] token)))) (assoc-in [:ids temp-id] token))))
@ -316,10 +327,7 @@
(update-token [_ token-name f] "update a token in the list") (update-token [_ token-name f] "update a token in the list")
(delete-token [_ token-name] "delete a token from the list") (delete-token [_ token-name] "delete a token from the list")
(get-token [_ token-name] "return token by token-name") (get-token [_ token-name] "return token by token-name")
(get-tokens [_] "return an ordered sequence of all tokens in the set") (get-tokens [_] "return an ordered sequence of all tokens in the set"))
(get-set-prefixed-path-string [_] "convert set name to prefixed full path string")
(get-tokens-tree [_] "returns a tree of tokens split & nested by their name path")
(get-dtcg-tokens-tree [_] "returns tokens tree formated to the dtcg spec"))
(defrecord TokenSet [name description modified-at tokens] (defrecord TokenSet [name description modified-at tokens]
ITokenSet ITokenSet
@ -363,20 +371,7 @@
(get tokens token-name)) (get tokens token-name))
(get-tokens [_] (get-tokens [_]
(vals tokens)) (vals tokens)))
(get-set-prefixed-path-string [_]
(-> (set-name->prefixed-full-path name)
(join-set-path)))
(get-tokens-tree [_]
(tokens-tree tokens))
(get-dtcg-tokens-tree [_]
(tokens-tree tokens :update-token-fn (fn [token]
(cond-> {"$value" (:value token)
"$type" (cto/token-type->dtcg-token-type (:type token))}
(:description token) (assoc "$description" (:description token)))))))
(defn token-set? (defn token-set?
[o] [o]
@ -435,7 +430,6 @@
Prefixed set full path or pfpath: a full path wit prefixes [\"G-some-group\", \"G-some-subgroup\", \"S-some-set\"]. Prefixed set full path or pfpath: a full path wit prefixes [\"G-some-group\", \"G-some-subgroup\", \"S-some-set\"].
Prefixed set final name or pfname: a final name with prefix \"S-some-set\"." Prefixed set final name or pfname: a final name with prefix \"S-some-set\"."
(add-set [_ token-set] "add a set to the library, at the end") (add-set [_ token-set] "add a set to the library, at the end")
(add-sets [_ token-set] "add a collection of sets to the library, at the end")
(update-set [_ set-name f] "modify a set in the library") (update-set [_ set-name f] "modify a set in the library")
(delete-set-path [_ set-path] "delete a set in the library") (delete-set-path [_ set-path] "delete a set in the library")
(delete-set [_ set-name] "delete a set at `set-name` in the library and disable the `set-name` in all themes") (delete-set [_ set-name] "delete a set at `set-name` in the library and disable the `set-name` in all themes")
@ -880,9 +874,6 @@ Will return a value that matches this schema:
themes themes
active-themes))) active-themes)))
(add-sets [this token-sets]
(reduce add-set this token-sets))
(update-set [this set-name f] (update-set [this set-name f]
(let [prefixed-full-path (set-name->prefixed-full-path set-name) (let [prefixed-full-path (set-name->prefixed-full-path set-name)
set (get-in sets prefixed-full-path)] set (get-in sets prefixed-full-path)]
@ -920,7 +911,7 @@ Will return a value that matches this schema:
active-themes))) active-themes)))
(delete-set-group [this set-group-name] (delete-set-group [this set-group-name]
(let [path (split-token-set-path set-group-name) (let [path (split-token-set-name set-group-name)
prefixed-path (map add-set-group-prefix path) prefixed-path (map add-set-group-prefix path)
child-set-names (->> (get-sets-at-path this path) child-set-names (->> (get-sets-at-path this path)
(map :name) (map :name)
@ -1245,31 +1236,49 @@ Will return a value that matches this schema:
(d/ordered-map) active-themes))) (d/ordered-map) active-themes)))
(encode-dtcg [this] (encode-dtcg [this]
(let [themes (into [] (let [themes-xform
(comp (comp
(filter #(and (instance? TokenTheme %) (filter #(and (instance? TokenTheme %)
(not (hidden-temporary-theme? %)))) (not (hidden-temporary-theme? %))))
(map (fn [token-theme] (map (fn [token-theme]
(let [theme-map (->> token-theme (let [theme-map (->> token-theme
(into {}) (into {})
walk/stringify-keys)] walk/stringify-keys)]
(-> theme-map (-> theme-map
(set/rename-keys {"sets" "selectedTokenSets"}) (set/rename-keys {"sets" "selectedTokenSets"})
(update "selectedTokenSets" (fn [sets] (update "selectedTokenSets" (fn [sets]
(->> (for [s sets] (->> (for [s sets] [s "enabled"])
[s "enabled"]) (into {})))))))))
(into {}))))))))) themes
(tree-seq d/ordered-map? vals themes)) (->> (tree-seq d/ordered-map? vals themes)
(into [] themes-xform))
;; Active themes without exposing hidden penpot theme ;; Active themes without exposing hidden penpot theme
active-themes-clear (disj active-themes hidden-token-theme-path) active-themes-clear
name-set-tuples (->> sets (disj active-themes hidden-token-theme-path)
(tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet)) update-token-fn
(map (fn [token-set] (fn [token]
[(:name token-set) (get-dtcg-tokens-tree token-set)]))) (cond-> {"$value" (:value token)
ordered-set-names (map first name-set-tuples) "$type" (cto/token-type->dtcg-token-type (:type token))}
sets (into {} name-set-tuples) (:description token) (assoc "$description" (:description token))))
active-sets (get-active-themes-set-names this)]
name-set-tuples
(->> sets
(tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet))
(map (fn [{:keys [name tokens]}]
[name (tokens-tree tokens :update-token-fn update-token-fn)])))
ordered-set-names
(mapv first name-set-tuples)
sets
(into {} name-set-tuples)
active-sets
(get-active-themes-set-names this)]
(-> sets (-> sets
(assoc "$themes" themes) (assoc "$themes" themes)
(assoc-in ["$metadata" "tokenSetOrder"] ordered-set-names) (assoc-in ["$metadata" "tokenSetOrder"] ordered-set-names)
@ -1470,10 +1479,12 @@ Will return a value that matches this schema:
prev-sets (->> (fres/read-object! r) prev-sets (->> (fres/read-object! r)
(tree-seq d/ordered-map? vals) (tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet))) (filter (partial instance? TokenSet)))
sets (-> (make-tokens-lib)
(add-sets prev-sets) ;; FIXME: wtf we usind deref here?
(deref) sets (-> (reduce add-set (make-tokens-lib) prev-sets)
:sets) (deref)
(:sets))
_set-groups (fres/read-object! r) _set-groups (fres/read-object! r)
themes (fres/read-object! r) themes (fres/read-object! r)
active-themes (fres/read-object! r)] active-themes (fres/read-object! r)]

File diff suppressed because it is too large Load diff

View file

@ -127,7 +127,7 @@
(wtu/update-workspace-tokens)))))) (wtu/update-workspace-tokens))))))
(defn create-token-set (defn create-token-set
[set-name token-set] [set-name]
(ptk/reify ::create-token-set (ptk/reify ::create-token-set
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
@ -136,17 +136,20 @@
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it state _]
(let [token-set' (-> token-set (let [data (dsh/lookup-file-data state)
(update :name #(if (empty? %) tokens-lib (get data :tokens-lib)
set-name set-name (ctob/normalize-set-name set-name)]
(ctob/join-set-path [% set-name])))) (if (and tokens-lib (ctob/get-set tokens-lib set-name))
data (dsh/lookup-file-data state) (rx/of (ntf/show {:content (tr "errors.token-set-already-exists")
token-set-name (:name token-set') :type :toast
changes (-> (pcb/empty-changes it) :level :error
(pcb/with-library-data data) :timeout 9000}))
(pcb/set-token-set token-set-name false token-set'))] (let [token-set (ctob/make-token-set :name set-name)
(rx/of (set-selected-token-set-name token-set-name) changes (-> (pcb/empty-changes it)
(dch/commit-changes changes)))))) (pcb/with-library-data data)
(pcb/set-token-set set-name false token-set))]
(rx/of (set-selected-token-set-name set-name)
(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]
(ptk/reify ::rename-token-set-group (ptk/reify ::rename-token-set-group
@ -157,17 +160,25 @@
(rx/of (rx/of
(dch/commit-changes changes)))))) (dch/commit-changes changes))))))
(defn update-token-set [set-name token-set] (defn update-token-set
[token-set name]
(ptk/reify ::update-token-set (ptk/reify ::update-token-set
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it state _]
(let [data (dsh/lookup-file-data state) (let [data (dsh/lookup-file-data state)
changes (-> (pcb/empty-changes it) name (ctob/normalize-set-name name (:name token-set))
(pcb/with-library-data data) tokens-lib (get data :tokens-lib)]
(pcb/set-token-set set-name false token-set))]
(rx/of (if (ctob/get-set tokens-lib name)
(set-selected-token-set-name (:name token-set)) (rx/of (ntf/show {:content (tr "errors.token-set-already-exists")
(dch/commit-changes changes)))))) :type :toast
:level :error
:timeout 9000}))
(let [changes (-> (pcb/empty-changes it)
(pcb/with-library-data data)
(pcb/rename-token-set (:name token-set) name))]
(rx/of (set-selected-token-set-name (:name token-set))
(dch/commit-changes changes))))))))
(defn toggle-token-set (defn toggle-token-set
[name] [name]
@ -224,8 +235,8 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ _] (watch [_ _ _]
(let [content (case error (let [content (case error
:path-exists (tr "errors.drag-drop.set-exists" to-path) :path-exists (tr "errors.token-set-exists-on-drop" to-path)
:parent-to-child (tr "errors.drag-drop.parent-to-child") :parent-to-child (tr "errors.drop-token-set-parent-to-child")
nil)] nil)]
(when content (when content
(rx/of (rx/of
@ -243,7 +254,7 @@
(rx/of (rx/of
(dch/commit-changes changes) (dch/commit-changes changes)
(wtu/update-workspace-tokens))) (wtu/update-workspace-tokens)))
(catch js/Error e (catch :default e
(rx/of (rx/of
(drop-error (ex-data e)))))))) (drop-error (ex-data e))))))))
@ -255,7 +266,7 @@
(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 (dch/commit-changes changes)
(wtu/update-workspace-tokens))) (wtu/update-workspace-tokens)))
(catch js/Error e (catch :default e
(rx/of (rx/of
(drop-error (ex-data e)))))))) (drop-error (ex-data e))))))))

View file

@ -293,11 +293,12 @@
:on-save-form on-save-form :on-save-form on-save-form
:disabled? disabled?}]]]]])) :disabled? disabled?}]]]]]))
(defn- make-lib-with-theme [theme sets] (defn- make-lib-with-theme
(-> (ctob/make-tokens-lib) [theme sets]
(ctob/add-theme theme) (let [tlib (-> (ctob/make-tokens-lib)
(ctob/add-sets sets) (ctob/add-theme theme))
(ctob/activate-theme (:group theme) (:name theme)))) tlib (reduce ctob/add-set tlib sets)]
(ctob/activate-theme tlib (:group theme) (:name theme))))
(mf/defc controlled-edit-theme (mf/defc controlled-edit-theme
[{:keys [state set-state]}] [{:keys [state set-state]}]

View file

@ -43,17 +43,27 @@
(st/emit! (dt/set-selected-token-set-name name))) (st/emit! (dt/set-selected-token-set-name name)))
(defn on-update-token-set (defn on-update-token-set
[name token-set] [token-set name]
(st/emit! (dt/clear-token-set-edition) (st/emit! (dt/clear-token-set-edition)
(dt/update-token-set (:name token-set) (ctob/update-name token-set name)))) (dt/update-token-set token-set name)))
(defn- on-update-token-set-group [path name] (defn- on-update-token-set-group
[path name]
(st/emit! (dt/clear-token-set-edition) (st/emit! (dt/clear-token-set-edition)
(dt/rename-token-set-group path name))) (dt/rename-token-set-group path name)))
(defn- on-create-token-set [name token-set] (defn- on-create-token-set
(st/emit! (ptk/data-event ::ev/event {::ev/name "create-token-set" :name name}) [parent-set name]
(dt/create-token-set name token-set))) (let [;; FIXME: this code should be reusable under helper under
;; common types namespace
name
(if-let [parent-path (ctob/get-token-set-path parent-set)]
(->> (concat parent-path (ctob/split-token-set-name name))
(ctob/join-set-path))
(ctob/normalize-set-name name))]
(st/emit! (ptk/data-event ::ev/event {::ev/name "create-token-set" :name name})
(dt/create-token-set name))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; COMPONENTS ;; COMPONENTS
@ -62,13 +72,11 @@
(mf/defc editing-label* (mf/defc editing-label*
{::mf/private true} {::mf/private true}
[{:keys [default-value on-cancel on-submit]}] [{:keys [default-value on-cancel on-submit]}]
(let [ref (mf/use-ref) (let [on-submit
on-submit-valid
(mf/use-fn (mf/use-fn
(mf/deps on-cancel on-submit default-value) (mf/deps on-cancel on-submit default-value)
(fn [event] (fn [event]
(let [value (str/trim (dom/get-target-val event))] (let [value (dom/get-target-val event)]
(if (or (str/empty? value) (if (or (str/empty? value)
(= value default-value)) (= value default-value))
(on-cancel) (on-cancel)
@ -76,16 +84,15 @@
on-key-down on-key-down
(mf/use-fn (mf/use-fn
(mf/deps on-submit-valid on-cancel) (mf/deps on-submit on-cancel)
(fn [event] (fn [event]
(cond (cond
(kbd/enter? event) (on-submit-valid event) (kbd/enter? event) (on-submit event)
(kbd/esc? event) (on-cancel))))] (kbd/esc? event) (on-cancel))))]
[:input [:input
{:class (stl/css :editing-node) {:class (stl/css :editing-node)
:type "text" :type "text"
:ref ref :on-blur on-submit
:on-blur on-submit-valid
:on-key-down on-key-down :on-key-down on-key-down
:auto-focus true :auto-focus true
:placeholder (tr "workspace.token.set-edit-placeholder") :placeholder (tr "workspace.token.set-edit-placeholder")
@ -234,6 +241,7 @@
(mf/defc sets-tree-set* (mf/defc sets-tree-set*
[{:keys [id set label tree-depth tree-path tree-index is-selected is-active is-draggable is-editing [{:keys [id set label tree-depth tree-path tree-index is-selected is-active is-draggable is-editing
on-select on-drop on-toggle on-start-edition on-reset-edition on-edit-submit]}] on-select on-drop on-toggle on-start-edition on-reset-edition on-edit-submit]}]
(let [set-name (get set :name) (let [set-name (get set :name)
can-edit? (mf/use-ctx ctx/can-edit?) can-edit? (mf/use-ctx ctx/can-edit?)
@ -273,7 +281,7 @@
on-edit-submit' on-edit-submit'
(mf/use-fn (mf/use-fn
(mf/deps set on-edit-submit) (mf/deps set on-edit-submit)
#(on-edit-submit % set)) #(on-edit-submit set %))
on-drag on-drag
(mf/use-fn (mf/use-fn

View file

@ -1160,11 +1160,14 @@ msgid "errors.clipboard-not-implemented"
msgstr "Your browser cannot do this operation" msgstr "Your browser cannot do this operation"
#: src/app/main/data/tokens.cljs:199 #: src/app/main/data/tokens.cljs:199
msgid "errors.drag-drop.parent-to-child" msgid "errors.drop-token-set-parent-to-child"
msgstr "Cannot drop a parent set to an own child path." msgstr "Cannot drop a parent set to an own child path."
msgid "errors.token-set-already-exists"
msgstr "A set with the same name already exists"
#: src/app/main/data/tokens.cljs:198 #: src/app/main/data/tokens.cljs:198
msgid "errors.drag-drop.set-exists" msgid "errors.token-set-exists-on-drop"
msgstr "Cannot complete drop, a set with same name already exists at path %s." msgstr "Cannot complete drop, a set with same name already exists at path %s."
#: src/app/main/data/tokens.cljs:294 #: src/app/main/data/tokens.cljs:294

View file

@ -7182,3 +7182,6 @@ msgstr "Soporte de Plugins"
msgid "loader.tips.10.message" msgid "loader.tips.10.message"
msgstr "Extiende Penpot con plugins creados por la comunidad para funcionalidad extra." msgstr "Extiende Penpot con plugins creados por la comunidad para funcionalidad extra."
msgid "errors.token-set-already-exists"
msgstr "Ya existe un set con el mismo nombre"