mirror of
https://github.com/penpot/penpot.git
synced 2025-06-07 12:11:40 +02:00
Merge remote-tracking branch 'origin/token-studio-develop' into florian/rename-set-groups
This commit is contained in:
commit
78d743406b
25 changed files with 886 additions and 173 deletions
|
@ -1166,7 +1166,7 @@
|
||||||
; We need to trigger a sync if the shape has changed any
|
; We need to trigger a sync if the shape has changed any
|
||||||
; attribute that participates in components synchronization.
|
; attribute that participates in components synchronization.
|
||||||
(and (= (:type operation) :set)
|
(and (= (:type operation) :set)
|
||||||
(get ctk/sync-attrs (:attr operation))))
|
(ctk/component-attr? (:attr operation))))
|
||||||
any-sync? (some need-sync? operations)]
|
any-sync? (some need-sync? operations)]
|
||||||
(when any-sync?
|
(when any-sync?
|
||||||
(if page-id
|
(if page-id
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.shape.interactions :as ctsi]
|
[app.common.types.shape.interactions :as ctsi]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
[app.common.types.token :as cto]
|
||||||
[app.common.types.typography :as cty]
|
[app.common.types.typography :as cty]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
|
@ -1479,6 +1480,44 @@
|
||||||
[{:type :set-remote-synced
|
[{:type :set-remote-synced
|
||||||
:remote-synced (:remote-synced shape)}]}))))))
|
:remote-synced (:remote-synced shape)}]}))))))
|
||||||
|
|
||||||
|
(defn- update-tokens
|
||||||
|
"Token synchronization algorithm. Copy the applied tokens that have changed
|
||||||
|
in the origin shape to the dest shape (applying or removing as necessary).
|
||||||
|
|
||||||
|
Only the given token attributes are synced."
|
||||||
|
[changes container dest-shape orig-shape token-attrs]
|
||||||
|
(let [orig-tokens (get orig-shape :applied-tokens {})
|
||||||
|
dest-tokens (get dest-shape :applied-tokens {})
|
||||||
|
dest-tokens' (reduce (fn [dest-tokens' token-attr]
|
||||||
|
(let [orig-token (get orig-tokens token-attr)
|
||||||
|
dest-token (get dest-tokens token-attr)]
|
||||||
|
(if (= orig-token dest-token)
|
||||||
|
dest-tokens'
|
||||||
|
(if (nil? orig-token)
|
||||||
|
(dissoc dest-tokens' token-attr)
|
||||||
|
(assoc dest-tokens' token-attr orig-token)))))
|
||||||
|
dest-tokens
|
||||||
|
token-attrs)]
|
||||||
|
(if (= dest-tokens dest-tokens')
|
||||||
|
changes
|
||||||
|
(-> changes
|
||||||
|
(update :redo-changes conj (make-change
|
||||||
|
container
|
||||||
|
{:type :mod-obj
|
||||||
|
:id (:id dest-shape)
|
||||||
|
:operations [{:type :set
|
||||||
|
:attr :applied-tokens
|
||||||
|
:val dest-tokens'
|
||||||
|
:ignore-touched true}]}))
|
||||||
|
(update :undo-changes conj (make-change
|
||||||
|
container
|
||||||
|
{:type :mod-obj
|
||||||
|
:id (:id dest-shape)
|
||||||
|
:operations [{:type :set
|
||||||
|
:attr :applied-tokens
|
||||||
|
:val dest-tokens
|
||||||
|
:ignore-touched true}]}))))))
|
||||||
|
|
||||||
(defn- update-attrs
|
(defn- update-attrs
|
||||||
"The main function that implements the attribute sync algorithm. Copy
|
"The main function that implements the attribute sync algorithm. Copy
|
||||||
attributes that have changed in the origin shape to the dest shape.
|
attributes that have changed in the origin shape to the dest shape.
|
||||||
|
@ -1511,37 +1550,41 @@
|
||||||
(loop [attrs (->> (seq (keys ctk/sync-attrs))
|
(loop [attrs (->> (seq (keys ctk/sync-attrs))
|
||||||
;; We don't update the flex-child attrs
|
;; We don't update the flex-child attrs
|
||||||
(remove ctk/swap-keep-attrs)
|
(remove ctk/swap-keep-attrs)
|
||||||
|
|
||||||
;; We don't do automatic update of the `layout-grid-cells` property.
|
;; We don't do automatic update of the `layout-grid-cells` property.
|
||||||
(remove #(= :layout-grid-cells %)))
|
(remove #(= :layout-grid-cells %)))
|
||||||
|
applied-tokens #{}
|
||||||
roperations []
|
roperations []
|
||||||
uoperations '()]
|
uoperations '()]
|
||||||
|
|
||||||
(let [attr (first attrs)]
|
(let [attr (first attrs)]
|
||||||
(if (nil? attr)
|
(if (nil? attr)
|
||||||
(if (empty? roperations)
|
(if (and (empty? roperations) (empty? applied-tokens))
|
||||||
changes
|
changes
|
||||||
(let [all-parents (cfh/get-parent-ids (:objects container)
|
(let [all-parents (cfh/get-parent-ids (:objects container)
|
||||||
(:id dest-shape))]
|
(:id dest-shape))]
|
||||||
(-> changes
|
(cond-> changes
|
||||||
(update :redo-changes conj (make-change
|
(seq roperations)
|
||||||
container
|
(-> (update :redo-changes conj (make-change
|
||||||
{:type :mod-obj
|
container
|
||||||
:id (:id dest-shape)
|
{:type :mod-obj
|
||||||
:operations roperations}))
|
:id (:id dest-shape)
|
||||||
(update :redo-changes conj (make-change
|
:operations roperations}))
|
||||||
container
|
(update :redo-changes conj (make-change
|
||||||
{:type :reg-objects
|
container
|
||||||
:shapes all-parents}))
|
{:type :reg-objects
|
||||||
(update :undo-changes conj (make-change
|
:shapes all-parents}))
|
||||||
container
|
(update :undo-changes conj (make-change
|
||||||
{:type :mod-obj
|
container
|
||||||
:id (:id dest-shape)
|
{:type :mod-obj
|
||||||
:operations (vec uoperations)}))
|
:id (:id dest-shape)
|
||||||
(update :undo-changes concat [(make-change
|
:operations (vec uoperations)}))
|
||||||
container
|
(update :undo-changes concat [(make-change
|
||||||
{:type :reg-objects
|
container
|
||||||
:shapes all-parents})]))))
|
{:type :reg-objects
|
||||||
|
:shapes all-parents})]))
|
||||||
|
(seq applied-tokens)
|
||||||
|
(update-tokens container dest-shape origin-shape applied-tokens))))
|
||||||
|
|
||||||
(let [;; position-data is a special case because can be affected by :geometry-group and :content-group
|
(let [;; position-data is a special case because can be affected by :geometry-group and :content-group
|
||||||
;; so, if the position-data changes but the geometry is touched we need to reset the position-data
|
;; so, if the position-data changes but the geometry is touched we need to reset the position-data
|
||||||
;; so it's calculated again
|
;; so it's calculated again
|
||||||
|
@ -1564,14 +1607,21 @@
|
||||||
:val (get dest-shape attr)
|
:val (get dest-shape attr)
|
||||||
:ignore-touched true}
|
:ignore-touched true}
|
||||||
|
|
||||||
attr-group (get ctk/sync-attrs attr)]
|
attr-group (get ctk/sync-attrs attr)
|
||||||
|
|
||||||
|
token-attrs (cto/shape-attr->token-attrs attr)
|
||||||
|
applied-tokens' (cond-> applied-tokens
|
||||||
|
(not (and (touched attr-group)
|
||||||
|
omit-touched?))
|
||||||
|
(into token-attrs))]
|
||||||
(if (or (= (get origin-shape attr) (get dest-shape attr))
|
(if (or (= (get origin-shape attr) (get dest-shape attr))
|
||||||
(and (touched attr-group) omit-touched?))
|
(and (touched attr-group) omit-touched?))
|
||||||
(recur (next attrs)
|
(recur (next attrs)
|
||||||
|
applied-tokens'
|
||||||
roperations
|
roperations
|
||||||
uoperations)
|
uoperations)
|
||||||
(recur (next attrs)
|
(recur (next attrs)
|
||||||
|
applied-tokens'
|
||||||
(conj roperations roperation)
|
(conj roperations roperation)
|
||||||
(conj uoperations uoperation)))))))))
|
(conj uoperations uoperation)))))))))
|
||||||
|
|
||||||
|
|
82
common/src/app/common/test_helpers/tokens.cljc
Normal file
82
common/src/app/common/test_helpers/tokens.cljc
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.common.test-helpers.tokens
|
||||||
|
(:require
|
||||||
|
[app.common.test-helpers.files :as thf]
|
||||||
|
[app.common.test-helpers.shapes :as ths]
|
||||||
|
[app.common.types.container :as ctn]
|
||||||
|
[app.common.types.file :as ctf]
|
||||||
|
[app.common.types.pages-list :as ctpl]
|
||||||
|
[app.common.types.shape-tree :as ctst]
|
||||||
|
[app.common.types.token :as cto]
|
||||||
|
[app.common.types.tokens-lib :as ctob]))
|
||||||
|
|
||||||
|
(defn add-tokens-lib
|
||||||
|
[file]
|
||||||
|
(ctf/update-file-data file #(update % :tokens-lib ctob/ensure-tokens-lib)))
|
||||||
|
|
||||||
|
(defn update-tokens-lib
|
||||||
|
[file f]
|
||||||
|
(ctf/update-file-data file #(update % :tokens-lib f)))
|
||||||
|
|
||||||
|
(defn- set-stroke-width
|
||||||
|
[shape stroke-width]
|
||||||
|
(let [strokes (if (seq (:strokes shape))
|
||||||
|
(:strokes shape)
|
||||||
|
[{:stroke-style :solid
|
||||||
|
:stroke-alignment :inner
|
||||||
|
:stroke-width 1
|
||||||
|
:stroke-color "#000000"
|
||||||
|
:stroke-opacity 1}])
|
||||||
|
new-strokes (update strokes 0 assoc :stroke-width stroke-width)]
|
||||||
|
(ctn/set-shape-attr shape :strokes new-strokes {:ignore-touched true})))
|
||||||
|
|
||||||
|
(defn- set-stroke-color
|
||||||
|
[shape stroke-color]
|
||||||
|
(let [strokes (if (seq (:strokes shape))
|
||||||
|
(:strokes shape)
|
||||||
|
[{:stroke-style :solid
|
||||||
|
:stroke-alignment :inner
|
||||||
|
:stroke-width 1
|
||||||
|
:stroke-color "#000000"
|
||||||
|
:stroke-opacity 1}])
|
||||||
|
new-strokes (update strokes 0 assoc :stroke-color stroke-color)]
|
||||||
|
(ctn/set-shape-attr shape :strokes new-strokes {:ignore-touched true})))
|
||||||
|
|
||||||
|
(defn- set-fill-color
|
||||||
|
[shape fill-color]
|
||||||
|
(let [fills (if (seq (:fills shape))
|
||||||
|
(:fills shape)
|
||||||
|
[{:fill-color "#000000"
|
||||||
|
:fill-opacity 1}])
|
||||||
|
new-fills (update fills 0 assoc :fill-color fill-color)]
|
||||||
|
(ctn/set-shape-attr shape :fills new-fills {:ignore-touched true})))
|
||||||
|
|
||||||
|
(defn apply-token-to-shape
|
||||||
|
[file shape-label token-name token-attrs shape-attrs resolved-value]
|
||||||
|
(let [page (thf/current-page file)
|
||||||
|
shape (ths/get-shape file shape-label)
|
||||||
|
shape' (as-> shape $
|
||||||
|
(cto/apply-token-to-shape {:shape $
|
||||||
|
:token {:name token-name}
|
||||||
|
:attributes token-attrs})
|
||||||
|
(reduce (fn [shape attr]
|
||||||
|
(case attr
|
||||||
|
:stroke-width (set-stroke-width shape resolved-value)
|
||||||
|
:stroke-color (set-stroke-color shape resolved-value)
|
||||||
|
:fill (set-fill-color shape resolved-value)
|
||||||
|
(ctn/set-shape-attr shape attr resolved-value {:ignore-touched true})))
|
||||||
|
$
|
||||||
|
shape-attrs))]
|
||||||
|
|
||||||
|
(ctf/update-file-data
|
||||||
|
file
|
||||||
|
(fn [file-data]
|
||||||
|
(ctpl/update-page file-data
|
||||||
|
(:id page)
|
||||||
|
#(ctst/set-shape % shape'))))))
|
||||||
|
|
|
@ -140,6 +140,14 @@
|
||||||
:layout-item-z-index
|
:layout-item-z-index
|
||||||
:layout-item-align-self})
|
:layout-item-align-self})
|
||||||
|
|
||||||
|
(defn component-attr?
|
||||||
|
"Check if some attribute is one that is involved in component syncrhonization.
|
||||||
|
Note that design tokens also are involved, although they go by an alternate
|
||||||
|
route and thus they are not part of :sync-attrs."
|
||||||
|
[attr]
|
||||||
|
(or (get sync-attrs attr)
|
||||||
|
(= :applied-tokens attr)))
|
||||||
|
|
||||||
(defn instance-root?
|
(defn instance-root?
|
||||||
"Check if this shape is the head of a top instance."
|
"Check if this shape is the head of a top instance."
|
||||||
[shape]
|
[shape]
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
[app.common.types.plugins :as ctpg]
|
[app.common.types.plugins :as ctpg]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
[app.common.types.token :as ctt]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -540,14 +541,28 @@
|
||||||
|
|
||||||
;; --- SHAPE UPDATE
|
;; --- SHAPE UPDATE
|
||||||
|
|
||||||
|
(defn- get-token-groups
|
||||||
|
[shape new-applied-tokens]
|
||||||
|
(let [old-applied-tokens (d/nilv (:applied-tokens shape) #{})
|
||||||
|
changed-token-attrs (filter #(not= (get old-applied-tokens %) (get new-applied-tokens %))
|
||||||
|
ctt/all-keys)
|
||||||
|
changed-groups (into #{}
|
||||||
|
(comp (map ctt/token-attr->shape-attr)
|
||||||
|
(map #(get ctk/sync-attrs %))
|
||||||
|
(filter some?))
|
||||||
|
changed-token-attrs)]
|
||||||
|
changed-groups))
|
||||||
|
|
||||||
(defn set-shape-attr
|
(defn set-shape-attr
|
||||||
"Assign attribute to shape with touched logic.
|
"Assign attribute to shape with touched logic.
|
||||||
|
|
||||||
The returned shape will contain a metadata associated with it
|
The returned shape will contain a metadata associated with it
|
||||||
indicating if shape is touched or not."
|
indicating if shape is touched or not."
|
||||||
[shape attr val & {:keys [ignore-touched ignore-geometry]}]
|
[shape attr val & {:keys [ignore-touched ignore-geometry]}]
|
||||||
(let [group (get ctk/sync-attrs attr)
|
(let [group (get ctk/sync-attrs attr)
|
||||||
shape-val (get shape attr)
|
token-groups (when (= attr :applied-tokens)
|
||||||
|
(get-token-groups shape val))
|
||||||
|
shape-val (get shape attr)
|
||||||
|
|
||||||
ignore?
|
ignore?
|
||||||
(or ignore-touched
|
(or ignore-touched
|
||||||
|
@ -585,9 +600,15 @@
|
||||||
;; set the "touched" flag for the group the attribute belongs to.
|
;; set the "touched" flag for the group the attribute belongs to.
|
||||||
;; In some cases we need to ignore touched only if the attribute is
|
;; In some cases we need to ignore touched only if the attribute is
|
||||||
;; geometric (position, width or transformation).
|
;; geometric (position, width or transformation).
|
||||||
(and in-copy? group (not ignore?) (not equal?)
|
(and in-copy?
|
||||||
(not (and ignore-geometry is-geometry?)))
|
(or (and group (not equal?)) (seq token-groups))
|
||||||
(-> (update :touched ctk/set-touched-group group)
|
(not ignore?) (not (and ignore-geometry is-geometry?)))
|
||||||
|
(-> (update :touched (fn [touched]
|
||||||
|
(reduce #(ctk/set-touched-group %1 %2)
|
||||||
|
touched
|
||||||
|
(if group
|
||||||
|
(cons group token-groups)
|
||||||
|
token-groups))))
|
||||||
(dissoc :remote-synced))
|
(dissoc :remote-synced))
|
||||||
|
|
||||||
(nil? val)
|
(nil? val)
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
|
|
||||||
(ns app.common.types.token
|
(ns app.common.types.token
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.schema.registry :as sr]
|
[app.common.schema.registry :as sr]
|
||||||
|
[clojure.data :as data]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[malli.util :as mu]))
|
[malli.util :as mu]))
|
||||||
|
|
||||||
|
@ -150,6 +152,15 @@
|
||||||
|
|
||||||
(def rotation-keys (schema-keys ::rotation))
|
(def rotation-keys (schema-keys ::rotation))
|
||||||
|
|
||||||
|
(def all-keys (set/union color-keys
|
||||||
|
border-radius-keys
|
||||||
|
stroke-width-keys
|
||||||
|
sizing-keys
|
||||||
|
opacity-keys
|
||||||
|
spacing-keys
|
||||||
|
dimensions-keys
|
||||||
|
rotation-keys))
|
||||||
|
|
||||||
(sm/register!
|
(sm/register!
|
||||||
^{::sm/type ::tokens}
|
^{::sm/type ::tokens}
|
||||||
[:map {:title "Applied Tokens"}])
|
[:map {:title "Applied Tokens"}])
|
||||||
|
@ -163,3 +174,58 @@
|
||||||
::spacing
|
::spacing
|
||||||
::rotation
|
::rotation
|
||||||
::dimensions])
|
::dimensions])
|
||||||
|
|
||||||
|
(defn shape-attr->token-attrs
|
||||||
|
[shape-attr]
|
||||||
|
(cond
|
||||||
|
(= :fills shape-attr) #{:fill}
|
||||||
|
(= :strokes shape-attr) #{:stroke-color :stroke-width}
|
||||||
|
(border-radius-keys shape-attr) #{shape-attr}
|
||||||
|
(sizing-keys shape-attr) #{shape-attr}
|
||||||
|
(opacity-keys shape-attr) #{shape-attr}
|
||||||
|
(spacing-keys shape-attr) #{shape-attr}
|
||||||
|
(rotation-keys shape-attr) #{shape-attr}))
|
||||||
|
|
||||||
|
(defn token-attr->shape-attr
|
||||||
|
[token-attr]
|
||||||
|
(case token-attr
|
||||||
|
:fill :fills
|
||||||
|
:stroke-color :strokes
|
||||||
|
:stroke-width :strokes
|
||||||
|
token-attr))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; TOKENS IN SHAPES
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn- toggle-or-apply-token
|
||||||
|
"Remove any shape attributes from token if they exists.
|
||||||
|
Othewise apply token attributes."
|
||||||
|
[shape token]
|
||||||
|
(let [[shape-leftover token-leftover _matching] (data/diff (:applied-tokens shape) token)]
|
||||||
|
(merge {} shape-leftover token-leftover)))
|
||||||
|
|
||||||
|
(defn- token-from-attributes [token attributes]
|
||||||
|
(->> (map (fn [attr] [attr (:name token)]) attributes)
|
||||||
|
(into {})))
|
||||||
|
|
||||||
|
(defn- apply-token-to-attributes [{:keys [shape token attributes]}]
|
||||||
|
(let [token (token-from-attributes token attributes)]
|
||||||
|
(toggle-or-apply-token shape token)))
|
||||||
|
|
||||||
|
(defn apply-token-to-shape
|
||||||
|
[{:keys [shape token attributes] :as _props}]
|
||||||
|
(let [applied-tokens (apply-token-to-attributes {:shape shape
|
||||||
|
:token token
|
||||||
|
:attributes attributes})]
|
||||||
|
(update shape :applied-tokens #(merge % applied-tokens))))
|
||||||
|
|
||||||
|
(defn maybe-apply-token-to-shape
|
||||||
|
"When the passed `:token` is non-nil apply it to the `:applied-tokens` on a shape."
|
||||||
|
[{:keys [shape token _attributes] :as props}]
|
||||||
|
(if token
|
||||||
|
(apply-token-to-shape props)
|
||||||
|
shape))
|
||||||
|
|
||||||
|
(defn unapply-token-id [shape attributes]
|
||||||
|
(update shape :applied-tokens d/without-keys attributes))
|
||||||
|
|
|
@ -634,6 +634,11 @@ When `before-set-name` is nil, move set to bottom")
|
||||||
(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")
|
(toggle-set-in-theme [_ group-name theme-name 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")
|
(get-active-themes-set-names [_] "set of set names that are active in the the active themes")
|
||||||
|
(sets-at-path-all-active? [_ prefixed-path] "compute active state for child sets at `prefixed-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-active-themes-set-tokens [_] "set of set names that are active in the the active themes")
|
(get-active-themes-set-tokens [_] "set of set names that are active in the the active themes")
|
||||||
(encode-dtcg [_] "Encodes library to a dtcg compatible json string")
|
(encode-dtcg [_] "Encodes library to a dtcg compatible json string")
|
||||||
(decode-dtcg-json [_ parsed-json] "Decodes parsed json containing tokens and converts to library")
|
(decode-dtcg-json [_ parsed-json] "Decodes parsed json containing tokens and converts to library")
|
||||||
|
@ -894,6 +899,19 @@ When `before-set-name` is nil, move set to bottom")
|
||||||
(mapcat :sets)
|
(mapcat :sets)
|
||||||
(get-active-themes this)))
|
(get-active-themes this)))
|
||||||
|
|
||||||
|
(sets-at-path-all-active? [this prefixed-path]
|
||||||
|
(let [active-set-names (get-active-themes-set-names this)]
|
||||||
|
(if (seq active-set-names)
|
||||||
|
(let [path-active-set-names (->> (get-sets-at-prefix-path this prefixed-path)
|
||||||
|
(map :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-active-themes-set-tokens [this]
|
(get-active-themes-set-tokens [this]
|
||||||
(let [sets-order (get-ordered-set-names this)
|
(let [sets-order (get-ordered-set-names this)
|
||||||
active-themes (get-active-themes this)
|
active-themes (get-active-themes this)
|
||||||
|
|
|
@ -193,7 +193,6 @@
|
||||||
(ths/add-sample-shape :free-shape))
|
(ths/add-sample-shape :free-shape))
|
||||||
|
|
||||||
page (thf/current-page file)
|
page (thf/current-page file)
|
||||||
main-root (ths/get-shape file :main-root)
|
|
||||||
|
|
||||||
;; ==== Action
|
;; ==== Action
|
||||||
changes1 (cls/generate-relocate (pcb/empty-changes)
|
changes1 (cls/generate-relocate (pcb/empty-changes)
|
||||||
|
@ -203,9 +202,6 @@
|
||||||
0 ; to-index
|
0 ; to-index
|
||||||
#{(thi/id :free-shape)}) ; ids
|
#{(thi/id :free-shape)}) ; ids
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updated-file (thf/apply-changes file changes1)
|
updated-file (thf/apply-changes file changes1)
|
||||||
|
|
||||||
changes2 (cll/generate-sync-file-changes (pcb/empty-changes)
|
changes2 (cll/generate-sync-file-changes (pcb/empty-changes)
|
||||||
|
@ -491,4 +487,4 @@
|
||||||
(t/is (= (:fill-color fill') "#fabada"))
|
(t/is (= (:fill-color fill') "#fabada"))
|
||||||
(t/is (= (:fill-opacity fill') 1))
|
(t/is (= (:fill-opacity fill') 1))
|
||||||
(t/is (= (:touched copy2-root') nil))
|
(t/is (= (:touched copy2-root') nil))
|
||||||
(t/is (= (:touched copy2-child') nil))))
|
(t/is (= (:touched copy2-child') nil))))
|
||||||
|
|
|
@ -417,8 +417,39 @@
|
||||||
expected-tokens (ctob/get-active-themes-set-tokens tokens-lib)
|
expected-tokens (ctob/get-active-themes-set-tokens tokens-lib)
|
||||||
expected-token-names (mapv key expected-tokens)]
|
expected-token-names (mapv key expected-tokens)]
|
||||||
(t/is (= '("set-a" "set-b" "inactive-set") expected-order))
|
(t/is (= '("set-a" "set-b" "inactive-set") expected-order))
|
||||||
(t/is (= ["set-a-token" "set-b-token"] expected-token-names)))))
|
(t/is (= ["set-a-token" "set-b-token"] expected-token-names))))
|
||||||
|
|
||||||
|
(t/testing "sets-at-path-active-state"
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz"))
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "foo/bar/bam"))
|
||||||
|
|
||||||
|
(ctob/add-theme (ctob/make-token-theme :name "none"))
|
||||||
|
(ctob/add-theme (ctob/make-token-theme :name "partial"
|
||||||
|
:sets #{"foo/bar/baz"}))
|
||||||
|
(ctob/add-theme (ctob/make-token-theme :name "all"
|
||||||
|
:sets #{"foo/bar/baz"
|
||||||
|
"foo/bar/bam"}))
|
||||||
|
(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? "G-foo"))
|
||||||
|
expected-all (-> tokens-lib
|
||||||
|
(ctob/set-active-themes #{"/all"})
|
||||||
|
(ctob/sets-at-path-all-active? "G-foo"))
|
||||||
|
expected-partial (-> tokens-lib
|
||||||
|
(ctob/set-active-themes #{"/partial"})
|
||||||
|
(ctob/sets-at-path-all-active? "G-foo"))
|
||||||
|
expected-invalid-none (-> tokens-lib
|
||||||
|
(ctob/set-active-themes #{"/invalid"})
|
||||||
|
(ctob/sets-at-path-all-active? "G-foo"))]
|
||||||
|
(t/is (= :none expected-none))
|
||||||
|
(t/is (= :all expected-all))
|
||||||
|
(t/is (= :partial expected-partial))
|
||||||
|
(t/is (= :none expected-invalid-none)))))
|
||||||
|
|
||||||
(t/deftest token-theme-in-a-lib
|
(t/deftest token-theme-in-a-lib
|
||||||
(t/testing "add-token-theme"
|
(t/testing "add-token-theme"
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
(ns app.main.data.tokens
|
(ns app.main.data.tokens
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.changes-builder :as pcb]
|
[app.common.files.changes-builder :as pcb]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
|
@ -15,11 +14,9 @@
|
||||||
[app.main.data.changes :as dch]
|
[app.main.data.changes :as dch]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.ui.workspace.tokens.token :as wtt]
|
|
||||||
[app.main.ui.workspace.tokens.token-set :as wtts]
|
[app.main.ui.workspace.tokens.token-set :as wtts]
|
||||||
[app.main.ui.workspace.tokens.update :as wtu]
|
[app.main.ui.workspace.tokens.update :as wtu]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[clojure.data :as data]
|
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -51,38 +48,6 @@
|
||||||
;; TOKENS Actions
|
;; TOKENS Actions
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn toggle-or-apply-token
|
|
||||||
"Remove any shape attributes from token if they exists.
|
|
||||||
Othewise apply token attributes."
|
|
||||||
[shape token]
|
|
||||||
(let [[shape-leftover token-leftover _matching] (data/diff (:applied-tokens shape) token)]
|
|
||||||
(merge {} shape-leftover token-leftover)))
|
|
||||||
|
|
||||||
(defn token-from-attributes [token attributes]
|
|
||||||
(->> (map (fn [attr] [attr (wtt/token-identifier token)]) attributes)
|
|
||||||
(into {})))
|
|
||||||
|
|
||||||
(defn unapply-token-id [shape attributes]
|
|
||||||
(update shape :applied-tokens d/without-keys attributes))
|
|
||||||
|
|
||||||
(defn apply-token-to-attributes [{:keys [shape token attributes]}]
|
|
||||||
(let [token (token-from-attributes token attributes)]
|
|
||||||
(toggle-or-apply-token shape token)))
|
|
||||||
|
|
||||||
(defn apply-token-to-shape
|
|
||||||
[{:keys [shape token attributes] :as _props}]
|
|
||||||
(let [applied-tokens (apply-token-to-attributes {:shape shape
|
|
||||||
:token token
|
|
||||||
:attributes attributes})]
|
|
||||||
(update shape :applied-tokens #(merge % applied-tokens))))
|
|
||||||
|
|
||||||
(defn maybe-apply-token-to-shape
|
|
||||||
"When the passed `:token` is non-nil apply it to the `:applied-tokens` on a shape."
|
|
||||||
[{:keys [shape token _attributes] :as props}]
|
|
||||||
(if token
|
|
||||||
(apply-token-to-shape props)
|
|
||||||
shape))
|
|
||||||
|
|
||||||
(defn get-token-data-from-token-id
|
(defn get-token-data-from-token-id
|
||||||
[id]
|
[id]
|
||||||
(let [workspace-data (deref refs/workspace-data)]
|
(let [workspace-data (deref refs/workspace-data)]
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
(assoc-in [:workspace-global :picked-shift?] shift?)))))
|
(assoc-in [:workspace-global :picked-shift?] shift?)))))
|
||||||
|
|
||||||
(defn transform-fill
|
(defn transform-fill
|
||||||
[state ids color transform]
|
[state ids color transform & options]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (wsh/lookup-page-objects state)
|
||||||
|
|
||||||
is-text? #(= :text (:type (get objects %)))
|
is-text? #(= :text (:type (get objects %)))
|
||||||
|
@ -118,8 +118,8 @@
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (dwu/start-undo-transaction undo-id))
|
(rx/of (dwu/start-undo-transaction undo-id))
|
||||||
(rx/from (map #(dwt/update-text-with-function % transform-attrs) text-ids))
|
(rx/from (map #(apply dwt/update-text-with-function % transform-attrs options) text-ids))
|
||||||
(rx/of (dwsh/update-shapes shape-ids transform-attrs))
|
(rx/of (dwsh/update-shapes shape-ids transform-attrs options))
|
||||||
(rx/of (dwu/commit-undo-transaction undo-id)))))
|
(rx/of (dwu/commit-undo-transaction undo-id)))))
|
||||||
|
|
||||||
(defn swap-attrs [shape attr index new-index]
|
(defn swap-attrs [shape attr index new-index]
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
(rx/of (dwsh/update-shapes shape-ids transform-attrs)))))))
|
(rx/of (dwsh/update-shapes shape-ids transform-attrs)))))))
|
||||||
|
|
||||||
(defn change-fill
|
(defn change-fill
|
||||||
[ids color position]
|
[ids color position & options]
|
||||||
(ptk/reify ::change-fill
|
(ptk/reify ::change-fill
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -155,18 +155,18 @@
|
||||||
(cond-> (not (contains? shape :fills))
|
(cond-> (not (contains? shape :fills))
|
||||||
(assoc :fills []))
|
(assoc :fills []))
|
||||||
(assoc-in [:fills position] (into {} attrs))))]
|
(assoc-in [:fills position] (into {} attrs))))]
|
||||||
(transform-fill state ids color change-fn)))))
|
(apply transform-fill state ids color change-fn options)))))
|
||||||
|
|
||||||
(defn change-fill-and-clear
|
(defn change-fill-and-clear
|
||||||
[ids color]
|
[ids color & options]
|
||||||
(ptk/reify ::change-fill-and-clear
|
(ptk/reify ::change-fill-and-clear
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [set (fn [shape attrs] (assoc shape :fills [attrs]))]
|
(let [set (fn [shape attrs] (assoc shape :fills [attrs]))]
|
||||||
(transform-fill state ids color set)))))
|
(apply transform-fill state ids color set options)))))
|
||||||
|
|
||||||
(defn add-fill
|
(defn add-fill
|
||||||
[ids color]
|
[ids color & options]
|
||||||
|
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected a valid color struct"
|
"expected a valid color struct"
|
||||||
|
@ -182,10 +182,10 @@
|
||||||
(let [add (fn [shape attrs]
|
(let [add (fn [shape attrs]
|
||||||
(-> shape
|
(-> shape
|
||||||
(update :fills #(into [attrs] %))))]
|
(update :fills #(into [attrs] %))))]
|
||||||
(transform-fill state ids color add)))))
|
(apply transform-fill state ids color add options)))))
|
||||||
|
|
||||||
(defn remove-fill
|
(defn remove-fill
|
||||||
[ids color position]
|
[ids color position & options]
|
||||||
|
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected a valid color struct"
|
"expected a valid color struct"
|
||||||
|
@ -203,10 +203,10 @@
|
||||||
(mapv second)))
|
(mapv second)))
|
||||||
|
|
||||||
remove (fn [shape _] (update shape :fills remove-fill-by-index position))]
|
remove (fn [shape _] (update shape :fills remove-fill-by-index position))]
|
||||||
(transform-fill state ids color remove)))))
|
(apply transform-fill state ids color remove options)))))
|
||||||
|
|
||||||
(defn remove-all-fills
|
(defn remove-all-fills
|
||||||
[ids color]
|
[ids color & options]
|
||||||
|
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected a valid color struct"
|
"expected a valid color struct"
|
||||||
|
@ -220,7 +220,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [remove-all (fn [shape _] (assoc shape :fills []))]
|
(let [remove-all (fn [shape _] (assoc shape :fills []))]
|
||||||
(transform-fill state ids color remove-all)))))
|
(apply transform-fill state ids color remove-all options)))))
|
||||||
|
|
||||||
(defn change-hide-fill-on-export
|
(defn change-hide-fill-on-export
|
||||||
[ids hide-fill-on-export]
|
[ids hide-fill-on-export]
|
||||||
|
@ -237,7 +237,7 @@
|
||||||
(d/merge shape attrs)
|
(d/merge shape attrs)
|
||||||
shape))))))))
|
shape))))))))
|
||||||
(defn change-stroke
|
(defn change-stroke
|
||||||
[ids attrs index]
|
[ids attrs index & options]
|
||||||
(ptk/reify ::change-stroke
|
(ptk/reify ::change-stroke
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
|
@ -286,7 +286,8 @@
|
||||||
(assoc :strokes [])
|
(assoc :strokes [])
|
||||||
|
|
||||||
:always
|
:always
|
||||||
(assoc-in [:strokes index] new-attrs))))))))))
|
(assoc-in [:strokes index] new-attrs))))
|
||||||
|
options))))))
|
||||||
|
|
||||||
(defn change-shadow
|
(defn change-shadow
|
||||||
[ids attrs index]
|
[ids attrs index]
|
||||||
|
|
|
@ -786,7 +786,6 @@
|
||||||
(rx/map #(reset-component %) (rx/from ids))
|
(rx/map #(reset-component %) (rx/from ids))
|
||||||
(rx/of (dwu/commit-undo-transaction undo-id)))))))
|
(rx/of (dwu/commit-undo-transaction undo-id)))))))
|
||||||
|
|
||||||
|
|
||||||
(defn update-component
|
(defn update-component
|
||||||
"Modify the component linked to the shape with the given id, in the
|
"Modify the component linked to the shape with the given id, in the
|
||||||
current page, so that all attributes of its shapes are equal to the
|
current page, so that all attributes of its shapes are equal to the
|
||||||
|
|
|
@ -465,8 +465,10 @@
|
||||||
([]
|
([]
|
||||||
(apply-modifiers nil))
|
(apply-modifiers nil))
|
||||||
|
|
||||||
([{:keys [modifiers undo-transation? stack-undo? ignore-constraints ignore-snap-pixel undo-group]
|
([{:keys [modifiers undo-transation? stack-undo? ignore-constraints
|
||||||
:or {undo-transation? true stack-undo? false ignore-constraints false ignore-snap-pixel false}}]
|
ignore-snap-pixel ignore-touched undo-group]
|
||||||
|
:or {undo-transation? true stack-undo? false ignore-constraints false
|
||||||
|
ignore-snap-pixel false ignore-touched false}}]
|
||||||
(ptk/reify ::apply-modifiers
|
(ptk/reify ::apply-modifiers
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -515,6 +517,7 @@
|
||||||
{:reg-objects? true
|
{:reg-objects? true
|
||||||
:stack-undo? stack-undo?
|
:stack-undo? stack-undo?
|
||||||
:ignore-tree ignore-tree
|
:ignore-tree ignore-tree
|
||||||
|
:ignore-touched ignore-touched
|
||||||
:undo-group undo-group
|
:undo-group undo-group
|
||||||
;; Attributes that can change in the transform. This way we don't have to check
|
;; Attributes that can change in the transform. This way we don't have to check
|
||||||
;; all the attributes
|
;; all the attributes
|
||||||
|
|
|
@ -260,13 +260,13 @@
|
||||||
(rx/of (with-meta event (meta it)))))))))
|
(rx/of (with-meta event (meta it)))))))))
|
||||||
|
|
||||||
(defn update-layout
|
(defn update-layout
|
||||||
[ids changes]
|
[ids changes & options]
|
||||||
(ptk/reify ::update-layout
|
(ptk/reify ::update-layout
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
(let [undo-id (js/Symbol)]
|
(let [undo-id (js/Symbol)]
|
||||||
(rx/of (dwu/start-undo-transaction undo-id)
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
(dwsh/update-shapes ids (d/patch-object changes))
|
(dwsh/update-shapes ids (d/patch-object changes) options)
|
||||||
(ptk/data-event :layout/update {:ids ids})
|
(ptk/data-event :layout/update {:ids ids})
|
||||||
(dwu/commit-undo-transaction undo-id))))))
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
|
@ -516,7 +516,7 @@
|
||||||
(assoc :layout-item-v-sizing :fix))))
|
(assoc :layout-item-v-sizing :fix))))
|
||||||
|
|
||||||
(defn update-layout-child
|
(defn update-layout-child
|
||||||
[ids changes]
|
[ids changes & options]
|
||||||
(ptk/reify ::update-layout-child
|
(ptk/reify ::update-layout-child
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -525,8 +525,8 @@
|
||||||
parent-ids (->> ids (map #(cfh/get-parent-id objects %)))
|
parent-ids (->> ids (map #(cfh/get-parent-id objects %)))
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
(rx/of (dwu/start-undo-transaction undo-id)
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
(dwsh/update-shapes ids (d/patch-object changes))
|
(dwsh/update-shapes ids (d/patch-object changes) options)
|
||||||
(dwsh/update-shapes children-ids (partial fix-child-sizing objects changes))
|
(dwsh/update-shapes children-ids (partial fix-child-sizing objects changes) options)
|
||||||
(dwsh/update-shapes
|
(dwsh/update-shapes
|
||||||
parent-ids
|
parent-ids
|
||||||
(fn [parent objects]
|
(fn [parent objects]
|
||||||
|
@ -534,7 +534,7 @@
|
||||||
(fix-parent-sizing objects (set ids) changes)
|
(fix-parent-sizing objects (set ids) changes)
|
||||||
(cond-> (ctl/grid-layout? parent)
|
(cond-> (ctl/grid-layout? parent)
|
||||||
(ctl/assign-cells objects))))
|
(ctl/assign-cells objects))))
|
||||||
{:with-objects? true})
|
(merge options {:with-objects? true}))
|
||||||
(ptk/data-event :layout/update {:ids ids})
|
(ptk/data-event :layout/update {:ids ids})
|
||||||
(dwu/commit-undo-transaction undo-id))))))
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
|
|
|
@ -432,7 +432,7 @@
|
||||||
(txt/transform-nodes (some-fn txt/is-text-node? txt/is-paragraph-node?) migrate-node content))
|
(txt/transform-nodes (some-fn txt/is-text-node? txt/is-paragraph-node?) migrate-node content))
|
||||||
|
|
||||||
(defn update-text-with-function
|
(defn update-text-with-function
|
||||||
[id update-node-fn]
|
[id update-node-fn & options]
|
||||||
(ptk/reify ::update-text-with-function
|
(ptk/reify ::update-text-with-function
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
@ -464,7 +464,7 @@
|
||||||
(-> shape
|
(-> shape
|
||||||
(dissoc :fills)
|
(dissoc :fills)
|
||||||
(d/update-when :content update-content)))]
|
(d/update-when :content update-content)))]
|
||||||
(rx/of (dwsh/update-shapes shape-ids update-shape)))))
|
(rx/of (dwsh/update-shapes shape-ids update-shape options)))))
|
||||||
|
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ state _]
|
(effect [_ state _]
|
||||||
|
|
|
@ -301,7 +301,7 @@
|
||||||
(defn update-dimensions
|
(defn update-dimensions
|
||||||
"Change size of shapes, from the sideber options form.
|
"Change size of shapes, from the sideber options form.
|
||||||
Will ignore pixel snap used in the options side panel"
|
Will ignore pixel snap used in the options side panel"
|
||||||
[ids attr value]
|
[ids attr value & options]
|
||||||
(dm/assert! (number? value))
|
(dm/assert! (number? value))
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"expected valid coll of uuids"
|
"expected valid coll of uuids"
|
||||||
|
@ -324,7 +324,7 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
(rx/of (dwm/apply-modifiers)))))
|
(rx/of (dwm/apply-modifiers options)))))
|
||||||
|
|
||||||
(defn change-orientation
|
(defn change-orientation
|
||||||
"Change orientation of shapes, from the sidebar options form.
|
"Change orientation of shapes, from the sidebar options form.
|
||||||
|
@ -402,7 +402,7 @@
|
||||||
"Rotate shapes a fixed angle, from a keyboard action."
|
"Rotate shapes a fixed angle, from a keyboard action."
|
||||||
([ids rotation]
|
([ids rotation]
|
||||||
(increase-rotation ids rotation nil))
|
(increase-rotation ids rotation nil))
|
||||||
([ids rotation params]
|
([ids rotation params & options]
|
||||||
(ptk/reify ::increase-rotation
|
(ptk/reify ::increase-rotation
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -411,7 +411,7 @@
|
||||||
shapes (->> ids (map #(get objects %)))]
|
shapes (->> ids (map #(get objects %)))]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (dwm/set-delta-rotation-modifiers rotation shapes params))
|
(rx/of (dwm/set-delta-rotation-modifiers rotation shapes params))
|
||||||
(rx/of (dwm/apply-modifiers))))))))
|
(rx/of (dwm/apply-modifiers options))))))))
|
||||||
|
|
||||||
|
|
||||||
;; -- Move ----------------------------------------------------------
|
;; -- Move ----------------------------------------------------------
|
||||||
|
|
|
@ -502,6 +502,14 @@
|
||||||
(def workspace-active-theme-paths
|
(def workspace-active-theme-paths
|
||||||
(l/derived (d/nilf ctob/get-active-theme-paths) tokens-lib))
|
(l/derived (d/nilf ctob/get-active-theme-paths) tokens-lib))
|
||||||
|
|
||||||
|
(defn token-sets-at-path-all-active?
|
||||||
|
[prefixed-path]
|
||||||
|
(l/derived
|
||||||
|
(fn [lib]
|
||||||
|
(when lib
|
||||||
|
(ctob/sets-at-path-all-active? lib prefixed-path)))
|
||||||
|
tokens-lib))
|
||||||
|
|
||||||
(def workspace-active-theme-paths-no-hidden
|
(def workspace-active-theme-paths-no-hidden
|
||||||
(l/derived #(disj % ctob/hidden-token-theme-path) workspace-active-theme-paths))
|
(l/derived #(disj % ctob/hidden-token-theme-path) workspace-active-theme-paths))
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.types.shape.radius :as ctsr]
|
[app.common.types.shape.radius :as ctsr]
|
||||||
|
[app.common.types.token :as cto]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.main.constants :refer [size-presets]]
|
[app.main.constants :refer [size-presets]]
|
||||||
[app.main.data.tokens :as dt]
|
|
||||||
[app.main.data.workspace :as udw]
|
[app.main.data.workspace :as udw]
|
||||||
[app.main.data.workspace.interactions :as dwi]
|
[app.main.data.workspace.interactions :as dwi]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
|
@ -342,7 +342,7 @@
|
||||||
(let [token-value (wtc/maybe-resolve-token-value token)]
|
(let [token-value (wtc/maybe-resolve-token-value token)]
|
||||||
(st/emit!
|
(st/emit!
|
||||||
(change-radius (fn [shape]
|
(change-radius (fn [shape]
|
||||||
(-> (dt/unapply-token-id shape (wtty/token-attributes :border-radius))
|
(-> (cto/unapply-token-id shape (wtty/token-attributes :border-radius))
|
||||||
(ctsr/set-radius-1 token-value))))))))
|
(ctsr/set-radius-1 token-value))))))))
|
||||||
|
|
||||||
on-radius-1-change
|
on-radius-1-change
|
||||||
|
@ -352,9 +352,9 @@
|
||||||
(let [token-value (wtc/maybe-resolve-token-value value)]
|
(let [token-value (wtc/maybe-resolve-token-value value)]
|
||||||
(st/emit!
|
(st/emit!
|
||||||
(change-radius (fn [shape]
|
(change-radius (fn [shape]
|
||||||
(-> (dt/maybe-apply-token-to-shape {:token (when token-value value)
|
(-> (cto/maybe-apply-token-to-shape {:token (when token-value value)
|
||||||
:shape shape
|
:shape shape
|
||||||
:attributes (wtty/token-attributes :border-radius)})
|
:attributes (wtty/token-attributes :border-radius)})
|
||||||
(ctsr/set-radius-1 (or token-value value)))))))))
|
(ctsr/set-radius-1 (or token-value value)))))))))
|
||||||
|
|
||||||
on-radius-multi-change
|
on-radius-multi-change
|
||||||
|
|
|
@ -95,20 +95,9 @@
|
||||||
(when (ctsr/has-radius? shape)
|
(when (ctsr/has-radius? shape)
|
||||||
(ctsr/set-radius-1 shape value)))
|
(ctsr/set-radius-1 shape value)))
|
||||||
{:reg-objects? true
|
{:reg-objects? true
|
||||||
|
:ignore-touched true
|
||||||
:attrs ctt/border-radius-keys}))
|
:attrs ctt/border-radius-keys}))
|
||||||
|
|
||||||
(defn update-opacity [value shape-ids]
|
|
||||||
(when (<= 0 value 1)
|
|
||||||
(dwsh/update-shapes shape-ids #(assoc % :opacity value))))
|
|
||||||
|
|
||||||
(defn update-rotation [value shape-ids]
|
|
||||||
(ptk/reify ::update-shape-rotation
|
|
||||||
ptk/WatchEvent
|
|
||||||
(watch [_ _ _]
|
|
||||||
(rx/of
|
|
||||||
(udw/trigger-bounding-box-cloaking shape-ids)
|
|
||||||
(udw/increase-rotation shape-ids value)))))
|
|
||||||
|
|
||||||
(defn update-shape-radius-single-corner [value shape-ids attributes]
|
(defn update-shape-radius-single-corner [value shape-ids attributes]
|
||||||
(dwsh/update-shapes shape-ids
|
(dwsh/update-shapes shape-ids
|
||||||
(fn [shape]
|
(fn [shape]
|
||||||
|
@ -117,8 +106,23 @@
|
||||||
(:rx shape) (ctsr/switch-to-radius-4)
|
(:rx shape) (ctsr/switch-to-radius-4)
|
||||||
:always (ctsr/set-radius-4 (first attributes) value))))
|
:always (ctsr/set-radius-4 (first attributes) value))))
|
||||||
{:reg-objects? true
|
{:reg-objects? true
|
||||||
|
:ignore-touched true
|
||||||
:attrs [:rx :ry :r1 :r2 :r3 :r4]}))
|
:attrs [:rx :ry :r1 :r2 :r3 :r4]}))
|
||||||
|
|
||||||
|
(defn update-opacity [value shape-ids]
|
||||||
|
(when (<= 0 value 1)
|
||||||
|
(dwsh/update-shapes shape-ids
|
||||||
|
#(assoc % :opacity value)
|
||||||
|
{:ignore-touched true})))
|
||||||
|
|
||||||
|
(defn update-rotation [value shape-ids]
|
||||||
|
(ptk/reify ::update-shape-rotation
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ _ _]
|
||||||
|
(rx/of
|
||||||
|
(udw/trigger-bounding-box-cloaking shape-ids)
|
||||||
|
(udw/increase-rotation shape-ids value nil :ignore-touched true)))))
|
||||||
|
|
||||||
(defn update-stroke-width
|
(defn update-stroke-width
|
||||||
[value shape-ids]
|
[value shape-ids]
|
||||||
(dwsh/update-shapes shape-ids
|
(dwsh/update-shapes shape-ids
|
||||||
|
@ -126,6 +130,7 @@
|
||||||
(when (seq (:strokes shape))
|
(when (seq (:strokes shape))
|
||||||
(assoc-in shape [:strokes 0 :stroke-width] value)))
|
(assoc-in shape [:strokes 0 :stroke-width] value)))
|
||||||
{:reg-objects? true
|
{:reg-objects? true
|
||||||
|
:ignore-touched true
|
||||||
:attrs [:strokes]}))
|
:attrs [:strokes]}))
|
||||||
|
|
||||||
(defn update-color [f value shape-ids]
|
(defn update-color [f value shape-ids]
|
||||||
|
@ -133,7 +138,7 @@
|
||||||
(tinycolor/valid-color)
|
(tinycolor/valid-color)
|
||||||
(tinycolor/->hex)
|
(tinycolor/->hex)
|
||||||
(str "#"))]
|
(str "#"))]
|
||||||
(f shape-ids {:color color} 0)))
|
(apply f shape-ids {:color color} 0 [:ignore-touched true])))
|
||||||
|
|
||||||
(defn update-fill
|
(defn update-fill
|
||||||
[value shape-ids]
|
[value shape-ids]
|
||||||
|
@ -156,8 +161,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
(rx/of
|
(rx/of
|
||||||
(when (:width attributes) (dwt/update-dimensions shape-ids :width value))
|
(when (:width attributes) (dwt/update-dimensions shape-ids :width value :ignore-touched true))
|
||||||
(when (:height attributes) (dwt/update-dimensions shape-ids :height value))))))
|
(when (:height attributes) (dwt/update-dimensions shape-ids :height value :ignore-touched true))))))
|
||||||
|
|
||||||
(defn- attributes->layout-gap [attributes value]
|
(defn- attributes->layout-gap [attributes value]
|
||||||
(let [layout-gap (-> (set/intersection attributes #{:column-gap :row-gap})
|
(let [layout-gap (-> (set/intersection attributes #{:column-gap :row-gap})
|
||||||
|
@ -165,7 +170,9 @@
|
||||||
{:layout-gap layout-gap}))
|
{:layout-gap layout-gap}))
|
||||||
|
|
||||||
(defn update-layout-padding [value shape-ids attrs]
|
(defn update-layout-padding [value shape-ids attrs]
|
||||||
(dwsl/update-layout shape-ids {:layout-padding (zipmap attrs (repeat value))}))
|
(dwsl/update-layout shape-ids
|
||||||
|
{:layout-padding (zipmap attrs (repeat value))}
|
||||||
|
:ignore-touched true))
|
||||||
|
|
||||||
(defn update-layout-spacing [value shape-ids attributes]
|
(defn update-layout-spacing [value shape-ids attributes]
|
||||||
(ptk/reify ::update-layout-spacing
|
(ptk/reify ::update-layout-spacing
|
||||||
|
@ -177,7 +184,9 @@
|
||||||
(map :id)))
|
(map :id)))
|
||||||
layout-attributes (attributes->layout-gap attributes value)]
|
layout-attributes (attributes->layout-gap attributes value)]
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwsl/update-layout layout-shape-ids layout-attributes))))))
|
(dwsl/update-layout layout-shape-ids
|
||||||
|
layout-attributes
|
||||||
|
:ignore-touched true))))))
|
||||||
|
|
||||||
(defn update-shape-position [value shape-ids attributes]
|
(defn update-shape-position [value shape-ids attributes]
|
||||||
(ptk/reify ::update-shape-position
|
(ptk/reify ::update-shape-position
|
||||||
|
@ -195,4 +204,4 @@
|
||||||
:layout-item-max-w value
|
:layout-item-max-w value
|
||||||
:layout-item-max-h value}
|
:layout-item-max-h value}
|
||||||
(select-keys attributes))]
|
(select-keys attributes))]
|
||||||
(dwsl/update-layout-child shape-ids props)))))
|
(dwsl/update-layout-child shape-ids props :ignore-touched true)))))
|
||||||
|
|
|
@ -254,41 +254,41 @@
|
||||||
[{:keys [state set-state]}]
|
[{:keys [state set-state]}]
|
||||||
(let [{:keys [theme-path]} @state
|
(let [{:keys [theme-path]} @state
|
||||||
[_ theme-group theme-name] theme-path
|
[_ theme-group theme-name] theme-path
|
||||||
|
ordered-token-sets (mf/deref refs/workspace-ordered-token-sets)
|
||||||
token-sets (mf/deref refs/workspace-token-sets-tree)
|
token-sets (mf/deref refs/workspace-token-sets-tree)
|
||||||
theme (mf/deref (refs/workspace-token-theme theme-group theme-name))
|
theme (mf/deref (refs/workspace-token-theme theme-group theme-name))
|
||||||
|
theme-state (mf/use-state theme)
|
||||||
|
lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-theme @theme-state)
|
||||||
|
(ctob/add-sets ordered-token-sets)
|
||||||
|
(ctob/activate-theme (:group @theme-state) (:name @theme-state)))
|
||||||
|
|
||||||
|
;; Form / Modal handlers
|
||||||
on-back #(set-state (constantly {:type :themes-overview}))
|
on-back #(set-state (constantly {:type :themes-overview}))
|
||||||
on-submit #(st/emit! (wdt/update-token-theme [(:group theme) (:name theme)] %))
|
on-submit #(st/emit! (wdt/update-token-theme [(:group theme) (:name theme)] %))
|
||||||
{:keys [dropdown-open? _on-open-dropdown on-close-dropdown on-toggle-dropdown]} (wtco/use-dropdown-open-state)
|
{:keys [dropdown-open? _on-open-dropdown on-close-dropdown on-toggle-dropdown]} (wtco/use-dropdown-open-state)
|
||||||
theme-state (mf/use-state theme)
|
|
||||||
disabled? (-> (:name @theme-state)
|
disabled? (-> (:name @theme-state)
|
||||||
(str/trim)
|
(str/trim)
|
||||||
(str/empty?))
|
(str/empty?))
|
||||||
token-set-active? (mf/use-callback
|
|
||||||
(mf/deps theme-state)
|
on-change-field
|
||||||
(fn [set-name]
|
(mf/use-fn
|
||||||
(get-in @theme-state [:sets set-name])))
|
(fn [field value]
|
||||||
on-toggle-token-set (mf/use-callback
|
(swap! theme-state #(assoc % field value))))
|
||||||
(mf/deps theme-state)
|
|
||||||
(fn [set-name]
|
on-save-form
|
||||||
(swap! theme-state #(ctob/toggle-set % set-name))))
|
(mf/use-callback
|
||||||
on-click-token-set (mf/use-callback
|
(mf/deps theme-state on-submit)
|
||||||
(mf/deps on-toggle-token-set)
|
(fn [e]
|
||||||
(fn [prefixed-set-path-str]
|
(dom/prevent-default e)
|
||||||
(let [set-name (ctob/prefixed-set-path-string->set-name-string prefixed-set-path-str)]
|
(let [theme (-> @theme-state
|
||||||
(on-toggle-token-set set-name))))
|
(update :name str/trim)
|
||||||
on-change-field (fn [field value]
|
(update :group str/trim)
|
||||||
(swap! theme-state #(assoc % field value)))
|
(update :description str/trim))]
|
||||||
on-save-form (mf/use-callback
|
(when-not (str/empty? (:name theme))
|
||||||
(mf/deps theme-state on-submit)
|
(on-submit theme)))
|
||||||
(fn [e]
|
(on-back)))
|
||||||
(dom/prevent-default e)
|
|
||||||
(let [theme (-> @theme-state
|
|
||||||
(update :name str/trim)
|
|
||||||
(update :group str/trim)
|
|
||||||
(update :description str/trim))]
|
|
||||||
(when-not (str/empty? (:name theme))
|
|
||||||
(on-submit theme)))
|
|
||||||
(on-back)))
|
|
||||||
close-modal
|
close-modal
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [e]
|
(fn [e]
|
||||||
|
@ -300,7 +300,33 @@
|
||||||
(mf/deps theme on-back)
|
(mf/deps theme on-back)
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (wdt/delete-token-theme (:group theme) (:name theme)))
|
(st/emit! (wdt/delete-token-theme (:group theme) (:name theme)))
|
||||||
(on-back)))]
|
(on-back)))
|
||||||
|
|
||||||
|
;; Sets tree handlers
|
||||||
|
token-set-group-active?
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps theme-state)
|
||||||
|
(fn [prefixed-path]
|
||||||
|
(ctob/sets-at-path-all-active? lib prefixed-path)))
|
||||||
|
|
||||||
|
token-set-active?
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps theme-state)
|
||||||
|
(fn [set-name]
|
||||||
|
(get-in @theme-state [:sets set-name])))
|
||||||
|
|
||||||
|
on-toggle-token-set
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps theme-state)
|
||||||
|
(fn [set-name]
|
||||||
|
(swap! theme-state #(ctob/toggle-set % set-name))))
|
||||||
|
|
||||||
|
on-click-token-set
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps on-toggle-token-set)
|
||||||
|
(fn [prefixed-set-path-str]
|
||||||
|
(let [set-name (ctob/prefixed-set-path-string->set-name-string prefixed-set-path-str)]
|
||||||
|
(on-toggle-token-set set-name))))]
|
||||||
|
|
||||||
[:div {:class (stl/css :themes-modal-wrapper)}
|
[:div {:class (stl/css :themes-modal-wrapper)}
|
||||||
[:> heading* {:level 2 :typography "headline-medium" :class (stl/css :themes-modal-title)}
|
[:> heading* {:level 2 :typography "headline-medium" :class (stl/css :themes-modal-title)}
|
||||||
|
@ -327,6 +353,7 @@
|
||||||
{:token-sets token-sets
|
{:token-sets token-sets
|
||||||
:token-set-selected? (constantly false)
|
:token-set-selected? (constantly false)
|
||||||
:token-set-active? token-set-active?
|
:token-set-active? token-set-active?
|
||||||
|
:token-set-group-active? token-set-group-active?
|
||||||
:on-select on-click-token-set
|
:on-select on-click-token-set
|
||||||
:on-toggle-token-set on-toggle-token-set
|
:on-toggle-token-set on-toggle-token-set
|
||||||
:origin "theme-modal"
|
:origin "theme-modal"
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns app.main.ui.workspace.tokens.sets
|
(ns app.main.ui.workspace.tokens.sets
|
||||||
(:require-macros [app.main.style :as stl])
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.main.data.tokens :as wdt]
|
[app.main.data.tokens :as wdt]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
|
@ -68,9 +69,28 @@
|
||||||
:auto-focus true
|
:auto-focus true
|
||||||
:default-value default-value}]))
|
:default-value default-value}]))
|
||||||
|
|
||||||
|
(mf/defc checkbox
|
||||||
|
[{:keys [checked aria-label on-click]}]
|
||||||
|
(let [all? (true? checked)
|
||||||
|
mixed? (= checked "mixed")
|
||||||
|
checked? (or all? mixed?)]
|
||||||
|
[:div {:role "checkbox"
|
||||||
|
:aria-checked (dm/str checked)
|
||||||
|
:tabindex 0
|
||||||
|
:class (stl/css-case :checkbox-style true
|
||||||
|
:checkbox-checked-style checked?)
|
||||||
|
:on-click on-click}
|
||||||
|
(when checked?
|
||||||
|
[:> icon*
|
||||||
|
{:aria-label aria-label
|
||||||
|
:class (stl/css :check-icon)
|
||||||
|
:size "s"
|
||||||
|
:id (if mixed? ic/remove ic/tick)}])]))
|
||||||
|
|
||||||
(mf/defc sets-tree-set-group
|
(mf/defc sets-tree-set-group
|
||||||
[{:keys [label tree-depth tree-path selected? collapsed? editing? on-edit on-edit-reset on-edit-submit]}]
|
[{:keys [label tree-depth tree-path active? selected? collapsed? editing? on-edit on-edit-reset on-edit-submit]}]
|
||||||
(let [editing?' (editing? tree-path)
|
(let [editing?' (editing? tree-path)
|
||||||
|
active?' (active? tree-path)
|
||||||
on-context-menu
|
on-context-menu
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps editing? tree-path)
|
(mf/deps editing? tree-path)
|
||||||
|
@ -114,9 +134,16 @@
|
||||||
:on-cancel on-edit-reset
|
:on-cancel on-edit-reset
|
||||||
:on-create on-edit-reset
|
:on-create on-edit-reset
|
||||||
:on-submit on-edit-submit'}]
|
:on-submit on-edit-submit'}]
|
||||||
[:div {:class (stl/css :set-name)
|
[:*
|
||||||
:on-double-click on-double-click}
|
[:div {:class (stl/css :set-name)
|
||||||
label])]))
|
:on-double-click on-double-click}
|
||||||
|
label]
|
||||||
|
[:& checkbox
|
||||||
|
{:checked (case active?'
|
||||||
|
:all true
|
||||||
|
:partial "mixed"
|
||||||
|
:none false)
|
||||||
|
:arial-label (tr "workspace.token.select-set")}]])]))
|
||||||
|
|
||||||
(mf/defc sets-tree-set
|
(mf/defc sets-tree-set
|
||||||
[{:keys [set label tree-depth tree-path selected? on-select active? on-toggle editing? on-edit on-edit-reset on-edit-submit]}]
|
[{:keys [set label tree-depth tree-path selected? on-select active? on-toggle editing? on-edit on-edit-reset on-edit-submit]}]
|
||||||
|
@ -173,18 +200,14 @@
|
||||||
[:div {:class (stl/css :set-name)
|
[:div {:class (stl/css :set-name)
|
||||||
:on-double-click on-double-click}
|
:on-double-click on-double-click}
|
||||||
label]
|
label]
|
||||||
[:button {:type "button"
|
[:& checkbox
|
||||||
:on-click on-checkbox-click
|
{:on-click on-checkbox-click
|
||||||
:class (stl/css-case :checkbox-style true
|
:arial-label (tr "workspace.token.select-set")
|
||||||
:checkbox-checked-style active?')}
|
:checked active?'}]])]))
|
||||||
(when active?'
|
|
||||||
[:> icon* {:aria-label (tr "workspace.token.select-set")
|
|
||||||
:class (stl/css :check-icon)
|
|
||||||
:size "s"
|
|
||||||
:id ic/tick}])]])]))
|
|
||||||
|
|
||||||
(mf/defc sets-tree
|
(mf/defc sets-tree
|
||||||
[{:keys [active?
|
[{:keys [active?
|
||||||
|
group-active?
|
||||||
editing?
|
editing?
|
||||||
on-edit
|
on-edit
|
||||||
on-edit-reset
|
on-edit-reset
|
||||||
|
@ -227,6 +250,7 @@
|
||||||
set-group?
|
set-group?
|
||||||
[:& sets-tree-set-group
|
[:& sets-tree-set-group
|
||||||
{:selected? (selected? tree-path)
|
{:selected? (selected? tree-path)
|
||||||
|
:active? group-active?
|
||||||
:on-select on-select
|
:on-select on-select
|
||||||
:label set-fname
|
:label set-fname
|
||||||
:collapsed? collapsed?
|
:collapsed? collapsed?
|
||||||
|
@ -249,6 +273,7 @@
|
||||||
:selected? selected?
|
:selected? selected?
|
||||||
:on-toggle on-toggle
|
:on-toggle on-toggle
|
||||||
:active? active?
|
:active? active?
|
||||||
|
:group-active? group-active?
|
||||||
:editing? editing?
|
:editing? editing?
|
||||||
:on-edit on-edit
|
:on-edit on-edit
|
||||||
:on-edit-reset on-edit-reset
|
:on-edit-reset on-edit-reset
|
||||||
|
@ -261,6 +286,7 @@
|
||||||
on-update-token-set-group
|
on-update-token-set-group
|
||||||
token-set-selected?
|
token-set-selected?
|
||||||
token-set-active?
|
token-set-active?
|
||||||
|
token-set-group-active?
|
||||||
on-create-token-set
|
on-create-token-set
|
||||||
on-toggle-token-set
|
on-toggle-token-set
|
||||||
origin
|
origin
|
||||||
|
@ -268,10 +294,9 @@
|
||||||
context]
|
context]
|
||||||
:as _props}]
|
:as _props}]
|
||||||
(let [{:keys [editing? new? on-edit on-reset] :as ctx} (or context (sets-context/use-context))]
|
(let [{:keys [editing? new? on-edit on-reset] :as ctx} (or context (sets-context/use-context))]
|
||||||
[:ul {:class (stl/css :sets-list)}
|
[:fieldset {:class (stl/css :sets-list)}
|
||||||
(if (and
|
(if (and (= origin "theme-modal")
|
||||||
(= origin "theme-modal")
|
(empty? token-sets))
|
||||||
(empty? token-sets))
|
|
||||||
[:> text* {:as "span" :typography "body-small" :class (stl/css :empty-state-message-sets)}
|
[:> text* {:as "span" :typography "body-small" :class (stl/css :empty-state-message-sets)}
|
||||||
(tr "workspace.token.no-sets-create")]
|
(tr "workspace.token.no-sets-create")]
|
||||||
(if (and (= origin "theme-modal")
|
(if (and (= origin "theme-modal")
|
||||||
|
@ -284,6 +309,7 @@
|
||||||
:selected? token-set-selected?
|
:selected? token-set-selected?
|
||||||
:on-select on-select
|
:on-select on-select
|
||||||
:active? token-set-active?
|
:active? token-set-active?
|
||||||
|
:group-active? token-set-group-active?
|
||||||
:on-toggle on-toggle-token-set
|
:on-toggle on-toggle-token-set
|
||||||
:editing? editing?
|
:editing? editing?
|
||||||
:on-edit on-edit
|
:on-edit on-edit
|
||||||
|
@ -314,11 +340,15 @@
|
||||||
token-set-active? (mf/use-fn
|
token-set-active? (mf/use-fn
|
||||||
(mf/deps active-token-set-names)
|
(mf/deps active-token-set-names)
|
||||||
(fn [set-name]
|
(fn [set-name]
|
||||||
(get active-token-set-names set-name)))]
|
(get active-token-set-names set-name)))
|
||||||
|
token-set-group-active? (mf/use-fn
|
||||||
|
(fn [prefixed-path]
|
||||||
|
@(refs/token-sets-at-path-all-active? prefixed-path)))]
|
||||||
[:& controlled-sets-list
|
[:& controlled-sets-list
|
||||||
{:token-sets token-sets
|
{:token-sets token-sets
|
||||||
:token-set-selected? token-set-selected?
|
:token-set-selected? token-set-selected?
|
||||||
:token-set-active? token-set-active?
|
:token-set-active? token-set-active?
|
||||||
|
:token-set-group-active? token-set-group-active?
|
||||||
:on-select on-select-token-set-click
|
:on-select on-select-token-set-click
|
||||||
:origin "set-panel"
|
:origin "set-panel"
|
||||||
:on-toggle-token-set on-toggle-token-set-click
|
:on-toggle-token-set on-toggle-token-set-click
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.types.token :as ctt]
|
[app.common.types.token :as ctt]
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.refs :as refs]
|
|
||||||
[app.main.ui.workspace.tokens.changes :as wtch]
|
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||||
[app.main.ui.workspace.tokens.style-dictionary :as wtsd]
|
[app.main.ui.workspace.tokens.style-dictionary :as wtsd]
|
||||||
[app.main.ui.workspace.tokens.token-set :as wtts]
|
[app.main.ui.workspace.tokens.token-set :as wtts]
|
||||||
|
@ -112,8 +112,8 @@
|
||||||
update-infos)))
|
update-infos)))
|
||||||
shapes-update-info))
|
shapes-update-info))
|
||||||
|
|
||||||
(defn update-tokens [resolved-tokens]
|
(defn update-tokens [state resolved-tokens]
|
||||||
(->> @refs/workspace-page-objects
|
(->> (wsh/lookup-page-objects state)
|
||||||
(collect-shapes-update-info resolved-tokens)
|
(collect-shapes-update-info resolved-tokens)
|
||||||
(actionize-shapes-update-info)))
|
(actionize-shapes-update-info)))
|
||||||
|
|
||||||
|
@ -131,5 +131,5 @@
|
||||||
(let [undo-id (js/Symbol)]
|
(let [undo-id (js/Symbol)]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (dwu/start-undo-transaction undo-id))
|
(rx/of (dwu/start-undo-transaction undo-id))
|
||||||
(update-tokens sd-tokens)
|
(update-tokens state sd-tokens)
|
||||||
(rx/of (dwu/commit-undo-transaction undo-id))))))))))
|
(rx/of (dwu/commit-undo-transaction undo-id))))))))))
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
(fn [cause]
|
(fn [cause]
|
||||||
(js/console.log "[error]:" cause))
|
(js/console.log "[error]:" cause))
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(js/console.log "[complete]"))))
|
#_(js/console.debug "[complete]"))))
|
||||||
|
|
||||||
(doseq [event events]
|
(doseq [event events]
|
||||||
(ptk/emit! store event))
|
(ptk/emit! store event))
|
||||||
|
|
397
frontend/test/frontend_tests/logic/components_and_tokens.cljs
Normal file
397
frontend/test/frontend_tests/logic/components_and_tokens.cljs
Normal file
|
@ -0,0 +1,397 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
(ns frontend-tests.logic.components-and-tokens
|
||||||
|
(:require
|
||||||
|
[app.common.geom.point :as geom]
|
||||||
|
[app.common.math :as mth]
|
||||||
|
[app.common.test-helpers.components :as cthc]
|
||||||
|
[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.tokens-lib :as ctob]
|
||||||
|
[app.main.data.tokens :as dt]
|
||||||
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
|
[app.main.data.workspace.selection :as dws]
|
||||||
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
|
[app.main.ui.workspace.tokens.changes :as wtch]
|
||||||
|
[app.main.ui.workspace.tokens.update :as wtu]
|
||||||
|
[cljs.test :as t :include-macros true]
|
||||||
|
[frontend-tests.helpers.pages :as thp]
|
||||||
|
[frontend-tests.helpers.state :as ths]
|
||||||
|
[frontend-tests.tokens.helpers.state :as tohs]
|
||||||
|
[frontend-tests.tokens.helpers.tokens :as toht]))
|
||||||
|
|
||||||
|
(t/use-fixtures :each
|
||||||
|
{:before thp/reset-idmap!})
|
||||||
|
|
||||||
|
(defn- setup-base-file
|
||||||
|
[]
|
||||||
|
(-> (cthf/sample-file :file1)
|
||||||
|
(ctht/add-tokens-lib)
|
||||||
|
(ctht/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-in-set "test-token-set"
|
||||||
|
(ctob/make-token :name "test-token-1"
|
||||||
|
:type :border-radius
|
||||||
|
:value 25))
|
||||||
|
(ctob/add-token-in-set "test-token-set"
|
||||||
|
(ctob/make-token :name "test-token-2"
|
||||||
|
:type :border-radius
|
||||||
|
:value 50))
|
||||||
|
(ctob/add-token-in-set "test-token-set"
|
||||||
|
(ctob/make-token :name "test-token-3"
|
||||||
|
:type :border-radius
|
||||||
|
:value 75))))
|
||||||
|
(ctho/add-frame :frame1)
|
||||||
|
(ctht/apply-token-to-shape :frame1 "test-token-1" [:rx :ry] [:rx :ry] 25)))
|
||||||
|
|
||||||
|
(defn- setup-file-with-main
|
||||||
|
[]
|
||||||
|
(-> (setup-base-file)
|
||||||
|
(cthc/make-component :component1 :frame1)))
|
||||||
|
|
||||||
|
(defn- setup-file-with-copy
|
||||||
|
[]
|
||||||
|
(-> (setup-file-with-main)
|
||||||
|
(cthc/instantiate-component :component1 :c-frame1)))
|
||||||
|
|
||||||
|
(t/deftest create-component-with-token
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (setup-base-file)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
events
|
||||||
|
[(dws/select-shape (cthi/id :frame1))
|
||||||
|
(dwl/add-component)]]
|
||||||
|
|
||||||
|
(ths/run-store
|
||||||
|
store done events
|
||||||
|
(fn [new-state]
|
||||||
|
(let [;; ==== Get
|
||||||
|
file' (ths/get-file-from-store new-state)
|
||||||
|
frame1' (cths/get-shape file' :frame1)
|
||||||
|
tokens-frame1' (:applied-tokens frame1')]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
(t/is (= (count tokens-frame1') 2))
|
||||||
|
(t/is (= (get tokens-frame1' :rx) "test-token-1"))
|
||||||
|
(t/is (= (get tokens-frame1' :ry) "test-token-1"))
|
||||||
|
(t/is (= (get frame1' :rx) 25))
|
||||||
|
(t/is (= (get frame1' :ry) 25))))))))
|
||||||
|
|
||||||
|
(t/deftest create-copy-with-token
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (setup-file-with-main)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
events
|
||||||
|
[(dwl/instantiate-component (:id file)
|
||||||
|
(cthi/id :component1)
|
||||||
|
(geom/point 0 0))]]
|
||||||
|
|
||||||
|
(ths/run-store
|
||||||
|
store done events
|
||||||
|
(fn [new-state]
|
||||||
|
(let [;; ==== Get
|
||||||
|
selected (wsh/lookup-selected new-state)
|
||||||
|
c-frame1' (wsh/lookup-shape new-state (first selected))
|
||||||
|
tokens-frame1' (:applied-tokens c-frame1')]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
(t/is (= (count tokens-frame1') 2))
|
||||||
|
(t/is (= (get tokens-frame1' :rx) "test-token-1"))
|
||||||
|
(t/is (= (get tokens-frame1' :ry) "test-token-1"))
|
||||||
|
(t/is (= (get c-frame1' :rx) 25))
|
||||||
|
(t/is (= (get c-frame1' :ry) 25))))))))
|
||||||
|
|
||||||
|
(t/deftest change-token-in-main
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (setup-file-with-copy)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
events [(wtch/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||||
|
:attributes #{:rx :ry}
|
||||||
|
:token (toht/get-token file "test-token-2")
|
||||||
|
:on-update-shape wtch/update-shape-radius-all})]
|
||||||
|
|
||||||
|
step2 (fn [_]
|
||||||
|
(let [events2 [(dwl/sync-file (:id file) (:id file))]]
|
||||||
|
(ths/run-store
|
||||||
|
store done events2
|
||||||
|
(fn [new-state]
|
||||||
|
(let [;; ==== Get
|
||||||
|
file' (ths/get-file-from-store new-state)
|
||||||
|
c-frame1' (cths/get-shape file' :c-frame1)
|
||||||
|
tokens-frame1' (:applied-tokens c-frame1')]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
(t/is (= (count tokens-frame1') 2))
|
||||||
|
(t/is (= (get tokens-frame1' :rx) "test-token-2"))
|
||||||
|
(t/is (= (get tokens-frame1' :ry) "test-token-2"))
|
||||||
|
(t/is (= (get c-frame1' :rx) 50))
|
||||||
|
(t/is (= (get c-frame1' :ry) 50)))))))]
|
||||||
|
|
||||||
|
(tohs/run-store-async
|
||||||
|
store step2 events identity))))
|
||||||
|
|
||||||
|
(t/deftest remove-token-in-main
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (setup-file-with-copy)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
events [(wtch/unapply-token {:shape-ids [(cthi/id :frame1)]
|
||||||
|
:attributes #{:rx :ry}
|
||||||
|
:token (toht/get-token file "test-token-1")})]
|
||||||
|
|
||||||
|
step2 (fn [_]
|
||||||
|
(let [events2 [(dwl/sync-file (:id file) (:id file))]]
|
||||||
|
(ths/run-store
|
||||||
|
store done events2
|
||||||
|
(fn [new-state]
|
||||||
|
(let [;; ==== Get
|
||||||
|
file' (ths/get-file-from-store new-state)
|
||||||
|
c-frame1' (cths/get-shape file' :c-frame1)
|
||||||
|
tokens-frame1' (:applied-tokens c-frame1')]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
(t/is (= (count tokens-frame1') 0))
|
||||||
|
(t/is (= (get c-frame1' :rx) 25))
|
||||||
|
(t/is (= (get c-frame1' :ry) 25)))))))]
|
||||||
|
|
||||||
|
(tohs/run-store-async
|
||||||
|
store step2 events identity))))
|
||||||
|
|
||||||
|
(t/deftest modify-token
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (setup-file-with-copy)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
events [(dt/update-create-token {:token (ctob/make-token :name "test-token-1"
|
||||||
|
:type :border-radius
|
||||||
|
:value 66)
|
||||||
|
:prev-token-name "test-token-1"})]
|
||||||
|
|
||||||
|
step2 (fn [_]
|
||||||
|
(let [events2 [(wtu/update-workspace-tokens)
|
||||||
|
(dwl/sync-file (:id file) (:id file))]]
|
||||||
|
(tohs/run-store-async
|
||||||
|
store done events2
|
||||||
|
(fn [new-state]
|
||||||
|
(let [;; ==== Get
|
||||||
|
file' (ths/get-file-from-store new-state)
|
||||||
|
c-frame1' (cths/get-shape file' :c-frame1)
|
||||||
|
tokens-frame1' (:applied-tokens c-frame1')]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
(t/is (= (count tokens-frame1') 2))
|
||||||
|
(t/is (= (get tokens-frame1' :rx) "test-token-1"))
|
||||||
|
(t/is (= (get tokens-frame1' :ry) "test-token-1"))
|
||||||
|
(t/is (= (get c-frame1' :rx) 66))
|
||||||
|
(t/is (= (get c-frame1' :ry) 66)))))))]
|
||||||
|
|
||||||
|
(tohs/run-store-async
|
||||||
|
store step2 events identity))))
|
||||||
|
|
||||||
|
(t/deftest change-token-in-copy-then-change-main
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (setup-file-with-copy)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
events [(wtch/apply-token {:shape-ids [(cthi/id :c-frame1)]
|
||||||
|
:attributes #{:rx :ry}
|
||||||
|
:token (toht/get-token file "test-token-2")
|
||||||
|
:on-update-shape wtch/update-shape-radius-all})
|
||||||
|
(wtch/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||||
|
:attributes #{:rx :ry}
|
||||||
|
:token (toht/get-token file "test-token-3")
|
||||||
|
:on-update-shape wtch/update-shape-radius-all})]
|
||||||
|
|
||||||
|
step2 (fn [_]
|
||||||
|
(let [events2 [(dwl/sync-file (:id file) (:id file))]]
|
||||||
|
(ths/run-store
|
||||||
|
store done events2
|
||||||
|
(fn [new-state]
|
||||||
|
(let [;; ==== Get
|
||||||
|
file' (ths/get-file-from-store new-state)
|
||||||
|
c-frame1' (cths/get-shape file' :c-frame1)
|
||||||
|
tokens-frame1' (:applied-tokens c-frame1')]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
(t/is (= (count tokens-frame1') 2))
|
||||||
|
(t/is (= (get tokens-frame1' :rx) "test-token-2"))
|
||||||
|
(t/is (= (get tokens-frame1' :ry) "test-token-2"))
|
||||||
|
(t/is (= (get c-frame1' :rx) 50))
|
||||||
|
(t/is (= (get c-frame1' :ry) 50)))))))]
|
||||||
|
|
||||||
|
(tohs/run-store-async
|
||||||
|
store step2 events identity))))
|
||||||
|
|
||||||
|
(t/deftest remove-token-in-copy-then-change-main
|
||||||
|
(t/async
|
||||||
|
done
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (setup-file-with-copy)
|
||||||
|
store (ths/setup-store file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
events [(wtch/unapply-token {:shape-ids [(cthi/id :c-frame1)]
|
||||||
|
:attributes #{:rx :ry}
|
||||||
|
:token (toht/get-token file "test-token-1")})
|
||||||
|
(wtch/apply-token {:shape-ids [(cthi/id :frame1)]
|
||||||
|
:attributes #{:rx :ry}
|
||||||
|
:token (toht/get-token file "test-token-3")
|
||||||
|
:on-update-shape wtch/update-shape-radius-all})]
|
||||||
|
|
||||||
|
step2 (fn [_]
|
||||||
|
(let [events2 [(dwl/sync-file (:id file) (:id file))]]
|
||||||
|
(ths/run-store
|
||||||
|
store done events2
|
||||||
|
(fn [new-state]
|
||||||
|
(let [;; ==== Get
|
||||||
|
file' (ths/get-file-from-store new-state)
|
||||||
|
c-frame1' (cths/get-shape file' :c-frame1)
|
||||||
|
tokens-frame1' (:applied-tokens c-frame1')]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
(t/is (= (count tokens-frame1') 0))
|
||||||
|
(t/is (= (get c-frame1' :rx) 25))
|
||||||
|
(t/is (= (get c-frame1' :ry) 25)))))))]
|
||||||
|
|
||||||
|
(tohs/run-store-async
|
||||||
|
store step2 events identity))))
|
||||||
|
|
||||||
|
(t/deftest modify-token-all-types
|
||||||
|
(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 :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-in-set "token-radius"
|
||||||
|
(ctob/make-token :name "token-radius"
|
||||||
|
:type :border-radius
|
||||||
|
:value 10))
|
||||||
|
(ctob/add-token-in-set "token-rotation"
|
||||||
|
(ctob/make-token :name "token-rotation"
|
||||||
|
:type :rotation
|
||||||
|
:value 30))
|
||||||
|
(ctob/add-token-in-set "token-opacity"
|
||||||
|
(ctob/make-token :name "token-opacity"
|
||||||
|
:type :opacity
|
||||||
|
:value 0.7))
|
||||||
|
(ctob/add-token-in-set "token-stroke-width"
|
||||||
|
(ctob/make-token :name "token-stroke-width"
|
||||||
|
:type :stroke-width
|
||||||
|
:value 2))
|
||||||
|
(ctob/add-token-in-set "token-color"
|
||||||
|
(ctob/make-token :name "token-color"
|
||||||
|
:type :color
|
||||||
|
:value "#00ff00"))
|
||||||
|
(ctob/add-token-in-set "token-dimensions"
|
||||||
|
(ctob/make-token :name "token-dimensions"
|
||||||
|
:type :dimensions
|
||||||
|
:value 100))))
|
||||||
|
(ctho/add-frame :frame1)
|
||||||
|
(ctht/apply-token-to-shape :frame1 "token-radius" [:rx :ry] [:rx :ry] 10)
|
||||||
|
(ctht/apply-token-to-shape :frame1 "token-rotation" [:rotation] [:rotation] 30)
|
||||||
|
(ctht/apply-token-to-shape :frame1 "token-opacity" [:opacity] [:opacity] 0.7)
|
||||||
|
(ctht/apply-token-to-shape :frame1 "token-stroke-width" [:stroke-width] [:stroke-width] 2)
|
||||||
|
(ctht/apply-token-to-shape :frame1 "token-color" [:stroke-color] [:stroke-color] "#00ff00")
|
||||||
|
(ctht/apply-token-to-shape :frame1 "token-color" [:fill] [:fill] "#00ff00")
|
||||||
|
(ctht/apply-token-to-shape :frame1 "token-dimensions" [:width :height] [:width :height] 100)
|
||||||
|
(cthc/make-component :component1 :frame1)
|
||||||
|
(cthc/instantiate-component :component1 :c-frame1))
|
||||||
|
store (ths/setup-store file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
events [(dt/update-create-token {:token (ctob/make-token :name "token-radius"
|
||||||
|
:type :border-radius
|
||||||
|
:value 30)
|
||||||
|
:prev-token-name "token-radius"})
|
||||||
|
(dt/update-create-token {:token (ctob/make-token :name "token-rotation"
|
||||||
|
:type :rotation
|
||||||
|
:value 45)
|
||||||
|
:prev-token-name "token-rotation"})
|
||||||
|
(dt/update-create-token {:token (ctob/make-token :name "token-opacity"
|
||||||
|
:type :opacity
|
||||||
|
:value 0.9)
|
||||||
|
:prev-token-name "token-opacity"})
|
||||||
|
(dt/update-create-token {:token (ctob/make-token :name "token-stroke-width"
|
||||||
|
:type :stroke-width
|
||||||
|
:value 8)
|
||||||
|
:prev-token-name "token-stroke-width"})
|
||||||
|
(dt/update-create-token {:token (ctob/make-token :name "token-color"
|
||||||
|
:type :color
|
||||||
|
:value "#ff0000")
|
||||||
|
:prev-token-name "token-color"})
|
||||||
|
(dt/update-create-token {:token (ctob/make-token :name "token-dimensions"
|
||||||
|
:type :dimensions
|
||||||
|
:value 200)
|
||||||
|
:prev-token-name "token-dimensions"})]
|
||||||
|
|
||||||
|
step2 (fn [_]
|
||||||
|
(let [events2 [(wtu/update-workspace-tokens)
|
||||||
|
(dwl/sync-file (:id file) (:id file))]]
|
||||||
|
(tohs/run-store-async
|
||||||
|
store done events2
|
||||||
|
(fn [new-state]
|
||||||
|
(let [;; ==== Get
|
||||||
|
file' (ths/get-file-from-store new-state)
|
||||||
|
c-frame1' (cths/get-shape file' :c-frame1)
|
||||||
|
tokens-frame1' (:applied-tokens c-frame1')]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
(t/is (= (count tokens-frame1') 9))
|
||||||
|
(t/is (= (get tokens-frame1' :rx) "token-radius"))
|
||||||
|
(t/is (= (get tokens-frame1' :ry) "token-radius"))
|
||||||
|
(t/is (= (get tokens-frame1' :rotation) "token-rotation"))
|
||||||
|
(t/is (= (get tokens-frame1' :opacity) "token-opacity"))
|
||||||
|
(t/is (= (get tokens-frame1' :stroke-width) "token-stroke-width"))
|
||||||
|
(t/is (= (get tokens-frame1' :stroke-color) "token-color"))
|
||||||
|
(t/is (= (get tokens-frame1' :fill) "token-color"))
|
||||||
|
(t/is (= (get tokens-frame1' :width) "token-dimensions"))
|
||||||
|
(t/is (= (get tokens-frame1' :height) "token-dimensions"))
|
||||||
|
(t/is (= (get c-frame1' :rx) 30))
|
||||||
|
(t/is (= (get c-frame1' :ry) 30))
|
||||||
|
(t/is (= (get c-frame1' :rotation) 45))
|
||||||
|
(t/is (= (get c-frame1' :opacity) 0.9))
|
||||||
|
(t/is (= (get-in c-frame1' [:strokes 0 :stroke-width]) 8))
|
||||||
|
(t/is (= (get-in c-frame1' [:strokes 0 :stroke-color]) "#ff0000"))
|
||||||
|
(t/is (= (get-in c-frame1' [:fills 0 :fill-color]) "#ff0000"))
|
||||||
|
(t/is (mth/close? (get c-frame1' :width) 200))
|
||||||
|
(t/is (mth/close? (get c-frame1' :height) 200))
|
||||||
|
|
||||||
|
(t/is (empty? (:touched c-frame1'))))))))]
|
||||||
|
|
||||||
|
(tohs/run-store-async
|
||||||
|
store step2 events identity))))
|
|
@ -4,6 +4,7 @@
|
||||||
[frontend-tests.basic-shapes-test]
|
[frontend-tests.basic-shapes-test]
|
||||||
[frontend-tests.helpers-shapes-test]
|
[frontend-tests.helpers-shapes-test]
|
||||||
[frontend-tests.logic.comp-remove-swap-slots-test]
|
[frontend-tests.logic.comp-remove-swap-slots-test]
|
||||||
|
[frontend-tests.logic.components-and-tokens]
|
||||||
[frontend-tests.logic.copying-and-duplicating-test]
|
[frontend-tests.logic.copying-and-duplicating-test]
|
||||||
[frontend-tests.logic.frame-guides-test]
|
[frontend-tests.logic.frame-guides-test]
|
||||||
[frontend-tests.logic.groups-test]
|
[frontend-tests.logic.groups-test]
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
(t/run-tests
|
(t/run-tests
|
||||||
'frontend-tests.helpers-shapes-test
|
'frontend-tests.helpers-shapes-test
|
||||||
'frontend-tests.logic.comp-remove-swap-slots-test
|
'frontend-tests.logic.comp-remove-swap-slots-test
|
||||||
|
'frontend-tests.logic.components-and-tokens
|
||||||
'frontend-tests.logic.copying-and-duplicating-test
|
'frontend-tests.logic.copying-and-duplicating-test
|
||||||
'frontend-tests.logic.frame-guides-test
|
'frontend-tests.logic.frame-guides-test
|
||||||
'frontend-tests.logic.groups-test
|
'frontend-tests.logic.groups-test
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue