From 73222f22d0d33d20474993544d6ac2fc3aa21df8 Mon Sep 17 00:00:00 2001 From: Xaviju Date: Thu, 2 Oct 2025 13:58:08 +0200 Subject: [PATCH] :tada: Add stroke panel to inspect styles tab (#7408) --- frontend/src/app/main/ui/inspect/styles.cljs | 15 +++- .../main/ui/inspect/styles/panels/fill.cljs | 2 +- .../main/ui/inspect/styles/panels/stroke.cljs | 73 +++++++++++++++++++ .../styles/rows/color_properties_row.cljs | 30 +++++--- .../app/util/code_gen/style_css_formats.cljs | 6 ++ .../app/util/code_gen/style_css_values.cljs | 6 ++ 6 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 frontend/src/app/main/ui/inspect/styles/panels/stroke.cljs diff --git a/frontend/src/app/main/ui/inspect/styles.cljs b/frontend/src/app/main/ui/inspect/styles.cljs index 2ca43b7e88..f25d766feb 100644 --- a/frontend/src/app/main/ui/inspect/styles.cljs +++ b/frontend/src/app/main/ui/inspect/styles.cljs @@ -20,6 +20,7 @@ [app.main.ui.inspect.styles.panels.geometry :refer [geometry-panel*]] [app.main.ui.inspect.styles.panels.layout :refer [layout-panel*]] [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.tokens-panel :refer [tokens-panel*]] [app.main.ui.inspect.styles.panels.variants-panel :refer [variants-panel*]] @@ -64,6 +65,9 @@ (not (contains? #{:text :group} (:type shape))) (seq (:fills shape)))) +(defn- has-stroke? [shape] + (seq (:strokes shape))) + (defn- has-blur? [shape] (:blur shape)) @@ -157,9 +161,18 @@ [:> style-box* {:panel :fill} [:> fill-panel* {:color-space color-space :shapes shapes - :objects objects :resolved-tokens resolved-active-tokens}]])) + ;; STROKE PANEL + :stroke + (let [shapes (filter has-stroke? shapes)] + (when (seq shapes) + [:> style-box* {:panel :stroke} + [:> stroke-panel* {:color-space color-space + :shapes shapes + :objects objects + :resolved-tokens resolved-active-tokens}]])) + ;; VISIBILITY PANEL :visibility (let [shapes (filter has-visibility-props? shapes)] diff --git a/frontend/src/app/main/ui/inspect/styles/panels/fill.cljs b/frontend/src/app/main/ui/inspect/styles/panels/fill.cljs index 7cf5a67237..074c58311a 100644 --- a/frontend/src/app/main/ui/inspect/styles/panels/fill.cljs +++ b/frontend/src/app/main/ui/inspect/styles/panels/fill.cljs @@ -26,7 +26,7 @@ token)) (mf/defc fill-panel* - [{:keys [shapes _objects resolved-tokens color-space]}] + [{:keys [shapes resolved-tokens color-space]}] [:div {:class (stl/css :fill-panel)} (for [shape shapes] [:div {:key (:id shape) :class "fill-shape"} diff --git a/frontend/src/app/main/ui/inspect/styles/panels/stroke.cljs b/frontend/src/app/main/ui/inspect/styles/panels/stroke.cljs new file mode 100644 index 0000000000..0592e8fe15 --- /dev/null +++ b/frontend/src/app/main/ui/inspect/styles/panels/stroke.cljs @@ -0,0 +1,73 @@ +;; 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.stroke + (:require-macros [app.main.style :as stl]) + (:require + [app.common.data :as d] + [app.common.data.macros :as dm] + [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] + [rumext.v2 :as mf])) + +(def ^:private properties [:border-style :border-width :border-color]) + +(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 + :border-color :stroke-color}) + +(defn- get-applied-tokens-in-shape + [shape-tokens property] + (let [border-prop (get shape-prop->stroke-prop property)] + (if border-prop + (get shape-tokens border-prop) + (get shape-tokens property)))) + +(defn- get-resolved-token + "Get the resolved token for a specific property in a shape." + [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)) + +(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 [stroke (:strokes shape)] + (for [property properties] + (let [property property + 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 (get-resolved-token property shape resolved-tokens)] + (if (= property :border-color) + [:> color-properties-row* {:key (dm/str "stroke-property-" (:id shape) (:color stroke-type)) + :term property-name + :color stroke-type + :token resolved-token + :format color-space + :copiable true}] + [:> properties-row* {:key (dm/str "svg-property-" (d/name property)) + :term (d/name property-name) + :detail (dm/str value) + :token resolved-token + :property property-value + :copiable true}]))))])]) diff --git a/frontend/src/app/main/ui/inspect/styles/rows/color_properties_row.cljs b/frontend/src/app/main/ui/inspect/styles/rows/color_properties_row.cljs index 002479c185..dc99c16703 100644 --- a/frontend/src/app/main/ui/inspect/styles/rows/color_properties_row.cljs +++ b/frontend/src/app/main/ui/inspect/styles/rows/color_properties_row.cljs @@ -18,6 +18,7 @@ [app.util.i18n :refer [tr]] [app.util.timers :as tm] [app.util.webapi :as wapi] + [cuerdas.core :as str] [rumext.v2 :as mf])) (def ^:private schema:color-properties-row @@ -47,6 +48,7 @@ (d/coalesce 1) (* 100) (fmt/format-number)) "%")) + formatted-color-value (mf/use-memo (mf/deps color) #(cond @@ -63,19 +65,23 @@ (some? (:image color)) (tr "media.image") :else "none")) + css-term (-> term + (str/replace #" " "-") + (str/replace #"([A-Z])" "-$1") + (str/lower) + (str/replace #"^-" "")) - copiable-value - (mf/use-memo - (mf/deps color formatted-color-value color-opacity color-image-url token) - #(if (some? token) - (:name token) - (cond - (:color color) (if (= format "hex") - (dm/str "background: " color-value "; opacity: " color-opacity ";") - (dm/str "background: " formatted-color-value ";")) - (:gradient color) (dm/str "background: " (uc/color->background color) ";") - (:image color) (dm/str "background: url(" color-image-url ") no-repeat center center / cover;") - :else "none"))) + copiable-value (mf/use-memo + (mf/deps color formatted-color-value color-opacity color-image-url token) + #(if (some? token) + (:name token) + (cond + (:color color) (if (= format "hex") + (dm/str css-term ": " color-value "; opacity: " color-opacity ";") + (dm/str css-term ": " formatted-color-value ";")) + (:gradient color) (dm/str css-term ": " (uc/color->background color) ";") + (:image color) (dm/str css-term ": url(" color-image-url ") no-repeat center center / cover;") + :else "none"))) copy-attr (mf/use-fn (mf/deps copied formatted-color-value) diff --git a/frontend/src/app/util/code_gen/style_css_formats.cljs b/frontend/src/app/util/code_gen/style_css_formats.cljs index 3cc1a9cb29..b2de3e7664 100644 --- a/frontend/src/app/util/code_gen/style_css_formats.cljs +++ b/frontend/src/app/util/code_gen/style_css_formats.cljs @@ -35,6 +35,7 @@ :border-end-end-radius :string-or-size-array :border-width :border-width :border-style :border-style + :border-color :border-color :box-shadow :shadows :filter :blur :gap :size-array @@ -122,6 +123,10 @@ [value] (fmt/format-pixels (:width value))) +(defn- format-border-color + [value options] + (format-color (:color value) options)) + (defn- format-size-array [value] (cond @@ -189,6 +194,7 @@ :border (format-border value options) :border-style (format-border-style value) :border-width (format-border-width value) + :border-color (format-border-color value options) :size-array (format-size-array value) :string-or-size-array (format-string-or-size-array value) :keyword (format-keyword value) diff --git a/frontend/src/app/util/code_gen/style_css_values.cljs b/frontend/src/app/util/code_gen/style_css_values.cljs index 4b3338aec0..cba1991599 100644 --- a/frontend/src/app/util/code_gen/style_css_values.cljs +++ b/frontend/src/app/util/code_gen/style_css_values.cljs @@ -243,6 +243,11 @@ (when-not (cgc/svg-markup? stroke) (get-stroke-data stroke))) +(defn- get-border-color + [stroke] + (when-not (cgc/svg-markup? stroke) + (get-stroke-data stroke))) + (defn- get-box-shadow [shape] (when-not (cgc/svg-markup? shape) @@ -529,6 +534,7 @@ :border (get-border shape) :border-style (get-border-style shape) :border-width (get-border-width shape) + :border-color (get-border-color shape) :border-radius (get-border-radius shape) :border-start-start-radius (get-border-start-start-radius shape) :border-start-end-radius (get-border-start-end-radius shape)