diff --git a/common/src/app/common/types/token.cljc b/common/src/app/common/types/token.cljc index 6de8f9c29..ed63908ab 100644 --- a/common/src/app/common/types/token.cljc +++ b/common/src/app/common/types/token.cljc @@ -35,8 +35,8 @@ (def token-types #{:boolean :border-radius - :stroke-width :box-shadow + :color :dimensions :numeric :opacity @@ -45,6 +45,7 @@ :sizing :spacing :string + :stroke-width :typography}) (defn valid-token-type? @@ -66,6 +67,12 @@ [:description {:optional true} :string] [:modified-at {:optional true} ::sm/inst]]) +(sm/register! ::color + [:map + [:color {:optional true} token-name-ref]]) + +(def color-keys (schema-keys ::color)) + (sm/register! ::border-radius [:map [:rx {:optional true} token-name-ref] diff --git a/frontend/src/app/main/ui/workspace/tokens/changes.cljs b/frontend/src/app/main/ui/workspace/tokens/changes.cljs index 95243ee51..57d09f703 100644 --- a/frontend/src/app/main/ui/workspace/tokens/changes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/changes.cljs @@ -8,6 +8,7 @@ (:require [app.common.types.shape.radius :as ctsr] [app.common.types.token :as ctt] + [app.main.data.workspace.colors :as wdc] [app.main.data.workspace :as udw] [app.main.data.workspace.shape-layout :as dwsl] [app.main.data.workspace.shapes :as dwsh] @@ -123,6 +124,10 @@ {:reg-objects? true :attrs [:strokes]})) +(defn update-color + [value shape-ids] + (wdc/change-fill shape-ids {:color (str "#" value)} 0)) + (defn update-shape-dimensions [value shape-ids attributes] (ptk/reify ::update-shape-dimensions ptk/WatchEvent diff --git a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs index 1eba57205..6e4156d03 100644 --- a/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/context_menu.cljs @@ -222,10 +222,10 @@ (defn selection-actions [{:keys [type token] :as context-data}] (let [with-actions (get shape-attribute-actions-map (or type (:type token))) - attribute-actions (with-actions context-data)] + attribute-actions (if with-actions (with-actions context-data) [])] (concat attribute-actions - [:separator] + (when (seq attribute-actions) [:separator]) (default-actions context-data)))) ;; Components ------------------------------------------------------------------ diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs index d58cca142..cc30768a6 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs @@ -101,15 +101,19 @@ Token names should only contain letters and digits separated by . characters.")} :else (let [token-id (or (:id token) (random-uuid)) new-tokens (update tokens token-name merge {:id token-id :value input - :name token-name})] - (-> (sd/resolve-tokens+ new-tokens {:names-map? true}) + :name token-name + :type (:type token)})] + (-> (sd/resolve-tokens+ new-tokens {:names-map? true + :debug? true}) (p/then (fn [resolved-tokens] + (js/console.log "resolved-tokens" resolved-tokens) (let [{:keys [errors resolved-value] :as resolved-token} (get resolved-tokens token-name)] (cond resolved-value (p/resolved resolved-token) (sd/missing-reference-error? errors) (p/rejected :error/token-missing-reference) - :else (p/rejected :error/unknown-error)))))))))) + :else (p/rejected :error/unknown-error))))) + (p/catch js/console.log)))))) (defn use-debonced-resolve-callback "Resolves a token values using `StyleDictionary`. @@ -143,8 +147,8 @@ Token names should only contain letters and digits separated by . characters.")} (mf/defc form {::mf/wrap-props false} - [{:keys [token token-type] :as _args}] - (let [tokens (mf/deref refs/workspace-ordered-token-sets-tokens) + [{:keys [token token-type]}] + (let [token (or token {:type token-type}) selected-set-tokens (mf/deref refs/workspace-selected-token-set-tokens) active-theme-tokens (mf/deref refs/workspace-active-theme-sets-tokens) resolved-tokens (sd/use-resolved-tokens active-theme-tokens {:names-map? true @@ -153,7 +157,7 @@ Token names should only contain letters and digits separated by . characters.")} (mf/deps (:name token)) #(wtt/token-name->path (:name token))) selected-set-tokens-tree (mf/use-memo - (mf/deps token-path tokens) + (mf/deps token-path selected-set-tokens) (fn [] (-> (wtt/token-names-tree selected-set-tokens) ;; Allow setting editing token to it's own path diff --git a/frontend/src/app/main/ui/workspace/tokens/modals.cljs b/frontend/src/app/main/ui/workspace/tokens/modals.cljs index 30a45c49f..5e4358d34 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals.cljs @@ -68,6 +68,12 @@ [properties] [:& token-update-create-modal properties]) +(mf/defc color-modal + {::mf/register modal/components + ::mf/register-as :tokens/color} + [properties] + [:& token-update-create-modal properties]) + (mf/defc stroke-width-modal {::mf/register modal/components ::mf/register-as :tokens/stroke-width} diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs index 879ef97af..c333a9a68 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs @@ -77,6 +77,7 @@ (case type :border-radius i/corner-radius :numeric [:span {:class (stl/css :section-text-icon)} "123"] + :color i/drop-icon :boolean i/boolean-difference :opacity [:span {:class (stl/css :section-text-icon)} "%"] :rotation i/rotation diff --git a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs index 62b068a32..919cfd738 100644 --- a/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/style_dictionary.cljs @@ -52,6 +52,7 @@ (.buildAllPlatforms "json") (.catch js/console.error) (.then (fn [^js resp] + (js/console.log "resp" resp) (let [performance-end (js/performance.now) duration-ms (- performance-end performance-start) resolved-tokens (.-allTokens resp)] @@ -82,8 +83,11 @@ (let [identifier (if names-map? (.. cur -original -name) (uuid (.-uuid (.-id cur)))) - origin-token (get tokens identifier) - parsed-value (wtt/parse-token-value (.-value cur)) + {:keys [type] :as origin-token} (get tokens identifier) + value (.-value cur) + parsed-value (case type + :color (wtt/parse-token-color-value value) + (wtt/parse-token-value value)) resolved-token (if (not parsed-value) (assoc origin-token :errors [:style-dictionary/missing-reference]) (assoc origin-token @@ -132,6 +136,7 @@ (defn use-resolved-workspace-tokens [& {:as config}] (-> (mf/deref refs/workspace-selected-token-set-tokens) + (doto js/console.log) (use-resolved-tokens config))) (defn use-active-theme-sets-tokens [& {:as config}] diff --git a/frontend/src/app/main/ui/workspace/tokens/token.cljs b/frontend/src/app/main/ui/workspace/tokens/token.cljs index aba9ae9a0..32b85ab85 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token.cljs @@ -12,6 +12,15 @@ [token-id state] (get-in state [:workspace-data :tokens token-id])) +(def parseable-token-color-value-regexp + "Regexp that can be used to parse a hex value out of resolved token value. + This regexp also trims whitespace around the value." + #"^\s*#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})\s*$") + +(defn parse-token-color-value [value] + (when-let [[_ hex] (re-find parseable-token-color-value-regexp value)] + {:value hex :unit :hex})) + (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." diff --git a/frontend/src/app/main/ui/workspace/tokens/token_types.cljs b/frontend/src/app/main/ui/workspace/tokens/token_types.cljs index 2faadab69..ce4c5cbf3 100644 --- a/frontend/src/app/main/ui/workspace/tokens/token_types.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/token_types.cljs @@ -20,6 +20,14 @@ :modal {:key :tokens/border-radius :fields [{:label "Border Radius" :key :border-radius}]}} + + :color + {:title "Color" + :attributes ctt/color-keys + :on-update-shape wtch/update-color + :modal {:key :tokens/color + :fields [{:label "Color" :key :color}]}} + :stroke-width {:title "Stroke Width" :attributes ctt/stroke-width-keys diff --git a/frontend/src/app/main/ui/workspace/tokens/update.cljs b/frontend/src/app/main/ui/workspace/tokens/update.cljs index 2f64aa65b..5f0b581a9 100644 --- a/frontend/src/app/main/ui/workspace/tokens/update.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/update.cljs @@ -19,6 +19,7 @@ (def attributes->shape-update {#{:rx :ry} (fn [v ids _] (wtch/update-shape-radius-all v ids)) #{:r1 :r2 :r3 :r4} wtch/update-shape-radius-single-corner + ctt/color-keys wtch/update-color ctt/stroke-width-keys wtch/update-stroke-width ctt/sizing-keys wtch/update-shape-dimensions ctt/opacity-keys wtch/update-opacity