🎉 Add text panel to inspect styles tab (#7413)

This commit is contained in:
Xaviju 2025-10-13 14:20:55 +02:00 committed by GitHub
parent 2548bec651
commit 253605f6cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 257 additions and 48 deletions

View File

@ -13,29 +13,18 @@
[app.common.types.fills :as types.fills]
[app.common.types.text :as types.text]
[app.main.fonts :as fonts]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.copy-button :refer [copy-button*]]
[app.main.ui.components.title-bar :refer [inspect-title-bar*]]
[app.main.ui.formats :as fmt]
[app.main.ui.inspect.attributes.common :refer [color-row]]
[app.main.ui.inspect.common.typography :as ict]
[app.util.i18n :refer [tr]]
[cuerdas.core :as str]
[okulary.core :as l]
[rumext.v2 :as mf]))
(defn- has-text? [shape]
(:content shape))
(def ^:private file-typographies-ref
(l/derived (l/in [:viewer :file :data :typographies]) st/state))
(defn- make-typographies-library-ref [file-id]
(let [get-library
(fn [state]
(get-in state [:viewer-libraries file-id :data :typographies]))]
#(l/derived get-library st/state)))
(defn- copy-style-data
[style & properties]
(->> properties
@ -44,24 +33,10 @@
(mf/defc typography-block
[{:keys [text style]}]
(let [typography-library-ref
(mf/use-memo
(mf/deps (:typography-ref-file style))
(make-typographies-library-ref (:typography-ref-file style)))
typography-library (mf/deref typography-library-ref)
;; FIXME: too many duplicate operations
file-typographies-viewer (mf/deref file-typographies-ref)
file-typographies-workspace (mf/deref refs/workspace-file-typography)
file-library-workspace (get (mf/deref refs/files) (:typography-ref-file style))
typography-external-lib (get-in file-library-workspace [:data :typographies (:typography-ref-id style)])
color-format* (mf/use-state :hex)
(let [color-format* (mf/use-state :hex)
color-format (deref color-format*)
typography (or (get (or typography-library file-typographies-viewer file-typographies-workspace) (:typography-ref-id style)) typography-external-lib)]
typography (ict/get-typography style)]
[:div {:class (stl/css :attributes-content)}
(when (:fills style)

View File

@ -0,0 +1,38 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.inspect.common.typography
(:require
[app.main.refs :as refs]
[app.main.store :as st]
[okulary.core :as l]
[rumext.v2 :as mf]))
(defn- make-typographies-library-ref
[file-id]
(let [get-library
(fn [state]
(get-in state [:viewer-libraries file-id :data :typographies]))]
#(l/derived get-library st/state)))
(def ^:private file-typographies-ref
(l/derived (l/in [:viewer :file :data :typographies]) st/state))
(defn get-typography
[style]
(let [typography-library-ref
(mf/use-memo
(mf/deps (:typography-ref-file style))
(make-typographies-library-ref (:typography-ref-file style)))
; FIXME: too many duplicate operations
typography-library (mf/deref typography-library-ref)
file-typographies-viewer (mf/deref file-typographies-ref)
file-typographies-workspace (mf/deref refs/workspace-file-typography)
file-library-workspace (get (mf/deref refs/files) (:typography-ref-file style))
typography-external-lib (get-in file-library-workspace [:data :typographies (:typography-ref-id style)])
typography (or (get (or typography-library file-typographies-viewer file-typographies-workspace) (:typography-ref-id style)) typography-external-lib)]
typography))

View File

@ -22,6 +22,7 @@
[app.main.ui.inspect.styles.panels.layout-element :refer [layout-element-panel*]]
[app.main.ui.inspect.styles.panels.stroke :refer [stroke-panel*]]
[app.main.ui.inspect.styles.panels.svg :refer [svg-panel*]]
[app.main.ui.inspect.styles.panels.text :refer [text-panel*]]
[app.main.ui.inspect.styles.panels.tokens-panel :refer [tokens-panel*]]
[app.main.ui.inspect.styles.panels.variants-panel :refer [variants-panel*]]
[app.main.ui.inspect.styles.panels.visibility :refer [visibility-panel*]]
@ -71,6 +72,9 @@
(defn- has-blur? [shape]
(:blur shape))
(defn- has-text? [shape]
(:content shape))
(defn- get-shape-type
[shapes first-shape first-component]
(if (= (count shapes) 1)
@ -195,6 +199,14 @@
[:> style-box* {:panel :blur}
[:> blur-panel* {:shapes shapes
:objects objects}]]))
:text
(let [shapes (filter has-text? shapes)]
(when (seq shapes)
[:> style-box* {:panel :text}
[:> text-panel* {:shapes shapes
:color-space color-space
:objects objects
:resolved-tokens resolved-active-tokens}]]))
;; DEFAULT WIP
[:> style-box* {:panel panel}
[:div color-space]])])]))

View File

@ -30,9 +30,9 @@
:term (d/name sub-attr-key)
:detail (dm/str sub-attr-value)
:property property-value
:copiable false}]))
:copiable true}]))
[:> properties-row* {:key (dm/str "svg-property-" (d/name attr-key))
:term (d/name attr-key)
:detail (dm/str attr-value)
:property (dm/str attr-key ": " attr-value ";")
:copiable false}]))]])
:copiable true}]))]])

View File

@ -0,0 +1,171 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.inspect.styles.panels.text
(:require-macros [app.main.style :as stl])
(:require
[app.common.types.fills :as types.fills]
[app.common.types.text :as txt]
[app.main.fonts :as fonts]
[app.main.ui.formats :as fmt]
[app.main.ui.inspect.common.typography :as ict]
[app.main.ui.inspect.styles.property-detail-copiable :refer [property-detail-copiable*]]
[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.timers :as tm]
[app.util.webapi :as wapi]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(defn- get-applied-tokens-in-shape
[shape-tokens property]
(get shape-tokens property))
(defn- get-resolved-token
[property shape resolved-tokens]
(let [shape-tokens (:applied-tokens shape)
applied-tokens-in-shape (get-applied-tokens-in-shape shape-tokens property)
token (get resolved-tokens applied-tokens-in-shape)]
token))
(defn- get-style-text
[shape]
(->> (:content shape)
(txt/content->text+styles)
(remove (fn [[_ text]] (str/empty? (str/trim text))))
(mapv (fn [[style text]] (vector (merge (txt/get-default-text-attrs) style) text)))))
(mf/defc typography-name-block*
[{:keys [style]}]
(let [typography (ict/get-typography style)
property-value (:name typography)]
(when typography
[:> properties-row* {:term "Typography"
:detail (:name typography)
:property property-value
:copiable true}])))
(mf/defc typography-color-row*
[{:keys [fill shape resolved-tokens color-space]}]
(let [color (types.fills/fill->color fill)
resolved-token (get-resolved-token :fill shape resolved-tokens)]
[:> color-properties-row* {:term "Font Color"
:color color
:token resolved-token
:format color-space
: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)]
[:div {:key (:id shape) :class "text-shape"}
(for [[style text] style-text-blocks]
[: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 (:typography-ref-id style)
[:> typography-name-block* {:style style}])
(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-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 (: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-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)
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

@ -0,0 +1,17 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
@use "ds/_borders.scss" as *;
.text-content-wrapper {
--border-color: var(--color-background-quaternary);
--border-radius: ${$br-8};
--text-color: var(--color-foreground-secondary);
border: $b-1 solid var(--border-color);
border-radius: var(--border-radius);
color: var(--text-color);
}

View File

@ -16,7 +16,6 @@
(def ^:private schema:property-detail-copiable
[:map
[:detail :string]
[:color {:optional true} :any] ;; color object with :color, :gradient or :image
[:token {:optional true} :any] ;; resolved token object
[:copied :boolean]
@ -24,7 +23,7 @@
(mf/defc property-detail-copiable*
{::mf/schema schema:property-detail-copiable}
[{:keys [detail color token copied on-click]}]
[{:keys [color token copied on-click children]}]
[:button {:class (stl/css-case :property-detail-copiable true
:property-detail-copied copied
:property-detail-copiable-color (some? color))
@ -45,7 +44,7 @@
color-library-name (get-in (or colors-library file-colors) [(:ref-id color) :name])
color (assoc color :name color-library-name)]
[:span {:class (stl/css :property-detail-text)} (:name color)])
[:span {:class (stl/css :property-detail-text)} detail]))
[:span {:class (stl/css :property-detail-text)} children]))
[:> icon* {:class (stl/css :property-detail-icon)
:icon-id (if copied i/tick i/clipboard)
:size "s"

View File

@ -101,18 +101,16 @@
[:div {:class (stl/css :tooltip-token-title)}
(tr "inspect.tabs.styles.token.resolved-value")]
[:div {:class (stl/css :tooltip-token-value)}
(:value token)]])}
[:> property-detail-copiable* {:detail formatted-color-value
:color color
(:resolved-value token)]])}
[:> property-detail-copiable* {:color color
:token token
:copied copied
:on-click copy-attr}]]
:on-click copy-attr} formatted-color-value]]
[:> property-detail-copiable* {:detail formatted-color-value
:color color
[:> property-detail-copiable* {:color color
:copied copied
:on-click copy-attr}])]]
:on-click copy-attr} formatted-color-value])]]
(when (:image color)
[:div {:class (stl/css :color-image-preview)}
[:div {:class (stl/css :color-image-preview-wrapper)}

View File

@ -7,6 +7,7 @@
(ns app.main.ui.inspect.styles.rows.properties-row
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.main.ui.ds.tooltip :refer [tooltip*]]
[app.main.ui.inspect.styles.property-detail-copiable :refer [property-detail-copiable*]]
[app.util.i18n :refer [tr]]
@ -26,7 +27,7 @@
(mf/defc properties-row*
{::mf/schema schema:properties-row}
[{:keys [class term detail token property copiable]}]
(let [copiable? (or copiable false)
(let [copiable? (d/nilv copiable false)
detail? (not (or (nil? detail) (str/blank? detail)))
detail (if detail? detail "-")
copied* (mf/use-state false)
@ -51,12 +52,10 @@
:content #(mf/html
[:div {:class (stl/css :tooltip-token)}
[:div {:class (stl/css :tooltip-token-title)} (tr "inspect.tabs.styles.token.resolved-value")]
[:div {:class (stl/css :tooltip-token-value)} (:value token)]])}
[:> property-detail-copiable* {:detail detail
:token token
[:div {:class (stl/css :tooltip-token-value)} (:resolved-value token)]])}
[:> property-detail-copiable* {:token token
:copied copied
:on-click copy-attr}]]
[:> property-detail-copiable* {:detail detail
:copied copied
:on-click copy-attr}])
:on-click copy-attr} detail]]
[:> property-detail-copiable* {:copied copied
:on-click copy-attr} detail])
detail)]]))