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 b7a5dde44..69842124e 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 @@ -27,6 +27,8 @@ [app.main.ui.formats :as fmt] [app.main.ui.hooks :as h] [app.main.ui.icons :as i] + [app.main.ui.workspace.tokens.core :as wtc] + [app.main.ui.workspace.tokens.editable-select :refer [editable-select]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.keyboard :as kbd] @@ -507,7 +509,7 @@ (mf/defc gap-section {::mf/props :obj} - [{:keys [is-column wrap-type on-change value] + [{:keys [is-column wrap-type on-change value spacing-column-options spacing-row-options] :or {wrap-type :none} :as props}] (let [nowrap? (= :nowrap wrap-type) @@ -541,38 +543,45 @@ :disabled row-gap-disabled?) :title "Row gap"} [:span {:class (stl/css :icon)} i/gap-vertical] - [:> numeric-input* - {:class (stl/css :numeric-input true) - :no-validate true + [:& editable-select + {:disabled row-gap-disabled? :placeholder "--" - :data-type "row-gap" - :data-wrap-type (d/name wrap-type) - :on-focus on-gap-focus :on-change on-change' :on-blur on-gap-blur - :nillable true - :min 0 + :on-token-remove js/console.log + :options spacing-column-options + :position :left :value (:row-gap value) - :disabled row-gap-disabled?}]] + :input-props {:type "number" + :data-type "row-gap" + :data-wrap-type (d/name wrap-type) + :no-validate true + :nillable true + :min 0 + :class (stl/css :numeric-input)}}]] [:div {:class (stl/css-case :column-gap true :disabled col-gap-disabled?) :title "Column gap"} [:span {:class (stl/css :icon)} i/gap-horizontal] - [:> numeric-input* - {:class (stl/css :numeric-input true) - :no-validate true + [:& editable-select + {:disabled col-gap-disabled? :placeholder "--" - :data-type "column-gap" - :data-wrap-type (d/name wrap-type) - :on-focus on-gap-focus :on-change on-change' :on-blur on-gap-blur - :nillable true - :min 0 + :on-token-remove js/console.log + :options spacing-row-options + :position :right :value (:column-gap value) - :disabled col-gap-disabled?}]]])) + :input-props {:type "number" + :data-type "column-gap" + :data-wrap-type (d/name wrap-type) + :no-validate true + :onFocus on-gap-focus + :nillable true + :min 0 + :class (stl/css :numeric-input)}}]]])) ;; GRID COMPONENTS @@ -823,9 +832,9 @@ (st/emit! (dom/open-new-window cf/grid-help-uri))) (mf/defc layout-container-menu - {::mf/memo #{:ids :values :multiple} + {::mf/memo #{:ids :values :multiple :shape} ::mf/props :obj} - [{:keys [ids values multiple]}] + [{:keys [ids values multiple] :as props}] (let [;; Display layout-type (:layout values) has-layout? (some? layout-type) @@ -839,6 +848,29 @@ on-toggle-visibility (mf/use-fn #(swap! open* not)) + shape (when-not multiple + (first (deref (refs/objects-by-id ids)))) + tokens (mf/deref refs/workspace-tokens) + spacing-tokens (mf/use-memo (mf/deps tokens) #(:spacing (wtc/group-tokens-by-type tokens))) + + spacing-column-options (mf/use-memo + (mf/deps shape spacing-tokens) + #(when shape + (wtc/tokens-name-map->select-options + {:shape shape + :tokens spacing-tokens + :attributes (wtc/token-attributes :spacing) + :selected-attributes #{:spacing-column}}))) + + spacing-row-options (mf/use-memo + (mf/deps shape spacing-tokens) + #(when shape + (wtc/tokens-name-map->select-options + {:shape shape + :tokens spacing-tokens + :attributes (wtc/token-attributes :spacing) + :selected-attributes #{:spacing-row}}))) + on-add-layout (mf/use-fn (fn [event] @@ -1084,7 +1116,9 @@ [:& gap-section {:is-column is-column :wrap-type wrap-type :on-change on-gap-change - :value (:layout-gap values)}] + :value (:layout-gap values) + :spacing-column-options spacing-column-options + :spacing-row-options spacing-row-options}] [:& padding-section {:value (:layout-padding values) :type (:layout-padding-type values) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss index a51118e29..c86ff11ae 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss @@ -84,6 +84,7 @@ gap: $s-4; .column-gap { @extend .input-element; + position: relative; width: $s-108; &.disabled { @extend .disabled-input; @@ -91,6 +92,7 @@ } .row-gap { @extend .input-element; + position: relative; width: $s-108; &.disabled { @extend .disabled-input; diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index 0a4aeef63..2362d9c19 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -237,15 +237,18 @@ (mf/use-fn (mf/deps ids) (fn [value attr] - (let [token-value (wtc/maybe-resolve-token-value value)] + (let [token-value (wtc/maybe-resolve-token-value value) + undo-id (js/Symbol)] (st/emit! (udw/trigger-bounding-box-cloaking ids) + (dwu/start-undo-transaction undo-id) (dch/update-shapes ids (if token-value #(assoc-in % [:applied-tokens attr] (:id value)) #(d/dissoc-in % [:applied-tokens attr])) {:reg-objects? true :attrs [:applied-tokens]}) - (udw/update-dimensions ids attr (or token-value value)))))) + (udw/update-dimensions ids attr (or token-value value)) + (dwu/commit-undo-transaction undo-id))))) @@ -450,34 +453,32 @@ [:span {:class (stl/css :icon-text)} "W"] [:& editable-select {:placeholder (if (= :multiple (:rx values)) (tr "settings.multiple") "--") - :no-validate true - :min 0.01 :class (stl/css :token-select) :disabled disabled-width-sizing? - :input-class (stl/css :numeric-input) :on-change on-width-change :on-token-remove #(on-width-change (wtc/maybe-resolve-token-value %)) :options width-options :position :left - :type "number" - :value (:width values)}]] + :value (:width values) + :input-props {:type "number" + :no-validate true + :min 0.01}}]] [:div {:class (stl/css-case :height true :disabled disabled-height-sizing?) :title (tr "workspace.options.height")} [:span {:class (stl/css :icon-text)} "H"] [:& editable-select {:placeholder (if (= :multiple (:rx values)) (tr "settings.multiple") "--") - :no-validate true - :min 0.01 :class (stl/css :token-select) :disabled disabled-height-sizing? - :input-class (stl/css :numeric-input) :on-change on-height-change :on-token-remove #(on-height-change (wtc/maybe-resolve-token-value %)) :options height-options :position :right - :type "number" - :value (:height values)}]] + :value (:height values) + :input-props {:type "number" + :no-validate true + :min 0.01}}]] [:button {:class (stl/css-case :lock-size-btn true :selected (true? proportion-lock) @@ -536,15 +537,14 @@ [:span {:class (stl/css :icon)} i/corner-radius] [:& editable-select {:placeholder (if (= :multiple (:rx values)) (tr "settings.multiple") "--") - :min 0 :class (stl/css :token-select) - :input-class (stl/css :numeric-input) :on-change on-radius-1-change :on-token-remove on-border-radius-token-unapply :options border-radius-options :position :right - :type "number" - :value (:rx values)}]] + :value (:rx values) + :input-props {:type "number" + :min 0}}]] @radius-multi? [:div {:class (stl/css :radius-1) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.scss index 10bbf5056..b10cc6b9d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.scss @@ -238,10 +238,3 @@ .checkbox-button { @extend .button-icon; } - -.token-select { - li > span { - display: flex; - align-content: center; - } -} diff --git a/frontend/src/app/main/ui/workspace/tokens/editable_select.cljs b/frontend/src/app/main/ui/workspace/tokens/editable_select.cljs index 6c487cbd3..90834ff56 100644 --- a/frontend/src/app/main/ui/workspace/tokens/editable_select.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/editable_select.cljs @@ -62,8 +62,10 @@ [:span {:class (stl/css :check-icon)} i/tick]])))]]]) (mf/defc editable-select - [{:keys [value type options class on-change placeholder on-blur input-class on-token-remove position] :as params}] - (let [state* (mf/use-state {:id (uuid/next) + [{:keys [value options disabled class on-change placeholder on-blur on-token-remove position input-props] :as params}] + (let [{:keys [type]} input-props + input-class (:class input-props) + state* (mf/use-state {:id (uuid/next) :is-open? false :current-value value :token-value nil @@ -107,11 +109,11 @@ (swap! state* assoc :token-value value)) set-value - (fn [value] + (fn [value event] (swap! state* assoc :current-value value :token-value value) - (when on-change (on-change value))) + (when on-change (on-change value event))) select-item (mf/use-fn @@ -133,7 +135,7 @@ (fn [event] (let [value (-> event dom/get-target dom/get-value) value (or (d/parse-double value) value)] - (set-value value))) + (set-value value event))) handle-token-change-input (fn [event] @@ -153,6 +155,7 @@ no-text-selected? (str/empty? (.toString (js/document.getSelection))) delete-token? (and backspace? caret-at-beginning? no-text-selected?) replace-token-with-value? (and enter? (seq (str/trim value)))] + (js/console.log "key-down" token delete-token?) (cond delete-token? (do (dom/prevent-default event) @@ -212,37 +215,42 @@ (mf/set-ref-val! emit-blur? (not is-open?))) - [:div {:class (dm/str class " " (stl/css :editable-select))} + [:div {:class (dm/str class " " (stl/css-case :editable-select true + :editable-select-disabled disabled))} (when-let [{:keys [label value]} token] [:div {:title (str label ": " value) :class (stl/css :token-pill)} value]) (cond - token [:input {:value (or (:token-value state) "") - :class input-class - :on-change handle-token-change-input - :on-key-down handle-key-down - :on-focus handle-focus - :on-blur handle-blur}] - (= type "number") [:> numeric-input* {:autoFocus refocus? - :value (or current-value "") - :className input-class - :on-change set-value - :on-focus handle-focus - :on-blur handle-blur - :placeholder placeholder}] - :else [:input {:value (or current-value "") - :class input-class - :on-change handle-change-input - :on-key-down handle-key-down - :on-focus handle-focus - :on-blur handle-blur - :placeholder placeholder - :type type}]) + token [:& :input (merge input-props + {:value (or (:token-value state) "") + :type "text" + :class input-class + :onChange handle-token-change-input + :onKeyDown handle-key-down + :onFocus handle-focus + :onBlur handle-blur})] + (= type "number") [:& numeric-input* (merge input-props + {:autoFocus refocus? + :value (or current-value "") + :className input-class + :onChange set-value + :onFocus handle-focus + :onBlur handle-blur + :placeholder placeholder})] + :else [:& :input (merge input-props + {:value (or current-value "") + :class input-class + :onChange handle-change-input + :onKeyDown handle-key-down + :onFocus handle-focus + :onBlur handle-blur + :placeholder placeholder + :type type})]) (when (seq options) - [:span {:class (stl/css :dropdown-button) - :on-click toggle-dropdown} + [:div {:class (stl/css :dropdown-button) + :on-click toggle-dropdown} i/arrow]) (when (and is-open? (seq options)) diff --git a/frontend/src/app/main/ui/workspace/tokens/editable_select.scss b/frontend/src/app/main/ui/workspace/tokens/editable_select.scss index 3f0eb03f9..4fbd3e593 100644 --- a/frontend/src/app/main/ui/workspace/tokens/editable_select.scss +++ b/frontend/src/app/main/ui/workspace/tokens/editable_select.scss @@ -30,6 +30,7 @@ .dropdown-button { @include flexCenter; margin-right: -$s-8; + padding-right: $s-8; padding-left: 0; aspect-ratio: 0.8 / 1; width: auto; @@ -88,6 +89,12 @@ padding: 0; display: flex; + & > span { + display: flex; + justify-content: flex-start; + align-content: center; + } + .label, .value { width: fit-content; @@ -100,6 +107,7 @@ .value { text-align: right; + justify-content: flex-end; flex: 0.6; } @@ -130,3 +138,7 @@ } } } + +.editable-select-disabled { + pointer-events: none; +}