mirror of
https://github.com/penpot/penpot.git
synced 2025-06-12 16:51:40 +02:00
🔧 Move token helpers to common.files
This commit is contained in:
parent
a5bbe765b9
commit
3e0f38e8c3
11 changed files with 83 additions and 75 deletions
|
@ -2,13 +2,13 @@
|
|||
(:require
|
||||
["@tokens-studio/sd-transforms" :as sd-transforms]
|
||||
["style-dictionary$default" :as sd]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.logging :as l]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.transit :as t]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.tinycolor :as tinycolor]
|
||||
[app.main.ui.workspace.tokens.errors :as wte]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.main.ui.workspace.tokens.warnings :as wtw]
|
||||
[app.util.time :as dt]
|
||||
[beicon.v2.core :as rx]
|
||||
|
@ -54,7 +54,7 @@
|
|||
"Parses `value` of a numeric `sd-token` into a map like `{:value 1 :unit \"px\"}`.
|
||||
If the `value` is not parseable and/or has missing references returns a map with `:errors`."
|
||||
[value]
|
||||
(let [parsed-value (wtt/parse-token-value value)
|
||||
(let [parsed-value (cft/parse-token-value value)
|
||||
out-of-bounds (or (>= (:value parsed-value) sm/max-safe-int)
|
||||
(<= (:value parsed-value) sm/min-safe-int))]
|
||||
(if (and parsed-value (not out-of-bounds))
|
||||
|
@ -72,7 +72,7 @@
|
|||
If the `value` is parseable but is out of range returns a map with `warnings`."
|
||||
[value has-references?]
|
||||
|
||||
(let [parsed-value (wtt/parse-token-value value)
|
||||
(let [parsed-value (cft/parse-token-value value)
|
||||
out-of-scope (not (<= 0 (:value parsed-value) 1))
|
||||
references (seq (ctob/find-token-value-references value))]
|
||||
(cond
|
||||
|
@ -98,7 +98,7 @@
|
|||
If the `value` is parseable but is out of range returns a map with `warnings`."
|
||||
[value has-references?]
|
||||
|
||||
(let [parsed-value (wtt/parse-token-value value)
|
||||
(let [parsed-value (cft/parse-token-value value)
|
||||
out-of-scope (< (:value parsed-value) 0)
|
||||
references (seq (ctob/find-token-value-references value))]
|
||||
(cond
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.types.shape.layout :as ctsl]
|
||||
[app.common.types.shape.radius :as ctsr]
|
||||
[app.common.types.token :as ctt]
|
||||
|
@ -23,7 +24,6 @@
|
|||
[app.main.data.workspace.transforms :as dwt]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[beicon.v2.core :as rx]
|
||||
[clojure.set :as set]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
@ -56,8 +56,8 @@
|
|||
(keys))
|
||||
[])
|
||||
|
||||
resolved-value (get-in resolved-tokens [(wtt/token-identifier token) :resolved-value])
|
||||
tokenized-attributes (wtt/attributes-map attributes token)]
|
||||
resolved-value (get-in resolved-tokens [(cft/token-identifier token) :resolved-value])
|
||||
tokenized-attributes (cft/attributes-map attributes token)]
|
||||
(rx/of
|
||||
(st/emit! (ptk/event ::ev/event {::ev/name "apply-tokens"}))
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
|
@ -80,7 +80,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of
|
||||
(let [remove-token #(when % (wtt/remove-attributes-for-token attributes token %))]
|
||||
(let [remove-token #(when % (cft/remove-attributes-for-token attributes token %))]
|
||||
(dwsh/update-shapes
|
||||
shape-ids
|
||||
(fn [shape]
|
||||
|
@ -95,7 +95,7 @@
|
|||
(get token-properties (:type token))
|
||||
|
||||
unapply-tokens?
|
||||
(wtt/shapes-token-applied? token shapes (or all-attributes attributes))
|
||||
(cft/shapes-token-applied? token shapes (or all-attributes attributes))
|
||||
|
||||
shape-ids (map :id shapes)]
|
||||
(if unapply-tokens?
|
||||
|
|
21
frontend/src/app/main/data/workspace/tokens/color.cljs
Normal file
21
frontend/src/app/main/data/workspace/tokens/color.cljs
Normal file
|
@ -0,0 +1,21 @@
|
|||
;; 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.main.data.workspace.tokens.color
|
||||
(:require
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.main.data.tinycolor :as tinycolor]))
|
||||
|
||||
(defn color-bullet-color [token-color-value]
|
||||
(when-let [tc (tinycolor/valid-color token-color-value)]
|
||||
(if (tinycolor/alpha tc)
|
||||
{:color (tinycolor/->hex-string tc)
|
||||
:opacity (tinycolor/alpha tc)}
|
||||
(tinycolor/->hex-string tc))))
|
||||
|
||||
(defn resolved-token-bullet-color [{:keys [resolved-value] :as token}]
|
||||
(when (and resolved-value (cft/color-token? token))
|
||||
(color-bullet-color resolved-value)))
|
|
@ -7,8 +7,8 @@
|
|||
(ns app.main.ui.workspace.tokens.components.controls.input-token-color-bullet
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.data.workspace.tokens.color :as dwtc]
|
||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private schema::input-token-color-bullet
|
||||
|
@ -23,6 +23,6 @@
|
|||
[:div {:data-testid "token-form-color-bullet"
|
||||
:class (stl/css :input-token-color-bullet)
|
||||
:on-click on-click}
|
||||
(if-let [color' (wtt/color-bullet-color color)]
|
||||
(if-let [color' (dwtc/color-bullet-color color)]
|
||||
[:> color-bullet {:color color' :mini true}]
|
||||
[:div {:class (stl/css :input-token-color-bullet-placeholder)}])])
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
|
@ -18,7 +19,6 @@
|
|||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.timers :as timers]
|
||||
|
@ -30,9 +30,9 @@
|
|||
;; Actions ---------------------------------------------------------------------
|
||||
|
||||
(defn attribute-actions [token selected-shapes attributes]
|
||||
(let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
(let [ids-by-attributes (cft/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
shape-ids (into #{} (map :id selected-shapes))]
|
||||
{:all-selected? (wtt/shapes-applied-all? ids-by-attributes shape-ids attributes)
|
||||
{:all-selected? (cft/shapes-applied-all? ids-by-attributes shape-ids attributes)
|
||||
:shape-ids shape-ids
|
||||
:selected-pred #(seq (% ids-by-attributes))}))
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.colors :as c]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
|
@ -28,7 +29,6 @@
|
|||
[app.main.ui.workspace.tokens.components.controls.input-token-color-bullet :refer [input-token-color-bullet*]]
|
||||
[app.main.ui.workspace.tokens.components.controls.input-tokens :refer [input-tokens*]]
|
||||
[app.main.ui.workspace.tokens.errors :as wte]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.main.ui.workspace.tokens.update :as wtu]
|
||||
[app.main.ui.workspace.tokens.warnings :as wtw]
|
||||
[app.util.dom :as dom]
|
||||
|
@ -64,7 +64,7 @@
|
|||
(let [path-exists-schema
|
||||
(m/-simple-schema
|
||||
{:type :token/name-exists
|
||||
:pred #(not (wtt/token-name-path-exists? % tokens-tree))
|
||||
:pred #(not (cft/token-name-path-exists? % tokens-tree))
|
||||
:type-properties {:error/fn #(str "A token already exists at the path: " (:value %))}})]
|
||||
(m/schema
|
||||
[:and
|
||||
|
@ -240,7 +240,7 @@
|
|||
(let [create? (not (instance? ctob/Token token))
|
||||
token (or token {:type token-type})
|
||||
token-properties (dwta/get-token-properties token)
|
||||
color? (wtt/color-token? token)
|
||||
color? (cft/color-token? token)
|
||||
selected-set-tokens (mf/deref refs/workspace-selected-token-set-tokens)
|
||||
|
||||
active-theme-tokens (cond-> (mf/deref refs/workspace-active-theme-sets-tokens)
|
||||
|
@ -254,7 +254,7 @@
|
|||
:interactive? true})
|
||||
token-path (mf/use-memo
|
||||
(mf/deps (:name token))
|
||||
#(wtt/token-name->path (:name token)))
|
||||
#(cft/token-name->path (:name token)))
|
||||
|
||||
selected-set-tokens-tree (mf/use-memo
|
||||
(mf/deps token-path selected-set-tokens)
|
||||
|
@ -329,7 +329,7 @@
|
|||
value-input-ref (mf/use-ref nil)
|
||||
value-ref (mf/use-var (:value token))
|
||||
|
||||
token-resolve-result* (mf/use-state (get resolved-tokens (wtt/token-identifier token)))
|
||||
token-resolve-result* (mf/use-state (get resolved-tokens (cft/token-identifier token)))
|
||||
token-resolve-result (deref token-resolve-result*)
|
||||
|
||||
set-resolve-value
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
(ns app.main.ui.workspace.tokens.token
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.tinycolor :as tinycolor]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(def parseable-token-value-regexp
|
||||
"Regexp that can be used to parse a number value out of resolved token value.
|
||||
This regexp also trims whitespace around the value."
|
||||
#"^\s*(-?[0-9]+\.?[0-9]*)(px|%)?\s*$")
|
||||
|
||||
(defn parse-token-value
|
||||
"Parses a resolved value and separates the unit from the value.
|
||||
Returns a map of {:value `number` :unit `string`}."
|
||||
[value]
|
||||
(cond
|
||||
(number? value) {:value value}
|
||||
(string? value) (when-let [[_ value unit] (re-find parseable-token-value-regexp value)]
|
||||
(when-let [parsed-value (d/parse-double value)]
|
||||
{:value parsed-value
|
||||
:unit unit}))))
|
||||
|
||||
;; FIXME: looks very redundant function
|
||||
(defn token-identifier
|
||||
[{:keys [name] :as _token}]
|
||||
name)
|
||||
|
||||
(defn attributes-map
|
||||
"Creats an attributes map using collection of `attributes` for `id`."
|
||||
[attributes token]
|
||||
(->> (map (fn [attr] [attr (token-identifier token)]) attributes)
|
||||
(into {})))
|
||||
|
||||
(defn remove-attributes-for-token
|
||||
"Removes applied tokens with `token-id` for the given `attributes` set from `applied-tokens`."
|
||||
[attributes token applied-tokens]
|
||||
(let [attr? (set attributes)]
|
||||
(->> (remove (fn [[k v]]
|
||||
(and (attr? k)
|
||||
(= v (token-identifier token))))
|
||||
applied-tokens)
|
||||
(into {}))))
|
||||
|
||||
(defn token-attribute-applied?
|
||||
"Test if `token` is applied to a `shape` on single `token-attribute`."
|
||||
[token shape token-attribute]
|
||||
(when-let [id (dm/get-in shape [:applied-tokens token-attribute])]
|
||||
(= (token-identifier token) id)))
|
||||
|
||||
(defn token-applied?
|
||||
"Test if `token` is applied to a `shape` with at least one of the given `token-attributes`."
|
||||
[token shape token-attributes]
|
||||
(some #(token-attribute-applied? token shape %) token-attributes))
|
||||
|
||||
(defn shapes-token-applied?
|
||||
"Test if `token` is applied to to any of `shapes` with at least one of the given `token-attributes`."
|
||||
[token shapes token-attributes]
|
||||
(some #(token-applied? token % token-attributes) shapes))
|
||||
|
||||
(defn shapes-ids-by-applied-attributes
|
||||
[token shapes token-attributes]
|
||||
(let [conj* (fnil conj #{})]
|
||||
(reduce (fn [result shape]
|
||||
(let [shape-id (dm/get-prop shape :id)]
|
||||
(->> token-attributes
|
||||
(filter #(token-attribute-applied? token shape %))
|
||||
(reduce (fn [result attr]
|
||||
(update result attr conj* shape-id))
|
||||
result))))
|
||||
{}
|
||||
shapes)))
|
||||
|
||||
(defn shapes-applied-all? [ids-by-attributes shape-ids attributes]
|
||||
(every? #(set/superset? (get ids-by-attributes %) shape-ids) attributes))
|
||||
|
||||
(defn token-name->path
|
||||
"Splits token-name into a path vector split by `.` characters.
|
||||
|
||||
Will concatenate multiple `.` characters into one."
|
||||
[token-name]
|
||||
(str/split token-name #"\.+"))
|
||||
|
||||
(defn token-name->path-selector
|
||||
"Splits token-name into map with `:path` and `:selector` using `token-name->path`.
|
||||
|
||||
`:selector` is the last item of the names path
|
||||
`:path` is everything leading up the the `:selector`."
|
||||
[token-name]
|
||||
(let [path-segments (token-name->path token-name)
|
||||
last-idx (dec (count path-segments))
|
||||
[path [selector]] (split-at last-idx path-segments)]
|
||||
{:path (seq path)
|
||||
:selector selector}))
|
||||
|
||||
(defn token-name-path-exists?
|
||||
"Traverses the path from `token-name` down a `token-tree` and checks if a token at that path exists.
|
||||
|
||||
It's not allowed to create a token inside a token. E.g.:
|
||||
Creating a token with
|
||||
|
||||
{:name \"foo.bar\"}
|
||||
|
||||
in the tokens tree:
|
||||
|
||||
{\"foo\" {:name \"other\"}}"
|
||||
[token-name token-names-tree]
|
||||
(let [{:keys [path selector]} (token-name->path-selector token-name)
|
||||
path-target (reduce
|
||||
(fn [acc cur]
|
||||
(let [target (get acc cur)]
|
||||
(cond
|
||||
;; Path segment doesn't exist yet
|
||||
(nil? target) (reduced false)
|
||||
;; A token exists at this path
|
||||
(:name target) (reduced true)
|
||||
;; Continue traversing the true
|
||||
:else target)))
|
||||
token-names-tree path)]
|
||||
(cond
|
||||
(boolean? path-target) path-target
|
||||
(get path-target :name) true
|
||||
:else (-> (get path-target selector)
|
||||
(seq)
|
||||
(boolean)))))
|
||||
|
||||
(defn color-token? [token]
|
||||
(= (:type token) :color))
|
||||
|
||||
|
||||
;; FIXME: this should be precalculated ?
|
||||
(defn is-reference? [token]
|
||||
(str/includes? (:value token) "{"))
|
||||
|
||||
(defn color-bullet-color [token-color-value]
|
||||
(when-let [tc (tinycolor/valid-color token-color-value)]
|
||||
(if (tinycolor/alpha tc)
|
||||
{:color (tinycolor/->hex-string tc)
|
||||
:opacity (tinycolor/alpha tc)}
|
||||
(tinycolor/->hex-string tc))))
|
||||
|
||||
(defn resolved-token-bullet-color [{:keys [resolved-value] :as token}]
|
||||
(when (and resolved-value (color-token? token))
|
||||
(color-bullet-color resolved-value)))
|
|
@ -11,12 +11,13 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.tokens.color :as dwtc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]]
|
||||
[app.main.ui.workspace.tokens.token :as wtt]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
|
@ -80,6 +81,7 @@
|
|||
:y "Y"})
|
||||
|
||||
;; Helper functions
|
||||
|
||||
(defn partially-applied-attr
|
||||
"Translates partially applied attributes based on the dictionary."
|
||||
[app-token-keys is-applied {:keys [attributes all-attributes]}]
|
||||
|
@ -156,9 +158,9 @@
|
|||
|
||||
(defn- applied-all-attributes?
|
||||
[token selected-shapes attributes]
|
||||
(let [ids-by-attributes (wtt/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
(let [ids-by-attributes (cft/shapes-ids-by-applied-attributes token selected-shapes attributes)
|
||||
shape-ids (into #{} xf:map-id selected-shapes)]
|
||||
(wtt/shapes-applied-all? ids-by-attributes shape-ids attributes)))
|
||||
(cft/shapes-applied-all? ids-by-attributes shape-ids attributes)))
|
||||
|
||||
(mf/defc token-pill*
|
||||
{::mf/wrap [mf/memo]}
|
||||
|
@ -166,7 +168,7 @@
|
|||
(let [{:keys [name value errors]} token
|
||||
|
||||
has-selected? (pos? (count selected-shapes))
|
||||
is-reference? (wtt/is-reference? token)
|
||||
is-reference? (cft/is-reference? token)
|
||||
contains-path? (str/includes? name ".")
|
||||
|
||||
{:keys [attributes all-attributes]}
|
||||
|
@ -179,7 +181,7 @@
|
|||
|
||||
applied?
|
||||
(if has-selected?
|
||||
(wtt/shapes-token-applied? token selected-shapes (d/nilv all-attributes attributes))
|
||||
(cft/shapes-token-applied? token selected-shapes (d/nilv all-attributes attributes))
|
||||
false)
|
||||
|
||||
half-applied?
|
||||
|
@ -201,10 +203,10 @@
|
|||
no-valid-value)
|
||||
|
||||
color
|
||||
(when (wtt/color-token? token)
|
||||
(when (cft/color-token? token)
|
||||
(let [theme-token (get active-theme-tokens (:name token))]
|
||||
(or (wtt/resolved-token-bullet-color theme-token)
|
||||
(wtt/resolved-token-bullet-color token))))
|
||||
(or (dwtc/resolved-token-bullet-color theme-token)
|
||||
(dwtc/resolved-token-bullet-color token))))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue