mirror of
https://github.com/penpot/penpot.git
synced 2026-09-12 23:19:28 +00:00
♻️ Fix color token reviews (#7322)
* ♻️ Fix some review changes * 🐛 Fix more errors * 🎉 Create token from colorpicker fixed --------- Co-authored-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
09e9340ba6
commit
3f87e768a7
@ -362,7 +362,9 @@
|
|||||||
:id "harmony"}
|
:id "harmony"}
|
||||||
{:aria-label "HSVA"
|
{:aria-label "HSVA"
|
||||||
:icon i/hsva
|
:icon i/hsva
|
||||||
:id "hsva"}])]
|
:id "hsva"}])
|
||||||
|
|
||||||
|
show-tokens? (contains? #{:fill :stroke :color-selection} color-origin)]
|
||||||
|
|
||||||
;; Initialize colorpicker state
|
;; Initialize colorpicker state
|
||||||
(mf/with-effect []
|
(mf/with-effect []
|
||||||
@ -415,7 +417,7 @@
|
|||||||
:options options
|
:options options
|
||||||
:on-change handle-change-mode}]])
|
:on-change handle-change-mode}]])
|
||||||
|
|
||||||
(when (and (= origin :sidebar) token-color)
|
(when (and (= origin :sidebar) show-tokens? token-color)
|
||||||
[:& radio-buttons {:selected color-style
|
[:& radio-buttons {:selected color-style
|
||||||
:on-change toggle-token-color
|
:on-change toggle-token-color
|
||||||
:name "color-style"}
|
:name "color-style"}
|
||||||
@ -658,7 +660,9 @@
|
|||||||
:sets sets
|
:sets sets
|
||||||
:tokens (->> tokens
|
:tokens (->> tokens
|
||||||
(map #(get token-map %))
|
(map #(get token-map %))
|
||||||
(remove nil?)
|
(remove #(or (nil? %)
|
||||||
|
(:errors %)
|
||||||
|
(nil? (:resolved-value %))))
|
||||||
vec)})
|
vec)})
|
||||||
groups)))
|
groups)))
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,11 @@
|
|||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.main.constants :refer [max-input-length]]
|
[app.main.constants :refer [max-input-length]]
|
||||||
|
[app.main.data.common :as dcm]
|
||||||
[app.main.data.event :as-alias ev]
|
[app.main.data.event :as-alias ev]
|
||||||
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.workspace.tokens.application :as dwta]
|
[app.main.data.workspace.tokens.application :as dwta]
|
||||||
|
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||||
@ -21,8 +24,8 @@
|
|||||||
[app.main.ui.ds.utilities.swatch :refer [swatch*]]
|
[app.main.ui.ds.utilities.swatch :refer [swatch*]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.timers :as tm]
|
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
|
[potok.v2.core :as ptk]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(mf/defc token-empty-state*
|
(mf/defc token-empty-state*
|
||||||
@ -76,26 +79,27 @@
|
|||||||
:tooltip-content
|
:tooltip-content
|
||||||
(mf/html
|
(mf/html
|
||||||
[:*
|
[:*
|
||||||
[:div (dm/str (tr "workspace.tokens.token-name") ": " token-name)]
|
[:div
|
||||||
|
[:span (dm/str (tr "workspace.tokens.token-name") ": ")] [:span {:class (stl/css :token-name)} token-name]]
|
||||||
[:div (tr "workspace.tokens.resolved-value" resolved)]])
|
[:div (tr "workspace.tokens.resolved-value" resolved)]])
|
||||||
:on-click on-click
|
:on-click on-click
|
||||||
:size "medium"}]]))
|
:size "medium"}]]))
|
||||||
|
|
||||||
(defn group->set-name
|
(defn group->paths
|
||||||
"Given a group structure, returns a representative set name.
|
"Given a map with :group string (slash-separated), returns a set of vectors
|
||||||
|
representing the cumulative group hierarchy.
|
||||||
|
|
||||||
Input:
|
Example:
|
||||||
{:group \"brand\"
|
{:group \"test/gracia\"}
|
||||||
:sets [\"light\" \"dark\"]
|
=> #{[\"test\"] [\"test\" \"gracia\"]}"
|
||||||
:tokens [...]}
|
[m]
|
||||||
|
(let [parts (when-let [g (:group m)]
|
||||||
Output:
|
(str/split g #"/"))]
|
||||||
- If :group exists → \"brand/light\" (first set in :sets)
|
(if (seq parts)
|
||||||
- If :group is nil → the first (and only) value of :sets"
|
(->> (range 1 (inc (count parts)))
|
||||||
[{:keys [group sets]}]
|
(map (fn [i] (vec (take i parts))))
|
||||||
(if group
|
set)
|
||||||
(str group "/" (first sets))
|
#{})))
|
||||||
(first sets)))
|
|
||||||
|
|
||||||
(mf/defc set-section*
|
(mf/defc set-section*
|
||||||
{::mf/private true}
|
{::mf/private true}
|
||||||
@ -122,9 +126,10 @@
|
|||||||
selected-shapes
|
selected-shapes
|
||||||
(mf/with-memo [selected objects]
|
(mf/with-memo [selected objects]
|
||||||
(into [] (keep (d/getf objects)) selected))
|
(into [] (keep (d/getf objects)) selected))
|
||||||
first-shape (first selected-shapes)
|
|
||||||
applied-tokens (:applied-tokens first-shape)
|
first-shape (first selected-shapes)
|
||||||
has-color-tokens? (get applied-tokens :fill)
|
applied-tokens (:applied-tokens first-shape)
|
||||||
|
has-color-tokens? (get applied-tokens :fill)
|
||||||
has-stroke-tokens? (get applied-tokens :stroke-color)
|
has-stroke-tokens? (get applied-tokens :stroke-color)
|
||||||
|
|
||||||
on-token-pill-click
|
on-token-pill-click
|
||||||
@ -138,8 +143,8 @@
|
|||||||
(let [attributes (if (= color-origin :stroke) #{:stroke-color} #{:fill})
|
(let [attributes (if (= color-origin :stroke) #{:stroke-color} #{:fill})
|
||||||
shape-ids (into #{} (map :id selected-shapes))]
|
shape-ids (into #{} (map :id selected-shapes))]
|
||||||
(if (or
|
(if (or
|
||||||
(= (:name token) has-stroke-tokens?)
|
(and (= (:name token) has-stroke-tokens?) (= color-origin :stroke))
|
||||||
(= (:name token) has-color-tokens?))
|
(and (= (:name token) has-color-tokens?) (= color-origin :fill)))
|
||||||
(st/emit! (dwta/unapply-token {:attributes attributes
|
(st/emit! (dwta/unapply-token {:attributes attributes
|
||||||
:token token
|
:token token
|
||||||
:shape-ids shape-ids}))
|
:shape-ids shape-ids}))
|
||||||
@ -152,14 +157,30 @@
|
|||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps set)
|
(mf/deps set)
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [first-set-name (group->set-name set)
|
(let [;; We want to create a token on the first set
|
||||||
set-item-id (dm/str "token-set-item-" first-set-name)
|
;; if there are many in this group
|
||||||
set-element (dom/get-element set-item-id)]
|
complete-name (str (:group set) "/" (first (:sets set)))
|
||||||
(when set-element
|
path-set (group->paths set)]
|
||||||
(dom/click set-element)
|
(st/emit! (dcm/go-to-workspace :layout :tokens)
|
||||||
(tm/schedule-on-idle
|
(ptk/data-event :expand-token-sets {:paths path-set})
|
||||||
(let [button-element (dom/get-element "add-token-button-Color")]
|
(dwtl/set-selected-token-set-name complete-name)
|
||||||
#(dom/click button-element)))))))
|
(dwtl/set-token-type-section-open :color true)
|
||||||
|
(let [{:keys [modal title]} (get dwta/token-properties :color)
|
||||||
|
window-size (dom/get-window-size)
|
||||||
|
left-sidebar (dom/get-element "left-sidebar-aside")
|
||||||
|
x-size (dom/get-data left-sidebar "size")
|
||||||
|
modal-height 392
|
||||||
|
x (- (int x-size) 30)
|
||||||
|
y (- (/ (:height window-size) 2) (/ modal-height 2))]
|
||||||
|
(modal/show (:key modal)
|
||||||
|
{:x x
|
||||||
|
:y y
|
||||||
|
:position :right
|
||||||
|
:fields (:fields modal)
|
||||||
|
:title title
|
||||||
|
:action "create"
|
||||||
|
:token-type :color}))))))
|
||||||
|
|
||||||
icon-id (if collapsed i/arrow-right i/arrow-down)]
|
icon-id (if collapsed i/arrow-right i/arrow-down)]
|
||||||
|
|
||||||
[:article {:class (stl/css :color-token-set)}
|
[:article {:class (stl/css :color-token-set)}
|
||||||
@ -260,6 +281,7 @@
|
|||||||
filter-term (deref filter-term*)
|
filter-term (deref filter-term*)
|
||||||
open-sets* (mf/use-state sets)
|
open-sets* (mf/use-state sets)
|
||||||
open-sets (deref open-sets*)
|
open-sets (deref open-sets*)
|
||||||
|
|
||||||
toggle-sets-open
|
toggle-sets-open
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps open-sets)
|
(mf/deps open-sets)
|
||||||
@ -274,7 +296,8 @@
|
|||||||
(fn [event]
|
(fn [event]
|
||||||
(let [value (-> event (dom/get-target)
|
(let [value (-> event (dom/get-target)
|
||||||
(dom/get-value))]
|
(dom/get-value))]
|
||||||
(reset! filter-term* value))))
|
(reset! filter-term* value)
|
||||||
|
(reset! open-sets* sets))))
|
||||||
filtered-combined (filter-combined-tokens combined-tokens filter-term)
|
filtered-combined (filter-combined-tokens combined-tokens filter-term)
|
||||||
sorted-tokens (sort-combined-tokens filtered-combined)]
|
sorted-tokens (sort-combined-tokens filtered-combined)]
|
||||||
(if (seq combined-tokens)
|
(if (seq combined-tokens)
|
||||||
@ -286,15 +309,18 @@
|
|||||||
:class (stl/css :search-input)
|
:class (stl/css :search-input)
|
||||||
:default-value filter-term
|
:default-value filter-term
|
||||||
:on-change on-filter-tokens}]
|
:on-change on-filter-tokens}]
|
||||||
(for [combined-sets sorted-tokens]
|
(if (seq sorted-tokens)
|
||||||
(let [name (label-group-or-set combined-sets)]
|
[:div {:class (stl/css :color-tokens-inputs)}
|
||||||
[:> set-section*
|
(for [combined-sets sorted-tokens]
|
||||||
{:collapsed (not (contains? open-sets name))
|
(let [name (label-group-or-set combined-sets)]
|
||||||
:key (str "set-" name)
|
[:> set-section*
|
||||||
:toggle-sets-open toggle-sets-open
|
{:collapsed (not (contains? open-sets name))
|
||||||
:color-origin color-origin
|
:key (str "set-" name)
|
||||||
:on-token-change on-token-change
|
:toggle-sets-open toggle-sets-open
|
||||||
:name name
|
:color-origin color-origin
|
||||||
:set combined-sets}]))]
|
:on-token-change on-token-change
|
||||||
|
:name name
|
||||||
|
:set combined-sets}]))]
|
||||||
|
[:> token-empty-state*])]
|
||||||
[:> token-empty-state*])))
|
[:> token-empty-state*])))
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.token-selected-icon {
|
.token-selected-icon {
|
||||||
color: var(--color-foreground-secondary);
|
color: var(--color-accent-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.token-name {
|
.token-name {
|
||||||
@ -64,7 +64,6 @@
|
|||||||
|
|
||||||
.color-tokens-section {
|
.color-tokens-section {
|
||||||
max-height: $sz-430;
|
max-height: $sz-430;
|
||||||
overflow: auto;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--sp-s);
|
gap: var(--sp-s);
|
||||||
@ -87,6 +86,10 @@
|
|||||||
padding: $sz-1;
|
padding: $sz-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.color-tokens-inputs {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
// Title bar
|
// Title bar
|
||||||
.set-title-bar {
|
.set-title-bar {
|
||||||
--title-color: var(--color-foreground-secondary);
|
--title-color: var(--color-foreground-secondary);
|
||||||
@ -134,3 +137,7 @@
|
|||||||
.set-title-action-hidden {
|
.set-title-action-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.token-name {
|
||||||
|
color: var(--color-foreground-primary);
|
||||||
|
}
|
||||||
|
|||||||
@ -152,7 +152,7 @@
|
|||||||
:on-change #(on-change %1 color %2)
|
:on-change #(on-change %1 color %2)
|
||||||
:on-token-change #(on-token-change %1 %2 color)
|
:on-token-change #(on-token-change %1 %2 color)
|
||||||
:on-open on-open
|
:on-open on-open
|
||||||
:origin :color-selection-library
|
:origin :color-selection
|
||||||
:on-close on-close}]))
|
:on-close on-close}]))
|
||||||
(when (and (false? @expand-lib-color) (< 3 (count library-colors)))
|
(when (and (false? @expand-lib-color) (< 3 (count library-colors)))
|
||||||
[:button {:class (stl/css :more-colors-btn)
|
[:button {:class (stl/css :more-colors-btn)
|
||||||
|
|||||||
@ -81,24 +81,10 @@
|
|||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(st/emit! (dwtl/set-token-type-section-open type true)
|
(st/emit! (dwtl/set-token-type-section-open type true)
|
||||||
;; Normally the modal position is calculated by client-position,
|
(let [pos (dom/get-client-position event)]
|
||||||
;; but in some cases it is opened programmatically (not by a user click),
|
|
||||||
;; so we need to set its position explicitly.
|
|
||||||
(let [pos (dom/get-client-position event)
|
|
||||||
window-size (dom/get-window-size)
|
|
||||||
left-sidebar (dom/get-element "left-sidebar-aside")
|
|
||||||
x-size (dom/get-data left-sidebar "size")
|
|
||||||
modal-size {:width 452
|
|
||||||
:height 392}
|
|
||||||
x (if (= 0 (:x pos))
|
|
||||||
(- (int x-size) 30)
|
|
||||||
(:x pos))
|
|
||||||
y (if (= 0 (:y pos))
|
|
||||||
(- (/ (:height window-size) 2) (/ (:height modal-size) 2))
|
|
||||||
(:y pos))]
|
|
||||||
(modal/show (:key modal)
|
(modal/show (:key modal)
|
||||||
{:x x
|
{:x (:x pos)
|
||||||
:y y
|
:y (:y pos)
|
||||||
:position :right
|
:position :right
|
||||||
:fields (:fields modal)
|
:fields (:fields modal)
|
||||||
:title title
|
:title title
|
||||||
|
|||||||
@ -21,7 +21,9 @@
|
|||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
|
[beicon.v2.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
|
[potok.v2.core :as ptk]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(defn- on-start-creation
|
(defn- on-start-creation
|
||||||
@ -359,6 +361,16 @@
|
|||||||
(disj % path)
|
(disj % path)
|
||||||
(conj % path)))))]
|
(conj % path)))))]
|
||||||
|
|
||||||
|
(mf/with-effect []
|
||||||
|
(let [sub (rx/subs! (fn [paths']
|
||||||
|
(swap! collapsed-paths* (fn [paths] (apply disj paths paths'))))
|
||||||
|
(->> st/stream
|
||||||
|
(rx/filter (ptk/type? :expand-token-sets))
|
||||||
|
(rx/map deref)
|
||||||
|
(rx/map :paths)))]
|
||||||
|
(fn []
|
||||||
|
(rx/dispose! sub))))
|
||||||
|
|
||||||
(for [{:keys [id token-set index is-new is-group path parent-path depth] :as node}
|
(for [{:keys [id token-set index is-new is-group path parent-path depth] :as node}
|
||||||
(ctob/sets-tree-seq token-sets
|
(ctob/sets-tree-seq token-sets
|
||||||
{:skip-children-pred collapsed?
|
{:skip-children-pred collapsed?
|
||||||
@ -431,7 +443,6 @@
|
|||||||
:on-edit-submit on-edit-submit-set}]))))
|
:on-edit-submit on-edit-submit-set}]))))
|
||||||
|
|
||||||
(mf/defc controlled-sets-list*
|
(mf/defc controlled-sets-list*
|
||||||
{::mf/props :obj}
|
|
||||||
[{:keys [token-sets
|
[{:keys [token-sets
|
||||||
selected
|
selected
|
||||||
on-update-token-set
|
on-update-token-set
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user