0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-06 14:50:20 -05:00

Merge pull request #128 from tokens-studio/119-higlight-applied-token-in-the-editing-field

Show token value inside shapes panel (border-radius)
This commit is contained in:
Florian Schrödl 2024-05-23 08:43:51 +02:00 committed by GitHub
commit 2818d097ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 110 additions and 42 deletions

View file

@ -6,6 +6,7 @@
(ns app.main.data.tokens
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.changes-builder :as pcb]
[app.common.geom.point :as gpt]
@ -57,6 +58,9 @@
(->> (map (fn [attr] [attr token-id]) attributes)
(into {})))
(defn unapply-token-id [shape attributes]
(update shape :applied-tokens d/without-keys attributes))
(defn apply-token-id-to-attributes [{:keys [shape token-id attributes]}]
(let [token (token-from-attributes token-id attributes)]
(toggle-or-apply-token shape token)))

View file

@ -291,6 +291,16 @@
(on-switch-to-radius-4)
(on-switch-to-radius-1))))
on-border-radius-token-unapply
(mf/use-fn
(mf/deps ids change-radius border-radius-tokens)
(fn [token]
(let [token-value (some-> token wtc/resolve-token-value)]
(st/emit!
(change-radius (fn [shape]
(-> (dt/unapply-token-id shape (wtc/token-attributes :border-radius))
(ctsr/set-radius-1 token-value))))))))
on-radius-1-change
(mf/use-fn
(mf/deps ids change-radius border-radius-tokens)
@ -488,6 +498,7 @@
[:span {:class (stl/css :icon)} i/corner-radius]
[:& editable-select
{: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

View file

@ -13,7 +13,6 @@
[app.main.data.workspace :as udw]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.transforms :as dwt]
[app.main.store :as st]))

View file

@ -17,6 +17,7 @@
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
[app.util.timers :as timers]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(defn on-number-input-key-down [{:keys [event min-val max-val set-value!]}]
@ -59,22 +60,28 @@
[:span {:class (stl/css :check-icon)} i/tick]])))]]])
(mf/defc editable-select
[{:keys [value type options class on-change placeholder on-blur input-class] :as params}]
[{:keys [value type options class on-change placeholder on-blur input-class on-token-remove] :as params}]
(let [state* (mf/use-state {:id (uuid/next)
:is-open? false
:current-value value
:token-value nil
:current-item nil
:top nil
:left nil
:bottom nil})
state (deref state*)
is-open? (:is-open? state)
refocus? (:refocus? state)
current-value (:current-value state)
element-id (:id state)
min-val (get params :min)
max-val (get params :max)
multiple? (= :multiple value)
token (when-not multiple?
(-> (filter :selected? options) (first)))
emit-blur? (mf/use-ref nil)
select-wrapper-ref (mf/use-ref)
@ -93,9 +100,15 @@
options)
(into {}))
set-token-value!
(fn [value]
(swap! state* assoc :token-value value))
set-value
(fn [value]
(swap! state* assoc :current-value value)
(swap! state* assoc
:current-value value
:token-value value)
(when on-change (on-change value)))
select-item
@ -109,6 +122,7 @@
{:keys [value] :as item} (get labels-map label)]
(swap! state* assoc
:current-value value
:token-value nil
:current-item item)
(when on-change (on-change item))
(when on-blur (on-blur)))))
@ -119,32 +133,33 @@
value (or (d/parse-double value) value)]
(set-value value)))
on-node-load
(fn [node]
;; There is a problem when changing the state in this callback that
;; produces the dropdown to close in the same event
(when node
(timers/schedule
#(when-let [bounds (when node (dom/get-bounding-rect node))]
(let [{window-height :height} (dom/get-window-size)
{:keys [left top height]} bounds
bottom (when (< (- window-height top) 300) (- window-height top))
top (when (>= (- window-height top) 300) (+ top height))]
(swap! state*
assoc
:left left
:top top
:bottom bottom))))))
handle-key-down
(mf/use-fn
(mf/deps set-value is-open?)
(fn [event]
(mf/deps set-value is-open? token)
(fn [^js event]
(cond
token (let [backspace? (kbd/backspace? event)
enter? (kbd/enter? event)
value (-> event dom/get-target dom/get-value)
caret-at-beginning? (nil? (.. event -target -selectionStart))
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)))]
(cond
delete-token? (do
(dom/prevent-default event)
(on-token-remove token)
;; Re-focus the input value of the newly rendered input element
(swap! state* assoc :refocus? true))
replace-token-with-value? (do
(dom/prevent-default event)
(on-token-remove token)
(handle-change-input event)
(set-token-value! nil))
:else (set-token-value! value)))
is-open? (let [up? (kbd/up-arrow? event)
down? (kbd/down-arrow? event)]
(dom/prevent-default event)
(js/console.log "up? down?" up? down?))
(dom/prevent-default event))
(= type "number") (on-number-input-key-down {:event event
:min-val min-val
:max-val max-val
@ -152,13 +167,17 @@
handle-focus
(mf/use-fn
(mf/deps refocus?)
(fn []
(when refocus?
(swap! state* dissoc :refocus?))
(mf/set-ref-val! emit-blur? false)))
handle-blur
(mf/use-fn
(fn []
(mf/set-ref-val! emit-blur? true)
(swap! state* assoc :token-value nil)
(timers/schedule
200
(fn []
@ -167,7 +186,7 @@
(mf/use-effect
(mf/deps value current-value)
#(when (not= (str value) current-value)
(reset! state* {:current-value value})))
(swap! state* assoc :current-value value)))
(mf/with-effect [is-open?]
(let [wrapper-node (mf/ref-val select-wrapper-ref)
@ -185,23 +204,34 @@
(mf/set-ref-val! emit-blur? (not is-open?)))
[:div {:class (dm/str class " " (stl/css :editable-select))
:ref on-node-load}
(if (= type "number")
[:> numeric-input* {:value (or current-value "")
:className input-class
:on-change set-value
:on-focus handle-focus
:on-blur handle-blur
:placeholder placeholder}]
[: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}])
[:div {:class (dm/str class " " (stl/css :editable-select))}
(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-change-input
:on-key-down handle-key-down
:on-focus handle-focus
:on-blur handle-blur
:type type}]
(= 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}])
(when (seq options)
[:span {:class (stl/css :dropdown-button)

View file

@ -17,6 +17,17 @@
border-radius: $br-8;
cursor: pointer;
background: transparent;
&:hover {
background: transparent;
}
&:focus-within {
.token-pill {
background-color: var(--button-primary-background-color-rest);
color: var(--button-primary-foreground-color-rest);
}
}
.dropdown-button {
@include flexCenter;
margin-right: -$s-8;
@ -38,6 +49,19 @@
margin-bottom: 0;
}
.token-pill {
background-color: rgb(94 107 120 / 25%);
border-radius: $br-4;
padding: $s-2 $s-6;
text-overflow: ellipsis;
flex: 0 0 auto;
}
.token-pill + input {
flex: 1 1 auto;
width: 0;
}
.custom-select-dropdown {
@extend .dropdown-wrapper;
max-height: $s-320;