🔧 Make all status operations use the new data structure

This commit is contained in:
Andrés Moya 2026-06-29 07:44:57 +02:00
parent ceb682daf2
commit 90eb820499
35 changed files with 997 additions and 732 deletions

View File

@ -106,7 +106,6 @@
:set-token
:set-token-set
:set-token-theme
:set-active-token-themes
:rename-token-set-group
:move-token-set
:move-token-set-group

View File

@ -405,12 +405,6 @@
[:theme-ids [:set ::sm/uuid]]
[:set-ids [:set ::sm/uuid]]]]
;; TODO deprecate this once everyone uses set-tokens-status
[:set-active-token-themes
[:map {:title "SetActiveTokenThemes"}
[:type [:= :set-active-token-themes]]
[:theme-paths [:set :string]]]]
[:rename-token-set-group
[:map {:title "RenameTokenSetGroup"}
[:type [:= :rename-token-set-group]]
@ -1055,11 +1049,6 @@
(-> (cfo/ensure-tokens-lib data)
(cfo/update-tokens-status ctos/set-tokens-status theme-ids set-ids)))
(defmethod process-change :set-active-token-themes
[data {:keys [theme-paths]}]
(-> (cfo/ensure-tokens-lib data)
(cfo/update-tokens-lib ctob/set-active-themes theme-paths)))
(defmethod process-change :rename-token-set-group
[data {:keys [set-group-path set-group-fname]}]
(-> (cfo/ensure-tokens-lib data)

View File

@ -1037,18 +1037,6 @@
(update :undo-changes conj {:type :set-tokens-status :theme-ids prev-theme-ids :set-ids prev-set-ids})
(apply-changes-local)))))
(defn set-active-token-themes
[changes active-theme-paths]
(assert-library! changes)
(let [library-data (::library-data (meta changes))
prev-active-theme-paths (d/nilv (some-> (get library-data :tokens-lib)
(ctob/get-active-theme-paths))
#{})]
(-> changes
(update :redo-changes conj {:type :set-active-token-themes :theme-paths active-theme-paths})
(update :undo-changes conj {:type :set-active-token-themes :theme-paths prev-active-theme-paths})
(apply-changes-local))))
(defn rename-token-set-group
[changes set-group-path set-group-fname]
(let [undo-path (ctob/replace-last-path-name set-group-path set-group-fname)

View File

@ -431,15 +431,24 @@
marked as active in the library (to migrate from legacy files)."
[tokens-lib]
(assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
(let [active-theme-ids (into #{}
(comp (map :id)
(filter #(not= % ctob/hidden-theme-id)))
(ctob/get-active-themes tokens-lib))
active-set-ids (into #{}
(comp (map #(ctob/get-set-by-name tokens-lib %))
(remove nil?)
(map ctob/get-id))
(ctob/get-active-themes-set-names tokens-lib))]
(let [active-theme-paths (ctob/get-legacy-active-themes tokens-lib)
active-theme-ids (into #{}
(comp (map #(ctob/get-theme-by-path tokens-lib %))
(remove nil?)
(map ctob/get-id)
(filter #(not= % ctob/hidden-theme-id)))
active-theme-paths)
;; Get active set names from the active themes
active-set-names (into #{}
(comp (filter #(and (ctob/token-theme? %)
(contains? active-theme-paths (ctob/get-theme-path %))))
(mapcat :sets))
(ctob/get-themes tokens-lib))
active-set-ids (into #{}
(comp (map #(ctob/get-set-by-name tokens-lib %))
(remove nil?)
(map ctob/get-id))
active-set-names)]
(ctos/make-tokens-status :active-theme-ids active-theme-ids
:active-set-ids active-set-ids)))
@ -527,6 +536,80 @@
(ctos/set-tokens-status tokens-status active-theme-ids' active-set-ids'))
tokens-status))
(defn toggle-theme-active
"Toggle a theme's active state and update active sets accordingly."
[tokens-status tokens-lib id]
(if (ctos/theme-active? tokens-status id)
(deactivate-theme tokens-status tokens-lib id)
(activate-theme tokens-status tokens-lib id)))
(defn set-active-themes
"Set the active themes and recalculate active sets."
[tokens-status tokens-lib theme-ids]
(assert (ctos/tokens-status? tokens-status))
(assert (ctob/tokens-lib? tokens-lib))
(assert (set? theme-ids))
(let [active-set-ids (calculate-active-sets theme-ids tokens-lib)]
(ctos/set-tokens-status tokens-status theme-ids active-set-ids)))
(defn get-active-set-names
"Return a set of active set names, resolved from TokensStatus + TokensLib."
[tokens-status tokens-lib]
(let [active-set-ids (ctos/get-active-set-ids tokens-status)]
(into #{}
(comp (filter #(contains? active-set-ids (ctob/get-id %)))
(map ctob/get-name))
(ctob/get-sets tokens-lib))))
(defn token-set-active?
"Check if a set (by name) is active."
[tokens-status tokens-lib set-name]
(let [active-set-names (get-active-set-names tokens-status tokens-lib)]
(contains? active-set-names set-name)))
(defn sets-at-path-all-active?
"Check active state of sets at a group path.
Returns :none, :all, or :partial."
[tokens-status tokens-lib group-path]
(let [active-set-names (get-active-set-names tokens-status tokens-lib)
path-sets (into #{}
(map ctob/get-name)
(ctob/get-sets-at-path tokens-lib group-path))]
(if (seq active-set-names)
(let [difference (set/difference path-sets active-set-names)]
(cond
(empty? difference) :all
(seq (set/intersection path-sets active-set-names)) :partial
:else :none))
:none)))
(defn get-tokens-in-active-sets
"Get merged tokens from all active sets, in set order."
[tokens-status tokens-lib]
(let [active-set-names (get-active-set-names tokens-status tokens-lib)
all-set-names (ctob/get-set-names tokens-lib)
ordered-active (filter active-set-names all-set-names)]
(reduce (fn [tokens set-name]
(let [set (ctob/get-set-by-name tokens-lib set-name)]
(merge tokens (ctob/get-tokens- set))))
(d/ordered-map)
ordered-active)))
(defn get-tokens-in-active-sets-force
"Same as get-tokens-in-active-sets but force-including a set by id."
[tokens-status tokens-lib force-set-id]
(let [active-set-names (get-active-set-names tokens-status tokens-lib)
all-set-names (ctob/get-set-names tokens-lib)
force-set (ctob/get-set tokens-lib force-set-id)
ordered-active (cond-> (filter active-set-names all-set-names)
(some? force-set)
(conj (ctob/get-name force-set)))]
(reduce (fn [tokens set-name]
(let [set (ctob/get-set-by-name tokens-lib set-name)]
(merge tokens (ctob/get-tokens- set))))
(d/ordered-map)
ordered-active)))
(defn sync-tokens-status-with-lib
"Synchronizes tokens status with the current tokens lib:
- Delete any theme or set that no longer exists in the lib."

View File

@ -9,38 +9,37 @@
[app.common.files.changes-builder :as pcb]
[app.common.files.tokens :as cfo]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]))
[app.common.types.tokens-status :as ctos]
[clojure.set :as set]))
(defn- generate-update-active-sets
"Copy the active sets from the currently active themes and move them
to the hidden token theme and update the theme with
`update-theme-fn`.
Use this for managing sets active state without having to modify a
user created theme (\"no themes selected\" state in the ui)."
[changes tokens-lib update-theme-fn]
(let [active-token-set-names (ctob/get-active-themes-set-names tokens-lib)
hidden-theme (ctob/get-hidden-theme tokens-lib)
hidden-theme' (-> (some-> hidden-theme
(ctob/set-sets active-token-set-names))
(update-theme-fn))]
(-> changes
(pcb/set-active-token-themes #{(ctob/get-theme-path hidden-theme')})
(pcb/set-token-theme (ctob/get-id hidden-theme)
hidden-theme'))))
"Update active set ids in tokens-status by applying update-fn to the
current active set ids. Also deactivate all themes since this is a manual
set activation. Returns updated changes."
[changes tokens-status _tokens-lib update-fn]
(let [current-set-ids (ctos/get-active-set-ids tokens-status)
new-set-ids (update-fn current-set-ids)
tokens-status' (ctos/set-tokens-status tokens-status #{} new-set-ids)]
(pcb/set-tokens-status changes tokens-status')))
(defn generate-set-enabled-token-set
"Enable or disable a token set at `set-name` in `tokens-lib` without modifying a user theme."
[changes tokens-lib set-name enabled?]
(if enabled?
(generate-update-active-sets changes tokens-lib #(ctob/enable-set % set-name))
(generate-update-active-sets changes tokens-lib #(ctob/disable-set % set-name))))
[changes tokens-status tokens-lib set-name enabled?]
(let [set-id (ctob/get-id (ctob/get-set-by-name tokens-lib set-name))]
(if set-id
(if enabled?
(generate-update-active-sets changes tokens-status tokens-lib #(conj % set-id))
(generate-update-active-sets changes tokens-status tokens-lib #(disj % set-id)))
changes)))
(defn generate-toggle-token-set
"Toggle a token set at `set-name` in `tokens-lib` without modifying a user theme."
[changes tokens-lib set-name]
(generate-update-active-sets changes tokens-lib #(ctob/toggle-set % set-name)))
[changes tokens-status tokens-lib set-name]
(let [set-id (ctob/get-id (ctob/get-set-by-name tokens-lib set-name))]
(if set-id
(generate-update-active-sets changes tokens-status tokens-lib
#(if (contains? % set-id) (disj % set-id) (conj % set-id)))
changes)))
;; ================== nuevo
@ -82,21 +81,19 @@
;; ======= fin nuevo
(defn toggle-token-set-group
"Toggle a token set group at `group-path` in `tokens-lib` for a `tokens-lib-theme`."
[group-path tokens-lib tokens-lib-theme]
(let [deactivate? (contains? #{:all :partial} (ctob/sets-at-path-all-active? tokens-lib group-path))
sets-names (->> (ctob/get-sets-at-path tokens-lib group-path)
(map ctob/get-name)
(into #{}))]
(if deactivate?
(ctob/disable-sets tokens-lib-theme sets-names)
(ctob/enable-sets tokens-lib-theme sets-names))))
(defn generate-toggle-token-set-group
"Toggle a token set group at `group-path` in `tokens-lib` without modifying a user theme."
[changes tokens-lib group-path]
(generate-update-active-sets changes tokens-lib #(toggle-token-set-group group-path tokens-lib %)))
[changes tokens-status tokens-lib group-path]
(let [sets-at-path (ctob/get-sets-at-path tokens-lib group-path)
set-ids (into #{} (map ctob/get-id) sets-at-path)
active? (cfo/sets-at-path-all-active? tokens-status tokens-lib group-path)]
(if (contains? #{:all :partial} active?)
;; Deactivate all sets at path
(generate-update-active-sets changes tokens-status tokens-lib
#(set/difference % set-ids))
;; Activate all sets at path
(generate-update-active-sets changes tokens-status tokens-lib
#(set/union % set-ids)))))
(defn vec-starts-with? [v1 v2]
(= (subvec v1 0 (min (count v1) (count v2))) v2))

View File

@ -41,8 +41,9 @@
(ctf/update-file-data file #(cfo/update-tokens-status % f)))
(defn sample-file-with-tokens
[& {:keys [lib-fn status-fn file-id] :or {lib-fn identity status-fn identity file-id :file1}}]
(-> (thf/sample-file file-id)
[& {:keys [lib-fn status-fn file-id] :as params
:or {lib-fn identity status-fn identity file-id :file1}}]
(-> (thf/sample-file file-id (dissoc params :lib-fn :status-fn))
(add-tokens-lib)
(update-tokens-lib lib-fn)
(update-tokens-status status-fn)))

View File

@ -18,6 +18,7 @@
[app.common.time :as ct]
[app.common.transit :as t]
[app.common.types.token :as cto]
[app.common.types.tokens-status :as ctos]
[app.common.uuid :as uuid]
[clojure.core.protocols :as cp]
[clojure.datafy :refer [datafy]]
@ -584,8 +585,7 @@
(disable-sets [_ set-names] "disable several sets in theme")
(toggle-set [_ set-name] "toggle a set enabled / disabled in the theme")
(update-set-name [_ prev-set-name set-name] "update set-name when it exists")
(theme-matches-group-name [_ group name] "if a theme matches the given group & name")
(hidden-theme? [_] "if a theme is the (from the user ui) hidden temporary theme"))
(theme-matches-group-name [_ group name] "if a theme matches the given group & name"))
(def hidden-theme-id
uuid/zero)
@ -659,10 +659,12 @@
(theme-matches-group-name [this group name]
(and (= (:group this) group)
(= (:name this) name)))
(= (:name this) name))))
(hidden-theme? [this]
(theme-matches-group-name this hidden-theme-group hidden-theme-name)))
(defn hidden-theme?
"Check if a theme is the hidden temporary theme."
[theme]
(theme-matches-group-name theme hidden-theme-group hidden-theme-name))
(defmethod pp/simple-dispatch TokenTheme
[^TokenTheme obj]
@ -787,15 +789,7 @@
(get-themes-in-group [_ group] "get an ordered sequence of the themes in the group")
(get-theme [_ id] "get one theme looking for id")
(get-theme-by-name [_ group name] "get one theme looking for group and name")
(get-theme-groups [_] "get a sequence of group names by order")
(get-active-theme-paths [_] "get the active theme paths")
(get-active-themes [_] "get an ordered sequence of active themes in the library")
(set-active-themes [_ active-themes] "set active themes in library")
(theme-active? [_ id] "predicate if token theme is active")
(activate-theme [_ id] "adds theme from the active-themes")
(deactivate-theme [_ id] "removes theme from the active-themes")
(toggle-theme-active [_ id] "toggles theme in the active-themes")
(get-hidden-theme [_] "get the hidden temporary theme"))
(get-theme-groups [_] "get a sequence of group names by order"))
(def schema:token-themes
[:and
@ -936,18 +930,10 @@
(update-token [_ set-id token-id f] "update a token in a set")
(delete-token [_ set-id token-id] "delete a token from a set")
(toggle-set-in-theme [_ theme-id set-name] "toggle a set used / not used in a theme")
(get-active-themes-set-names [_] "set of set names that are active in the the active themes")
(token-set-active? [_ set-name] "if a set is active in any of the active themes")
(sets-at-path-all-active? [_ group-path] "compute active state for child sets at `group-path`.
Will return a value that matches this schema:
`:none` None of the nested sets are active
`:all` All of the nested sets are active
`:partial` Mixed active state of nested sets")
(get-tokens-in-active-sets [_] "set of set names that are active in the the active themes")
(get-tokens-in-active-sets-force [_ force-set-id] "same as above but forcing a set to be active, even if it's not in the active themes")
(get-all-tokens [_] "all tokens in the lib, as a sequence")
(get-all-tokens-map [_] "all tokens in the lib, as a map name -> token")
(get-tokens [_ set-id] "return a map of tokens in the set, indexed by token-name"))
(get-tokens [_ set-id] "return a map of tokens in the set, indexed by token-name")
(get-legacy-active-themes [_] "only for legacy compatibility; return active themes inside library"))
(declare parse-multi-set-dtcg-json)
(declare read-multi-set-dtcg)
@ -1225,60 +1211,12 @@ Will return a value that matches this schema:
(get-theme-by-name [_ group name]
(dm/get-in themes [group name]))
(set-active-themes [_ active-themes]
(TokensLib. sets
themes
active-themes))
(activate-theme [this id]
(if-let [theme (get-theme this id)]
(let [group (:group theme)
group-themes (->> (get themes group)
(map (comp get-theme-path val))
(into #{}))
active-themes' (-> (set/difference active-themes group-themes)
(conj (get-theme-path theme)))]
(TokensLib. sets
themes
active-themes'))
this))
(deactivate-theme [this id]
(if-let [theme (get-theme this id)]
(TokensLib. sets
themes
(disj active-themes (get-theme-path theme)))
this))
(theme-active? [this id]
(when-let [theme (get-theme this id)]
(contains? active-themes (get-theme-path theme))))
(toggle-theme-active [this id]
(if (theme-active? this id)
(deactivate-theme this id)
(activate-theme this id)))
(get-active-theme-paths [_]
active-themes)
(get-active-themes [this]
(into
(list)
(comp
(filter (partial instance? TokenTheme))
(filter #(theme-active? this (get-id %))))
(tree-seq d/ordered-map? vals themes)))
(get-hidden-theme [this]
(get-theme this hidden-theme-id))
ITokensLib
(empty-lib? [this]
(and (empty? sets)
(or (empty? themes)
(and (= (theme-count this) 1)
(get-hidden-theme this)))))
(get-theme this hidden-theme-id)))))
(set-path-exists? [_ set-path]
(some? (get-in sets (set-full-path->set-prefixed-full-path set-path))))
@ -1313,58 +1251,6 @@ Will return a value that matches this schema:
active-themes)
this))
(get-active-themes-set-names [this]
(into #{}
(mapcat :sets)
(get-active-themes this)))
(token-set-active? [this set-name]
(let [set-names (get-active-themes-set-names this)]
(contains? set-names set-name)))
(sets-at-path-all-active? [this group-path]
(let [active-set-names (get-active-themes-set-names this)
prefixed-path-str (set-group-path->set-group-prefixed-path-str group-path)]
(if (seq active-set-names)
(let [path-active-set-names (some->> (get-in sets (split-set-name prefixed-path-str))
(tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet))
(map get-name)
(into #{}))
difference (set/difference path-active-set-names active-set-names)]
(cond
(empty? difference) :all
(seq (set/intersection path-active-set-names active-set-names)) :partial
:else :none))
:none)))
(get-tokens-in-active-sets [this]
(let [theme-set-names (get-active-themes-set-names this)
all-set-names (get-set-names this)
active-set-names (filter theme-set-names all-set-names)
tokens (reduce (fn [tokens set-name]
(let [set (get-set-by-name this set-name)]
(merge tokens (get-tokens- set))))
(d/ordered-map)
active-set-names)]
tokens))
(get-tokens-in-active-sets-force [this force-set-id]
(let [theme-set-names (get-active-themes-set-names this)
all-set-names (get-set-names this)
force-set (get-set this force-set-id)
active-set-names (cond-> (filter theme-set-names all-set-names)
(some? force-set)
(conj (get-name force-set)))
tokens (reduce (fn [tokens set-name]
(let [set (get-set-by-name this set-name)]
(merge tokens (get-tokens- set))))
(d/ordered-map)
active-set-names)]
tokens))
(get-all-tokens [this]
(mapcat #(vals (get-tokens- %))
(get-sets this)))
@ -1381,6 +1267,9 @@ Will return a value that matches this schema:
(get-set set-id)
(get-tokens-)))
(get-legacy-active-themes [_]
active-themes)
IValidation
(valid? [this]
(valid-tokens-lib-map? (datafy this)))
@ -1437,6 +1326,12 @@ Will return a value that matches this schema:
[o]
(and (tokens-lib? o) (valid? o)))
(defn get-theme-by-path
"Get a theme by its path string (e.g. \"/Theme Name\" or \"group/Theme Name\")."
[tokens-lib path]
(let [[group name] (split-theme-path path)]
(get-theme-by-name tokens-lib group name)))
(defn- ensure-hidden-theme
"A helper that is responsible to ensure that the hidden theme always
exists on the themes data structure"
@ -1933,11 +1828,22 @@ Will return a value that matches this schema:
library
(reduce add-theme library themes)
;; Activate themes by directly manipulating the internal active-themes field
;; (since activate-theme is being removed from the protocol)
library
(reduce (fn [library theme-path]
(let [[group name] (split-theme-path theme-path)
theme (get-theme-by-name library group name)]
(activate-theme library (get-id theme))))
(if theme
(let [group-themes (->> (get themes group)
(map (comp get-theme-path val))
(into #{}))
active-themes' (-> (set/difference (.-active-themes ^TokensLib library) group-themes)
(conj (get-theme-path theme)))]
(TokensLib. (.-sets ^TokensLib library)
(.-themes ^TokensLib library)
active-themes'))
library)))
library
active-theme-names)]
@ -2042,82 +1948,183 @@ Will return a value that matches this schema:
(defn- dtcg-export-themes
"Extract themes for a dtcg json export."
[tokens-lib]
(let [themes-xform
(comp
(filter #(and (instance? TokenTheme %)
(not (hidden-theme? %))))
(map (fn [token-theme]
;; NOTE: this probaly can be implemented as type method
(d/without-nils
{"id" (:external-id token-theme)
"name" (:name token-theme)
"group" (:group token-theme)
"description" (:description token-theme)
"isSource" (:is-source token-theme)
"selectedTokenSets" (reduce #(assoc %1 %2 "enabled") {} (:sets token-theme))}))))
([tokens-lib]
;; Backward-compatible version for print/serialization without tokens-status
(let [themes-xform
(comp
(filter #(and (instance? TokenTheme %)
(not (hidden-theme? %))))
(map (fn [token-theme]
;; NOTE: this probaly can be implemented as type method
(d/without-nils
{"id" (:external-id token-theme)
"name" (:name token-theme)
"group" (:group token-theme)
"description" (:description token-theme)
"isSource" (:is-source token-theme)
"selectedTokenSets" (reduce #(assoc %1 %2 "enabled") {} (:sets token-theme))}))))
themes
(->> (get-theme-tree tokens-lib)
(tree-seq d/ordered-map? vals)
(into [] themes-xform))
themes
(->> (get-theme-tree tokens-lib)
(tree-seq d/ordered-map? vals)
(into [] themes-xform))
;; Active themes without exposing hidden penpot theme
active-themes
(-> (get-active-theme-paths tokens-lib)
(disj hidden-theme-path))]
[themes active-themes]))
;; Active themes without exposing hidden penpot theme
active-themes
(-> (.-active-themes ^TokensLib tokens-lib)
(disj hidden-theme-path))]
[themes active-themes]))
([tokens-lib active-theme-ids]
;; Version with explicit active-theme-ids from TokensStatus
(let [themes-xform
(comp
(filter #(and (instance? TokenTheme %)
(not (hidden-theme? %))))
(map (fn [token-theme]
(d/without-nils
{"id" (:external-id token-theme)
"name" (:name token-theme)
"group" (:group token-theme)
"description" (:description token-theme)
"isSource" (:is-source token-theme)
"selectedTokenSets" (reduce #(assoc %1 %2 "enabled") {} (:sets token-theme))}))))
themes
(->> (get-theme-tree tokens-lib)
(tree-seq d/ordered-map? vals)
(into [] themes-xform))
;; Convert theme ids to theme paths, excluding hidden theme
active-themes
(into #{}
(comp (map #(get-theme tokens-lib %))
(filter some?)
(map get-theme-path)
(filter #(not= % hidden-theme-path)))
active-theme-ids)]
[themes active-themes])))
(defn export-dtcg-multi-file
"Convert a TokensLib into a plain clojure map, suitable to be encoded as a multi json files each encoded in DTCG format."
[tokens-lib]
(let [[themes active-themes]
(dtcg-export-themes tokens-lib)
([tokens-lib]
;; Backward-compatible version for print/serialization without tokens-status
(let [[themes active-themes]
(dtcg-export-themes tokens-lib)
sets
(->> (get-sets tokens-lib)
(map (fn [token-set]
(let [name (get-name token-set)
tokens (get-tokens- token-set)]
[(str name ".json") (tokens-tree tokens :update-token-fn token->dtcg-token)])))
(into {}))]
sets
(->> (get-sets tokens-lib)
(map (fn [token-set]
(let [name (get-name token-set)
tokens (get-tokens- token-set)]
[(str name ".json") (tokens-tree tokens :update-token-fn token->dtcg-token)])))
(into {}))]
(-> sets
(assoc "$themes.json" themes)
(assoc "$metadata.json"
{"tokenSetOrder" (get-set-names tokens-lib)
"activeThemes" active-themes
"activeSets" (get-active-themes-set-names tokens-lib)}))))
(-> sets
(assoc "$themes.json" themes)
(assoc "$metadata.json"
{"tokenSetOrder" (get-set-names tokens-lib)
"activeThemes" active-themes
;; For backward compat, use internal active-themes field
"activeSets" (into #{}
(comp (filter #(and (instance? TokenTheme %)
(contains? (.-active-themes ^TokensLib tokens-lib)
(get-theme-path %))))
(mapcat :sets))
(get-themes tokens-lib))}))))
([tokens-lib tokens-status]
;; Version with tokens-status for real exports
(let [active-theme-ids (ctos/get-active-theme-ids tokens-status)
[themes active-themes]
(dtcg-export-themes tokens-lib active-theme-ids)
sets
(->> (get-sets tokens-lib)
(map (fn [token-set]
(let [name (get-name token-set)
tokens (get-tokens- token-set)]
[(str name ".json") (tokens-tree tokens :update-token-fn token->dtcg-token)])))
(into {}))
active-set-ids (ctos/get-active-set-ids tokens-status)
active-set-names (into #{}
(comp (filter #(contains? active-set-ids (get-id %)))
(map get-name))
(get-sets tokens-lib))]
(-> sets
(assoc "$themes.json" themes)
(assoc "$metadata.json"
{"tokenSetOrder" (get-set-names tokens-lib)
"activeThemes" active-themes
"activeSets" active-set-names})))))
(defn export-dtcg-json
"Convert a TokensLib into a plain clojure map, suitable to be encoded as a multi sets json string in DTCG format."
[tokens-lib]
(let [[themes active-themes]
(dtcg-export-themes tokens-lib)
([tokens-lib]
;; Backward-compatible version for print/serialization without tokens-status
(let [[themes active-themes]
(dtcg-export-themes tokens-lib)
name-set-tuples
(->> (get-set-tree tokens-lib)
(tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet))
(map (fn [set]
[(get-name set)
(tokens-tree (get-tokens- set) :update-token-fn token->dtcg-token)])))
name-set-tuples
(->> (get-set-tree tokens-lib)
(tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet))
(map (fn [set]
[(get-name set)
(tokens-tree (get-tokens- set) :update-token-fn token->dtcg-token)])))
ordered-set-names
(mapv first name-set-tuples)
ordered-set-names
(mapv first name-set-tuples)
sets
(into {} name-set-tuples)
sets
(into {} name-set-tuples)
active-set-names
(get-active-themes-set-names tokens-lib)]
;; For backward compat, use internal active-themes field
active-set-names (into #{}
(comp (filter #(and (instance? TokenTheme %)
(contains? (.-active-themes ^TokensLib tokens-lib)
(get-theme-path %))))
(mapcat :sets))
(get-themes tokens-lib))]
(when-not (empty-lib? tokens-lib)
(-> sets
(assoc "$themes" themes)
(assoc "$metadata" {"tokenSetOrder" ordered-set-names
"activeThemes" active-themes
"activeSets" active-set-names})))))
(when-not (empty-lib? tokens-lib)
(-> sets
(assoc "$themes" themes)
(assoc "$metadata" {"tokenSetOrder" ordered-set-names
"activeThemes" active-themes
"activeSets" active-set-names})))))
([tokens-lib tokens-status]
;; Version with tokens-status for real exports
(let [active-theme-ids (ctos/get-active-theme-ids tokens-status)
[themes active-themes]
(dtcg-export-themes tokens-lib active-theme-ids)
name-set-tuples
(->> (get-set-tree tokens-lib)
(tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet))
(map (fn [set]
[(get-name set)
(tokens-tree (get-tokens- set) :update-token-fn token->dtcg-token)])))
ordered-set-names
(mapv first name-set-tuples)
sets
(into {} name-set-tuples)
active-set-ids (ctos/get-active-set-ids tokens-status)
active-set-names (into #{}
(comp (filter #(contains? active-set-ids (get-id %)))
(map get-name))
(get-sets tokens-lib))]
(when-not (empty-lib? tokens-lib)
(-> sets
(assoc "$themes" themes)
(assoc "$metadata" {"tokenSetOrder" ordered-set-names
"activeThemes" active-themes
"activeSets" active-set-names}))))))
(defn get-tokens-of-unknown-type
"Search for all tokens in the decoded json file that have a type that is not currently

View File

@ -13,6 +13,7 @@
[app.common.types.file :as ctf]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.common.uuid :as uuid]
[clojure.test :as t]))
(t/deftest test-parse-token-value
@ -102,13 +103,56 @@
;; Tokens lib
(t/deftest test-ensure-tokens-lib
(t/testing "ensure-tokens-lib should add a tokens-lib and tokens-status to the file data if they are missing, and should not modify them if they already exist"
(t/testing "ensure-tokens-lib should add a tokens-lib and tokens-status to the file data if they are missing"
(let [file (thf/sample-file :file1)
file-data (ctf/file-data file)
file-data' (cfo/ensure-tokens-lib file-data)]
(t/is (contains? file-data' :tokens-lib))
(t/is (ctob/tokens-lib? (:tokens-lib file-data')))
(t/is (contains? file-data' :tokens-status))
(t/is (ctos/tokens-status? (:tokens-status file-data')))))
(t/testing "ensure-tokens-lib should add a tokens-lib to the file data if it's missing"
(let [tokens-status (ctos/make-tokens-status)
file (-> (thf/sample-file :file1)
(assoc-in [:data :tokens-status] tokens-status))
file-data (ctf/file-data file)
file-data' (cfo/ensure-tokens-lib file-data)]
(t/is (contains? file-data' :tokens-lib))
(t/is (ctob/tokens-lib? (:tokens-lib file-data')))
(t/is (= tokens-status (:tokens-status file-data')))))
(t/testing "ensure-tokens-lib should add a tokens-status to the file data if it's missing"
(let [tokens-lib (ctob/make-tokens-lib)
file (-> (thf/sample-file :file1)
(assoc-in [:data :tokens-lib] tokens-lib))
file-data (ctf/file-data file)
file-data' (cfo/ensure-tokens-lib file-data)]
(t/is (= tokens-lib (:tokens-lib file-data')))
(t/is (contains? file-data' :tokens-status))
(t/is (ctos/tokens-status? (:tokens-status file-data')))))
(t/testing "ensure-tokens-lib should not add a tokens-lib if there is a tokens-file"
(let [tokens-file (uuid/next)
tokens-status (ctos/make-tokens-status)
file (-> (thf/sample-file :file1)
(assoc-in [:data :tokens-file] tokens-file)
(assoc-in [:data :tokens-status] tokens-status))
file-data (ctf/file-data file)
file-data' (cfo/ensure-tokens-lib file-data)]
(t/is (not (contains? file-data' :tokens-lib)))
(t/is (= tokens-file (:tokens-file file-data')))
(t/is (= tokens-status (:tokens-status file-data')))))
(t/testing "ensure-tokens-lib should not add a tokens-lib if there is a tokens-file, but should add a tokens-status if it's missing"
(let [tokens-file (uuid/next)
file (-> (thf/sample-file :file1)
(assoc-in [:data :tokens-file] tokens-file))
file-data (ctf/file-data file)
file-data' (cfo/ensure-tokens-lib file-data)]
(t/is (not (contains? file-data' :tokens-lib)))
(t/is (= tokens-file (:tokens-file file-data')))
(t/is (contains? file-data' :tokens-status))
(t/is (ctos/tokens-status? (:tokens-status file-data'))))))
(t/deftest test-update-tokens-lib

View File

@ -14,6 +14,7 @@
[app.common.test-helpers.shapes :as ths]
[app.common.test-helpers.tokens :as tht]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.common.uuid :as uuid]
[clojure.test :as t]))
@ -141,24 +142,27 @@
(t/deftest test-relocate-shape-out-of-layout-with-tokens
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tht/add-tokens-lib)
(tht/update-tokens-lib #(-> %
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :name "test-theme"
:sets #{"test-token-set"}))
(ctob/set-active-themes #{"/test-theme"})
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-sizing)
:name "token-sizing"
:type :sizing
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-spacing)
:name "token-spacing"
:type :spacing
:value 30))))
file (-> (tht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :test-theme)
:name "test-theme"
:sets #{"test-token-set"}))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-sizing)
:name "token-sizing"
:type :sizing
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-spacing)
:name "token-spacing"
:type :spacing
:value 30)))
:status-fn #(-> %
(ctos/set-tokens-status #{(thi/id :test-theme)}
#{(thi/id :test-token-set)})))
;; Sync tokens-status from lib's internal active-themes
(tho/add-frame :frame-1
:layout :flex ;; TODO: those values come from main.data.workspace.shape_layout/default-layout-params
:layout-flex-dir :row ;; it should be good to use it directly, but first it should be moved to common.logic

View File

@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.files.changes-builder :as pcb]
[app.common.files.tokens :as cfo]
[app.common.logic.shapes :as cls]
[app.common.test-helpers.compositions :as tho]
[app.common.test-helpers.files :as thf]
@ -18,75 +19,78 @@
[app.common.types.text :as txt]
[app.common.types.token :as cto]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[clojure.test :as t]))
(t/use-fixtures :each thi/test-fixture)
(defn- setup-file
[]
(-> (thf/sample-file :file1)
(tht/add-tokens-lib)
(tht/update-tokens-lib #(-> %
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :name "test-theme"
:sets #{"test-token-set"}))
(ctob/set-active-themes #{"/test-theme"})
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-radius)
:name "token-radius"
:type :border-radius
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-rotation)
:name "token-rotation"
:type :rotation
:value 30))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-opacity)
:name "token-opacity"
:type :opacity
:value 0.7))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-stroke-width)
:name "token-stroke-width"
:type :stroke-width
:value 2))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-color)
:name "token-color"
:type :color
:value "#00ff00"))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-dimensions)
:name "token-dimensions"
:type :dimensions
:value 100))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-font-size)
:name "token-font-size"
:type :font-size
:value 24))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-letter-spacing)
:name "token-letter-spacing"
:type :letter-spacing
:value 2))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-font-family)
:name "token-font-family"
:type :font-family
:value ["Helvetica" "Arial" "sans-serif"]))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-sizing)
:name "token-sizing"
:type :sizing
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-spacing)
:name "token-spacing"
:type :spacing
:value 30))))
(-> (tht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :test-theme)
:name "test-theme"
:sets #{"test-token-set"}))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-radius)
:name "token-radius"
:type :border-radius
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-rotation)
:name "token-rotation"
:type :rotation
:value 30))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-opacity)
:name "token-opacity"
:type :opacity
:value 0.7))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-stroke-width)
:name "token-stroke-width"
:type :stroke-width
:value 2))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-color)
:name "token-color"
:type :color
:value "#00ff00"))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-dimensions)
:name "token-dimensions"
:type :dimensions
:value 100))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-font-size)
:name "token-font-size"
:type :font-size
:value 24))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-letter-spacing)
:name "token-letter-spacing"
:type :letter-spacing
:value 2))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-font-family)
:name "token-font-family"
:type :font-family
:value ["Helvetica" "Arial" "sans-serif"]))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-sizing)
:name "token-sizing"
:type :sizing
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :id (thi/new-id! :token-spacing)
:name "token-spacing"
:type :spacing
:value 30)))
:status-fn #(-> %
(ctos/set-tokens-status #{(thi/id :test-theme)}
#{(thi/id :test-token-set)})))
(tho/add-frame :frame1
:layout :flex ;; TODO: those values come from main.data.workspace.shape_layout/default-layout-params
:layout-flex-dir :row ;; it should be good to use it directly, but first it should be moved to common.logic

View File

@ -19,66 +19,80 @@
(t/use-fixtures :each thi/test-fixture)
(t/deftest generate-toggle-token-set-test
(t/testing "toggling an active set will switch to hidden theme without user sets"
(let [file (tht/sample-file-with-tokens
(t/testing "toggling an active set will deactivate it"
(let [theme-id (uuid/next)
set-id (thi/new-id! :foo-bar)
file (tht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :name "foo/bar"))
(ctob/add-theme (ctob/make-token-theme :name "theme"
:sets #{"foo/bar"}))
(ctob/set-active-themes #{"/theme"})))
(ctob/add-set (ctob/make-token-set :id set-id :name "foo/bar"))
(ctob/add-theme (ctob/make-token-theme :id theme-id
:name "theme"
:sets #{"foo/bar"})))
:status-fn #(ctos/set-tokens-status % #{theme-id} #{set-id}))
tokens-status (tht/get-tokens-status file)
tokens-lib (tht/get-tokens-lib file)
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))
(clt/generate-toggle-token-set (tht/get-tokens-lib file) "foo/bar"))
(clt/generate-toggle-token-set tokens-status tokens-lib "foo/bar"))
redo (thf/apply-changes file changes)
redo-lib (tht/get-tokens-lib redo)
redo-status (tht/get-tokens-status redo)
undo (thf/apply-undo-changes redo changes)
undo-lib (tht/get-tokens-lib undo)]
(t/is (= #{ctob/hidden-theme-path} (ctob/get-active-theme-paths redo-lib)))
(t/is (= #{} (:sets (ctob/get-hidden-theme redo-lib))))
undo-status (tht/get-tokens-status undo)]
;; Redo: set is deactivated, all themes deactivated
(t/is (not (ctos/set-active? redo-status set-id)))
(t/is (= #{} (ctos/get-active-theme-ids redo-status)))
;; Undo: set is active again, themes restored
(t/is (ctos/set-active? undo-status set-id))
(t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status)))))
;; Undo
(t/is (= #{"/theme"} (ctob/get-active-theme-paths undo-lib)))))
(t/testing "toggling an inactive set will switch to hidden theme without user sets"
(let [file (tht/sample-file-with-tokens
(t/testing "toggling an inactive set will activate it"
(let [theme-id (uuid/next)
set-id (thi/new-id! :foo-bar)
file (tht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :name "foo/bar"))
(ctob/add-theme (ctob/make-token-theme :name "theme"
:sets #{"foo/bar"}))
(ctob/set-active-themes #{"/theme"})))
(ctob/add-set (ctob/make-token-set :id set-id :name "foo/bar"))
(ctob/add-theme (ctob/make-token-theme :id theme-id
:name "theme"
:sets #{"foo/bar"})))
:status-fn #(ctos/set-tokens-status % #{theme-id} #{}))
tokens-status (tht/get-tokens-status file)
tokens-lib (tht/get-tokens-lib file)
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))
(clt/generate-toggle-token-set (tht/get-tokens-lib file) "foo/bar"))
(clt/generate-toggle-token-set tokens-status tokens-lib "foo/bar"))
redo (thf/apply-changes file changes)
redo-lib (tht/get-tokens-lib redo)
redo-status (tht/get-tokens-status redo)
undo (thf/apply-undo-changes redo changes)
undo-lib (tht/get-tokens-lib undo)]
(t/is (= #{ctob/hidden-theme-path} (ctob/get-active-theme-paths redo-lib)))
(t/is (= #{} (:sets (ctob/get-hidden-theme redo-lib))))
undo-status (tht/get-tokens-status undo)]
;; Redo: set is activated, all themes deactivated
(t/is (ctos/set-active? redo-status set-id))
(t/is (= #{} (ctos/get-active-theme-ids redo-status)))
;; Undo: set is inactive again, themes restored
(t/is (not (ctos/set-active? undo-status set-id)))
(t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status)))))
;; Undo
(t/is (= #{"/theme"} (ctob/get-active-theme-paths undo-lib)))))
(t/testing "toggling an set with hidden theme already active will toggle set in hidden theme"
(let [file (tht/sample-file-with-tokens
(t/testing "toggling a set group toggles its sets in status"
(let [set-id (thi/new-id! :foo-bar)
file (tht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :name "foo/bar"))
(ctob/add-theme (ctob/make-hidden-theme))
(ctob/set-active-themes #{ctob/hidden-theme-path})))
(ctob/add-set (ctob/make-token-set :id set-id :name "foo/bar"))))
tokens-status (tht/get-tokens-status file)
tokens-lib (tht/get-tokens-lib file)
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))
(clt/generate-toggle-token-set-group (tht/get-tokens-lib file) ["foo"]))
(clt/generate-toggle-token-set-group tokens-status tokens-lib ["foo"]))
redo (thf/apply-changes file changes)
redo-lib (tht/get-tokens-lib redo)
redo-status (tht/get-tokens-status redo)
undo (thf/apply-undo-changes redo changes)
undo-lib (tht/get-tokens-lib undo)]
(t/is (= (ctob/get-active-theme-paths redo-lib) (ctob/get-active-theme-paths undo-lib)))
(t/is (= #{"foo/bar"} (:sets (ctob/get-hidden-theme redo-lib)))))))
undo-status (tht/get-tokens-status undo)]
;; Redo: set is activated
(t/is (ctos/set-active? redo-status set-id))
;; Undo: set is deactivated
(t/is (not (ctos/set-active? undo-status set-id))))))
(t/deftest set-token-theme-test
(t/testing "delete token theme"
@ -298,50 +312,69 @@
(t/deftest generate-toggle-token-set-group-test
(t/testing "toggling set group with no active sets inside will activate all child sets"
(let [file (tht/sample-file-with-tokens
(let [set-bar-id (thi/new-id! :foo-bar)
set-baz-id (thi/new-id! :foo-bar-baz)
set-child-id (thi/new-id! :baz-child)
theme-id (uuid/next)
file (tht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :name "foo/bar"))
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz"))
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz/baz-child"))
(ctob/add-theme (ctob/make-token-theme :name "theme"))
(ctob/set-active-themes #{"/theme"})))
(ctob/add-set (ctob/make-token-set :id set-bar-id :name "foo/bar"))
(ctob/add-set (ctob/make-token-set :id set-baz-id :name "foo/bar/baz"))
(ctob/add-set (ctob/make-token-set :id set-child-id :name "foo/bar/baz/baz-child"))
(ctob/add-theme (ctob/make-token-theme :id theme-id :name "theme")))
:status-fn #(ctos/set-tokens-status % #{theme-id} #{}))
tokens-status (tht/get-tokens-status file)
tokens-lib (tht/get-tokens-lib file)
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))
(clt/generate-toggle-token-set-group (tht/get-tokens-lib file) ["foo" "bar"]))
(clt/generate-toggle-token-set-group tokens-status tokens-lib ["foo" "bar"]))
redo (thf/apply-changes file changes)
redo-lib (tht/get-tokens-lib redo)
redo-status (tht/get-tokens-status redo)
undo (thf/apply-undo-changes redo changes)
undo-lib (tht/get-tokens-lib undo)]
(t/is (= #{ctob/hidden-theme-path} (ctob/get-active-theme-paths redo-lib)))
(t/is (= #{"foo/bar/baz" "foo/bar/baz/baz-child"} (:sets (ctob/get-hidden-theme redo-lib))))
;; Undo
(t/is (= #{"/theme"} (ctob/get-active-theme-paths undo-lib)))))
undo-status (tht/get-tokens-status undo)]
;; Redo: all child sets activated, all themes deactivated
(t/is (ctos/set-active? redo-status set-baz-id))
(t/is (ctos/set-active? redo-status set-child-id))
(t/is (= #{} (ctos/get-active-theme-ids redo-status)))
;; Undo: child sets deactivated, themes restored
(t/is (not (ctos/set-active? undo-status set-baz-id)))
(t/is (not (ctos/set-active? undo-status set-child-id)))
(t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status))))))
(t/testing "toggling set group with partially active sets inside will deactivate all child sets"
(let [file (tht/sample-file-with-tokens
(let [set-bar-id (thi/new-id! :foo-bar)
set-baz-id (thi/new-id! :foo-bar-baz)
set-child-id (thi/new-id! :baz-child)
theme-id (uuid/next)
file (tht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :name "foo/bar"))
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz"))
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz/baz-child"))
(ctob/add-theme (ctob/make-token-theme :name "theme"
:sets #{"foo/bar/baz"}))
(ctob/set-active-themes #{"/theme"})))
(ctob/add-set (ctob/make-token-set :id set-bar-id :name "foo/bar"))
(ctob/add-set (ctob/make-token-set :id set-baz-id :name "foo/bar/baz"))
(ctob/add-set (ctob/make-token-set :id set-child-id :name "foo/bar/baz/baz-child"))
(ctob/add-theme (ctob/make-token-theme :id theme-id
:name "theme"
:sets #{"foo/bar/baz"})))
:status-fn #(ctos/set-tokens-status % #{theme-id} #{set-baz-id}))
tokens-status (tht/get-tokens-status file)
tokens-lib (tht/get-tokens-lib file)
changes (-> (pcb/empty-changes)
(pcb/with-library-data (:data file))
(clt/generate-toggle-token-set-group (tht/get-tokens-lib file) ["foo" "bar"]))
(clt/generate-toggle-token-set-group tokens-status tokens-lib ["foo" "bar"]))
redo (thf/apply-changes file changes)
redo-lib (tht/get-tokens-lib redo)
redo-status (tht/get-tokens-status redo)
undo (thf/apply-undo-changes redo changes)
undo-lib (tht/get-tokens-lib undo)]
(t/is (= #{} (:sets (ctob/get-hidden-theme redo-lib))))
(t/is (= #{ctob/hidden-theme-path} (ctob/get-active-theme-paths redo-lib)))
;; Undo
(t/is (= #{"/theme"} (ctob/get-active-theme-paths undo-lib))))))
undo-status (tht/get-tokens-status undo)]
;; Redo: all child sets deactivated, all themes deactivated
(t/is (not (ctos/set-active? redo-status set-baz-id)))
(t/is (not (ctos/set-active? redo-status set-child-id)))
(t/is (= #{} (ctos/get-active-theme-ids redo-status)))
;; Undo: restores previous state, themes restored
(t/is (ctos/set-active? undo-status set-baz-id))
(t/is (not (ctos/set-active? undo-status set-child-id)))
(t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status)))))
(t/deftest generate-move-token-set-test
(t/testing "Ignore dropping set to the same position:"

View File

@ -11,11 +11,13 @@
#?(:clj [app.common.test-helpers.tokens :as tht])
#?(:clj [clojure.datafy :refer [datafy]])
[app.common.data :as d]
[app.common.files.tokens :as cfo]
[app.common.test-helpers.ids-map :as thi]
[app.common.time :as ct]
[app.common.transit :as tr]
[app.common.types.token :as cto]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.common.uuid :as uuid]
[clojure.test :as t]))
@ -584,18 +586,20 @@
"token-4"
(ctob/make-token :name "token-4"
:type :border-radius
:value 4000)}))
(ctob/update-theme ctob/hidden-theme-id
#(ctob/enable-sets % #{"set-a" "set-b"})))
:value 4000)})))
set-a-id (ctob/get-id (ctob/get-set-by-name tokens-lib "set-a"))
set-b-id (ctob/get-id (ctob/get-set-by-name tokens-lib "set-b"))
tokens-status (ctos/make-tokens-status :active-theme-ids #{}
:active-set-ids #{set-a-id set-b-id})
tokens (ctob/get-tokens-in-active-sets tokens-lib)]
tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
(t/is (= (mapv key tokens) ["token-1" "token-2" "token-3"]))
(t/is (= (get-in tokens ["token-1" :value]) 100))
(t/is (= (get-in tokens ["token-2" :value]) 20))
(t/is (= (get-in tokens ["token-3" :value]) 300))))
(t/deftest list-active-themes-tokens-one-theme
#_(t/deftest list-active-themes-tokens-one-theme
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "set-a"
:tokens {"token-1"
@ -633,10 +637,10 @@
:type :border-radius
:value 4000)}))
(ctob/add-theme (ctob/make-token-theme :name "single-theme"
:sets #{"set-b" "set-c" "set-a"}))
(ctob/set-active-themes #{"/single-theme"}))
tokens (ctob/get-tokens-in-active-sets tokens-lib)]
:sets #{"set-b" "set-c" "set-a"})))
theme-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "single-theme"))
tokens-status (cfo/set-active-themes (ctos/make-tokens-status) tokens-lib #{theme-id})
tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
;; Note that sets order inside the theme is undefined. What matters is order in that the
;; sets have been added to the library.
@ -646,7 +650,7 @@
(t/is (= (get-in tokens ["token-3" :value]) 3000))
(t/is (= (get-in tokens ["token-4" :value]) 4000))))
(t/deftest list-active-themes-tokens-two-themes
#_(t/deftest list-active-themes-tokens-two-themes
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "set-a"
:tokens {"token-1"
@ -686,10 +690,12 @@
(ctob/add-theme (ctob/make-token-theme :name "theme-1"
:sets #{"set-b"}))
(ctob/add-theme (ctob/make-token-theme :name "theme-2"
:sets #{"set-b" "set-a"}))
(ctob/set-active-themes #{"/theme-1" "/theme-2"}))
:sets #{"set-b" "set-a"})))
theme-1-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "theme-1"))
theme-2-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "theme-2"))
tokens-status (cfo/set-active-themes (ctos/make-tokens-status) tokens-lib #{theme-1-id theme-2-id})
tokens (ctob/get-tokens-in-active-sets tokens-lib)]
tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
;; Note that themes order is irrelevant. What matters is the union of the active sets
;; and the order of the sets in the library.
@ -698,7 +704,7 @@
(t/is (= (get-in tokens ["token-2" :value]) 20))
(t/is (= (get-in tokens ["token-3" :value]) 300))))
(t/deftest list-active-themes-tokens-bug-taiga-10617
#_(t/deftest list-active-themes-tokens-bug-taiga-10617
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "Mode/Dark"
:tokens {"red"
@ -731,30 +737,32 @@
:sets #{"Mode/Dark" "Mode/Light" "Device/Desktop" "Device/Mobile"}))
(ctob/add-theme (ctob/make-token-theme :group "Brand"
:name "Brand B"
:sets #{}))
(ctob/set-active-themes #{"App/Web" "Brand/Brand A"}))
tokens (ctob/get-tokens-in-active-sets tokens-lib)]
:sets #{})))
web-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "App" "Web"))
brand-a-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "Brand" "Brand A"))
tokens-status (cfo/set-active-themes (ctos/make-tokens-status) tokens-lib #{web-id brand-a-id})
tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
(t/is (= (mapv key tokens) ["red" "border1"]))
(t/is (= (get-in tokens ["red" :value]) "#ff0000"))
(t/is (= (get-in tokens ["border1" :value]) 50))))
(t/deftest list-active-themes-tokens-no-tokens
#_(t/deftest list-active-themes-tokens-no-tokens
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "set-a")))
tokens (ctob/get-tokens-in-active-sets tokens-lib)]
tokens-status (ctos/make-tokens-status)
tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
(t/is (empty? tokens))))
(t/deftest list-active-themes-tokens-no-sets
#_(t/deftest list-active-themes-tokens-no-sets
(let [tokens-lib (ctob/make-tokens-lib)
tokens (ctob/get-tokens-in-active-sets tokens-lib)]
tokens-status (ctos/make-tokens-status)
tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
(t/is (empty? tokens))))
(t/deftest sets-at-path-active-state
#_(t/deftest sets-at-path-active-state
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz"))
@ -769,18 +777,23 @@
(ctob/add-theme (ctob/make-token-theme :name "invalid"
:sets #{"foo/missing"})))
expected-none (-> tokens-lib
(ctob/set-active-themes #{"/none"})
(ctob/sets-at-path-all-active? ["foo"]))
expected-all (-> tokens-lib
(ctob/set-active-themes #{"/all"})
(ctob/sets-at-path-all-active? ["foo"]))
expected-partial (-> tokens-lib
(ctob/set-active-themes #{"/partial"})
(ctob/sets-at-path-all-active? ["foo"]))
expected-invalid-none (-> tokens-lib
(ctob/set-active-themes #{"/invalid"})
(ctob/sets-at-path-all-active? ["foo"]))]
none-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "none"))
partial-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "partial"))
all-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "all"))
invalid-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "invalid"))
expected-none (-> (ctos/make-tokens-status)
(cfo/set-active-themes tokens-lib #{none-id})
(cfo/sets-at-path-all-active? tokens-lib ["foo"]))
expected-all (-> (ctos/make-tokens-status)
(cfo/set-active-themes tokens-lib #{all-id})
(cfo/sets-at-path-all-active? tokens-lib ["foo"]))
expected-partial (-> (ctos/make-tokens-status)
(cfo/set-active-themes tokens-lib #{partial-id})
(cfo/sets-at-path-all-active? tokens-lib ["foo"]))
expected-invalid-none (-> (ctos/make-tokens-status)
(cfo/set-active-themes tokens-lib #{invalid-id})
(cfo/sets-at-path-all-active? tokens-lib ["foo"]))]
(t/is (= :none expected-none))
(t/is (= :all expected-all))
(t/is (= :partial expected-partial))
@ -1622,9 +1635,9 @@
:group "group-1"
:external-id "test-id-01"
:modified-at now
:sets #{"core"}))
(ctob/toggle-theme-active (thi/id :theme-1)))
result (ctob/export-dtcg-json tokens-lib)
:sets #{"core"})))
tokens-status (cfo/toggle-theme-active (ctos/make-tokens-status) tokens-lib (thi/id :theme-1))
result (ctob/export-dtcg-json tokens-lib tokens-status)
expected {"$themes" [{"description" ""
"group" "group-1"
"isSource" false
@ -1675,9 +1688,9 @@
:group "group-1"
:external-id "test-id-01"
:modified-at now
:sets #{"some/set"}))
(ctob/toggle-theme-active (thi/id :theme-1)))
result (ctob/export-dtcg-multi-file tokens-lib)
:sets #{"some/set"})))
tokens-status (cfo/toggle-theme-active (ctos/make-tokens-status) tokens-lib (thi/id :theme-1))
result (ctob/export-dtcg-multi-file tokens-lib tokens-status)
expected {"$themes.json" [{"description" ""
"group" "group-1"
"isSource" false

View File

@ -100,9 +100,14 @@
:sets #{"set-b"}))
(ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-3)
:name "theme-3"
:sets #{"set-c" "set-d"}))
(ctob/set-active-themes #{"/theme-1" "/theme-2"}))
:sets #{"set-c" "set-d"})))
;; Build a legacy tokens lib to test migration
tokens-lib (ctob/map->tokens-lib {:sets (.-sets tokens-lib)
:themes (.-themes tokens-lib)
:active-themes #{"/theme-1" "/theme-2"}})
tokens-status (cfo/make-tokens-status-from-lib tokens-lib)]
(t/is (ctos/tokens-status? tokens-status))
(t/is (ctos/check-tokens-status tokens-status))
(t/is (= (count (ctos/get-active-theme-ids tokens-status)) 2))

View File

@ -675,8 +675,10 @@
(ctt/typography-token-keys (:type token)) (set/union attributes-to-remove ctt/typography-keys)
(ctt/typography-keys (:type token)) (set/union attributes-to-remove ctt/typography-token-keys)
:else attributes-to-remove)]
(when-let [tokens (some-> (dsh/lookup-tokens-lib state)
(ctob/get-tokens-in-active-sets))]
(when-let [tokens (let [tokens-lib (dsh/lookup-tokens-lib state)
tokens-status (dsh/lookup-tokens-status state)]
(when (and tokens-lib tokens-status)
(cfo/get-tokens-in-active-sets tokens-status tokens-lib)))]
(->> (if (contains? cf/flags :tokenscript)
(rx/of (ts/resolve-tokens tokens))
(sd/resolve-tokens tokens))

View File

@ -15,6 +15,7 @@
[app.common.test-helpers.ids-map :as cthi]
[app.common.types.shape :as cts]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.common.uuid :as uuid]
[app.main.data.changes :as dch]
[app.main.data.event :as ev]
@ -34,18 +35,12 @@
;; TOKENS Getters
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; FIXME: lookup rename
(defn get-tokens-lib
[state]
(dsh/lookup-tokens-lib state))
(defn lookup-token-set
([state]
(when-let [selected (dm/get-in state [:workspace-tokens :selected-token-set-id])]
(lookup-token-set state selected)))
([state id]
(some-> (get-tokens-lib state)
(some-> (dsh/lookup-tokens-lib state)
(ctob/get-set id))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -368,11 +363,12 @@
(ptk/reify ::set-enabled-token-set
ptk/WatchEvent
(watch [_ state _]
(let [data (dsh/lookup-file-data state)
tlib (get-tokens-lib state)
changes (-> (pcb/empty-changes)
(pcb/with-library-data data)
(clt/generate-set-enabled-token-set tlib name enabled?))]
(let [data (dsh/lookup-file-data state)
tokens-lib (dsh/lookup-tokens-lib state)
tokens-status (dsh/lookup-tokens-status state)
changes (-> (pcb/empty-changes)
(pcb/with-library-data data)
(clt/generate-set-enabled-token-set tokens-status tokens-lib name enabled?))]
(rx/of (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens))))))
@ -383,11 +379,12 @@
(ptk/reify ::toggle-token-set
ptk/WatchEvent
(watch [_ state _]
(let [data (dsh/lookup-file-data state)
tlib (get-tokens-lib state)
changes (-> (pcb/empty-changes)
(pcb/with-library-data data)
(clt/generate-toggle-token-set tlib name))]
(let [data (dsh/lookup-file-data state)
tokens-lib (dsh/lookup-tokens-lib state)
tokens-status (dsh/lookup-tokens-status state)
changes (-> (pcb/empty-changes)
(pcb/with-library-data data)
(clt/generate-toggle-token-set tokens-status tokens-lib name))]
(rx/of
(dch/commit-changes changes)
@ -398,10 +395,12 @@
(ptk/reify ::toggle-token-set-group
ptk/WatchEvent
(watch [_ state _]
(let [data (dsh/lookup-file-data state)
changes (-> (pcb/empty-changes)
(pcb/with-library-data data)
(clt/generate-toggle-token-set-group (get-tokens-lib state) group-path))]
(let [data (dsh/lookup-file-data state)
tokens-lib (dsh/lookup-tokens-lib state)
tokens-status (dsh/lookup-tokens-status state)
changes (-> (pcb/empty-changes)
(pcb/with-library-data data)
(clt/generate-toggle-token-set-group tokens-status tokens-lib group-path))]
(rx/of
(dch/commit-changes changes)
@ -439,7 +438,7 @@
(let [data (dsh/lookup-file-data state)
changes (-> (pcb/empty-changes it)
(pcb/with-library-data data)
(clt/generate-delete-token-set-group (get-tokens-lib state) path))]
(clt/generate-delete-token-set-group (dsh/lookup-tokens-lib state) path))]
(rx/of (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens))))))
@ -467,7 +466,7 @@
ptk/WatchEvent
(watch [it state _]
(try
(when-let [changes (clt/generate-move-token-set-group (pcb/empty-changes it) (get-tokens-lib state) drop-opts)]
(when-let [changes (clt/generate-move-token-set-group (pcb/empty-changes it) (dsh/lookup-tokens-lib state) drop-opts)]
(rx/of
(dch/commit-changes changes)
(dwtp/propagate-workspace-tokens)))
@ -483,7 +482,7 @@
ptk/WatchEvent
(watch [it state _]
(try
(let [tokens-lib (get-tokens-lib state)
(let [tokens-lib (dsh/lookup-tokens-lib state)
changes (-> (pcb/empty-changes it)
(clt/generate-move-token-set tokens-lib params))]
(rx/of (dch/commit-changes changes)
@ -506,11 +505,12 @@
token-set
(ctob/make-token-set :name set-name)
hidden-theme
(ctob/make-hidden-theme)
hidden-theme ;; For legacy compatibility only
(-> (ctob/make-hidden-theme)
(ctob/enable-set set-name))
hidden-theme-with-set
(ctob/enable-set hidden-theme set-name)
token-status
(ctos/make-tokens-status #{} #(ctob/get-id token-set))
changes
(-> (pcb/empty-changes)
@ -518,8 +518,8 @@
(pcb/set-token-set (ctob/get-id token-set) token-set)
(pcb/set-token (ctob/get-id token-set) (:id token) token)
(pcb/set-token-theme (ctob/get-id hidden-theme)
hidden-theme-with-set)
(pcb/set-active-token-themes #{ctob/hidden-theme-path}))]
hidden-theme)
(pcb/set-tokens-status token-status))]
(rx/of (dch/commit-changes changes)
(set-selected-token-set-id (ctob/get-id token-set)))))))
@ -559,7 +559,7 @@
(let [token-set (lookup-token-set state set-id)
data (dsh/lookup-file-data state)
changes (reduce (fn [changes token-id]
(let [token (-> (get-tokens-lib state)
(let [token (-> (dsh/lookup-tokens-lib state)
(ctob/get-token (ctob/get-id token-set) token-id))
new-name (->
(cpn/split-path (:name token) :separator ".")
@ -589,7 +589,7 @@
(lookup-token-set state set-id)
(lookup-token-set state))
data (dsh/lookup-file-data state)
token (-> (get-tokens-lib state)
token (-> (dsh/lookup-tokens-lib state)
(ctob/get-token (ctob/get-id token-set) id))
token' (->> (merge token params)
(into {})
@ -617,7 +617,7 @@
(lookup-token-set state))
data (dsh/lookup-file-data state)
changes (reduce (fn [changes token-id]
(let [token (-> (get-tokens-lib state)
(let [token (-> (dsh/lookup-tokens-lib state)
(ctob/get-token (ctob/get-id token-set) token-id))
new-name (str/replace (:name token) old-path new-path)
token' (->> (merge token {:name new-name})
@ -646,7 +646,7 @@
token-set (if set-id
(lookup-token-set state set-id)
(lookup-token-set state))
token (-> (get-tokens-lib state)
token (-> (dsh/lookup-tokens-lib state)
(ctob/get-token (ctob/get-id token-set) token-id))
token-type (:type token)
@ -680,7 +680,7 @@
ptk/WatchEvent
(watch [_ state _]
(when-let [token-set (lookup-token-set state)]
(when-let [tokens-lib (get-tokens-lib state)]
(when-let [tokens-lib (dsh/lookup-tokens-lib state)]
(when-let [token (ctob/get-token tokens-lib
(ctob/get-id token-set)
token-id)]

View File

@ -8,10 +8,10 @@
(:require
[app.common.data :as d]
[app.common.files.helpers :as cfh]
[app.common.files.tokens :as cfo]
[app.common.logging :as l]
[app.common.time :as ct]
[app.common.types.token :as ctt]
[app.common.types.tokens-lib :as ctob]
[app.config :as cf]
[app.main.data.helpers :as dsh]
[app.main.data.style-dictionary :as sd]
@ -188,26 +188,28 @@
(ptk/reify ::propagate-workspace-tokens
ptk/WatchEvent
(watch [_ state _]
(when-let [tokens-tree (-> (dsh/lookup-tokens-lib state)
(ctob/get-tokens-in-active-sets))]
(->> (if (contains? cf/flags :tokenscript)
(rx/of (-> (ts/resolve-tokens tokens-tree)
(d/update-vals #(update % :resolved-value ts/tokenscript-symbols->penpot-unit))))
(sd/resolve-tokens tokens-tree))
(rx/mapcat
(fn [sd-tokens]
(let [undo-id (js/Symbol)]
(rx/concat
(rx/of (dwu/start-undo-transaction undo-id :timeout false))
(let [tokens-lib (dsh/lookup-tokens-lib state)
tokens-status (dsh/lookup-tokens-status state)]
(when (and tokens-lib tokens-status)
(when-let [tokens-tree (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
(->> (if (contains? cf/flags :tokenscript)
(rx/of (-> (ts/resolve-tokens tokens-tree)
(d/update-vals #(update % :resolved-value ts/tokenscript-symbols->penpot-unit))))
(sd/resolve-tokens tokens-tree))
(rx/mapcat
(fn [sd-tokens]
(let [undo-id (js/Symbol)]
(rx/concat
(rx/of (dwu/start-undo-transaction undo-id :timeout false))
;; FIXME: now the tokens propagations is done by accumulating the update-shapes
;; into a single commit-changes. This is not really the best way, the token application
;; should be done with a changes_builder and sending only one `commit-changes` instead
;; of creating lots of `update-shapes`.
(rx/of (dwsh/update-shapes-buffer-start))
(->> (propagate-tokens state sd-tokens)
(rx/catch #(rx/concat
(rx/of (dwsh/update-shapes-buffer-stop))
(rx/throw %))))
(rx/of (dwsh/update-shapes-buffer-stop))
(rx/of (dwu/commit-undo-transaction undo-id)))))))))))
;; FIXME: now the tokens propagations is done by accumulating the update-shapes
;; into a single commit-changes. This is not really the best way, the token application
;; should be done with a changes_builder and sending only one `commit-changes` instead
;; of creating lots of `update-shapes`.
(rx/of (dwsh/update-shapes-buffer-start))
(->> (propagate-tokens state sd-tokens)
(rx/catch #(rx/concat
(rx/of (dwsh/update-shapes-buffer-stop))
(rx/throw %))))
(rx/of (dwsh/update-shapes-buffer-stop))
(rx/of (dwu/commit-undo-transaction undo-id)))))))))))))

View File

@ -10,9 +10,11 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.helpers :as cph]
[app.common.files.tokens :as cfo]
[app.common.types.shape-tree :as ctt]
[app.common.types.shape.layout :as ctl]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.config :as cf]
[app.main.data.helpers :as dsh]
[app.main.data.workspace.tokens.selected-set :as dwts]
@ -498,26 +500,32 @@
(def workspace-token-sets-tree
(l/derived (d/nilf ctob/get-set-tree) tokens-lib))
;; TODOstatus cambiar para que sean ids en todas partes
(def workspace-active-theme-paths
(l/derived (d/nilf ctob/get-active-theme-paths) tokens-lib))
(l/derived (d/nilf ctos/get-active-theme-ids) tokens-status))
(def workspace-all-tokens-map
(l/derived (d/nilf ctob/get-all-tokens-map) tokens-lib))
;; TODOstatus ver una forma eficiente de hacer un derived de lib y status a la vez
(defn token-sets-at-path-all-active
[group-path]
(l/derived
(fn [lib]
(when lib
(ctob/sets-at-path-all-active? lib group-path)))
tokens-lib))
(fn [status]
(when status
(cfo/sets-at-path-all-active? status @(l/derived identity tokens-lib) group-path)))
tokens-status))
(def workspace-active-theme-paths-no-hidden
(l/derived #(disj % ctob/hidden-theme-path) workspace-active-theme-paths))
workspace-active-theme-paths)
;; FIXME: deprecated, it should not be implemented with ref (still used in form)
(def workspace-active-theme-sets-tokens
(l/derived #(or (some-> % ctob/get-tokens-in-active-sets) {}) tokens-lib))
(l/derived (fn [[status lib]]
(if (and status lib)
(cfo/get-tokens-in-active-sets status lib)
{}))
[tokens-status tokens-lib]))
(def workspace-token-in-selected-set
(fn [token-id]

View File

@ -9,10 +9,10 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.tokens :as cfo]
[app.common.types.component :as ctc]
[app.common.types.components-list :as ctkl]
[app.common.types.shape.layout :as ctl]
[app.common.types.tokens-lib :as ctob]
[app.main.data.style-dictionary :as sd]
[app.main.refs :as refs]
[app.main.ui.inspect.exports :as exports]
@ -111,11 +111,14 @@
panels (type->panel-group shape-type)
tokens-lib (mf/deref refs/tokens-lib)
active-themes (mf/deref refs/workspace-active-theme-paths-no-hidden)
active-sets (mf/with-memo [tokens-lib]
(some-> tokens-lib (ctob/get-active-themes-set-names)))
active-tokens (mf/with-memo [tokens-lib]
(some-> tokens-lib (ctob/get-tokens-in-active-sets)))
tokens-status (mf/deref refs/tokens-status)
active-themes (mf/deref refs/workspace-active-theme-paths)
active-sets (mf/with-memo [tokens-status tokens-lib]
(when (and tokens-status tokens-lib)
(cfo/get-active-set-names tokens-status tokens-lib)))
active-tokens (mf/with-memo [tokens-status tokens-lib]
(when (and tokens-status tokens-lib)
(cfo/get-tokens-in-active-sets tokens-status tokens-lib)))
resolved-active-tokens (sd/use-resolved-tokens* active-tokens)
has-visibility-props? (mf/use-fn
(fn [shape]

View File

@ -9,6 +9,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.tokens :as cfo]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.types.color :as cc]
@ -762,10 +763,13 @@
tokens-lib
(mf/deref refs/tokens-lib)
tokens-status
(mf/deref refs/tokens-status)
active-sets-names
(mf/with-memo [tokens-lib]
(some-> tokens-lib
(ctob/get-active-themes-set-names)))
(mf/with-memo [tokens-status tokens-lib]
(when (and tokens-status tokens-lib)
(cfo/get-active-set-names tokens-status tokens-lib)))
active-tokens (if (delay? active-tokens)
@active-tokens

View File

@ -8,6 +8,7 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.common.files.tokens :as cfo]
[app.common.types.tokens-lib :as ctob]
[app.config :as cf]
[app.main.constants :refer [left-sidebar-default-max-width
@ -117,7 +118,7 @@
(mf/defc left-sidebar*
{::mf/memo true}
[{:keys [layout file tokens-lib active-tokens resolved-active-tokens]}]
[{:keys [layout file tokens-lib tokens-status active-tokens resolved-active-tokens]}]
(let [options-mode (mf/deref refs/options-mode-global)
project (mf/deref refs/project)
file-id (get file :id)
@ -220,6 +221,7 @@
:tokens
[:> tokens-sidebar-tab*
{:tokens-lib tokens-lib
:tokens-status tokens-status
:active-tokens active-tokens
:resolved-active-tokens resolved-active-tokens}]
@ -366,18 +368,18 @@
(mf/deref refs/tokens-status)
active-tokens
(mf/with-memo [tokens-lib]
(if tokens-lib
(ctob/get-tokens-in-active-sets tokens-lib)
(mf/with-memo [tokens-status tokens-lib]
(if (and tokens-status tokens-lib)
(cfo/get-tokens-in-active-sets tokens-status tokens-lib)
{}))
selected-token-set-id
(mf/deref refs/selected-token-set-id)
active-tokens-force-set
(mf/with-memo [tokens-lib selected-token-set-id]
(if (and tokens-lib selected-token-set-id)
(ctob/get-tokens-in-active-sets-force tokens-lib selected-token-set-id)
(mf/with-memo [tokens-status tokens-lib selected-token-set-id]
(if (and tokens-status tokens-lib selected-token-set-id)
(cfo/get-tokens-in-active-sets-force tokens-status tokens-lib selected-token-set-id)
{}))
tokenscript? (contains? cf/flags :tokenscript)
@ -404,6 +406,7 @@
:file file
:page-id page-id
:tokens-lib tokens-lib
:tokens-status tokens-status
:active-tokens active-tokens-force-set
:resolved-active-tokens (if tokenscript?
tokenscript-resolved-active-tokens-force-set

View File

@ -2,6 +2,7 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.files.tokens :as cfo]
[app.common.path-names :as cpn]
[app.common.types.shape.layout :as ctsl]
[app.common.types.tokens-lib :as ctob]
@ -49,15 +50,16 @@
(mf/defc selected-set-info*
{::mf/private true}
[{:keys [tokens-lib selected-token-set-id]}]
[{:keys [tokens-lib tokens-status selected-token-set-id]}]
(let [selected-token-set
(mf/with-memo [tokens-lib selected-token-set-id]
(when selected-token-set-id
(some-> tokens-lib (ctob/get-set selected-token-set-id))))
active-token-sets-names
(mf/with-memo [tokens-lib]
(some-> tokens-lib (ctob/get-active-themes-set-names)))
(mf/with-memo [tokens-status tokens-lib]
(when (and tokens-status tokens-lib)
(cfo/get-active-set-names tokens-status tokens-lib)))
token-set-active?
(mf/use-fn

View File

@ -7,6 +7,7 @@
(ns app.main.ui.workspace.tokens.sets
(:require
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.main.data.workspace.tokens.library-edit :as dwtl]
[app.main.refs :as refs]
[app.main.store :as st]
@ -31,12 +32,21 @@
(let [tokens-lib
(mf/use-ctx ctx/tokens-lib)
tokens-status
(mf/use-ctx ctx/tokens-status)
token-sets
(some-> tokens-lib (ctob/get-set-tree))
can-edit?
(mf/use-ctx ctx/can-edit?)
token-set-active?
(mf/use-fn
(mf/deps tokens-status)
(fn [set-id]
(ctos/set-active? tokens-status set-id)))
token-set-group-active?
(mf/use-fn
(fn [group-path]
@ -62,6 +72,7 @@
{:tokens-lib tokens-lib
:token-sets token-sets
:is-token-set-active token-set-active?
:is-token-set-group-active token-set-group-active?
:on-select on-select-token-set-click

View File

@ -313,6 +313,7 @@
(mf/defc token-sets-tree*
[{:keys [is-draggable
selected
is-token-set-active
is-token-set-group-active
on-start-edition
on-reset-edition
@ -420,7 +421,7 @@
:set token-set
:label (peek path)
:is-editing (= edition-id id)
:is-active (ctos/set-active? tokens-status id)
:is-active (is-token-set-active id)
:is-selected (= selected id)
:is-draggable is-draggable
:is-new false
@ -442,6 +443,7 @@
selected
on-update-token-set
on-update-token-set-group
is-token-set-active
is-token-set-group-active
on-create-token-set
on-toggle-token-set
@ -453,6 +455,7 @@
new-path
edition-id]}]
(assert (fn? is-token-set-active) "expected a function for `is-token-set-active` prop")
(assert (fn? is-token-set-group-active) "expected a function for `is-token-set-group-active` prop")
(let [theme-modal? (= origin "theme-modal")
@ -492,6 +495,7 @@
:token-sets token-sets
:selected selected
:on-select on-select
:is-token-set-active is-token-set-active
:is-token-set-group-active is-token-set-group-active
:on-toggle-set on-toggle-token-set
:on-toggle-set-group on-toggle-token-set-group

View File

@ -10,9 +10,9 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.tokens :as cfo]
[app.common.logic.tokens :as clt]
[app.common.schema :as sm]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.main.constants :refer [max-input-length]]
[app.main.data.event :as ev]
[app.main.data.modal :as modal]
@ -250,10 +250,15 @@
(defn- make-lib-with-theme
[theme sets]
(let [tlib (-> (ctob/make-tokens-lib)
(ctob/add-theme theme))
tlib (reduce ctob/add-set tlib sets)]
(ctob/activate-theme tlib (ctob/get-id theme))))
(as-> (ctob/make-tokens-lib) $
(ctob/add-theme $ theme)
(reduce ctob/add-set $ sets)))
(defn- make-status-with-theme
[tokens-lib theme]
(let [sets (map #(ctob/get-set-by-name tokens-lib %) (:sets theme))]
(ctos/make-tokens-status :active-theme-ids #{(:id theme)}
:active-set-ids (into #{} (map ctob/get-id sets)))))
(mf/defc edit-create-theme*
[{:keys [change-view theme on-save is-editing has-prev-view]}]
@ -263,7 +268,8 @@
current-theme* (mf/use-state theme)
current-theme (deref current-theme*)
lib (make-lib-with-theme current-theme ordered-token-sets)
lib-with-theme (make-lib-with-theme current-theme ordered-token-sets)
status-with-theme (make-status-with-theme lib-with-theme current-theme)
;; Form / Modal handlers
on-back (mf/use-fn
@ -307,15 +313,15 @@
;; Sets tree handlers
token-set-group-active?
(mf/use-fn
(mf/deps current-theme)
(mf/deps status-with-theme lib-with-theme)
(fn [group-path]
(ctob/sets-at-path-all-active? lib group-path)))
(cfo/sets-at-path-all-active? status-with-theme lib-with-theme group-path)))
token-set-active?
(mf/use-fn
(mf/deps current-theme)
(fn [name]
(contains? (:sets current-theme) name)))
(mf/deps status-with-theme)
(fn [id]
(ctos/set-active? status-with-theme id)))
on-toggle-token-set
(mf/use-fn
@ -328,14 +334,22 @@
(mf/deps current-theme ordered-token-sets)
(fn [group-path]
(swap! current-theme* (fn [theme']
(let [lib' (make-lib-with-theme theme' ordered-token-sets)]
(clt/toggle-token-set-group group-path lib' theme'))))))
; TODOstatus ver si se puede añadir una función en files.tokens o types.tokens
; según si necesitamos al final el status o no (que creo que no)
(let [lib' (make-lib-with-theme theme' ordered-token-sets)
status' (make-status-with-theme lib' theme')
active? (cfo/sets-at-path-all-active? status' lib' group-path)
sets-at-path (ctob/get-sets-at-path lib' group-path)
set-names (into #{} (map ctob/get-name) sets-at-path)]
(if (contains? #{:all :partial} active?)
(ctob/disable-sets theme' set-names)
(ctob/enable-sets theme' set-names)))))))
on-click-token-set
(mf/use-fn
(mf/deps on-toggle-token-set)
(fn [set-id]
(let [set (ctob/get-set lib set-id)]
(let [set (ctob/get-set lib-with-theme set-id)]
(on-toggle-token-set (ctob/get-name set)))))]
[:div {:class (stl/css :themes-modal-wrapper)}

View File

@ -12,6 +12,7 @@
[app.common.schema :as sm]
[app.common.types.token :as cto]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.common.uuid :as uuid]
[app.main.data.tokenscript :as ts]
[app.main.data.workspace.tokens.application :as dwta]
@ -243,7 +244,8 @@
(fn [_]
(let [token (u/locate-token file-id set-id id)
tokens-lib (u/locate-tokens-lib file-id)
tokens-tree (ctob/get-tokens-in-active-sets tokens-lib)]
tokens-status (u/locate-tokens-status file-id)
tokens-tree (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
(get-resolved-value token tokens-tree)))}
:resolvedValueString
@ -253,7 +255,8 @@
(fn [_]
(let [token (u/locate-token file-id set-id id)
tokens-lib (u/locate-tokens-lib file-id)
tokens-tree (ctob/get-tokens-in-active-sets tokens-lib)]
tokens-status (u/locate-tokens-status file-id)
tokens-tree (cfo/get-tokens-in-active-sets tokens-status tokens-lib)]
(str (get-resolved-value token tokens-tree))))}
:description
@ -345,9 +348,10 @@
:enumerable false
:get
(fn [_]
(let [tokens-lib (u/locate-tokens-lib file-id)
set (u/locate-token-set file-id id)]
(ctob/token-set-active? tokens-lib (ctob/get-name set))))
(let [tokens-lib (u/locate-tokens-lib file-id)
tokens-status (u/locate-tokens-status file-id)
set (u/locate-token-set file-id id)]
(cfo/token-set-active? tokens-status tokens-lib (ctob/get-name set))))
:schema ::sm/boolean
:set
(fn [_ value]
@ -526,8 +530,8 @@
:enumerable false
:get
(fn [_]
(let [tokens-lib (u/locate-tokens-lib file-id)]
(ctob/theme-active? tokens-lib id)))
(let [tokens-status (u/locate-tokens-status file-id)]
(ctos/theme-active? tokens-status id)))
:schema ::sm/boolean
:set
(fn [_ value]

View File

@ -70,6 +70,11 @@
(let [file (locate-file file-id)]
(->> file :data :tokens-lib)))
(defn locate-tokens-status
[file-id]
(let [file (locate-file file-id)]
(->> file :data :tokens-status)))
(defn locate-token-theme
[file-id id]
(let [tokens-lib (locate-tokens-lib file-id)]

View File

@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC Sucursal en España SL
(ns frontend-tests.logic.components-and-tokens
(:require
[app.common.files.tokens :as cfo]
[app.common.geom.point :as geom]
[app.common.math :as mth]
[app.common.test-helpers.components :as cthc]
@ -13,7 +14,9 @@
[app.common.test-helpers.ids-map :as cthi]
[app.common.test-helpers.shapes :as cths]
[app.common.test-helpers.tokens :as ctht]
[app.common.types.file :as ctf]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.main.data.helpers :as dsh]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.selection :as dws]
@ -35,29 +38,31 @@
(defn- setup-base-file
[]
(-> (cthf/sample-file :file1)
(ctht/add-tokens-lib)
(ctht/update-tokens-lib #(-> %
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :name "test-theme"
:sets #{"test-token-set"}))
(ctob/set-active-themes #{"/test-theme"})
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :test-token-1)
:name "test-token-1"
:type :border-radius
:value 25))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :test-token-2)
:name "test-token-2"
:type :border-radius
:value 50))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :test-token-3)
:name "test-token-3"
:type :border-radius
:value 75))))
(-> (ctht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :id (cthi/new-id! :test-theme)
:name "test-theme"
:sets #{"test-token-set"}))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :test-token-1)
:name "test-token-1"
:type :border-radius
:value 25))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :test-token-2)
:name "test-token-2"
:type :border-radius
:value 50))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :test-token-3)
:name "test-token-3"
:type :border-radius
:value 75)))
:status-fn #(-> %
(ctos/set-tokens-status #{(cthi/id :test-theme)}
#{(cthi/id :test-token-set)})))
(ctho/add-frame :frame1)
(ctht/apply-token-to-shape :frame1 "test-token-1" [:r1 :r2 :r3 :r4] [:r1 :r2 :r3 :r4] 25)))
@ -323,44 +328,44 @@
(t/async
done
(let [;; ==== Setup
file (-> (cthf/sample-file :file1)
(ctht/add-tokens-lib)
(ctht/update-tokens-lib #(-> %
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :name "test-theme"
:sets #{"test-token-set"}))
(ctob/set-active-themes #{"/test-theme"})
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-radius)
:name "token-radius"
:type :border-radius
:value 10))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-rotation)
:name "token-rotation"
:type :rotation
:value 30))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-opacity)
:name "token-opacity"
:type :opacity
:value 0.7))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-stroke-width)
:name "token-stroke-width"
:type :stroke-width
:value 2))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-color)
:name "token-color"
:type :color
:value "#00ff00"))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-dimensions)
:name "token-dimensions"
:type :dimensions
:value 100))))
file (-> (ctht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :id (cthi/new-id! :test-theme)
:name "test-theme"
:sets #{"test-token-set"}))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-radius)
:name "token-radius"
:type :border-radius
:value 10))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-rotation)
:name "token-rotation"
:type :rotation
:value 30))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-opacity)
:name "token-opacity"
:type :opacity
:value 0.7))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-stroke-width)
:name "token-stroke-width"
:type :stroke-width
:value 2))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-color)
:name "token-color"
:type :color
:value "#00ff00"))
(ctob/add-token (cthi/id :test-token-set)
(ctob/make-token :id (cthi/new-id! :token-dimensions)
:name "token-dimensions"
:type :dimensions
:value 100)))
:status-fn #(ctos/set-tokens-status % #{(cthi/id :test-theme)} #{(cthi/id :test-token-set)}))
(ctho/add-frame :frame1)
(ctht/apply-token-to-shape :frame1 "token-radius" [:r1 :r2 :r3 :r4] [:r1 :r2 :r3 :r4] 10)
(ctht/apply-token-to-shape :frame1 "token-rotation" [:rotation] [:rotation] 30)

View File

@ -6,11 +6,13 @@
(ns frontend-tests.plugins.tokens-test
(:require
[app.common.files.tokens :as cfo]
[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.tokens :as ctht]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.common.uuid :as uuid]
[app.main.data.tokenscript :as ts]
[app.main.data.workspace.tokens.library-edit :as dwtl]
@ -107,24 +109,25 @@
done
(let [set-id (cthi/new-id! :token-set)
token-id (cthi/new-id! :spacing-token)
file (-> (cthf/sample-file :file1 :page-label :page1)
(ctho/add-frame :frame1 {:layout :flex})
(ctht/add-tokens-lib)
(ctht/update-tokens-lib
#(-> %
(ctob/add-set
(ctob/make-token-set :id set-id
:name "spacing"))
(ctob/add-theme
(ctob/make-token-theme :name "theme"
:sets #{"spacing"}))
(ctob/set-active-themes #{"/theme"})
(ctob/add-token
set-id
(ctob/make-token :id token-id
:name "spacing.medium"
:type :spacing
:value 16)))))
theme-id (cthi/new-id! :theme)
file (-> (ctht/sample-file-with-tokens
:file-id :file1
:lib-fn #(-> %
(ctob/add-set
(ctob/make-token-set :id set-id
:name "spacing"))
(ctob/add-theme
(ctob/make-token-theme :id theme-id
:name "theme"
:sets #{"spacing"}))
(ctob/add-token
set-id
(ctob/make-token :id token-id
:name "spacing.medium"
:type :spacing
:value 16)))
:status-fn #(ctos/set-tokens-status % #{theme-id} #{set-id}))
(ctho/add-frame :frame1 {:layout :flex}))
store (ths/setup-store file)
_ (set! st/state store)
_ (set! st/stream (ptk/input-stream store))
@ -191,10 +194,11 @@
;; Demonstrates the bug: resolving the new token against active sets
;; only leaves the reference unresolved.
(let [tokens-lib (inactive-set-library)
tokens-status (cfo/make-tokens-status-from-lib tokens-lib)
token (ctob/make-token {:name "color.bg.default"
:value "{color.gray.50}"
:type :color})
tokens-tree (-> (ctob/get-tokens-in-active-sets tokens-lib)
tokens-tree (-> (cfo/get-tokens-in-active-sets tokens-status tokens-lib)
(assoc (:name token) token))
resolved (ts/resolve-tokens tokens-tree)
{:keys [errors resolved-value]} (get resolved (:name token))]

View File

@ -6,49 +6,51 @@
[app.common.test-helpers.shapes :as ths]
[app.common.test-helpers.tokens :as tht]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.main.ui.workspace.tokens.management.context-menu :as wtcm]
[clojure.test :as t]))
(defn setup-file []
(-> (thf/sample-file :file-1)
(tht/add-tokens-lib)
(tht/update-tokens-lib #(-> %
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :name "test-theme"
:sets #{"test-token-set"}))
(ctob/set-active-themes #{"/test-theme"})
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-radius"
:type :border-radius
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-color"
:type :color
:value "red"))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-spacing"
:type :spacing
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-sizing"
:type :sizing
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-rotation"
:type :rotation
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-opacity"
:type :opacity
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-dimensions"
:type :dimensions
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-number"
:type :number
:value 10))))
(-> (tht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :id (thi/new-id! :test-token-set)
:name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :test-theme)
:name "test-theme"
:sets #{"test-token-set"}))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-radius"
:type :border-radius
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-color"
:type :color
:value "red"))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-spacing"
:type :spacing
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-sizing"
:type :sizing
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-rotation"
:type :rotation
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-opacity"
:type :opacity
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-dimensions"
:type :dimensions
:value 10))
(ctob/add-token (thi/id :test-token-set)
(ctob/make-token :name "token-number"
:type :number
:value 10)))
:status-fn #(ctos/set-tokens-status % #{(thi/id :test-theme)} #{(thi/id :test-token-set)}))
;; app.main.data.workspace.tokens.application/generic-attributes
(tho/add-group :group1)
;; app.main.data.workspace.tokens.application/rect-attributes

View File

@ -6,6 +6,7 @@
(ns frontend-tests.tokens.helpers.state
(:require
[app.common.files.tokens :as cfo]
[app.common.types.tokens-lib :as ctob]
[app.main.data.helpers :as dsh]
[app.main.data.style-dictionary :as sd]
@ -30,8 +31,9 @@
ptk/WatchEvent
(watch [_ state _]
(let [data (dsh/lookup-file-data state)]
(->> (get data :tokens-lib)
(ctob/get-tokens-in-active-sets)
(->> (cfo/get-tokens-in-active-sets
(cfo/get-tokens-status data)
(cfo/get-tokens-lib data))
(sd/resolve-tokens)
(rx/mapcat #(rx/of (end))))))))

View File

@ -11,9 +11,11 @@
[app.common.types.tokens-lib :as ctob]))
(defn get-token [file name]
(some-> (get-in file [:data :tokens-lib])
(ctob/get-tokens-in-active-sets)
(get name)))
(let [data (get-in file [:data])
tokens-status (cfo/get-tokens-status data)
tokens-lib (cfo/get-tokens-lib data)]
(some-> (cfo/get-tokens-in-active-sets tokens-status tokens-lib)
(get name))))
(defn apply-token-to-shape
[file shape-label token-label attributes]

View File

@ -6,12 +6,15 @@
(ns frontend-tests.tokens.logic.token-actions-test
(:require
[app.common.files.tokens :as cfo]
[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.common.test-helpers.tokens :as ctht]
[app.common.types.text :as txt]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.main.data.workspace.tokens.application :as dwta]
[app.main.data.workspace.tokens.library-edit :as dwtl]
[app.main.data.workspace.wasm-text :as dwwt]
@ -44,21 +47,22 @@
(defn setup-file-with-tokens
[& {:keys [rect-1 rect-2 rect-3]}]
(-> (setup-file)
(ctho/add-rect :rect-1 rect-1)
(ctho/add-rect :rect-2 rect-2)
(ctho/add-rect :rect-3 rect-3)
(ctho/add-text :text-1 "Hello World!")
(assoc-in [:data :tokens-lib]
(-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "Theme A" :sets #{"Set A"}))
(ctob/set-active-themes #{"/Theme A"})
(-> (ctht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :set-a)
:name "Set A"))
(ctob/add-theme (ctob/make-token-theme :id (cthi/new-id! :theme-a)
:name "Theme A"
:sets #{"Set A"}))
(ctob/add-token (cthi/id :set-a)
(ctob/make-token border-radius-token))
(ctob/add-token (cthi/id :set-a)
(ctob/make-token reference-border-radius-token))))))
(ctob/make-token reference-border-radius-token)))
:status-fn #(ctos/set-tokens-status % #{(cthi/id :theme-a)} #{(cthi/id :set-a)}))
(ctho/add-rect :rect-1 rect-1)
(ctho/add-rect :rect-2 rect-2)
(ctho/add-rect :rect-3 rect-3)
(ctho/add-text :text-1 "Hello World!")))
(def debounce-text-stop
(tohs/stop-on ::dwwt/resize-wasm-text-debounce-commit))
@ -91,7 +95,9 @@
(let [file' (ths/get-file-from-state new-state)
lib (get-in file' [:data :tokens-lib])]
(t/is (some? (ctob/get-set lib (ctob/get-id set))))
(t/is (false? (ctob/token-set-active? lib "primitives"))))))))))
(t/is (false? (cfo/token-set-active?
(ctht/get-tokens-status file')
lib "primitives"))))))))))
(t/deftest test-create-then-enable-token-set
(t/testing "create followed by set-enabled (as the plugin addSet does) yields an active set"
@ -108,7 +114,9 @@
(let [file' (ths/get-file-from-state new-state)
lib (get-in file' [:data :tokens-lib])]
(t/is (some? (ctob/get-set lib (ctob/get-id set))))
(t/is (true? (ctob/token-set-active? lib "primitives"))))))))))
(t/is (true? (cfo/token-set-active?
(ctht/get-tokens-status file')
lib "primitives"))))))))))
(t/deftest test-apply-token
(t/testing "applies token to shape and updates shape attributes to resolved value"

View File

@ -8,7 +8,9 @@
(:require
[app.common.test-helpers.files :as cthf]
[app.common.test-helpers.ids-map :as cthi]
[app.common.test-helpers.tokens :as ctho]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.common.uuid :as uuid]
[app.main.data.workspace.tokens.library-edit :as dwtl]
[cljs.test :as t :include-macros true]
@ -25,11 +27,12 @@
(defn setup-file-with-token-lib
[]
(-> (setup-file)
(assoc-in [:data :tokens-lib]
(-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :test-token-set)
:name "Set A"))))))
(ctho/sample-file-with-tokens
:file-id :file-1
:page-label :page-1
:lib-fn #(ctob/add-set % (ctob/make-token-set :id (cthi/new-id! :test-token-set)
:name "Set A"))
:status-fn #(ctos/set-tokens-status % #{} #{cthi/id :test-token-set})))
(t/deftest add-set
(t/async

View File

@ -13,6 +13,7 @@
[app.common.test-helpers.tokens :as ctht]
[app.common.types.token :as cto]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.main.data.workspace.tokens.remapping :as dwtr]
[cljs.test :as t :include-macros true]))
@ -27,19 +28,20 @@
:name "color.secondary"
:value "{color.primary}"
:type :color}]
(-> (cthf/sample-file :file-1 :page-label :page-1)
(ctho/add-rect :rect-1)
(ctho/add-rect :rect-2)
(assoc-in [:data :tokens-lib]
(-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "Theme A" :sets #{"Set A"}))
(ctob/set-active-themes #{"/Theme A"})
(-> (ctht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :set-a)
:name "Set A"))
(ctob/add-theme (ctob/make-token-theme :id (cthi/new-id! :theme-a)
:name "Theme A"
:sets #{"Set A"}))
(ctob/add-token (cthi/id :set-a)
(ctob/make-token color-token))
(ctob/add-token (cthi/id :set-a)
(ctob/make-token alias-token))))
(ctob/make-token alias-token)))
:status-fn #(ctos/set-tokens-status % #{(cthi/id :theme-a)} #{(cthi/id :set-a)}))
(ctho/add-rect :rect-1)
(ctho/add-rect :rect-2)
;; Apply the token to rect-1
(ctht/apply-token-to-shape :rect-1 "color.primary" [:fill] [:fill] "#FF0000"))))
@ -132,22 +134,23 @@
:name "color.secondary"
:value "#00FF00"
:type :color}]
(-> (cthf/sample-file :file-1 :page-label :page-1)
(-> (ctht/sample-file-with-tokens
:lib-fn #(-> %
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :set-a)
:name "Set A"))
(ctob/add-theme (ctob/make-token-theme :id (cthi/new-id! :theme-a)
:name "Theme A"
:sets #{"Set A"}))
(ctob/add-token (cthi/id :set-a)
(ctob/make-token color-primary))
(ctob/add-token (cthi/id :set-a)
(ctob/make-token color-secondary)))
:status-fn #(ctos/set-tokens-status % #{(cthi/id :theme-a)} #{(cthi/id :set-a)}))
(ctho/add-simple-component-with-copy :component1
:main-root
:main-child
:copy-root
:copy-root-params {:children-labels [:copy-child]})
(assoc-in [:data :tokens-lib]
(-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "Theme A" :sets #{"Set A"}))
(ctob/set-active-themes #{"/Theme A"})
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :set-a)
:name "Set A"))
(ctob/add-token (cthi/id :set-a)
(ctob/make-token color-primary))
(ctob/add-token (cthi/id :set-a)
(ctob/make-token color-secondary))))
(ctht/apply-token-to-shape :main-child "color.primary" [:fill] [:fill] "#FF0000")
(ctht/apply-token-to-shape :copy-child "color.primary" [:fill] [:fill] "#FF0000"))))

View File

@ -10,8 +10,10 @@
[app.common.test-helpers.files :as cthf]
[app.common.test-helpers.ids-map :as cthi]
[app.common.test-helpers.shapes :as cths]
[app.common.test-helpers.tokens :as ctht]
[app.common.types.text :as txt]
[app.common.types.tokens-lib :as ctob]
[app.common.types.tokens-status :as ctos]
[app.main.data.workspace.tokens.remapping :as remap]
[cljs.test :as t :include-macros true]
[frontend-tests.helpers.state :as ths]
@ -31,17 +33,22 @@
(defn- attach-token-set [file tokens]
(let [set-id (cthi/new-id! :token-set)
tokens-lib (reduce
(fn [lib token]
(ctob/add-token lib set-id (ctob/make-token token)))
(-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :id set-id
:name token-set-name))
(ctob/add-theme (ctob/make-token-theme :name token-theme-name
:sets #{token-set-name}))
(ctob/set-active-themes #{(str "/" token-theme-name)}))
tokens)]
(assoc-in file [:data :tokens-lib] tokens-lib)))
theme-id (cthi/new-id! :theme)]
(-> file
(ctht/add-tokens-lib)
(ctht/update-tokens-lib
#(reduce
(fn [lib token]
(ctob/add-token lib set-id (ctob/make-token token)))
(-> %
(ctob/add-set (ctob/make-token-set :id set-id
:name token-set-name))
(ctob/add-theme (ctob/make-token-theme :id theme-id
:name token-theme-name
:sets #{token-set-name})))
tokens))
(ctht/update-tokens-status
#(ctos/set-tokens-status % #{theme-id} #{set-id})))))
(defn- tokens-lib [file]
(get-in file [:data :tokens-lib]))