🎉 Add copy shortands button to panels (#7580)

* 🎉 Add copy shorthands button to panels
* 🎉 Add shorthand for strokes
* 🎉 Add shorthand for fonts
* 🎉 Add shorthand for borders
* 🎉 Add shorthand for padding
* 🎉 Add shorthand for grid
* 🎉 Add shorthand for layout element
* 🐛 Refactor to fix hook rendering
This commit is contained in:
Xaviju
2025-10-29 13:51:36 +01:00
committed by GitHub
parent 034463e63a
commit 6c824651df
14 changed files with 483 additions and 231 deletions

View File

@@ -77,7 +77,7 @@
(:content shape))
(defn- has-shadow? [shape]
(:shadow shape))
(seq (:shadow shape)))
(defn- get-shape-type
[shapes first-shape first-component]
@@ -111,7 +111,26 @@
(not (or (= shape-type :text) (= shape-type :group)))
(or (:opacity shape)
(:blend-mode shape)
(:visibility shape))))))]
(:visibility shape))))))
shorthands* (mf/use-state #(do {:fill nil
:stroke nil
:text nil
:shadow nil
:blur nil
:layout nil
:layout-element nil
:geometry nil
:svg nil
:visibility nil
:variant nil
:grid-element nil}))
shorthands (deref shorthands*)
set-shorthands
;; This fn must receive an object `shorthand` with :panel and :property (the shorthand string) keys
(mf/use-fn
(mf/deps shorthands*)
(fn [shorthand]
(swap! shorthands* assoc (:panel shorthand) (:property shorthand))))]
[:ol {:class (stl/css :styles-tab) :aria-label (tr "labels.styles")}
;; TOKENS PANEL
(when (or active-themes active-sets)
@@ -130,18 +149,22 @@
:data data}]]
;; GEOMETRY PANEL
:geometry
[:> style-box* {:panel :geometry}
[:> style-box* {:panel :geometry
:shorthand (:geometry shorthands)}
[:> geometry-panel* {:shapes shapes
:objects objects
:resolved-tokens resolved-active-tokens}]]
:resolved-tokens resolved-active-tokens
:on-geometry-shorthand set-shorthands}]]
;; LAYOUT PANEL
:layout
(let [layout-shapes (->> shapes (filter ctl/any-layout?))]
(when (seq layout-shapes)
[:> style-box* {:panel :layout}
[:> style-box* {:panel :layout
:shorthand (:layout shorthands)}
[:> layout-panel* {:shapes layout-shapes
:objects objects
:resolved-tokens resolved-active-tokens}]]))
:resolved-tokens resolved-active-tokens
:on-layout-shorthand set-shorthands}]]))
;; LAYOUT ELEMENT PANEL
:layout-element
(let [shapes (->> shapes (filter #(ctl/any-layout-immediate-child? objects %)))
@@ -157,29 +180,35 @@
(if only-grid?
:grid-element
:layout-element))]
[:> style-box* {:panel panel}
[:> style-box* {:panel panel
:shorthand (:layout-element shorthands)}
[:> layout-element-panel* {:shapes shapes
:objects objects
:resolved-tokens resolved-active-tokens
:layout-element-properties layout-element-properties}]])))
:layout-element-properties layout-element-properties
:on-layout-element-shorthand set-shorthands}]])))
;; FILL PANEL
:fill
(let [shapes (filter has-fill? shapes)]
(when (seq shapes)
[:> style-box* {:panel :fill}
[:> style-box* {:panel :fill
:shorthand (:fill shorthands)}
[:> fill-panel* {:color-space color-space
:shapes shapes
:resolved-tokens resolved-active-tokens}]]))
:resolved-tokens resolved-active-tokens
:on-fill-shorthand set-shorthands}]]))
;; STROKE PANEL
:stroke
(let [shapes (filter has-stroke? shapes)]
(when (seq shapes)
[:> style-box* {:panel :stroke}
[:> style-box* {:panel :stroke
:shorthand (:stroke shorthands)}
[:> stroke-panel* {:color-space color-space
:shapes shapes
:objects objects
:resolved-tokens resolved-active-tokens}]]))
:resolved-tokens resolved-active-tokens
:on-stroke-shorthand set-shorthands}]]))
;; VISIBILITY PANEL
:visibility
@@ -207,18 +236,23 @@
:text
(let [shapes (filter has-text? shapes)]
(when (seq shapes)
[:> style-box* {:panel :text}
[:> style-box* {:panel :text
:shorthand (:text shorthands)}
[:> text-panel* {:shapes shapes
:color-space color-space
:objects objects
:resolved-tokens resolved-active-tokens}]]))
:resolved-tokens resolved-active-tokens
:on-font-shorthand set-shorthands}]]))
;; SHADOW PANEL
:shadow
(let [shapes (filter has-shadow? shapes)]
(when (seq shapes)
[:> style-box* {:panel :shadow}
[:> style-box* {:panel :shadow
:shorthand (:shadow shorthands)}
[:> shadow-panel* {:shapes shapes
:color-space color-space}]]))
:color-space color-space
:on-shadow-shorthand set-shorthands}]]))
;; DEFAULT WIP
[:> style-box* {:panel panel}
[:div color-space]])])]))

View File

@@ -17,7 +17,7 @@
[{:keys [shapes objects]}]
[:div {:class (stl/css :blur-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class "blur-shape"}
[:div {:key (:id shape) :class (stl/css :blur-shape)}
(let [property :filter
value (css/get-css-value objects shape property)
property-name (cmm/get-css-rule-humanized property)

View File

@@ -7,9 +7,12 @@
(ns app.main.ui.inspect.styles.panels.fill
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.common.types.fills :as types.fills]
[app.config :as cfg]
[app.main.ui.inspect.attributes.common :as cmm]
[app.main.ui.inspect.styles.rows.color-properties-row :refer [color-properties-row*]]
[app.util.color :as uc]
[rumext.v2 :as mf]))
(defn- get-applied-tokens-in-shape
@@ -32,28 +35,56 @@
(and (= (:resolved-value resolved-token) (:color color-type))
(= 0 idx)))
(mf/defc fill-panel*
[{:keys [shapes resolved-tokens color-space]}]
[:div {:class (stl/css :fill-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class "fill-shape"}
(for [[idx fill] (map-indexed vector (:fills shape))]
(let [property :background
color-type (types.fills/fill->color fill) ;; can be :color, :gradient or :image
property-name (cmm/get-css-rule-humanized property)
resolved-token (get-resolved-token shape resolved-tokens)
has-token (has-token? resolved-token color-type idx)]
(defn- generate-fill-shorthand
[shape]
(reduce
(fn [acc fill]
(let [color-type (types.fills/fill->color fill)
color-value (:color color-type)
color-gradient (:gradient color-type)
gradient-data {:type color-type
:stops (:stops color-gradient)}
color-image (:image color-type)
prefix (if color-value "background-color: " "background-image: ")
value (cond
(:color color-type) (dm/str color-value)
color-gradient (uc/gradient->css gradient-data)
color-image (str "url(\"" (cfg/resolve-file-media color-image) "\")")
:else "")
full-value (str prefix value ";")]
(if (empty? acc)
full-value
(str acc " " full-value))))
""
(:fills shape)))
(if (:color color-type)
[:> color-properties-row* {:key idx
:term property-name
:color color-type
:token (when has-token resolved-token)
:format color-space
:copiable true}]
(if (or (:gradient color-type) (:image color-type))
(mf/defc fill-panel*
[{:keys [shapes resolved-tokens color-space on-fill-shorthand]}]
(let [shorthand* (mf/use-state #(generate-fill-shorthand (first shapes)))
shorthand (deref shorthand*)]
(mf/use-effect
(mf/deps shorthand on-fill-shorthand shapes)
(fn []
(reset! shorthand* (generate-fill-shorthand (first shapes)))
(on-fill-shorthand {:panel :fill
:property shorthand})))
[:div {:class (stl/css :fill-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class (stl/css :fill-shape)}
(for [[idx fill] (map-indexed vector (:fills shape))]
(let [property :background
color-type (types.fills/fill->color fill) ;; can be :color, :gradient or :image
property-name (cmm/get-css-rule-humanized property)
resolved-token (get-resolved-token shape resolved-tokens)
has-token (has-token? resolved-token color-type idx)]
(if (:color color-type)
[:> color-properties-row* {:key idx
:term property-name
:color color-type
:token (when has-token resolved-token)
:format color-space
:copiable true}]
[:span "background-image"]))))])])
[:> color-properties-row* {:key idx
:term property-name
:color color-type
:copiable true}])))])]))

View File

@@ -30,6 +30,15 @@
:border-end-start-radius :r3
:border-end-end-radius :r4})
(defn- has-border-radius?
"Returns true if the shape has any non-zero border radius values."
[shape]
(let [radius-keys [:r1 :r2 :r3 :r4]]
(some (fn [key]
(and (contains? shape key)
(not= 0 (get shape key))))
radius-keys)))
(defn- get-applied-tokens-in-shape
[shape-tokens property]
(let [border-prop (get shape-prop->border-radius-prop property)]
@@ -44,19 +53,33 @@
token (get resolved-tokens applied-tokens-in-shape)]
token))
(defn- generate-geometry-shorthand
[shapes objects]
(when (and (= (count shapes) 1) (has-border-radius? (first shapes)))
(css/get-css-property objects (first shapes) :border-radius)))
(mf/defc geometry-panel*
[{:keys [shapes objects resolved-tokens]}]
[:div {:class (stl/css :geometry-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class "geometry-shape"}
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
(let [property-name (cmm/get-css-rule-humanized property)
resolved-token (get-resolved-token property shape resolved-tokens)
property-value (if (not resolved-token) (css/get-css-property objects shape property) "")]
[:> properties-row* {:key (dm/str "geometry-property-" property)
:term property-name
:detail value
:token resolved-token
:property property-value
:copiable true}])))])])
[{:keys [shapes objects resolved-tokens on-geometry-shorthand]}]
(let [shorthand* (mf/use-state #(generate-geometry-shorthand shapes objects))
shorthand (deref shorthand*)]
(mf/use-effect
(mf/deps shorthand on-geometry-shorthand shapes objects)
(fn []
(reset! shorthand* (generate-geometry-shorthand shapes objects))
(on-geometry-shorthand {:panel :geometry
:property shorthand})))
[:div {:class (stl/css :geometry-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class (stl/css :geometry-shape)}
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
(let [property-name (cmm/get-css-rule-humanized property)
resolved-token (get-resolved-token property shape resolved-tokens)
property-value (if (not resolved-token) (css/get-css-property objects shape property) "")]
[:> properties-row* {:key (dm/str "geometry-property-" property)
:term property-name
:detail value
:token resolved-token
:property property-value
:copiable true}])))])]))

View File

@@ -37,6 +37,15 @@
:padding-block-end :p3
:padding-inline-start :p4})
(defn- has-padding?
[shape]
(let [padding (:layout-padding shape)
padding-keys [:p1 :p2 :p3 :p4]]
(some (fn [key]
(and (contains? padding key)
(not= 0 (get padding key))))
padding-keys)))
(defn- get-applied-tokens-in-shape
[shape-tokens property]
(let [padding-prop (get shape-prop->padding-prop property)]
@@ -51,19 +60,43 @@
token (get resolved-tokens applied-tokens-in-shape)]
token))
(defn- generate-layout-shorthand
[shapes objects]
(let [shape (first shapes)
shorthand-padding (when (and (= (count shapes) 1) (has-padding? shape))
(css/get-css-property objects shape :padding))
shorthand-grid (when (and (= (count shapes) 1)
(= :grid (:layout shape)))
(str "grid: "
(css/get-css-value objects shape :grid-template-rows)
" / "
(css/get-css-value objects shape :grid-template-columns)
";"))
shorthand (when (or shorthand-padding shorthand-grid)
(str shorthand-grid " " shorthand-padding))]
shorthand))
(mf/defc layout-panel*
[{:keys [shapes objects resolved-tokens]}]
[:div {:class (stl/css :variants-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class "layout-shape"}
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
(let [property-name (cmm/get-css-rule-humanized property)
resolved-token (get-resolved-token property shape resolved-tokens)
property-value (if (not resolved-token) (css/get-css-property objects shape property) "")]
[:> properties-row* {:key (dm/str "layout-property-" property)
:term property-name
:detail value
:token resolved-token
:property property-value
:copiable true}])))])])
[{:keys [shapes objects resolved-tokens on-layout-shorthand]}]
(let [shorthand* (mf/use-state #(generate-layout-shorthand shapes objects))
shorthand (deref shorthand*)]
(mf/use-effect
(mf/deps shorthand on-layout-shorthand shapes objects)
(fn []
(reset! shorthand* (generate-layout-shorthand shapes objects))
(on-layout-shorthand {:panel :layout
:property shorthand})))
[:div {:class (stl/css :variants-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class (stl/css :layout-shape)}
(for [property properties]
(when-let [value (css/get-css-value objects shape property)]
(let [property-name (cmm/get-css-rule-humanized property)
resolved-token (get-resolved-token property shape resolved-tokens)
property-value (if (not resolved-token) (css/get-css-property objects shape property) "")]
[:> properties-row* {:key (dm/str "layout-property-" property)
:term property-name
:detail value
:token resolved-token
:property property-value
:copiable true}])))])]))

View File

@@ -25,6 +25,15 @@
:min-inline-size :layout-item-min-w ;; :min-width
})
(defn- has-margin?
[shape]
(let [margin (:layout-item-margin shape)
margin-keys [:m1 :m2 :m3 :m4]]
(some (fn [key]
(and (contains? margin key)
(not= 0 (get margin key))))
margin-keys)))
(defn- get-applied-margins-in-shape
[shape-tokens property]
(if-let [margin-prop (get shape-prop->margin-prop property)]
@@ -38,12 +47,40 @@
token (get resolved-tokens applied-tokens-in-shape)]
token)))
(defn- generate-layout-element-shorthand
[shapes objects]
(let [shape (first shapes)
shorthand-margin (when (and (= (count shapes) 1) (has-margin? shape))
(css/get-css-property objects shape :margin))
shorthand-grow (when (and (= (count shapes) 1)
(ctl/flex-layout-immediate-child? objects shape))
(if-let [flex-value (css/get-css-value objects shape :flex)]
flex-value
0))
shorthand-basis 0 ;; Default-value. Currently not supported in the UI
shorthand-shrink (when (and (= (count shapes) 1)
(ctl/flex-layout-immediate-child? objects shape))
(if-let [flex-shrink-value (css/get-css-value objects shape :flex-shrink)]
flex-shrink-value
0))
shorthand-flex (dm/str "flex: " shorthand-grow " " shorthand-basis " " shorthand-shrink ";")
shorthand (dm/str shorthand-margin " " shorthand-flex)]
shorthand))
(mf/defc layout-element-panel*
[{:keys [shapes objects resolved-tokens layout-element-properties]}]
(let [shapes (->> shapes (filter #(ctl/any-layout-immediate-child? objects %)))]
[{:keys [shapes objects resolved-tokens layout-element-properties on-layout-element-shorthand]}]
(let [shapes (->> shapes (filter #(ctl/any-layout-immediate-child? objects %)))
shorthand* (mf/use-state #(generate-layout-element-shorthand shapes objects))
shorthand (deref shorthand*)]
(mf/use-effect
(mf/deps shorthand on-layout-element-shorthand shapes objects)
(fn []
(reset! shorthand* (generate-layout-element-shorthand shapes objects))
(on-layout-element-shorthand {:panel :layout-element
:property shorthand})))
[:div {:class (stl/css :layout-element-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class "layout-element-shape"}
[:div {:key (:id shape) :class (stl/css :layout-element-shape)}
(for [property layout-element-properties]
(when-let [value (css/get-css-value objects shape property)]
(let [property-name (cmm/get-css-rule-humanized property)

View File

@@ -12,22 +12,45 @@
[app.main.ui.inspect.styles.rows.color-properties-row :refer [color-properties-row*]]
[app.main.ui.inspect.styles.rows.properties-row :refer [properties-row*]]
[app.util.code-gen.style-css :as css]
[app.util.code-gen.style-css-formats :as scf]
[rumext.v2 :as mf]))
(defn- generate-shadow-shorthand
[shapes]
(when (= (count shapes) 1)
(let [shorthand-property (dm/str "box-shadow: ")
shorthand-value (reduce
(fn [acc shadow]
(let [value (scf/format-shadow->css shadow {})]
(if (empty? acc)
value
(dm/str acc ", " value))))
""
(:shadow (first shapes)))]
(dm/str shorthand-property shorthand-value ";"))))
(mf/defc shadow-panel*
[{:keys [shapes color-space]}]
[:div {:class (stl/css :shadow-panel)}
(for [shape shapes]
(for [shadow (:shadow shape)]
[:div {:key (dm/str (:id shape) (:type shadow)) :class "shadow-shape"}
[:> color-properties-row* {:term "Shadow Color"
:color (:color shadow)
:format color-space
:copiable true}]
(let [value (dm/str (:offset-x shadow) "px" " " (:offset-y shadow) "px" " " (:blur shadow) "px" " " (:spread shadow) "px")
property-name (cmm/get-css-rule-humanized (:style shadow))
property-value (css/shadow->css shadow)]
[:> properties-row* {:term property-name
:detail (dm/str value)
:property property-value
:copiable true}])]))])
[{:keys [shapes color-space on-shadow-shorthand]}]
(let [shorthand* (mf/use-state #(generate-shadow-shorthand shapes))
shorthand (deref shorthand*)]
(mf/use-effect
(mf/deps shorthand on-shadow-shorthand shapes)
(fn []
(reset! shorthand* (generate-shadow-shorthand shapes))
(on-shadow-shorthand {:panel :shadow
:property shorthand})))
[:div {:class (stl/css :shadow-panel)}
(for [shape shapes]
(for [[idx shadow] (map-indexed vector (:shadow shape))]
[:div {:key (dm/str idx) :class (stl/css :shadow-shape)}
[:> color-properties-row* {:term "Shadow Color"
:color (:color shadow)
:format color-space
:copiable true}]
(let [value (dm/str (:offset-x shadow) "px" " " (:offset-y shadow) "px" " " (:blur shadow) "px" " " (:spread shadow) "px")
property-name (cmm/get-css-rule-humanized (:style shadow))
property-value (css/shadow->css shadow)]
[:> properties-row* {:term property-name
:detail (dm/str value)
:property property-value
:copiable true}])]))]))

View File

@@ -9,22 +9,17 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.types.color :as ctc]
[app.config :as cfg]
[app.main.ui.inspect.attributes.common :as cmm]
[app.main.ui.inspect.styles.rows.color-properties-row :refer [color-properties-row*]]
[app.main.ui.inspect.styles.rows.properties-row :refer [properties-row*]]
[app.util.code-gen.style-css :as css]
[app.util.color :as uc]
[rumext.v2 :as mf]))
(def ^:private properties [:border-color :border-style :border-width])
(defn- stroke->color [shape]
{:color (:stroke-color shape)
:opacity (:stroke-opacity shape)
:gradient (:stroke-color-gradient shape)
:id (:stroke-color-ref-id shape)
:file-id (:stroke-color-ref-file shape)
:image (:stroke-image shape)})
(def ^:private shape-prop->stroke-prop
{:border-style :stroke-style
:border-width :stroke-width
@@ -57,29 +52,62 @@
(and (= (:resolved-value resolved-token) (:color stroke-type))
(is-first-element? idx)))
(defn- generate-stroke-shorthand
[shapes]
(when (= (count shapes) 1)
(let [shape (first shapes)]
(reduce
(fn [acc stroke]
(let [stroke-type (ctc/stroke->color stroke)
stroke-width (:stroke-width stroke)
stroke-style (:stroke-style stroke)
color-value (:color stroke-type)
color-gradient (:gradient stroke-type)
gradient-data {:type (get-in stroke-type [:gradient :type])
:stops (get-in stroke-type [:gradient :stops])}
color-image (:image stroke-type)
value (cond
color-value (dm/str "border: " stroke-width "px " (d/name stroke-style) " " color-value ";")
color-gradient (dm/str "border-image: " (uc/gradient->css gradient-data) " 100 / " stroke-width "px;")
color-image (dm/str "border-image: url(" (cfg/resolve-file-media color-image) ") 100 / " stroke-width "px;")
:else "")]
(if (empty? acc)
value
(str acc " " value))))
""
(:strokes shape)))))
(mf/defc stroke-panel*
[{:keys [shapes objects resolved-tokens color-space]}]
[:div {:class (stl/css :stroke-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class "stroke-shape"}
(for [[idx stroke] (map-indexed vector (:strokes shape))]
(for [property properties]
(let [value (css/get-css-value objects stroke property)
stroke-type (stroke->color stroke)
property-name (cmm/get-css-rule-humanized property)
property-value (css/get-css-property objects stroke property)
resolved-token (when (is-first-element? idx) (get-resolved-token property shape resolved-tokens))
has-color-token (has-color-token? resolved-token stroke-type idx)]
(if (= property :border-color)
[:> color-properties-row* {:key (str idx property)
:term property-name
:color stroke-type
:token (when has-color-token resolved-token)
:format color-space
:copiable true}]
[:> properties-row* {:key (str idx property)
:term (d/name property-name)
:detail (dm/str value)
:token resolved-token
:property property-value
:copiable true}]))))])])
[{:keys [shapes objects resolved-tokens color-space on-stroke-shorthand]}]
(let [shorthand* (mf/use-state #(generate-stroke-shorthand shapes))
shorthand (deref shorthand*)]
(mf/use-effect
(mf/deps shorthand on-stroke-shorthand shapes)
(fn []
(reset! shorthand* (generate-stroke-shorthand shapes))
(on-stroke-shorthand {:panel :stroke
:property shorthand})))
[:div {:class (stl/css :stroke-panel)}
(for [shape shapes]
[:div {:key (:id shape) :class (stl/css :stroke-shape)}
(for [[idx stroke] (map-indexed vector (:strokes shape))]
(for [property properties]
(let [value (css/get-css-value objects stroke property)
stroke-type (ctc/stroke->color stroke)
property-name (cmm/get-css-rule-humanized property)
property-value (css/get-css-property objects stroke property)
resolved-token (when (is-first-element? idx) (get-resolved-token property shape resolved-tokens))
has-color-token (has-color-token? resolved-token stroke-type idx)]
(if (= property :border-color)
[:> color-properties-row* {:key (str idx property)
:term property-name
:color stroke-type
:token (when has-color-token resolved-token)
:format color-space
:copiable true}]
[:> properties-row* {:key (str idx property)
:term (d/name property-name)
:detail (dm/str value)
:token resolved-token
:property property-value
:copiable true}]))))])]))

View File

@@ -7,6 +7,7 @@
(ns app.main.ui.inspect.styles.panels.text
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.common.types.fills :as types.fills]
[app.common.types.text :as txt]
[app.main.fonts :as fonts]
@@ -38,6 +39,23 @@
(remove (fn [[_ text]] (str/empty? (str/trim text))))
(mapv (fn [[style text]] (vector (merge (txt/get-default-text-attrs) style) text)))))
(defn- generate-typography-shorthand
[shapes]
(when (= (count shapes) 1)
(let [shape (first shapes)
style-text-blocks (get-style-text shape)]
(reduce
(fn [acc [style _]]
(let [font-style (:font-style style)
font-family (dm/str (:font-family style))
font-size (:font-size style)
font-weight (:font-weight style)
line-height (:line-height style)
text-transform (:text-transform style)]
(dm/str acc "font:" font-style " " text-transform " " font-weight " " font-size "/" line-height " " \" font-family \" ";")))
""
style-text-blocks))))
(mf/defc typography-name-block*
[{:keys [style]}]
(let [typography (ict/get-typography style)
@@ -59,126 +77,133 @@
:copiable true}]))
(mf/defc text-panel*
[{:keys [shapes _ resolved-tokens color-space]}]
[:div {:class (stl/css :text-panel)}
(for [shape shapes]
(let [style-text-blocks (get-style-text shape)
composite-typography-token (get-resolved-token :typography shape resolved-tokens)]
[{:keys [shapes resolved-tokens color-space on-font-shorthand]}]
(let [shorthand* (mf/use-state #(generate-typography-shorthand shapes))
shorthand (deref shorthand*)]
(mf/use-effect
(mf/deps shorthand on-font-shorthand shapes)
(fn []
(reset! shorthand* (generate-typography-shorthand shapes))
(on-font-shorthand {:panel :text
:property shorthand})))
[:div {:class (stl/css :text-panel)}
(for [shape shapes]
(let [style-text-blocks (get-style-text shape)
composite-typography-token (get-resolved-token :typography shape resolved-tokens)]
[:div {:key (:id shape) :class (stl/css :text-shape)}
(for [[style text] style-text-blocks]
[:div {:key (:id shape) :class "text-shape"}
(for [[style text] style-text-blocks]
[:div {:key (:id shape) :class (stl/css :text-properties)}
[:div {:key (:id shape) :class "text-properties"}
(when (:fills style)
(for [[idx fill] (map-indexed vector (:fills style))]
[:> typography-color-row* {:key idx
:fill fill
:shape shape
:resolved-tokens resolved-tokens
:color-space color-space}]))
(when (:fills style)
(for [[idx fill] (map-indexed vector (:fills style))]
[:> typography-color-row* {:key idx
:fill fill
:shape shape
:resolved-tokens resolved-tokens
:color-space color-space}]))
;; Typography style
(when (and (not composite-typography-token)
(:typography-ref-id style))
[:> typography-name-block* {:style style}])
(when (and (not composite-typography-token)
(:typography-ref-id style))
[:> typography-name-block* {:style style}])
;; Composite Typography token
(when (and (not (:typography-ref-id style))
composite-typography-token)
[:> properties-row* {:term "Typography"
:detail (:name composite-typography-token)
:token composite-typography-token
:property (:name composite-typography-token)
:copiable true}])
(when (and (not (:typography-ref-id style))
composite-typography-token)
[:> properties-row* {:term "Typography"
:detail (:name composite-typography-token)
:token composite-typography-token
:property (:name composite-typography-token)
:copiable true}])
(when (:font-id style)
(let [name (get (fonts/get-font-data (:font-id style)) :name)
resolved-token (get-resolved-token :font-family shape resolved-tokens)]
[:> properties-row* {:term "Font Family"
:detail name
:token resolved-token
:property (str "font-family: \"" name "\";")
:copiable true}]))
(when (:font-id style)
(let [name (get (fonts/get-font-data (:font-id style)) :name)
resolved-token (get-resolved-token :font-family shape resolved-tokens)]
[:> properties-row* {:term "Font Family"
:detail name
:token resolved-token
:property (str "font-family: \"" name "\";")
:copiable true}]))
(when (:font-style style)
[:> properties-row* {:term "Font Style"
:detail (:font-style style)
:property (str "font-style: " (:font-style style) ";")
:copiable true}])
(when (:font-style style)
[:> properties-row* {:term "Font Style"
:detail (:font-style style)
:property (str "font-style: " (:font-style style) ";")
:copiable true}])
(when (:font-size style)
(let [font-size (fmt/format-pixels (:font-size style))
resolved-token (get-resolved-token :font-size shape resolved-tokens)]
[:> properties-row* {:term "Font Size"
:detail font-size
:token resolved-token
:property (str "font-size: " font-size ";")
:copiable true}]))
(when (:font-weight style)
(let [resolved-token (get-resolved-token :font-weight shape resolved-tokens)]
[:> properties-row* {:term "Font Weight"
:detail (:font-weight style)
:token resolved-token
:property (str "font-weight: " (:font-weight style) ";")
:copiable true}]))
(when (:font-size style)
(let [font-size (fmt/format-pixels (:font-size style))
resolved-token (get-resolved-token :font-size shape resolved-tokens)]
[:> properties-row* {:term "Font Size"
:detail font-size
:token resolved-token
:property (str "font-size: " font-size ";")
:copiable true}]))
(when (:font-weight style)
(let [resolved-token (get-resolved-token :font-weight shape resolved-tokens)]
[:> properties-row* {:term "Font Weight"
:detail (:font-weight style)
:token resolved-token
:property (str "font-weight: " (:font-weight style) ";")
:copiable true}]))
(when (:line-height style)
(let [line-height (:line-height style)
resolved-token (get-resolved-token :line-height shape resolved-tokens)]
[:> properties-row* {:term "Line Height"
:detail (str line-height)
:token resolved-token
:property (str "line-height: " line-height ";")
:copiable true}]))
(when (:line-height style)
(let [line-height (:line-height style)
resolved-token (get-resolved-token :line-height shape resolved-tokens)]
[:> properties-row* {:term "Line Height"
:detail (str line-height)
:token resolved-token
:property (str "line-height: " line-height ";")
:copiable true}]))
(when (:letter-spacing style)
(let [letter-spacing (fmt/format-pixels (:letter-spacing style))
resolved-token (get-resolved-token :letter-spacing shape resolved-tokens)]
[:> properties-row* {:term "Letter Spacing"
:detail letter-spacing
:token resolved-token
:property (str "letter-spacing: " letter-spacing ";")
:copiable true}]))
(when (:letter-spacing style)
(let [letter-spacing (fmt/format-pixels (:letter-spacing style))
resolved-token (get-resolved-token :letter-spacing shape resolved-tokens)]
[:> properties-row* {:term "Letter Spacing"
:detail letter-spacing
:token resolved-token
:property (str "letter-spacing: " letter-spacing ";")
:copiable true}]))
(when (:text-decoration style)
(let [resolved-token (get-resolved-token :text-decoration shape resolved-tokens)]
[:> properties-row* {:term "Text Decoration"
:detail (:text-decoration style)
:token resolved-token
:property (str "text-decoration: " (:text-decoration style) ";")
:copiable true}]))
(when (:text-decoration style)
(let [resolved-token (get-resolved-token :text-decoration shape resolved-tokens)]
[:> properties-row* {:term "Text Decoration"
:detail (:text-decoration style)
:token resolved-token
:property (str "text-decoration: " (:text-decoration style) ";")
:copiable true}]))
(when (:text-transform style)
(let [resolved-token (get-resolved-token :text-case shape resolved-tokens)]
[:> properties-row* {:term "Text Transform"
:detail (:text-transform style)
:token resolved-token
:property (str "text-transform: " (:text-transform style) ";")
:copiable true}]))
(when text
(let [copied* (mf/use-state false)
copied (deref copied*)
(when (:text-transform style)
(let [resolved-token (get-resolved-token :text-case shape resolved-tokens)]
[:> properties-row* {:term "Text Transform"
:detail (:text-transform style)
:token resolved-token
:property (str "text-transform: " (:text-transform style) ";")
:copiable true}]))
(when text
(let [copied* (mf/use-state false)
copied (deref copied*)
text (str/trim text)
text (str/trim text)
copy-text
(mf/use-fn
(mf/deps copied)
(fn []
(let [formatted-text (if (= (:text-transform style) "uppercase")
(.toUpperCase text)
text)]
(reset! copied* true)
(wapi/write-to-clipboard formatted-text)
(tm/schedule 1000 #(reset! copied* false)))))]
[:div {:class (stl/css :text-content-wrapper)}
[:> property-detail-copiable* {:copied copied
:on-click copy-text}
[:span {:class (stl/css :text-content)
:style {:font-family (:font-family style)
:font-weight (:font-weight style)
:text-transform (:text-transform style)
:letter-spacing (fmt/format-pixels (:letter-spacing style))
:font-style (:font-style style)}}
text]]]))])]))])
copy-text
(mf/use-fn
(mf/deps copied)
(fn []
(let [formatted-text (if (= (:text-transform style) "uppercase")
(.toUpperCase text)
text)]
(reset! copied* true)
(wapi/write-to-clipboard formatted-text)
(tm/schedule 1000 #(reset! copied* false)))))]
[:div {:class (stl/css :text-content-wrapper)}
[:> property-detail-copiable* {:copied copied
:on-click copy-text}
[:span {:class (stl/css :text-content)
:style {:font-family (:font-family style)
:font-weight (:font-weight style)
:text-transform (:text-transform style)
:letter-spacing (fmt/format-pixels (:letter-spacing style))
:font-style (:font-style style)}}
text]]]))])]))]))

View File

@@ -34,7 +34,6 @@
[{:keys [class term color format token]}]
(let [copied* (mf/use-state false)
copied (deref copied*)
color-value (:color color)
color-gradient (:gradient color)
color-image (:image color)

View File

@@ -48,8 +48,9 @@
copy-shorthand
(mf/use-fn
(mf/deps shorthand)
(fn []
(wapi/write-to-clipboard (str "Style: " title))))]
(wapi/write-to-clipboard (str shorthand))))]
[:article {:class (stl/css :style-box)}
[:header {:class (stl/css :disclosure-header)}
[:button {:class (stl/css :disclosure-button)

View File

@@ -17,6 +17,7 @@
.disclosure-header {
display: flex;
align-items: center;
gap: var(--title-gap);
padding-block: var(--title-padding);
}

View File

@@ -1904,7 +1904,7 @@ msgstr "Info"
#: src/app/main/ui/inspect/styles/style_box.cljs:66
#, fuzzy
msgid "inspect.tabs.styles.panel.copy-style-shorthand"
msgstr ""
msgstr "Copy CSS shorthand to clipboard"
#: src/app/main/ui/inspect/styles/property_detail_copiable.cljs:52
msgid "inspect.tabs.styles.panel.copy-to-clipboard"

View File

@@ -1896,6 +1896,23 @@ msgstr "Calculado"
msgid "inspect.tabs.info"
msgstr "Información"
#: src/app/main/ui/inspect/styles/style_box.cljs:66
#, fuzzy
msgid "inspect.tabs.styles.panel.copy-style-shorthand"
msgstr "Copiar CSS shorthand al portapapeles"
#: src/app/main/ui/inspect/styles/property_detail_copiable.cljs:52
msgid "inspect.tabs.styles.panel.copy-to-clipboard"
msgstr "Copiar al portapapeles"
#: src/app/main/ui/inspect/styles/panels/tokens_panel.cljs:26
msgid "inspect.tabs.styles.panel.tokens.active-sets"
msgstr "Sets activos"
#: src/app/main/ui/inspect/styles/panels/tokens_panel.cljs:21
msgid "inspect.tabs.styles.panel.tokens.active-themes"
msgstr "Temas activos"
#: src/app/main/ui/inspect/styles/style_box.cljs:22
msgid "inspect.tabs.styles.panel.geometry"
msgstr "Tamaño y posición"