mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
🎉 Inspect styles tab: geometry panel
This commit is contained in:
@@ -146,7 +146,6 @@
|
||||
position: relative;
|
||||
min-height: $s-32;
|
||||
width: $s-144;
|
||||
max-width: $s-144;
|
||||
padding: calc($s-8 - $s-1) 0 calc($s-8 - $s-1) calc($s-8 - $s-1);
|
||||
border-radius: $s-8;
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -16,6 +16,7 @@ $sz-40: px2rem(40);
|
||||
$sz-48: px2rem(48);
|
||||
$sz-80: px2rem(80);
|
||||
$sz-88: px2rem(88);
|
||||
$sz-154: px2rem(154);
|
||||
$sz-160: px2rem(160);
|
||||
$sz-200: px2rem(200);
|
||||
$sz-224: px2rem(224);
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
[app.common.types.component :as ctc]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.style-dictionary :as sd]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.inspect.styles.panels.geometry :refer [geometry-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.style-box :refer [style-box*]]
|
||||
@@ -45,6 +47,13 @@
|
||||
active-sets
|
||||
(mf/with-memo [tokens-lib]
|
||||
(some-> tokens-lib (ctob/get-active-themes-set-names)))
|
||||
active-tokens
|
||||
(mf/with-memo [tokens-lib]
|
||||
(if tokens-lib
|
||||
(ctob/get-tokens-in-active-sets tokens-lib)
|
||||
{}))
|
||||
resolved-active-tokens
|
||||
(sd/use-resolved-tokens* active-tokens)
|
||||
panels (type->panel-group type)]
|
||||
[:ol {:class (stl/css :styles-tab) :aria-label (tr "labels.styles")}
|
||||
(when (or active-themes active-sets)
|
||||
@@ -59,6 +68,9 @@
|
||||
:objects objects
|
||||
:shape first-shape
|
||||
:data data}]
|
||||
:geometry [:> geometry-panel* {:shapes shapes
|
||||
:objects objects
|
||||
:resolved-tokens resolved-active-tokens}]
|
||||
color-space)]])]))
|
||||
|
||||
|
||||
|
||||
40
frontend/src/app/main/ui/inspect/styles/panels/geometry.cljs
Normal file
40
frontend/src/app/main/ui/inspect/styles/panels/geometry.cljs
Normal file
@@ -0,0 +1,40 @@
|
||||
(ns app.main.ui.inspect.styles.panels.geometry
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.ui.inspect.attributes.common :as cmm]
|
||||
[app.main.ui.inspect.styles.properties-row :refer [properties-row*]]
|
||||
[app.util.code-gen.style-css :as css]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private properties
|
||||
[:width
|
||||
:height
|
||||
:left
|
||||
:top
|
||||
:border-radius
|
||||
:transform])
|
||||
|
||||
(defn- get-resolved-token
|
||||
[property shape resolved-tokens]
|
||||
(let [shape-tokens (:applied-tokens shape)
|
||||
applied-tokens-in-shape (get shape-tokens property)
|
||||
token (get resolved-tokens applied-tokens-in-shape)]
|
||||
token))
|
||||
|
||||
(mf/defc geometry-panel*
|
||||
[{:keys [shapes objects resolved-tokens]}]
|
||||
[:div {:class (stl/css :variants-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}])))])])
|
||||
@@ -1,6 +1,10 @@
|
||||
(ns app.main.ui.inspect.styles.properties-row
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.ui.ds.tooltip :refer [tooltip*]]
|
||||
[app.main.ui.inspect.styles.property-detail-copiable :refer [property-detail-copiable*]]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.timers :as tm]
|
||||
[app.util.webapi :as wapi]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
@@ -9,22 +13,44 @@
|
||||
[:map
|
||||
[:term :string]
|
||||
[:detail :string]
|
||||
[:property {:optional true} :string] ;; CSS valid property
|
||||
[:token {:optional true} :any] ;; resolved token object
|
||||
[:copiable {:optional true} :boolean]])
|
||||
|
||||
(mf/defc properties-row*
|
||||
{::mf/schema schema:properties-row}
|
||||
[{:keys [term detail copiable]}]
|
||||
[{:keys [term detail token property copiable]}]
|
||||
(let [copiable? (or copiable false)
|
||||
detail? (not (or (nil? detail) (str/blank? detail)))
|
||||
detail (if detail? detail "-")
|
||||
copied* (mf/use-state false)
|
||||
copied (deref copied*)
|
||||
copiable-value (if (some? token)
|
||||
(:name token)
|
||||
property)
|
||||
copy-attr
|
||||
(mf/use-fn
|
||||
(mf/deps copied)
|
||||
(fn []
|
||||
(wapi/write-to-clipboard (str term ": " detail))))]
|
||||
(reset! copied* true)
|
||||
(wapi/write-to-clipboard copiable-value)
|
||||
(tm/schedule 1000 #(reset! copied* false))))]
|
||||
[:dl {:class (stl/css :property-row)}
|
||||
[:dt {:class (stl/css :property-term)} term]
|
||||
[:dd {:class (stl/css :property-detail)}
|
||||
(if (and copiable? detail?)
|
||||
[:button {:class (stl/css :property-detail-copiable)
|
||||
:on-click copy-attr} detail]
|
||||
(if copiable?
|
||||
(if token
|
||||
[:> tooltip* {:id (:name token)
|
||||
:class (stl/css :tooltip-token-wrapper)
|
||||
: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
|
||||
:copied copied
|
||||
:on-click copy-attr}]]
|
||||
[:> property-detail-copiable* {:detail detail
|
||||
:copied copied
|
||||
:on-click copy-attr}])
|
||||
detail)]]))
|
||||
|
||||
@@ -5,15 +5,22 @@
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@use "../../ds/typography.scss" as *;
|
||||
@use "../../ds/_sizes.scss" as *;
|
||||
@use "../../ds/_borders.scss" as *;
|
||||
|
||||
// TOKENS ROW
|
||||
|
||||
.property-row {
|
||||
--term-color: var(--color-foreground-secondary);
|
||||
--detail-color: var(--color-foreground-primary);
|
||||
--button-min-inline-size: #{$sz-154};
|
||||
--button-min-block-size: #{$sz-36};
|
||||
|
||||
display: flex;
|
||||
padding-block: var(--sp-s);
|
||||
display: grid;
|
||||
grid-template-columns: 30% 1fr;
|
||||
align-items: center;
|
||||
min-inline-size: var(--button-min-inline-size);
|
||||
min-block-size: var(--button-min-block-size);
|
||||
}
|
||||
|
||||
.property-term,
|
||||
@@ -23,10 +30,29 @@
|
||||
|
||||
.property-term {
|
||||
color: var(--term-color);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.property-detail {
|
||||
flex: 2;
|
||||
color: var(--detail-color);
|
||||
}
|
||||
|
||||
// TOOLTIP CONTENT
|
||||
|
||||
.tooltip-token {
|
||||
--title-color: var(--color-foreground-secondary);
|
||||
--title-value: var(--color-foreground-primary);
|
||||
}
|
||||
|
||||
.tooltip-token-title {
|
||||
@include use-typography("body-small");
|
||||
color: var(--title-color);
|
||||
}
|
||||
|
||||
.tooltip-token-value {
|
||||
@include use-typography("body-small");
|
||||
color: var(--title-value);
|
||||
}
|
||||
|
||||
.tooltip-token-wrapper {
|
||||
inline-size: 100%;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
(ns app.main.ui.inspect.styles.property-detail-copiable
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private schema:property-detail-copiable
|
||||
[:map
|
||||
[:detail :string]
|
||||
[:token {:optional true} :any] ;; resolved token object
|
||||
[:copied :boolean]
|
||||
[:on-click fn?]])
|
||||
|
||||
(mf/defc property-detail-copiable*
|
||||
{::mf/schema schema:property-detail-copiable}
|
||||
[{:keys [detail token copied on-click]}]
|
||||
[:button {:class (stl/css-case :property-detail-copiable true
|
||||
:property-detail-copied copied)
|
||||
:on-click on-click}
|
||||
(if token
|
||||
[:span {:class (stl/css :property-detail-text :property-detail-text-token)} (:name token)]
|
||||
[:span {:class (stl/css :property-detail-text)} detail])
|
||||
[:> icon* {:class (stl/css :property-detail-icon)
|
||||
:icon-id (if copied "tick" "clipboard")
|
||||
:size "s"
|
||||
:aria-label (tr "inspect.tabs.styles.panel.copy-to-clipboard")}]])
|
||||
@@ -0,0 +1,66 @@
|
||||
// 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/typography.scss" as *;
|
||||
@use "../../ds/_sizes.scss" as *;
|
||||
@use "../../ds/_borders.scss" as *;
|
||||
|
||||
.property-detail-copiable {
|
||||
--detail-color: var(--color-foreground-primary);
|
||||
--button-min-inline-size: #{$sz-154};
|
||||
--button-min-block-size: #{$sz-36};
|
||||
}
|
||||
|
||||
.property-detail-text {
|
||||
color: var(--detail-color);
|
||||
}
|
||||
|
||||
.property-detail-text-token {
|
||||
@include use-typography("code-font");
|
||||
--detail-color: var(--color-token-foreground);
|
||||
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.property-detail-copiable {
|
||||
--button-border-radius: #{$br-4};
|
||||
--button-background: none;
|
||||
|
||||
appearance: none;
|
||||
background: var(--button-background);
|
||||
cursor: pointer;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
color: var(--detail-color);
|
||||
min-block-size: var(--button-min-block-size);
|
||||
min-inline-size: var(--button-min-inline-size);
|
||||
padding: var(--sp-s);
|
||||
border-radius: var(--button-border-radius);
|
||||
border: 1px solid transparent;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
--button-background: var(--color-background-tertiary);
|
||||
|
||||
& .property-detail-icon {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.property-detail-copied {
|
||||
--button-border-active: var(--color-accent-tertiary);
|
||||
border: 1px solid var(--button-border-active);
|
||||
}
|
||||
|
||||
.property-detail-icon {
|
||||
display: none;
|
||||
}
|
||||
@@ -1885,6 +1885,14 @@ msgstr "Layout Element"
|
||||
msgid "inspect.tabs.styles.panel.toggle-style"
|
||||
msgstr "Toggle panel %s"
|
||||
|
||||
#: src/app/main/ui/inspect/styles/style_box.cljs:12
|
||||
msgid "inspect.tabs.styles.panel.copy-to-clipboard"
|
||||
msgstr "Copy to clipboard"
|
||||
|
||||
#: src/app/main/ui/inspect/styles/properties_row.cljs:48
|
||||
msgid "inspect.tabs.styles.token.resolved-value"
|
||||
msgstr "Resolved value:"
|
||||
|
||||
#: src/app/main/ui/dashboard/comments.cljs:95
|
||||
msgid "label.mark-all-as-read"
|
||||
msgstr "Mark all as read"
|
||||
|
||||
@@ -1891,6 +1891,14 @@ msgstr "Layout de elemento"
|
||||
msgid "inspect.tabs.styles.panel.toggle-style"
|
||||
msgstr "Alternar panel %s"
|
||||
|
||||
#: src/app/main/ui/inspect/styles/style_box.cljs:12
|
||||
msgid "inspect.tabs.styles.panel.copy-to-clipboard"
|
||||
msgstr "Copiar al portapapeles"
|
||||
|
||||
#: src/app/main/ui/inspect/styles/properties_row.cljs:48
|
||||
msgid "inspect.tabs.styles.token.resolved-value"
|
||||
msgstr "Valor resuelto:"
|
||||
|
||||
#: src/app/main/ui/dashboard/comments.cljs:95
|
||||
msgid "label.mark-all-as-read"
|
||||
msgstr "Marcar todo como leído"
|
||||
@@ -2601,6 +2609,10 @@ msgstr "Tu cuenta"
|
||||
msgid "labels.youtube"
|
||||
msgstr "YouTube"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:518
|
||||
msgid "labels.variant"
|
||||
msgstr "Variante"
|
||||
|
||||
#: src/app/main/ui/inspect/styles/style_box.cljs:12
|
||||
msgid "labels.fill"
|
||||
msgstr "Relleno"
|
||||
|
||||
Reference in New Issue
Block a user