0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-10 06:41:40 -05:00

Merge pull request #134 from tokens-studio/123-other-fields-to-update

Width/Height Token Changing from the sidebar
This commit is contained in:
Florian Schrödl 2024-05-24 11:46:45 +02:00 committed by GitHub
commit 968c6437fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 108 additions and 43 deletions

View file

@ -99,12 +99,30 @@
selection-parents (mf/deref selection-parents-ref) selection-parents (mf/deref selection-parents-ref)
tokens (mf/deref refs/workspace-tokens) tokens (mf/deref refs/workspace-tokens)
border-radius-tokens (mf/use-memo (mf/deps tokens) #(wtc/tokens-name-map-for-type :border-radius tokens)) tokens-by-type (mf/use-memo (mf/deps tokens) #(wtc/group-tokens-by-type tokens))
border-radius-options (mf/use-memo (mf/deps shape border-radius-tokens)
#(map (fn [[_k {:keys [name] :as item}]] border-radius-tokens (:border-radius tokens-by-type)
(cond-> (assoc item :label name) border-radius-options (mf/use-memo
(wtc/token-applied? item shape (wtc/token-attributes :border-radius)) (assoc :selected? true))) (mf/deps shape border-radius-tokens)
border-radius-tokens)) #(wtc/tokens-name-map->select-options
{:shape shape
:tokens border-radius-tokens
:attributes (wtc/token-attributes :border-radius)}))
sizing-tokens (:sizing tokens-by-type)
width-options (mf/use-memo
(mf/deps shape sizing-tokens)
#(wtc/tokens-name-map->select-options
{:shape shape
:tokens sizing-tokens
:attributes (wtc/token-attributes :sizing)
:selected-attributes #{:width}}))
height-options (mf/use-memo
(mf/deps shape sizing-tokens)
#(wtc/tokens-name-map->select-options
{:shape shape
:tokens sizing-tokens
:attributes (wtc/token-attributes :sizing)
:selected-attributes #{:height}}))
flex-child? (->> selection-parents (some ctl/flex-layout?)) flex-child? (->> selection-parents (some ctl/flex-layout?))
absolute? (ctl/item-absolute? shape) absolute? (ctl/item-absolute? shape)
@ -219,8 +237,17 @@
(mf/use-fn (mf/use-fn
(mf/deps ids) (mf/deps ids)
(fn [value attr] (fn [value attr]
(st/emit! (udw/trigger-bounding-box-cloaking ids) (let [token-value (wtc/maybe-resolve-token-value value)]
(udw/update-dimensions ids attr value)))) (st/emit! (udw/trigger-bounding-box-cloaking ids)
(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))))))
on-proportion-lock-change on-proportion-lock-change
(mf/use-fn (mf/use-fn
@ -293,9 +320,9 @@
on-border-radius-token-unapply on-border-radius-token-unapply
(mf/use-fn (mf/use-fn
(mf/deps ids change-radius border-radius-tokens) (mf/deps ids change-radius)
(fn [token] (fn [token]
(let [token-value (some-> token wtc/resolve-token-value)] (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 (wtc/token-attributes :border-radius)) (-> (dt/unapply-token-id shape (wtc/token-attributes :border-radius))
@ -303,13 +330,12 @@
on-radius-1-change on-radius-1-change
(mf/use-fn (mf/use-fn
(mf/deps ids change-radius border-radius-tokens) (mf/deps ids change-radius)
(fn [value] (fn [value]
(let [token (when (map? value) value) (let [token-value (wtc/maybe-resolve-token-value value)]
token-value (some-> token wtc/resolve-token-value)]
(st/emit! (st/emit!
(change-radius (fn [shape] (change-radius (fn [shape]
(-> (dt/maybe-apply-token-to-shape {:token token (-> (dt/maybe-apply-token-to-shape {:token (when token-value value)
:shape shape :shape shape
:attributes (wtc/token-attributes :border-radius)}) :attributes (wtc/token-attributes :border-radius)})
(ctsr/set-radius-1 (or token-value value))))))))) (ctsr/set-radius-1 (or token-value value)))))))))
@ -422,24 +448,36 @@
:disabled disabled-width-sizing?) :disabled disabled-width-sizing?)
:title (tr "workspace.options.width")} :title (tr "workspace.options.width")}
[:span {:class (stl/css :icon-text)} "W"] [:span {:class (stl/css :icon-text)} "W"]
[:> numeric-input* {:min 0.01 [:& editable-select
:no-validate true {:placeholder (if (= :multiple (:rx values)) (tr "settings.multiple") "--")
:placeholder (if (= :multiple (:width values)) (tr "settings.multiple") "--") :no-validate true
:on-change on-width-change :min 0.01
:disabled disabled-width-sizing? :class (stl/css :token-select)
:className (stl/css :numeric-input) :disabled disabled-width-sizing?
:value (:width values)}]] :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)}]]
[:div {:class (stl/css-case :height true [:div {:class (stl/css-case :height true
:disabled disabled-height-sizing?) :disabled disabled-height-sizing?)
:title (tr "workspace.options.height")} :title (tr "workspace.options.height")}
[:span {:class (stl/css :icon-text)} "H"] [:span {:class (stl/css :icon-text)} "H"]
[:> numeric-input* {:min 0.01 [:& editable-select
:no-validate true {:placeholder (if (= :multiple (:rx values)) (tr "settings.multiple") "--")
:placeholder (if (= :multiple (:height values)) (tr "settings.multiple") "--") :no-validate true
:on-change on-height-change :min 0.01
:disabled disabled-height-sizing? :class (stl/css :token-select)
:className (stl/css :numeric-input) :disabled disabled-height-sizing?
:value (:height values)}]] :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)}]]
[:button {:class (stl/css-case [:button {:class (stl/css-case
:lock-size-btn true :lock-size-btn true
:selected (true? proportion-lock) :selected (true? proportion-lock)
@ -498,13 +536,14 @@
[:span {:class (stl/css :icon)} i/corner-radius] [:span {:class (stl/css :icon)} i/corner-radius]
[:& editable-select [:& editable-select
{:placeholder (if (= :multiple (:rx values)) (tr "settings.multiple") "--") {:placeholder (if (= :multiple (:rx values)) (tr "settings.multiple") "--")
:on-token-remove on-border-radius-token-unapply
:class (stl/css :token-select)
:type "number"
:min 0 :min 0
:class (stl/css :token-select)
:input-class (stl/css :numeric-input) :input-class (stl/css :numeric-input)
:on-change on-radius-1-change :on-change on-radius-1-change
:on-token-remove on-border-radius-token-unapply
:options border-radius-options :options border-radius-options
:position :right
:type "number"
:value (:rx values)}]] :value (:rx values)}]]
@radius-multi? @radius-multi?

View file

@ -109,6 +109,7 @@
.size { .size {
@include flexRow; @include flexRow;
position: relative;
} }
.height, .height,
@ -182,6 +183,7 @@
.radius-1 { .radius-1 {
@extend .input-element; @extend .input-element;
width: $s-108; width: $s-108;
position: relative;
} }
.radius-4 { .radius-4 {

View file

@ -37,6 +37,9 @@
int-or-double int-or-double
(throw (ex-info (str "Implement token value resolve for " value) token)))) (throw (ex-info (str "Implement token value resolve for " value) token))))
(defn maybe-resolve-token-value [{:keys [value] :as token}]
(when value (resolve-token-value token)))
(defn group-tokens-by-type (defn group-tokens-by-type
"Groups tokens by their `:type` property." "Groups tokens by their `:type` property."
[tokens] [tokens]
@ -60,6 +63,12 @@
(get token-type []) (get token-type [])
(tokens-name-map))) (tokens-name-map)))
(defn tokens-name-map->select-options [{:keys [shape tokens attributes selected-attributes]}]
(->> (tokens-name-map tokens)
(map (fn [[_k {:keys [name] :as item}]]
(cond-> (assoc item :label name)
(token-applied? item shape (or selected-attributes attributes)) (assoc :selected? true))))))
;; Update functions ------------------------------------------------------------ ;; Update functions ------------------------------------------------------------
(defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}] (defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}]

View file

@ -38,11 +38,13 @@
:else new-value)] :else new-value)]
(set-value! new-value))))) (set-value! new-value)))))
(mf/defc dropdown-select [{:keys [on-close element-id element-ref options on-select]}] (mf/defc dropdown-select [{:keys [position on-close element-id element-ref options on-select]}]
[:& dropdown {:show true [:& dropdown {:show true
:on-close on-close} :on-close on-close}
[:div {:class (stl/css :custom-select-dropdown) [:> :div {:class (stl/css-case :custom-select-dropdown true
:ref element-ref} :custom-select-dropdown-right (= position :right)
:custom-select-dropdown-left (= position :left))
:ref element-ref}
[:ul {:class (stl/css :custom-select-dropdown-list)} [:ul {:class (stl/css :custom-select-dropdown-list)}
(for [[index item] (d/enumerate options)] (for [[index item] (d/enumerate options)]
(cond (cond
@ -60,7 +62,7 @@
[:span {:class (stl/css :check-icon)} i/tick]])))]]]) [:span {:class (stl/css :check-icon)} i/tick]])))]]])
(mf/defc editable-select (mf/defc editable-select
[{:keys [value type options class on-change placeholder on-blur input-class on-token-remove] :as params}] [{: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) (let [state* (mf/use-state {:id (uuid/next)
:is-open? false :is-open? false
:current-value value :current-value value
@ -133,6 +135,12 @@
value (or (d/parse-double value) value)] value (or (d/parse-double value) value)]
(set-value value))) (set-value value)))
handle-token-change-input
(fn [event]
(let [value (-> event dom/get-target dom/get-value)
value (or (d/parse-double value) value)]
(set-token-value! value)))
handle-key-down handle-key-down
(mf/use-fn (mf/use-fn
(mf/deps set-value is-open? token) (mf/deps set-value is-open? token)
@ -141,7 +149,7 @@
token (let [backspace? (kbd/backspace? event) token (let [backspace? (kbd/backspace? event)
enter? (kbd/enter? event) enter? (kbd/enter? event)
value (-> event dom/get-target dom/get-value) value (-> event dom/get-target dom/get-value)
caret-at-beginning? (nil? (.. event -target -selectionStart)) caret-at-beginning? (zero? (.. event -target -selectionStart))
no-text-selected? (str/empty? (.toString (js/document.getSelection))) no-text-selected? (str/empty? (.toString (js/document.getSelection)))
delete-token? (and backspace? caret-at-beginning? no-text-selected?) delete-token? (and backspace? caret-at-beginning? no-text-selected?)
replace-token-with-value? (and enter? (seq (str/trim value)))] replace-token-with-value? (and enter? (seq (str/trim value)))]
@ -212,11 +220,10 @@
(cond (cond
token [:input {:value (or (:token-value state) "") token [:input {:value (or (:token-value state) "")
:class input-class :class input-class
:on-change handle-change-input :on-change handle-token-change-input
:on-key-down handle-key-down :on-key-down handle-key-down
:on-focus handle-focus :on-focus handle-focus
:on-blur handle-blur :on-blur handle-blur}]
:type type}]
(= type "number") [:> numeric-input* {:autoFocus refocus? (= type "number") [:> numeric-input* {:autoFocus refocus?
:value (or current-value "") :value (or current-value "")
:className input-class :className input-class
@ -239,7 +246,8 @@
i/arrow]) i/arrow])
(when (and is-open? (seq options)) (when (and is-open? (seq options))
[:& dropdown-select {:on-close close-dropdown [:& dropdown-select {:position position
:on-close close-dropdown
:element-id element-id :element-id element-id
:element-ref select-wrapper-ref :element-ref select-wrapper-ref
:options options :options options

View file

@ -9,7 +9,6 @@
.editable-select { .editable-select {
@extend .asset-element; @extend .asset-element;
margin: 0; margin: 0;
position: relative;
display: flex; display: flex;
height: calc($s-32 - 2px); // Fixes border being clipped by the input field height: calc($s-32 - 2px); // Fixes border being clipped by the input field
width: 100%; width: 100%;
@ -62,13 +61,21 @@
width: 0; width: 0;
} }
.custom-select-dropdown-left {
left: 0;
right: unset;
}
.custom-select-dropdown-right {
right: 0;
left: unset;
}
.custom-select-dropdown { .custom-select-dropdown {
@extend .dropdown-wrapper; @extend .dropdown-wrapper;
max-height: $s-320; max-height: $s-320;
width: auto; width: auto;
margin-top: $s-4; margin-top: $s-4;
right: 0;
left: unset;
.separator { .separator {
margin: 0; margin: 0;