mirror of
https://github.com/penpot/penpot.git
synced 2025-02-01 11:59:17 -05:00
✨ Add viewer role to theme selection
This commit is contained in:
parent
554311cd1f
commit
3e2a6d7e0b
5 changed files with 185 additions and 22 deletions
|
@ -78,7 +78,7 @@
|
|||
active-theme-paths (mf/deref refs/workspace-active-theme-paths-no-hidden)
|
||||
active-themes-count (count active-theme-paths)
|
||||
themes (mf/deref refs/workspace-token-theme-tree-no-hidden)
|
||||
|
||||
can-edit? (:can-edit (deref refs/permissions))
|
||||
;; Data
|
||||
current-label (cond
|
||||
(> active-themes-count 1) (tr "workspace.token.active-themes" active-themes-count)
|
||||
|
@ -97,15 +97,23 @@
|
|||
;; Dropdown
|
||||
dropdown-element* (mf/use-ref nil)
|
||||
on-close-dropdown (mf/use-fn #(swap! state* assoc :is-open? false))
|
||||
on-open-dropdown (mf/use-fn #(swap! state* assoc :is-open? true))]
|
||||
|
||||
on-open-dropdown
|
||||
(mf/use-fn
|
||||
(mf/deps can-edit?)
|
||||
(fn []
|
||||
(when can-edit?
|
||||
(swap! state* assoc :is-open? true))))]
|
||||
|
||||
;; TODO: This element should be accessible by keyboard
|
||||
[:div {:on-click on-open-dropdown
|
||||
:disabled (not can-edit?)
|
||||
:aria-expanded is-open?
|
||||
:aria-haspopup "listbox"
|
||||
:tab-index "0"
|
||||
:role "combobox"
|
||||
:class (stl/css :custom-select)}
|
||||
:class (stl/css-case :custom-select true
|
||||
:disabled-select (not can-edit?))}
|
||||
[:> text* {:as "span" :typography "body-small" :class (stl/css :current-label)}
|
||||
current-label]
|
||||
[:> icon* {:icon-id i/arrow-down :class (stl/css :dropdown-button) :aria-hidden true}]
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
|
||||
.disabled {
|
||||
.disabled-select {
|
||||
--custom-select-bg-color: var(--menu-background-color-disabled);
|
||||
--custom-select-border-color: var(--menu-border-color-disabled);
|
||||
--custom-select-icon-color: var(--menu-foreground-color-disabled);
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
(ns app.main.ui.workspace.tokens.token-pill
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require-macros
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.components.color-bullet :refer [color-bullet]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon*]]
|
||||
|
@ -13,16 +16,135 @@
|
|||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
;; Translation dictionaries
|
||||
(def ^:private attribute-dictionary
|
||||
{:rotation "Rotation"
|
||||
:opacity "Opacity"
|
||||
:stroke-width "Stroke Width"
|
||||
|
||||
;; Spacing
|
||||
:p1 "Top" :p2 "Right" :p3 "Bottom" :p4 "Left"
|
||||
:column-gap "Column Gap" :row-gap "Row Gap"
|
||||
|
||||
;; Sizing
|
||||
:width "Width"
|
||||
:height "Height"
|
||||
:layout-item-min-w "Min Width"
|
||||
:layout-item-min-h "Min Height"
|
||||
:layout-item-max-w "Max Width"
|
||||
:layout-item-max-h "Max Height"
|
||||
|
||||
;; Border Radius
|
||||
:r1 "Top Left" :r2 "Top Right" :r4 "Bottom Left" :r3 "Bottom Right"
|
||||
|
||||
;; Dimensions
|
||||
:x "X" :y "Y"
|
||||
|
||||
;; Color
|
||||
:fill "Fill"
|
||||
:stroke-color "Stroke Color"})
|
||||
|
||||
(def ^:private dimensions-dictionary
|
||||
{:stroke-width :stroke-width
|
||||
:p1 :spacing
|
||||
:p2 :spacing
|
||||
:p3 :spacing
|
||||
:p4 :spacing
|
||||
:column-gap :spacing
|
||||
:row-gap :spacing
|
||||
:width :sizing
|
||||
:height :sizing
|
||||
:layout-item-min-w :sizing
|
||||
:layout-item-min-h :sizing
|
||||
:layout-item-max-w :sizing
|
||||
:layout-item-max-h :sizing
|
||||
:r1 :border-radius
|
||||
:r2 :border-radius
|
||||
:r4 :border-radius
|
||||
:r3 :border-radius
|
||||
:x :x
|
||||
:y :y})
|
||||
|
||||
(def ^:private category-dictionary
|
||||
{:stroke-width "Stroke Width"
|
||||
:spacing "Spacing"
|
||||
:sizing "Sizing"
|
||||
:border-radius "Border Radius"
|
||||
:x "X"
|
||||
:y "Y"})
|
||||
|
||||
;; Helper functions
|
||||
(defn partially-applied-attr
|
||||
"Translates partially applied attributes based on the dictionary."
|
||||
[app-token-keys is-applied token-type-props]
|
||||
(let [{:keys [attributes all-attributes]} token-type-props
|
||||
filtered-keys (if all-attributes
|
||||
(filter #(contains? all-attributes %) app-token-keys)
|
||||
(filter #(contains? attributes %) app-token-keys))]
|
||||
(when is-applied
|
||||
(str/join ", " (map attribute-dictionary filtered-keys)))))
|
||||
|
||||
(defn translate-and-format
|
||||
"Translates and formats grouped values by category."
|
||||
[grouped-values]
|
||||
(str/join "\n"
|
||||
(map (fn [[category values]]
|
||||
(if (#{:x :y} category)
|
||||
(dm/str "- " (category-dictionary category))
|
||||
(dm/str "- " (category-dictionary category) ": "
|
||||
(str/join ", " (map attribute-dictionary values)) ".")))
|
||||
grouped-values)))
|
||||
|
||||
(defn token-pill-tooltip
|
||||
"Generates a tooltip for a given token."
|
||||
[theme-token is-viewer shape token-type-props token half-applied]
|
||||
(let [{:keys [name value resolved-value errors type]} token
|
||||
{:keys [title]} token-type-props
|
||||
applied-tokens (:applied-tokens shape)
|
||||
app-token-vals (set (vals applied-tokens))
|
||||
app-token-keys (keys applied-tokens)
|
||||
is-applied? (contains? app-token-vals name)
|
||||
no-token-active (nil? theme-token)
|
||||
errors? (or no-token-active (seq errors))
|
||||
applied-to (if half-applied
|
||||
(partially-applied-attr app-token-keys is-applied? token-type-props)
|
||||
(tr "labels.all"))
|
||||
grouped-values (group-by dimensions-dictionary app-token-keys)
|
||||
|
||||
base-title (dm/str "Token: " name "\n"
|
||||
(tr "workspace.token.original-value" value) "\n"
|
||||
(tr "workspace.token.resolved-value" resolved-value))]
|
||||
|
||||
(cond
|
||||
;; If there are errors, show the appropriate message
|
||||
errors? (if no-token-active
|
||||
(tr "workspace.token-set.not-active")
|
||||
(sd/humanize-errors token))
|
||||
;; If the token is applied and the user is a is-viewer, show the details
|
||||
(and is-applied? is-viewer)
|
||||
(->> [base-title
|
||||
(tr "workspace.token.applied-to")
|
||||
(if (= :dimensions type)
|
||||
(translate-and-format grouped-values)
|
||||
(str "- " title ": " applied-to))]
|
||||
(str/join "\n"))
|
||||
;; Otherwise only show the base title
|
||||
:else base-title)))
|
||||
|
||||
(mf/defc token-pill
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [on-click token theme-token full-applied on-context-menu half-applied]}]
|
||||
(let [{:keys [name value resolved-value errors]} token
|
||||
errors? (or (nil? theme-token) (and (seq errors) (seq (:errors theme-token))))
|
||||
color (when (seq (ctob/find-token-value-references value))
|
||||
(wtt/resolved-value-hex theme-token))
|
||||
[{:keys [on-click token theme-token full-applied on-context-menu half-applied selected-shapes token-type-props]}]
|
||||
(let [{:keys [name value errors]} token
|
||||
|
||||
can-edit? (:can-edit (deref refs/permissions))
|
||||
is-viewer (not can-edit?)
|
||||
errors? (or (nil? theme-token) (and (seq errors) (seq (:errors theme-token))))
|
||||
color (when (seq (ctob/find-token-value-references value))
|
||||
(wtt/resolved-value-hex theme-token))
|
||||
contains-path? (str/includes? name ".")
|
||||
splitted-name (cfh/split-by-last-period name)
|
||||
color (or color (wtt/resolved-value-hex token))
|
||||
|
||||
on-click
|
||||
(mf/use-callback
|
||||
(mf/deps errors? on-click)
|
||||
|
@ -37,21 +159,46 @@
|
|||
full-applied
|
||||
"token-status-full"
|
||||
:else
|
||||
"token-status-non-applied")]
|
||||
"token-status-non-applied")
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps can-edit? on-context-menu)
|
||||
(fn [e]
|
||||
(dom/stop-propagation e)
|
||||
(when can-edit?
|
||||
(on-context-menu e))))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(mf/deps errors? on-click)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(when (and can-edit? (not (seq errors)) on-click)
|
||||
(on-click event))))
|
||||
|
||||
on-hover
|
||||
(mf/use-fn
|
||||
(mf/deps selected-shapes is-viewer)
|
||||
(fn [event]
|
||||
(let [node (dom/get-current-target event)
|
||||
title (token-pill-tooltip theme-token is-viewer (first selected-shapes) token-type-props token half-applied)]
|
||||
(dom/set-attribute! node "title" title))))]
|
||||
|
||||
[:button {:class (stl/css-case :token-pill true
|
||||
:token-pill-applied (or half-applied full-applied)
|
||||
:token-pill-invalid errors?
|
||||
:token-pill-invalid-applied (and full-applied errors?))
|
||||
:token-pill-applied (and can-edit? (or half-applied full-applied))
|
||||
:token-pill-invalid (and can-edit? errors?)
|
||||
:token-pill-invalid-applied (and full-applied errors? can-edit?)
|
||||
:token-pill-viewer is-viewer
|
||||
:token-pill-applied-viewer (and is-viewer
|
||||
(or half-applied full-applied))
|
||||
:token-pill-invalid-viewer (and is-viewer
|
||||
errors?)
|
||||
:token-pill-invalid-applied-viewer (and is-viewer
|
||||
(and full-applied errors?)))
|
||||
:type "button"
|
||||
:title (cond
|
||||
errors? (if (nil? theme-token)
|
||||
(tr "workspace.token-set.not-active")
|
||||
(sd/humanize-errors token))
|
||||
:else (->> [(str "Token: " name)
|
||||
(tr "workspace.token.original-value" value)
|
||||
(tr "workspace.token.resolved-value" resolved-value)]
|
||||
(str/join "\n")))
|
||||
:on-click on-click
|
||||
:on-mouse-enter on-hover
|
||||
:on-context-menu on-context-menu}
|
||||
(cond
|
||||
errors?
|
||||
|
|
|
@ -6717,6 +6717,10 @@ msgstr "Add set"
|
|||
msgid "workspace.token.tools"
|
||||
msgstr "Tools"
|
||||
|
||||
#: src/app/main/ui/workspace/tokens/sidebar.cljs
|
||||
msgid "workspace.token.no-permission-themes"
|
||||
msgstr "You need to be an editor to use themes"
|
||||
|
||||
#: src/app/main/ui/workspace/tokens/modals/themes.cljs
|
||||
msgid "workspace.token.save-theme"
|
||||
msgstr "Save theme"
|
||||
|
|
|
@ -6729,6 +6729,10 @@ msgstr "Añadir set"
|
|||
msgid "workspace.token.tools"
|
||||
msgstr "Herramientas"
|
||||
|
||||
#: src/app/main/ui/workspace/tokens/sidebar.cljs
|
||||
msgid "workspace.token.no-permission-themes"
|
||||
msgstr "Debes ser editor para usar temas"
|
||||
|
||||
#: src/app/main/ui/workspace/tokens/modals/themes.cljs
|
||||
msgid "workspace.token.save-theme"
|
||||
msgstr "Guardar tema"
|
||||
|
|
Loading…
Add table
Reference in a new issue