From 8e7e6ffc2fc540417e8f2c3a7502098320e58c82 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Thu, 19 Mar 2026 16:46:18 +0100 Subject: [PATCH] :recycle: Design review for numeric inputs (#8630) * :recycle: Update tooltip position on icon buttons * :recycle: Sort token groups by priority not alphabetically * :recycle: Add proper padding on text-icon-inputs * :recycle: Hide detach button when dropdown is open * :bug: Fix detach stroke width * :bug: Fix strokes applied on all rows * :bug: Fix nillable inputs * :bug: Fix comments on PR --- common/src/app/common/types/token.cljc | 50 +++++------ .../main/ui/ds/controls/numeric_input.cljs | 86 ++----------------- .../main/ui/ds/controls/numeric_input.scss | 5 +- .../ui/ds/controls/utilities/token_field.cljs | 7 +- .../ui/ds/controls/utilities/token_field.scss | 3 + .../src/app/main/ui/ds/tooltip/tooltip.cljs | 4 +- .../ui/workspace/sidebar/options/common.cljs | 16 ++++ .../sidebar/options/menus/border_radius.cljs | 26 +++--- .../options/menus/input_wrapper_tokens.cljs | 9 +- .../options/menus/layout_container.cljs | 23 ++--- .../sidebar/options/menus/layout_item.cljs | 40 ++++----- .../sidebar/options/menus/stroke.cljs | 5 +- .../sidebar/options/rows/color_row.cljs | 11 +-- .../sidebar/options/rows/stroke_row.cljs | 16 ++-- .../management/forms/controls/utils.cljs | 30 ++++--- 15 files changed, 131 insertions(+), 200 deletions(-) diff --git a/common/src/app/common/types/token.cljc b/common/src/app/common/types/token.cljc index 55ecc842e7..15e5168a0b 100644 --- a/common/src/app/common/types/token.cljc +++ b/common/src/app/common/types/token.cljc @@ -522,31 +522,31 @@ (def tokens-by-input "A map from input name to applicable token for that input." - {:width #{:sizing :dimensions} - :height #{:sizing :dimensions} - :max-width #{:sizing :dimensions} - :max-height #{:sizing :dimensions} - :min-width #{:sizing :dimensions} - :min-height #{:sizing :dimensions} - :x #{:dimensions} - :y #{:dimensions} - :rotation #{:number :rotation} - :border-radius #{:border-radius :dimensions} - :row-gap #{:spacing :dimensions} - :column-gap #{:spacing :dimensions} - :horizontal-padding #{:spacing :dimensions} - :vertical-padding #{:spacing :dimensions} - :sided-paddings #{:spacing :dimensions} - :horizontal-margin #{:spacing :dimensions} - :vertical-margin #{:spacing :dimensions} - :sided-margins #{:spacing :dimensions} - :line-height #{:line-height :number} - :opacity #{:opacity} - :stroke-width #{:stroke-width :dimensions} - :font-size #{:font-size} - :letter-spacing #{:letter-spacing} - :fill #{:color} - :stroke-color #{:color}}) + {:width [:sizing :dimensions] + :height [:sizing :dimensions] + :max-width [:sizing :dimensions] + :max-height [:sizing :dimensions] + :min-width [:sizing :dimensions] + :min-height [:sizing :dimensions] + :x [:dimensions] + :y [:dimensions] + :rotation [:rotation :number] + :border-radius [:border-radius :dimensions] + :row-gap [:spacing :dimensions] + :column-gap [:spacing :dimensions] + :horizontal-padding [:spacing :dimensions] + :vertical-padding [:spacing :dimensions] + :sided-paddings [:spacing :dimensions] + :horizontal-margin [:spacing :dimensions] + :vertical-margin [:spacing :dimensions] + :sided-margins [:spacing :dimensions] + :line-height [:line-height :number] + :opacity [:opacity] + :stroke-width [:stroke-width :dimensions] + :font-size [:font-size] + :letter-spacing [:letter-spacing] + :fill [:color] + :stroke-color [:color]}) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; HELPERS for tokens application diff --git a/frontend/src/app/main/ui/ds/controls/numeric_input.cljs b/frontend/src/app/main/ui/ds/controls/numeric_input.cljs index 5ffed93c6c..cb86f6bdab 100644 --- a/frontend/src/app/main/ui/ds/controls/numeric_input.cljs +++ b/frontend/src/app/main/ui/ds/controls/numeric_input.cljs @@ -19,6 +19,7 @@ [app.main.ui.ds.controls.utilities.token-field :refer [token-field*]] [app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list] :as i] [app.main.ui.formats :as fmt] + [app.main.ui.workspace.tokens.management.forms.controls.utils :as csu] [app.util.dom :as dom] [app.util.i18n :refer [tr]] [app.util.keyboard :as kbd] @@ -83,48 +84,6 @@ (str/replace #"^\{" "") (str/replace #"\}$" ""))) -(defn- token->dropdown-option - [token] - {:id (str (get token :id)) - :type :token - :resolved-value (get token :resolved-value) - :name (get token :name)}) - -(defn- generate-dropdown-options - [tokens no-sets] - (if (empty? tokens) - [{:type :empty - :label (if no-sets - (tr "ds.inputs.numeric-input.no-applicable-tokens") - (tr "ds.inputs.numeric-input.no-matches"))}] - (->> tokens - (map (fn [[type items]] - (cons {:group true - :type :group - :id (dm/str "group-" (name type)) - :name (name type)} - (map token->dropdown-option items)))) - (interpose [{:separator true - :id "separator" - :type :separator}]) - (apply concat) - (vec) - (not-empty)))) - -(defn- extract-partial-brace-text - [s] - (when-let [start (str/last-index-of s "{")] - (subs s (inc start)))) - -(defn- filter-token-groups-by-name - [tokens filter-text] - (let [lc-filter (str/lower filter-text)] - (into {} - (keep (fn [[group tokens]] - (let [filtered (filter #(str/includes? (str/lower (:name %)) lc-filter) tokens)] - (when (seq filtered) - [group filtered])))) - tokens))) (defn- focusable-option? [option] @@ -149,31 +108,6 @@ j))) indices))) -(defn- sort-groups-and-tokens - "Sorts both the groups and the tokens inside them alphabetically. - - Input: - A map where: - - keys are groups (keywords or strings, e.g. :dimensions, :colors) - - values are vectors of token maps, each containing at least a :name key - - Example input: - {:dimensions [{:name \"tres\"} {:name \"quini\"}] - :colors [{:name \"azul\"} {:name \"rojo\"}]} - - Output: - A sorted map where: - - groups are ordered alphabetically by key - - tokens inside each group are sorted alphabetically by :name - - Example output: - {:colors [{:name \"azul\"} {:name \"rojo\"}] - :dimensions [{:name \"quini\"} {:name \"tres\"}]}" - - [groups->tokens] - (into (sorted-map) ;; ensure groups are ordered alphabetically by their key - (for [[group tokens] groups->tokens] - [group (sort-by :name tokens)]))) (def ^:private schema:icon [:and :string [:fn #(contains? icon-list %)]]) @@ -288,16 +222,7 @@ dropdown-options (mf/with-memo [tokens filter-id] - (delay - (let [tokens (if (delay? tokens) @tokens tokens) - - sorted-tokens (sort-groups-and-tokens tokens) - partial (extract-partial-brace-text filter-id) - options (if (seq partial) - (filter-token-groups-by-name sorted-tokens partial) - sorted-tokens) - no-sets? (nil? sorted-tokens)] - (generate-dropdown-options options no-sets?)))) + (csu/get-token-dropdown-options tokens filter-id)) selected-id* (mf/use-state (fn [] @@ -649,6 +574,7 @@ :icon i/tokens :tooltip-class (stl/css :button-tooltip) :class (stl/css :invisible-button) + :tooltip-placement "top-left" :aria-label (tr "ds.inputs.numeric-input.open-token-list-dropdown") :ref open-dropdown-ref :on-click open-dropdown}]))) @@ -676,6 +602,7 @@ :on-blur on-blur :class inner-class :property property + :is-open is-open :slot-start (when (or icon text-icon) (mf/html (cond @@ -714,6 +641,11 @@ (when-let [node (mf/ref-val ref)] (dom/set-value! node value')))) + (mf/with-effect [applied-token] + (when (nil? applied-token) + (reset! token-applied* nil) + (reset! selected-id* nil))) + (mf/with-layout-effect [on-mouse-wheel] (when-let [node (mf/ref-val ref)] (let [key (events/listen node "wheel" on-mouse-wheel #js {:passive false})] diff --git a/frontend/src/app/main/ui/ds/controls/numeric_input.scss b/frontend/src/app/main/ui/ds/controls/numeric_input.scss index 7825f6a7fb..bbec005618 100644 --- a/frontend/src/app/main/ui/ds/controls/numeric_input.scss +++ b/frontend/src/app/main/ui/ds/controls/numeric_input.scss @@ -35,9 +35,10 @@ .text-icon { color: var(--color-foreground-secondary); - @include t.use-typography("code-font"); + @include t.use-typography("body-small"); inline-size: fit-content; - min-inline-size: px2rem(40); + min-inline-size: px2rem(46); + padding-inline-start: var(--sp-xs); } .invisible-button { diff --git a/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs b/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs index 7af90350e4..3e825f2b38 100644 --- a/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs +++ b/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs @@ -25,6 +25,7 @@ [:property {:optional true} [:maybe :string]] [:value :any] [:disabled {:optional true} :boolean] + [:is-open {:optional true} :boolean] [:slot-start {:optional true} [:maybe some?]] [:on-click {:optional true} fn?] [:on-token-key-down fn?] @@ -36,7 +37,7 @@ {::mf/schema schema:token-field} [{:keys [id label value slot-start disabled class on-click on-token-key-down on-blur detach-token - token-wrapper-ref token-detach-btn-ref on-focus property]}] + token-wrapper-ref token-detach-btn-ref on-focus property is-open]}] (let [set-active? (some? id) content (if set-active? label @@ -88,9 +89,11 @@ (when-not ^boolean disabled [:> icon-button* {:variant "ghost" - :class (stl/css :invisible-button) + :class (stl/css-case :invisible-button true + :invisible-btn-dropdown-open is-open) :tooltip-class (stl/css :button-tooltip) :icon i/broken-link :ref token-detach-btn-ref + :tooltip-placement "top-left" :aria-label (tr "ds.inputs.token-field.detach-token") :on-click detach-token}])]])) diff --git a/frontend/src/app/main/ui/ds/controls/utilities/token_field.scss b/frontend/src/app/main/ui/ds/controls/utilities/token_field.scss index e96c5b583e..4233b2305d 100644 --- a/frontend/src/app/main/ui/ds/controls/utilities/token_field.scss +++ b/frontend/src/app/main/ui/ds/controls/utilities/token_field.scss @@ -136,6 +136,9 @@ --opacity-button: 1; } } +.invisible-btn-dropdown-open { + --opacity-button: 0; +} .content-wrapper { inline-size: 100%; diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs index 968361f865..9fe9ff3fbf 100644 --- a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs +++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs @@ -172,7 +172,7 @@ (deref placement*) delay - (d/nilv delay 300) + (d/nilv delay 700) schedule-ref (mf/use-ref nil) @@ -188,7 +188,7 @@ (when-not (.-hidden js/document) (let [trigger-el (mf/ref-val trigger-ref)] (clear-schedule schedule-ref) - (add-schedule schedule-ref (d/nilv delay 300) + (add-schedule schedule-ref delay (fn [] (when-let [active @active-tooltip] (when (not= (:id active) tooltip-id) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/common.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/common.cljs index 7ea8e42132..065984f819 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/common.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/common.cljs @@ -7,6 +7,8 @@ (ns app.main.ui.workspace.sidebar.options.common (:require-macros [app.main.style :as stl]) (:require + [app.main.data.workspace.tokens.application :as dwta] + [app.main.store :as st] [app.util.dom :as dom] [rumext.v2 :as mf])) @@ -24,3 +26,17 @@ :ref ref} children]))) +(defn emit-value-or-token [value emit-value-fn ids attrs] + (cond + (nil? value) + (emit-value-fn nil) + + (or (string? value) (number? value)) + (emit-value-fn value) + + :else + (st/emit! + (dwta/toggle-token {:token (first value) + :attrs attrs + :shape-ids ids})))) + diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs index d1d7a55fc5..13c260726f 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/border_radius.cljs @@ -11,6 +11,7 @@ [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] [app.main.ui.hooks :as hooks] + [app.main.ui.workspace.sidebar.options.common :as soc] [app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]] [app.util.i18n :as i18n :refer [tr]] [beicon.v2.core :as rx] @@ -130,26 +131,21 @@ (mf/use-fn (mf/deps change-radius ids) (fn [value] - (if (or (string? value) (number? value)) - (st/emit! - (change-radius (fn [shape] - (ctsr/set-radius-to-all-corners shape value)))) - (st/emit! - (dwta/toggle-token {:token (first value) - :attrs #{:r1 :r2 :r3 :r4} - :shape-ids ids}))))) - + (soc/emit-value-or-token + value + #(st/emit! (change-radius (fn [shape] (ctsr/set-radius-to-all-corners shape %)))) + ids + #{:r1 :r2 :r3 :r4}))) on-single-radius-change (mf/use-fn (mf/deps change-one-radius ids) (fn [value attr] - (if (or (string? value) (number? value)) - (st/emit! (change-one-radius #(ctsr/set-radius-to-single-corner % attr value) attr)) - (st/emit! (st/emit! - (dwta/toggle-token {:token (first value) - :attrs #{attr} - :shape-ids ids})))))) + (soc/emit-value-or-token + value + #(st/emit! (change-one-radius (fn [shape] (ctsr/set-radius-to-single-corner shape attr %)) attr)) + ids + #{attr}))) on-radius-r1-change #(on-single-radius-change % :r1) on-radius-r2-change #(on-single-radius-change % :r2) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/input_wrapper_tokens.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/input_wrapper_tokens.cljs index be7c58ebb2..099a38b5c9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/input_wrapper_tokens.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/input_wrapper_tokens.cljs @@ -1,9 +1,9 @@ (ns app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens (:require-macros [app.main.style :as stl]) (:require - [app.common.types.token :as tk] [app.main.ui.context :as muc] [app.main.ui.ds.controls.numeric-input :refer [numeric-input*]] + [app.main.ui.workspace.tokens.management.forms.controls.utils :as csu] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) @@ -11,11 +11,8 @@ [{:keys [value attr applied-token align on-detach placeholder input-type class] :rest props}] (let [tokens (mf/use-ctx muc/active-tokens-by-type) - tokens (mf/with-memo [tokens input-type] - (delay - (-> (deref tokens) - (select-keys (get tk/tokens-by-input (or input-type attr))) - (not-empty)))) + tokens (mf/with-memo [tokens input-type attr] + (csu/filter-tokens-for-input tokens (or input-type attr))) on-detach-attr (mf/use-fn diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index e07c3cd958..568bea26da 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -30,6 +30,7 @@ [app.main.ui.formats :as fmt] [app.main.ui.hooks :as h] [app.main.ui.icons :as deprecated-icon] + [app.main.ui.workspace.sidebar.options.common :as soc] [app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -335,15 +336,8 @@ (mf/use-fn (mf/deps on-change ids) (fn [value attr event] - (if (or (string? value) (number? value)) - (on-change :simple attr value event) - (do - (st/emit! - (dwta/toggle-token {:token (first value) - :attrs (if (= :p1 attr) - #{:p1 :p3} - #{:p2 :p4}) - :shape-ids ids})))))) + (let [on-change-fn #(on-change :simple attr % event)] + (soc/emit-value-or-token value on-change-fn ids #{attr})))) on-detach-token (mf/use-fn @@ -719,15 +713,8 @@ (mf/use-fn (mf/deps on-change wrap-type ids) (fn [value event attr] - (if (or (string? value) (number? value)) - (on-change (= "nowrap" wrap-type) attr value event) - (do - (st/emit! - (dwta/toggle-token {:token (first value) - :attrs (if (= "nowrap" wrap-type) - #{:row-gap :colum-gap} - #{attr}) - :shape-ids ids})))))) + (let [on-change-fn #((on-change (= "nowrap" wrap-type) attr % event))] + (soc/emit-value-or-token value on-change-fn ids #{attr})))) on-detach-token (mf/use-fn diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs index 8af6905212..d30939e51c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs @@ -21,6 +21,7 @@ [app.main.ui.components.title-bar :refer [title-bar*]] [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.icons :as deprecated-icon] + [app.main.ui.workspace.sidebar.options.common :as soc] [app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]] [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [get-layout-flex-icon]] [app.util.dom :as dom] @@ -117,15 +118,11 @@ (mf/use-fn (mf/deps on-change ids) (fn [value attr] - (if (or (string? value) (number? value)) - (on-change :simple attr value) - (do - (st/emit! - (dwta/toggle-token {:token (first value) - :attrs (if (= :m1 attr) - #{:m1 :m3} - #{:m2 :m4}) - :shape-ids ids})))))) + (soc/emit-value-or-token + value + #(on-change :simple attr %) + ids + (if (= :m1 attr) #{:m1 :m3} #{:m2 :m4})))) on-focus-m1 (mf/use-fn (mf/deps on-focus) #(on-focus :m1)) @@ -247,14 +244,11 @@ (mf/use-fn (mf/deps on-change ids) (fn [value attr] - (if (or (string? value) (number? value)) - (on-change :multiple attr value) - (do - (st/emit! - (dwta/toggle-token {:token (first value) - :attrs #{attr} - :shape-ids ids})))))) - + (soc/emit-value-or-token + value + #(on-change :multiple attr %) + ids + #{attr}))) on-m1-change (mf/use-fn (mf/deps on-change') #(on-change' % :m1)) @@ -577,13 +571,11 @@ (mf/use-fn (mf/deps ids) (fn [value attr] - (if (or (string? value) (number? value)) - (st/emit! (dwsl/update-layout-child ids {attr value})) - (do - (st/emit! - (dwta/toggle-token {:token (first value) - :attrs #{attr} - :shape-ids ids})))))) + (soc/emit-value-or-token + value + #(st/emit! (dwsl/update-layout-child ids {attr %})) + ids + #{attr}))) on-layout-item-min-w-change (mf/use-fn (mf/deps on-size-change) #(on-size-change % :layout-item-min-w)) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs index c35bac471e..96cf70f8f5 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs @@ -168,6 +168,7 @@ on-blur (fn [_] (reset! disable-drag false)) + on-detach-token (mf/use-fn (mf/deps ids) @@ -205,7 +206,7 @@ (seq strokes) [:> h/sortable-container* {} (for [[index value] (d/enumerate (:strokes values []))] - [:> stroke-row* {:key (dm/str "stroke-" index) + [:> stroke-row* {:key (dm/str "stroke-" index "-" (hash applied-tokens)) :stroke value :title (tr "workspace.options.stroke-color") :index index @@ -222,7 +223,7 @@ :on-stroke-cap-start-change on-stroke-cap-start-change :on-stroke-cap-end-change on-stroke-cap-end-change :on-stroke-cap-switch on-stroke-cap-switch - :applied-tokens applied-tokens + :applied-tokens (when (= 0 index) applied-tokens) :on-detach-token on-detach-token :on-remove on-remove :on-reorder handle-reorder diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs index ce2a8ae403..f2f4df6423 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs @@ -11,7 +11,6 @@ [app.common.data.macros :as dm] [app.common.types.color :as clr] [app.common.types.shape.attrs :refer [default-color]] - [app.common.types.token :as tk] [app.config :as cfg] [app.main.data.modal :as modal] [app.main.data.workspace.colors :as dwc] @@ -27,6 +26,7 @@ [app.main.ui.ds.utilities.swatch :refer [swatch*]] [app.main.ui.formats :as fmt] [app.main.ui.hooks :as h] + [app.main.ui.workspace.tokens.management.forms.controls.utils :as csu] [app.util.color :as uc] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -176,12 +176,9 @@ active-tokens* (mf/use-ctx ctx/active-tokens-by-type) - tokens (mf/with-memo [active-tokens* origin] - (let [origin (if (= :color-selection origin) :fill origin)] - (delay - (-> (deref active-tokens*) - (select-keys (get tk/tokens-by-input origin)) - (not-empty))))) + tokens (mf/with-memo [active-tokens* origin] + (csu/filter-tokens-for-input active-tokens* origin)) + on-focus' (mf/use-fn (mf/deps on-focus) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs index ec5770eabb..9fe822f9df 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/stroke_row.cljs @@ -18,6 +18,7 @@ [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] [app.main.ui.hooks :as h] + [app.main.ui.workspace.sidebar.options.common :as soc] [app.main.ui.workspace.sidebar.options.menus.input-wrapper-tokens :refer [numeric-input-wrapper*]] [app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]] [app.util.i18n :as i18n :refer [tr]] @@ -92,14 +93,13 @@ on-width-change (mf/use-fn - (mf/deps index on-stroke-width-change) + (mf/deps index on-stroke-width-change ids) (fn [value] - (if (or (string? value) (number? value)) - (on-stroke-width-change index value) - - (st/emit! (dwta/toggle-token {:token (first value) - :attrs #{:stroke-width} - :shape-ids ids}))))) + (soc/emit-value-or-token + value + #(on-stroke-width-change index %) + ids + #{:stroke-width}))) stroke-alignment (or (:stroke-alignment stroke) :center) @@ -164,7 +164,7 @@ (mf/use-fn (mf/deps on-detach-token) (fn [token] - (on-detach-token (first token) #{:stroke-width}))) + (on-detach-token token #{:stroke-width}))) stroke-caps-options [{:value nil :label (tr "workspace.options.stroke-cap.none")} diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/utils.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/utils.cljs index f29c348e9d..e75989cdc8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/utils.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/utils.cljs @@ -9,7 +9,7 @@ [token] {:id (str (get token :id)) :type :token - :resolved-value (get token :value) + :resolved-value (get token :resolved-value) :name (get token :name)}) (defn- generate-dropdown-options @@ -53,7 +53,7 @@ tokens))) (defn- sort-groups-and-tokens - "Sorts both the groups and the tokens inside them alphabetically. + "Sorts the tokens inside the groups alphabetically. Input: A map where: @@ -65,18 +65,18 @@ :colors [{:name \"azul\"} {:name \"rojo\"}]} Output: - A sorted map where: - - groups are ordered alphabetically by key + A map which: - tokens inside each group are sorted alphabetically by :name Example output: - {:colors [{:name \"azul\"} {:name \"rojo\"}] - :dimensions [{:name \"quini\"} {:name \"tres\"}]}" + {:dimensions [{:name \"quini\"} {:name \"tres\"}] + :colors [{:name \"azul\"} {:name \"rojo\"}]}" [groups->tokens] - (into (sorted-map) ;; ensure groups are ordered alphabetically by their key - (for [[group tokens] groups->tokens] - [group (sort-by :name tokens)]))) + (reduce (fn [acc [group tokens]] + (assoc acc group (sort-by :name tokens))) + {} + groups->tokens)) (defn get-token-dropdown-options [tokens filter-term] @@ -94,9 +94,15 @@ (defn filter-tokens-for-input [raw-tokens input-type] (delay - (-> (deref raw-tokens) - (select-keys (get cto/tokens-by-input input-type)) - (not-empty)))) + (let [raw-tokens (deref raw-tokens) + key-order (get cto/tokens-by-input input-type)] + (-> (reduce (fn [acc k] + (if (contains? raw-tokens k) + (assoc acc k (get raw-tokens k)) + acc)) + (array-map) + key-order) + (not-empty))))) (defn focusable-options [options] (filter #(= (:type %) :token) options)) \ No newline at end of file