mirror of
https://github.com/penpot/penpot.git
synced 2025-01-21 06:02:32 -05:00
Merge pull request #283 from tokens-studio/refactor-types-2
Refactor types 2
This commit is contained in:
commit
0697e69888
9 changed files with 1332 additions and 280 deletions
|
@ -57,6 +57,54 @@
|
|||
#?(:cljs (instance? lkm/LinkedMap o)
|
||||
:clj (instance? LinkedMap o)))
|
||||
|
||||
(defn oassoc
|
||||
[o & kvs]
|
||||
(apply assoc (or o (ordered-map)) kvs))
|
||||
|
||||
(defn oassoc-in
|
||||
[o [k & ks] v]
|
||||
(if ks
|
||||
(oassoc o k (oassoc-in (get o k) ks v))
|
||||
(oassoc o k v)))
|
||||
|
||||
(defn oupdate-in
|
||||
[m ks f & args]
|
||||
(let [up (fn up [m ks f args]
|
||||
(let [[k & ks] ks]
|
||||
(if ks
|
||||
(oassoc m k (up (get m k) ks f args))
|
||||
(oassoc m k (apply f (get m k) args)))))]
|
||||
(up m ks f args)))
|
||||
|
||||
(declare index-of)
|
||||
|
||||
(defn oassoc-before
|
||||
"Assoc a k v pair, in the order position just before the other key"
|
||||
[o before-k k v]
|
||||
(if-let [index (index-of (keys o) before-k)]
|
||||
(-> (ordered-map)
|
||||
(into (take index o))
|
||||
(assoc k v)
|
||||
(into (drop index o)))
|
||||
(oassoc o k v)))
|
||||
|
||||
(defn oassoc-in-before
|
||||
[o [before-k & before-ks] [k & ks] v]
|
||||
(if-let [index (index-of (keys o) before-k)]
|
||||
(let [new-v (if ks
|
||||
(oassoc-in-before (get o k) before-ks ks v)
|
||||
v)]
|
||||
(if (= k before-k)
|
||||
(-> (ordered-map)
|
||||
(into (take index o))
|
||||
(assoc k new-v)
|
||||
(into (drop (inc index) o)))
|
||||
(-> (ordered-map)
|
||||
(into (take index o))
|
||||
(assoc k new-v)
|
||||
(into (drop index o)))))
|
||||
(oassoc-in o (cons k ks) v)))
|
||||
|
||||
(defn vec2
|
||||
"Creates a optimized vector compatible type of length 2 backed
|
||||
internally with MapEntry impl because it has faster access method
|
||||
|
@ -564,6 +612,7 @@
|
|||
new-elems
|
||||
(remove p? after))))
|
||||
|
||||
;; TODO: remove this
|
||||
(defn addm-at-index
|
||||
"Insert an element in an ordered map at an arbitrary index"
|
||||
[coll index key element]
|
||||
|
|
|
@ -263,7 +263,8 @@
|
|||
[:delete-temporary-token-theme
|
||||
[:map {:title "DeleteTemporaryTokenThemeChange"}
|
||||
[:type [:= :delete-temporary-token-theme]]
|
||||
[:id ::sm/uuid]]]
|
||||
[:id ::sm/uuid]
|
||||
[:name :string]]]
|
||||
|
||||
[:add-token-theme
|
||||
[:map {:title "AddTokenThemeChange"}
|
||||
|
@ -274,12 +275,14 @@
|
|||
[:map {:title "ModTokenThemeChange"}
|
||||
[:type [:= :mod-token-theme]]
|
||||
[:id ::sm/uuid]
|
||||
[:name :string]
|
||||
[:token-theme ::ctot/token-theme]]]
|
||||
|
||||
[:del-token-theme
|
||||
[:map {:title "DelTokenThemeChange"}
|
||||
[:type [:= :del-token-theme]]
|
||||
[:id ::sm/uuid]]]
|
||||
[:id ::sm/uuid]
|
||||
[:name :string]]]
|
||||
|
||||
[:add-token-set
|
||||
[:map {:title "AddTokenSetChange"}
|
||||
|
@ -822,29 +825,70 @@
|
|||
set-name
|
||||
name)))))
|
||||
|
||||
(defn- set-ids->names
|
||||
[data sets]
|
||||
(let [lib-sets (:token-sets-index data)
|
||||
set-id->name
|
||||
(fn [set-id]
|
||||
(dm/get-in lib-sets [set-id :name]))]
|
||||
(map set-id->name sets)))
|
||||
|
||||
(defmethod process-change :add-temporary-token-theme
|
||||
[data {:keys [token-theme]}]
|
||||
(ctotl/add-temporary-token-theme data token-theme))
|
||||
(-> data
|
||||
(ctotl/add-temporary-token-theme token-theme)
|
||||
(update :tokens-lib
|
||||
#(-> %
|
||||
(ctob/ensure-tokens-lib)
|
||||
(ctob/add-theme (-> token-theme
|
||||
(update :sets (partial set-ids->names data))
|
||||
(ctob/make-token-theme)))))))
|
||||
|
||||
(defmethod process-change :update-active-token-themes
|
||||
[data {:keys [theme-ids]}]
|
||||
(ctotl/assoc-active-token-themes data theme-ids))
|
||||
|
||||
(defmethod process-change :delete-temporary-token-theme
|
||||
[data {:keys [id]}]
|
||||
(ctotl/delete-temporary-token-theme data id))
|
||||
[data {:keys [id group name]}]
|
||||
(-> data
|
||||
(ctotl/delete-temporary-token-theme id)
|
||||
(update :tokens-lib
|
||||
#(-> %
|
||||
(ctob/ensure-tokens-lib)
|
||||
(ctob/delete-theme group name)))))
|
||||
|
||||
(defmethod process-change :add-token-theme
|
||||
[data {:keys [token-theme]}]
|
||||
(ctotl/add-token-theme data token-theme))
|
||||
(-> data
|
||||
(ctotl/add-token-theme token-theme)
|
||||
(update :tokens-lib
|
||||
#(-> %
|
||||
(ctob/ensure-tokens-lib)
|
||||
(ctob/add-theme (-> token-theme
|
||||
(update :sets (partial set-ids->names data))
|
||||
(ctob/make-token-theme)))))))
|
||||
|
||||
(defmethod process-change :mod-token-theme
|
||||
[data {:keys [id token-theme]}]
|
||||
(ctotl/update-token-theme data id merge token-theme))
|
||||
[data {:keys [id name group token-theme]}]
|
||||
(-> data
|
||||
(ctotl/update-token-theme id merge token-theme)
|
||||
(update :tokens-lib
|
||||
#(-> %
|
||||
(ctob/ensure-tokens-lib)
|
||||
(ctob/update-theme name group
|
||||
(fn [prev-theme]
|
||||
(merge prev-theme
|
||||
(-> token-theme
|
||||
(update :sets (partial set-ids->names data))))))))))
|
||||
|
||||
(defmethod process-change :del-token-theme
|
||||
[data {:keys [id]}]
|
||||
(ctotl/delete-token-theme data id))
|
||||
[data {:keys [id group name]}]
|
||||
(-> data
|
||||
(ctotl/delete-token-theme id)
|
||||
(update :tokens-lib
|
||||
#(-> %
|
||||
(ctob/ensure-tokens-lib)
|
||||
(ctob/delete-theme group name)))))
|
||||
|
||||
(defmethod process-change :add-token-set
|
||||
[data {:keys [token-set]}]
|
||||
|
|
|
@ -699,7 +699,7 @@
|
|||
[changes token-theme]
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :add-temporary-token-theme :token-theme token-theme})
|
||||
(update :undo-changes conj {:type :delete-temporary-token-theme :id (:id token-theme)})
|
||||
(update :undo-changes conj {:type :delete-temporary-token-theme :id (:id token-theme) :name (:name token-theme)})
|
||||
(apply-changes-local)))
|
||||
|
||||
(defn update-active-token-themes
|
||||
|
@ -713,14 +713,14 @@
|
|||
[changes token-theme]
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :add-token-theme :token-theme token-theme})
|
||||
(update :undo-changes conj {:type :del-token-theme :id (:id token-theme)})
|
||||
(update :undo-changes conj {:type :del-token-theme :id (:id token-theme) :name (:name token-theme)})
|
||||
(apply-changes-local)))
|
||||
|
||||
(defn update-token-theme
|
||||
[changes token-theme prev-token-theme]
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :mod-token-theme :id (:id token-theme) :token-theme token-theme})
|
||||
(update :undo-changes conj {:type :mod-token-theme :id (:id token-theme) :token-theme (or prev-token-theme token-theme)})
|
||||
(update :redo-changes conj {:type :mod-token-theme :id (:id token-theme) :name (:name prev-token-theme) :token-theme token-theme})
|
||||
(update :undo-changes conj {:type :mod-token-theme :id (:id token-theme) :name (:name token-theme) :token-theme (or prev-token-theme token-theme)})
|
||||
(apply-changes-local)))
|
||||
|
||||
(defn delete-token-theme
|
||||
|
@ -729,7 +729,7 @@
|
|||
(let [library-data (::library-data (meta changes))
|
||||
prev-token-theme (get-in library-data [:token-themes-index token-theme-id])]
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :del-token-theme :id token-theme-id})
|
||||
(update :redo-changes conj {:type :del-token-theme :id token-theme-id :name (:name prev-token-theme)})
|
||||
(update :undo-changes conj {:type :add-token-theme :token-theme prev-token-theme})
|
||||
(apply-changes-local))))
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
java.time.OffsetDateTime
|
||||
java.util.List
|
||||
linked.map.LinkedMap
|
||||
linked.set.LinkedSet
|
||||
org.fressian.Reader
|
||||
org.fressian.StreamingWriter
|
||||
org.fressian.Writer
|
||||
|
@ -275,7 +276,12 @@
|
|||
{:name "clj/seq"
|
||||
:class clojure.lang.ISeq
|
||||
:wfn write-list-like
|
||||
:rfn (comp sequence read-object!)})
|
||||
:rfn (comp sequence read-object!)}
|
||||
|
||||
{:name "linked/set"
|
||||
:class LinkedSet
|
||||
:wfn write-list-like
|
||||
:rfn (comp #(into (d/ordered-set) %) read-object!)})
|
||||
|
||||
;; --- PUBLIC API
|
||||
|
||||
|
|
|
@ -12,9 +12,88 @@
|
|||
[app.common.time :as dt]
|
||||
[app.common.transit :as t]
|
||||
[app.common.types.token :as cto]
|
||||
[cuerdas.core :as str]
|
||||
#?(:clj [app.common.fressian :as fres])))
|
||||
|
||||
;; #?(:clj (set! *warn-on-reflection* true))
|
||||
;; === Groups handling
|
||||
|
||||
(def schema:groupable-item
|
||||
[:map {:title "Groupable item"}
|
||||
[:name :string]])
|
||||
|
||||
(def valid-groupable-item?
|
||||
(sm/validator schema:groupable-item))
|
||||
|
||||
(defn split-path
|
||||
"Decompose a string in the form 'one.two.three' into a vector of strings, removing spaces."
|
||||
[path separator]
|
||||
(let [xf (comp (map str/trim)
|
||||
(remove str/empty?))]
|
||||
(->> (str/split path separator)
|
||||
(into [] xf))))
|
||||
|
||||
(defn join-path
|
||||
"Regenerate a path as a string, from a vector."
|
||||
[path separator]
|
||||
(str/join separator path))
|
||||
|
||||
(defn group-item
|
||||
"Add a group to the item name, in the form group.name."
|
||||
[item group-name separator]
|
||||
(dm/assert!
|
||||
"expected groupable item"
|
||||
(valid-groupable-item? item))
|
||||
(update item :name #(str group-name separator %)))
|
||||
|
||||
(defn ungroup-item
|
||||
"Remove the first group from the item name."
|
||||
[item separator]
|
||||
(dm/assert!
|
||||
"expected groupable item"
|
||||
(valid-groupable-item? item))
|
||||
(update item :name #(-> %
|
||||
(split-path separator)
|
||||
(rest)
|
||||
(join-path separator))))
|
||||
|
||||
(defn get-path
|
||||
"Get the groups part of the name as a vector. E.g. group.subgroup.name -> ['group' 'subrgoup']"
|
||||
[item separator]
|
||||
(dm/assert!
|
||||
"expected groupable item"
|
||||
(valid-groupable-item? item))
|
||||
(split-path (:name item) separator))
|
||||
|
||||
(defn get-groups-str
|
||||
"Get the groups part of the name. E.g. group.subgroup.name -> group.subrgoup"
|
||||
[item separator]
|
||||
(-> (get-path item separator)
|
||||
(butlast)
|
||||
(join-path separator)))
|
||||
|
||||
(defn get-final-name
|
||||
"Get the final part of the name. E.g. group.subgroup.name -> name"
|
||||
[item separator]
|
||||
(dm/assert!
|
||||
"expected groupable item"
|
||||
(valid-groupable-item? item))
|
||||
(-> (:name item)
|
||||
(split-path separator)
|
||||
(last)))
|
||||
|
||||
(defn group?
|
||||
"Check if a node of the grouping tree is a group or a final item."
|
||||
[item]
|
||||
(d/ordered-map? item))
|
||||
|
||||
(defn get-children
|
||||
"Get all children of a group of a grouping tree. Each child is
|
||||
a tuple [name item], where item "
|
||||
[group]
|
||||
(dm/assert!
|
||||
"expected group node"
|
||||
(group? group))
|
||||
(seq group))
|
||||
|
||||
;; === Token
|
||||
|
||||
|
@ -23,10 +102,10 @@
|
|||
(def schema:token
|
||||
[:and
|
||||
[:map {:title "Token"}
|
||||
[:name cto/token-name-ref] ;; not necessary to have uuid
|
||||
[:name cto/token-name-ref] ;; not necessary to have uuid
|
||||
[:type [::sm/one-of cto/token-types]]
|
||||
[:value :any]
|
||||
[:description [:maybe :string]] ;; defrecord always have the attributes, even with nil value
|
||||
[:description [:maybe :string]] ;; defrecord always have the attributes, even with nil value
|
||||
[:modified-at ::sm/inst]]
|
||||
[:fn (partial instance? Token)]])
|
||||
|
||||
|
@ -56,7 +135,8 @@
|
|||
(defprotocol ITokenSet
|
||||
(add-token [_ token] "add a token at the end of the list")
|
||||
(update-token [_ token-name f] "update a token in the list")
|
||||
(delete-token [_ token-name] "delete a token from the list"))
|
||||
(delete-token [_ token-name] "delete a token from the list")
|
||||
(get-tokens [_] "return an ordered sequence of all tokens in the set"))
|
||||
|
||||
(defrecord TokenSet [name description modified-at tokens]
|
||||
ITokenSet
|
||||
|
@ -77,24 +157,27 @@
|
|||
(dt/now)
|
||||
(if (= (:name token) (:name token'))
|
||||
(assoc tokens (:name token') token')
|
||||
(let [index (d/index-of (keys tokens) (:name token))]
|
||||
(-> tokens
|
||||
(dissoc (:name token))
|
||||
(d/addm-at-index index (:name token') token'))))))
|
||||
(-> tokens
|
||||
(d/oassoc-before (:name token) (:name token') token')
|
||||
(dissoc (:name token))))))
|
||||
this))
|
||||
|
||||
(delete-token [_ token-name]
|
||||
(TokenSet. name
|
||||
description
|
||||
(dt/now)
|
||||
(dissoc tokens token-name))))
|
||||
(dissoc tokens token-name)))
|
||||
|
||||
(get-tokens [_]
|
||||
(vals tokens)))
|
||||
|
||||
(def schema:token-set
|
||||
[:and [:map {:title "TokenSet"}
|
||||
[:name :string]
|
||||
[:description [:maybe :string]]
|
||||
[:modified-at ::sm/inst]
|
||||
[:tokens [:map-of {:gen/max 5} :string ::token]]]
|
||||
[:tokens [:and [:map-of {:gen/max 5} :string ::token]
|
||||
[:fn d/ordered-map?]]]]
|
||||
[:fn (partial instance? TokenSet)]])
|
||||
|
||||
(sm/register! ::token-set schema:token-set)
|
||||
|
@ -119,6 +202,16 @@
|
|||
|
||||
token-set))
|
||||
|
||||
;; === TokenSetGroup
|
||||
|
||||
(defrecord TokenSetGroup [attr1 attr2])
|
||||
|
||||
;; TODO schema, validators, etc.
|
||||
|
||||
(defn make-token-set-group
|
||||
[]
|
||||
(TokenSetGroup. "one" "two"))
|
||||
|
||||
;; === TokenSets (collection)
|
||||
|
||||
(defprotocol ITokenSets
|
||||
|
@ -126,14 +219,24 @@
|
|||
(update-set [_ set-name f] "modify a set in the ilbrary")
|
||||
(delete-set [_ set-name] "delete a set in the library")
|
||||
(set-count [_] "get the total number if sets in the library")
|
||||
(get-set-tree [_] "get a nested tree of all sets in the library")
|
||||
(get-sets [_] "get an ordered sequence of all sets in the library")
|
||||
(get-set [_ set-name] "get one set looking for name")
|
||||
(validate [_]))
|
||||
(get-set-group [_ set-group-path] "get the attributes of a set group"))
|
||||
|
||||
(def schema:token-set-node
|
||||
[:schema {:registry {::node [:or ::token-set
|
||||
[:and
|
||||
[:map-of {:gen/max 5} :string [:ref ::node]]
|
||||
[:fn d/ordered-map?]]]}}
|
||||
[:ref ::node]])
|
||||
|
||||
(sm/register! ::token-set-node schema:token-set-node)
|
||||
|
||||
(def schema:token-sets
|
||||
[:and
|
||||
[:map-of {:title "TokenSets"}
|
||||
:string ::token-set]
|
||||
:string ::token-set-node]
|
||||
[:fn d/ordered-map?]])
|
||||
|
||||
(sm/register! ::token-sets schema:token-sets)
|
||||
|
@ -144,10 +247,83 @@
|
|||
(def check-token-sets!
|
||||
(sm/check-fn ::token-sets))
|
||||
|
||||
;; === TokenTheme
|
||||
|
||||
(defprotocol ITokenTheme
|
||||
(toggle-set [_ set-name] "togle a set used / not used in the theme"))
|
||||
|
||||
(defrecord TokenTheme [name group description is-source modified-at sets]
|
||||
ITokenTheme
|
||||
(toggle-set [_ set-name]
|
||||
(TokenTheme. name
|
||||
group
|
||||
description
|
||||
is-source
|
||||
(dt/now)
|
||||
(if (sets set-name)
|
||||
(disj sets set-name)
|
||||
(conj sets set-name)))))
|
||||
|
||||
(def schema:token-theme
|
||||
[:and [:map {:title "TokenTheme"}
|
||||
[:name :string]
|
||||
[:group :string]
|
||||
[:description [:maybe :string]]
|
||||
[:is-source :boolean]
|
||||
[:modified-at ::sm/inst]
|
||||
[:sets [:and [:set {:gen/max 5} :string]
|
||||
[:fn d/ordered-set?]]]]
|
||||
[:fn (partial instance? TokenTheme)]])
|
||||
|
||||
(sm/register! ::token-theme schema:token-theme)
|
||||
|
||||
(def valid-token-theme?
|
||||
(sm/validator schema:token-theme))
|
||||
|
||||
(def check-token-theme!
|
||||
(sm/check-fn ::token-theme))
|
||||
|
||||
(defn make-token-theme
|
||||
[& {:keys [] :as params}]
|
||||
(let [params (-> params
|
||||
(dissoc :id)
|
||||
(update :group #(or % ""))
|
||||
(update :is-source #(or % false))
|
||||
(update :modified-at #(or % (dt/now)))
|
||||
(update :sets #(into (d/ordered-set) %)))
|
||||
token-theme (map->TokenTheme params)]
|
||||
|
||||
(dm/assert!
|
||||
"expected valid token theme"
|
||||
(check-token-theme! token-theme))
|
||||
|
||||
token-theme))
|
||||
|
||||
;; === TokenThemes (collection)
|
||||
|
||||
(defprotocol ITokenThemes
|
||||
(add-theme [_ token-theme] "add a theme to the library, at the end")
|
||||
(update-theme [_ group name f] "modify a theme in the ilbrary")
|
||||
(delete-theme [_ group name] "delete a theme in the library")
|
||||
(theme-count [_] "get the total number if themes in the library")
|
||||
(get-theme-tree [_] "get a nested tree of all themes in the library")
|
||||
(get-themes [_] "get an ordered sequence of all themes in the library")
|
||||
(get-theme [_ group name] "get one theme looking for name"))
|
||||
|
||||
(def schema:token-themes
|
||||
[:and
|
||||
[:map-of {:title "TokenThemes"}
|
||||
:string [:and [:map-of :string ::token-theme]
|
||||
[:fn d/ordered-map?]]]
|
||||
[:fn d/ordered-map?]])
|
||||
|
||||
(sm/register! ::token-themes schema:token-themes)
|
||||
|
||||
(def valid-token-themes?
|
||||
(constantly true))
|
||||
(sm/validator schema:token-themes))
|
||||
|
||||
(def check-token-themes!
|
||||
(sm/check-fn ::token-themes))
|
||||
|
||||
;; === Tokens Lib
|
||||
|
||||
|
@ -155,62 +331,122 @@
|
|||
"A library of tokens, sets and themes."
|
||||
(add-token-in-set [_ set-name token] "add token to a set")
|
||||
(update-token-in-set [_ set-name token-name f] "update a token in a set")
|
||||
(delete-token-from-set [_ set-name token-name] "delete a token from a set"))
|
||||
(delete-token-from-set [_ set-name token-name] "delete a token from a set")
|
||||
(toggle-set-in-theme [_ group-name theme-name set-name] "toggle a set used / not used in a theme")
|
||||
(validate [_]))
|
||||
|
||||
(deftype TokensLib [sets themes]
|
||||
(deftype TokensLib [sets set-groups themes]
|
||||
;; NOTE: This is only for debug purposes, pending to properly
|
||||
;; implement the toString and alternative printing.
|
||||
#?@(:clj [clojure.lang.IDeref
|
||||
(deref [_] {:sets sets :themes themes})]
|
||||
(deref [_] {:sets sets :set-groups set-groups :themes themes})]
|
||||
:cljs [cljs.core/IDeref
|
||||
(-deref [_] {:sets sets :themes themes})])
|
||||
(-deref [_] {:sets sets :set-groups set-groups :themes themes})])
|
||||
|
||||
#?@(:cljs [cljs.core/IEncodeJS
|
||||
(-clj->js [_] (js-obj "sets" (clj->js sets)
|
||||
"set-groups" (clj->js set-groups)
|
||||
"themes" (clj->js themes)))])
|
||||
|
||||
ITokenSets
|
||||
(add-set [_ token-set]
|
||||
(dm/assert! "expected valid token set" (check-token-set! token-set))
|
||||
(TokensLib. (assoc sets (:name token-set) token-set)
|
||||
themes))
|
||||
(let [path (get-path token-set "/")
|
||||
groups-str (get-groups-str token-set "/")]
|
||||
(TokensLib. (d/oassoc-in sets path token-set)
|
||||
(cond-> set-groups
|
||||
(not (str/empty? groups-str))
|
||||
(assoc groups-str (make-token-set-group)))
|
||||
themes)))
|
||||
|
||||
(update-set [this set-name f]
|
||||
(if-let [set (get sets set-name)]
|
||||
(let [set' (-> (make-token-set (f set))
|
||||
(assoc :modified-at (dt/now)))]
|
||||
(check-token-set! set')
|
||||
(TokensLib. (if (= (:name set) (:name set'))
|
||||
(assoc sets (:name set') set')
|
||||
(let [index (d/index-of (keys sets) (:name set))]
|
||||
(let [path (split-path set-name "/")
|
||||
set (get-in sets path)]
|
||||
(if set
|
||||
(let [set' (-> (make-token-set (f set))
|
||||
(assoc :modified-at (dt/now)))
|
||||
path' (get-path set' "/")]
|
||||
(check-token-set! set')
|
||||
(TokensLib. (if (= (:name set) (:name set'))
|
||||
(d/oassoc-in sets path set')
|
||||
(-> sets
|
||||
(dissoc (:name set))
|
||||
(d/addm-at-index index (:name set') set'))))
|
||||
themes))
|
||||
this))
|
||||
(d/oassoc-in-before path path' set')
|
||||
(d/dissoc-in path)))
|
||||
set-groups ;; TODO update set-groups as needed
|
||||
themes))
|
||||
this)))
|
||||
|
||||
(delete-set [_ set-name]
|
||||
(TokensLib. (dissoc sets set-name)
|
||||
themes))
|
||||
(let [path (split-path set-name "/")]
|
||||
(TokensLib. (d/dissoc-in sets path)
|
||||
set-groups ;; TODO remove set-group if needed
|
||||
themes)))
|
||||
|
||||
(validate [_]
|
||||
(and (valid-token-sets? sets)
|
||||
(valid-token-themes? themes)))
|
||||
|
||||
(set-count [_]
|
||||
(count sets))
|
||||
(get-set-tree [_]
|
||||
sets)
|
||||
|
||||
(get-sets [_]
|
||||
(vals sets))
|
||||
(->> (tree-seq d/ordered-map? vals sets)
|
||||
(filter (partial instance? TokenSet))))
|
||||
|
||||
(set-count [this]
|
||||
(count (get-sets this)))
|
||||
|
||||
(get-set [_ set-name]
|
||||
(get sets set-name))
|
||||
(let [path (split-path set-name "/")]
|
||||
(get-in sets path)))
|
||||
|
||||
(get-set-group [_ set-group-path]
|
||||
(get set-groups set-group-path))
|
||||
|
||||
ITokenThemes
|
||||
(add-theme [_ token-theme]
|
||||
(dm/assert! "expected valid token theme" (check-token-theme! token-theme))
|
||||
(TokensLib. sets
|
||||
set-groups
|
||||
(update themes (:group token-theme) d/oassoc (:name token-theme) token-theme)))
|
||||
|
||||
(update-theme [this group name f]
|
||||
(let [theme (dm/get-in themes [group name])]
|
||||
(if theme
|
||||
(let [theme' (-> (make-token-theme (f theme))
|
||||
(assoc :modified-at (dt/now)))
|
||||
group' (:group theme')
|
||||
name' (:name theme')]
|
||||
(check-token-theme! theme')
|
||||
(TokensLib. sets
|
||||
set-groups
|
||||
(if (and (= group group') (= name name'))
|
||||
(update themes group' assoc name' theme')
|
||||
(-> themes
|
||||
(d/oassoc-in-before [group name] [group' name'] theme')
|
||||
(d/dissoc-in [group name])))))
|
||||
this)))
|
||||
|
||||
(delete-theme [_ group name]
|
||||
(TokensLib. sets
|
||||
set-groups
|
||||
(d/dissoc-in themes [group name])))
|
||||
|
||||
(get-theme-tree [_]
|
||||
themes)
|
||||
|
||||
(get-themes [_]
|
||||
(->> (tree-seq d/ordered-map? vals themes)
|
||||
(filter (partial instance? TokenTheme))))
|
||||
|
||||
(theme-count [this]
|
||||
(count (get-themes this)))
|
||||
|
||||
(get-theme [_ group name]
|
||||
(dm/get-in themes [group name]))
|
||||
|
||||
ITokensLib
|
||||
(add-token-in-set [this set-name token]
|
||||
(dm/assert! "expected valid token instance" (check-token! token))
|
||||
(if (contains? sets set-name)
|
||||
(TokensLib. (update sets set-name add-token token)
|
||||
set-groups
|
||||
themes)
|
||||
this))
|
||||
|
||||
|
@ -218,6 +454,7 @@
|
|||
(if (contains? sets set-name)
|
||||
(TokensLib. (update sets set-name
|
||||
#(update-token % token-name f))
|
||||
set-groups
|
||||
themes)
|
||||
this))
|
||||
|
||||
|
@ -225,8 +462,21 @@
|
|||
(if (contains? sets set-name)
|
||||
(TokensLib. (update sets set-name
|
||||
#(delete-token % token-name))
|
||||
set-groups
|
||||
themes)
|
||||
this)))
|
||||
this))
|
||||
|
||||
(toggle-set-in-theme [this theme-group theme-name set-name]
|
||||
(if-let [_theme (get-in themes theme-group theme-name)]
|
||||
(TokensLib. sets
|
||||
set-groups
|
||||
(d/oupdate-in themes [theme-group theme-name]
|
||||
#(toggle-set % set-name)))
|
||||
this))
|
||||
|
||||
(validate [_]
|
||||
(and (valid-token-sets? sets) ;; TODO: validate set-groups
|
||||
(valid-token-themes? themes))))
|
||||
|
||||
(defn valid-tokens-lib?
|
||||
[o]
|
||||
|
@ -248,10 +498,11 @@
|
|||
;; structure the data and the order separately as we already do
|
||||
;; with pages and pages-index.
|
||||
(make-tokens-lib :sets (d/ordered-map)
|
||||
:set-groups {}
|
||||
:themes (d/ordered-map)))
|
||||
|
||||
([& {:keys [sets themes]}]
|
||||
(let [tokens-lib (TokensLib. sets themes)]
|
||||
([& {:keys [sets set-groups themes]}]
|
||||
(let [tokens-lib (TokensLib. sets set-groups themes)]
|
||||
|
||||
(dm/assert!
|
||||
"expected valid tokens lib"
|
||||
|
@ -269,7 +520,7 @@
|
|||
|
||||
(sm/register! ::tokens-lib type:tokens-lib)
|
||||
|
||||
;; === Serialization handlers for RPC API and database
|
||||
;; === Serialization handlers for RPC API (transit) and database (fressian)
|
||||
|
||||
(t/add-handlers!
|
||||
{:id "penpot/tokens-lib"
|
||||
|
@ -281,6 +532,11 @@
|
|||
:class TokenSet
|
||||
:wfn #(into {} %)
|
||||
:rfn #(make-token-set %)}
|
||||
|
||||
{:id "penpot/token-theme"
|
||||
:class TokenTheme
|
||||
:wfn #(into {} %)
|
||||
:rfn #(make-token-theme %)}
|
||||
|
||||
{:id "penpot/token"
|
||||
:class Token
|
||||
|
@ -307,13 +563,24 @@
|
|||
(let [obj (fres/read-object! r)]
|
||||
(map->TokenSet obj)))}
|
||||
|
||||
{:name "penpot/token-theme/v1"
|
||||
:class TokenTheme
|
||||
:wfn (fn [n w o]
|
||||
(fres/write-tag! w n 1)
|
||||
(fres/write-object! w (into {} o)))
|
||||
:rfn (fn [r]
|
||||
(let [obj (fres/read-object! r)]
|
||||
(map->TokenTheme obj)))}
|
||||
|
||||
{:name "penpot/tokens-lib/v1"
|
||||
:class TokensLib
|
||||
:wfn (fn [n w o]
|
||||
(fres/write-tag! w n 2)
|
||||
(fres/write-tag! w n 3)
|
||||
(fres/write-object! w (.-sets o))
|
||||
(fres/write-object! w (.-set-groups o))
|
||||
(fres/write-object! w (.-themes o)))
|
||||
:rfn (fn [r]
|
||||
(let [sets (fres/read-object! r)
|
||||
themes (fres/read-object! r)]
|
||||
(->TokensLib sets themes)))}))
|
||||
(let [sets (fres/read-object! r)
|
||||
set-groups (fres/read-object! r)
|
||||
themes (fres/read-object! r)]
|
||||
(->TokensLib sets set-groups themes)))}))
|
||||
|
|
|
@ -19,16 +19,17 @@
|
|||
(assoc file-data :token-active-themes theme-ids))
|
||||
|
||||
(defn add-temporary-token-theme
|
||||
[file-data {:keys [id] :as token-theme}]
|
||||
[file-data {:keys [id name] :as token-theme}]
|
||||
(-> file-data
|
||||
(d/dissoc-in [:token-themes-index (:token-theme-temporary-id file-data)])
|
||||
(assoc :token-theme-temporary-id id)
|
||||
(assoc :token-theme-temporary-name name)
|
||||
(update :token-themes-index assoc id token-theme)))
|
||||
|
||||
(defn delete-temporary-token-theme
|
||||
[file-data token-theme-id]
|
||||
(cond-> file-data
|
||||
(= (:token-theme-temporary-id file-data) token-theme-id) (dissoc :token-theme-temporary-id)
|
||||
(= (:token-theme-temporary-id file-data) token-theme-id) (dissoc :token-theme-temporary-id :token-theme-temporary-name)
|
||||
:always (d/dissoc-in [:token-themes-index (:token-theme-temporary-id file-data)])))
|
||||
|
||||
(defn add-token-theme
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -115,10 +115,9 @@
|
|||
(ptk/reify ::update-token-theme
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [prev-token-theme (wtts/get-workspace-token-theme state (:id token-theme))
|
||||
(let [prev-token-theme (wtts/get-workspace-token-theme (:id token-theme) state)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/update-token-theme token-theme prev-token-theme))]
|
||||
(js/console.log "changes" changes)
|
||||
(rx/of
|
||||
(dch/commit-changes changes))))))
|
||||
|
||||
|
|
|
@ -69,11 +69,11 @@
|
|||
(defn group-assets
|
||||
"Convert a list of assets in a nested structure like this:
|
||||
|
||||
{'': [{assetA} {assetB}]
|
||||
'group1': {'': [{asset1A} {asset1B}]
|
||||
'subgroup11': {'': [{asset11A} {asset11B} {asset11C}]}
|
||||
'subgroup12': {'': [{asset12A}]}}
|
||||
'group2': {'subgroup21': {'': [{asset21A}}}}
|
||||
{'': [assetA assetB]
|
||||
'group1': {'': [asset1A asset1B]
|
||||
'subgroup11': {'': [asset11A asset11B asset11C]}
|
||||
'subgroup12': {'': [asset12A]}}
|
||||
'group2': {'subgroup21': {'': [asset21A]}}}
|
||||
"
|
||||
[assets reverse-sort?]
|
||||
(when-not (empty? assets)
|
||||
|
|
Loading…
Add table
Reference in a new issue