mirror of
https://github.com/penpot/penpot.git
synced 2025-07-09 20:57:53 +02:00
🎉 Add variants properties to inspect panel
This commit is contained in:
parent
b2bc5aff68
commit
625cbfc50a
9 changed files with 146 additions and 32 deletions
|
@ -60,6 +60,11 @@
|
||||||
:value v}) remaining)]
|
:value v}) remaining)]
|
||||||
(into assigned new-properties)))
|
(into assigned new-properties)))
|
||||||
|
|
||||||
|
(defn- dashes-to-end
|
||||||
|
[property-values]
|
||||||
|
(let [dashes (if (some #(= % "--") property-values) ["--"] [])]
|
||||||
|
(concat (remove #(= % "--") property-values) dashes)))
|
||||||
|
|
||||||
|
|
||||||
(defn extract-properties-values
|
(defn extract-properties-values
|
||||||
[data objects variant-id]
|
[data objects variant-id]
|
||||||
|
@ -68,8 +73,10 @@
|
||||||
(group-by :name)
|
(group-by :name)
|
||||||
(map (fn [[k v]]
|
(map (fn [[k v]]
|
||||||
{:name k
|
{:name k
|
||||||
:values (distinct
|
:value (->> v
|
||||||
(map #(if (str/empty? (:value %)) "--" (:value %)) v))}))))
|
(map #(if (str/empty? (:value %)) "--" (:value %)))
|
||||||
|
distinct
|
||||||
|
dashes-to-end)}))))
|
||||||
|
|
||||||
|
|
||||||
(defn generate-update-property-name
|
(defn generate-update-property-name
|
||||||
|
|
|
@ -180,7 +180,7 @@
|
||||||
value (str clv/value-prefix
|
value (str clv/value-prefix
|
||||||
(-> (clv/extract-properties-values data objects (:variant-id component))
|
(-> (clv/extract-properties-values data objects (:variant-id component))
|
||||||
last
|
last
|
||||||
:values
|
:value
|
||||||
count
|
count
|
||||||
inc))
|
inc))
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
(ns app.main.ui.inspect.attributes
|
(ns app.main.ui.inspect.attributes
|
||||||
(:require-macros [app.main.style :as stl])
|
(:require-macros [app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.types.component :as ctc]
|
||||||
[app.common.types.components-list :as ctkl]
|
[app.common.types.components-list :as ctkl]
|
||||||
[app.main.ui.hooks :as hooks]
|
[app.main.ui.hooks :as hooks]
|
||||||
[app.main.ui.inspect.annotation :refer [annotation]]
|
[app.main.ui.inspect.annotation :refer [annotation]]
|
||||||
|
@ -20,6 +22,7 @@
|
||||||
[app.main.ui.inspect.attributes.stroke :refer [stroke-panel]]
|
[app.main.ui.inspect.attributes.stroke :refer [stroke-panel]]
|
||||||
[app.main.ui.inspect.attributes.svg :refer [svg-panel]]
|
[app.main.ui.inspect.attributes.svg :refer [svg-panel]]
|
||||||
[app.main.ui.inspect.attributes.text :refer [text-panel]]
|
[app.main.ui.inspect.attributes.text :refer [text-panel]]
|
||||||
|
[app.main.ui.inspect.attributes.variant :refer [variant-panel*]]
|
||||||
[app.main.ui.inspect.exports :refer [exports]]
|
[app.main.ui.inspect.exports :refer [exports]]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
@ -31,15 +34,29 @@
|
||||||
:circle [:geometry :fill :stroke :shadow :blur :svg :layout-element]
|
:circle [:geometry :fill :stroke :shadow :blur :svg :layout-element]
|
||||||
:path [:geometry :fill :stroke :shadow :blur :svg :layout-element]
|
:path [:geometry :fill :stroke :shadow :blur :svg :layout-element]
|
||||||
:image [:image :geometry :fill :stroke :shadow :blur :svg :layout-element]
|
:image [:image :geometry :fill :stroke :shadow :blur :svg :layout-element]
|
||||||
:text [:geometry :text :shadow :blur :stroke :layout-element]})
|
:text [:geometry :text :shadow :blur :stroke :layout-element]
|
||||||
|
:variant [:variant :geometry :fill :stroke :shadow :blur :layout :layout-element]})
|
||||||
|
|
||||||
(mf/defc attributes
|
(mf/defc attributes
|
||||||
[{:keys [page-id file-id shapes frame from libraries share-id objects]}]
|
[{:keys [page-id file-id shapes frame from libraries share-id objects]}]
|
||||||
(let [shapes (hooks/use-equal-memo shapes)
|
(let [shapes (hooks/use-equal-memo shapes)
|
||||||
type (if (= (count shapes) 1) (-> shapes first :type) :multiple)
|
first-shape (first shapes)
|
||||||
|
data (dm/get-in libraries [file-id :data])
|
||||||
|
first-component (ctkl/get-component data (:component-id first-shape))
|
||||||
|
type (cond
|
||||||
|
(and (= (count shapes) 1)
|
||||||
|
(or (ctc/is-variant-container? first-shape)
|
||||||
|
(ctc/is-variant? first-component)))
|
||||||
|
:variant
|
||||||
|
|
||||||
|
(= (count shapes) 1)
|
||||||
|
(:type first-shape)
|
||||||
|
|
||||||
|
:else
|
||||||
|
:multiple)
|
||||||
options (type->options type)
|
options (type->options type)
|
||||||
content (when (= (count shapes) 1)
|
annotation-content (when (= (count shapes) 1)
|
||||||
(ctkl/get-component-annotation (first shapes) libraries))]
|
(ctkl/get-component-annotation first-shape libraries))]
|
||||||
|
|
||||||
[:div {:class (stl/css-case :element-options true
|
[:div {:class (stl/css-case :element-options true
|
||||||
:workspace-element-options (= from :workspace))}
|
:workspace-element-options (= from :workspace))}
|
||||||
|
@ -54,14 +71,17 @@
|
||||||
:blur blur-panel
|
:blur blur-panel
|
||||||
:image image-panel
|
:image image-panel
|
||||||
:text text-panel
|
:text text-panel
|
||||||
:svg svg-panel)
|
:svg svg-panel
|
||||||
|
:variant variant-panel*)
|
||||||
{:key idx
|
{:key idx
|
||||||
:shapes shapes
|
:shapes shapes
|
||||||
:objects objects
|
:objects objects
|
||||||
:frame frame
|
:frame frame
|
||||||
:from from}])
|
:from from
|
||||||
(when content
|
:libraries libraries
|
||||||
[:& annotation {:content content}])
|
:file-id file-id}])
|
||||||
|
(when annotation-content
|
||||||
|
[:& annotation {:content annotation-content}])
|
||||||
[:& exports
|
[:& exports
|
||||||
{:shapes shapes
|
{:shapes shapes
|
||||||
:type type
|
:type type
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
(for [property properties]
|
(for [property properties]
|
||||||
(when-let [value (css/get-css-value objects shape property)]
|
(when-let [value (css/get-css-value objects shape property)]
|
||||||
(let [property-name (cmm/get-css-rule-humanized property)]
|
(let [property-name (cmm/get-css-rule-humanized property)]
|
||||||
[:div {:class (stl/css :layout-row)}
|
[:div {:class (stl/css :layout-row)
|
||||||
|
:key (dm/str "layout-" (:id shape) "-" (d/name property))}
|
||||||
[:div {:title property-name
|
[:div {:title property-name
|
||||||
:key (dm/str "layout-" (:id shape) "-" (d/name property))
|
|
||||||
:class (stl/css :global/attr-label)}
|
:class (stl/css :global/attr-label)}
|
||||||
property-name]
|
property-name]
|
||||||
[:div {:class (stl/css :global/attr-value)}
|
[:div {:class (stl/css :global/attr-value)}
|
||||||
|
|
56
frontend/src/app/main/ui/inspect/attributes/variant.cljs
Normal file
56
frontend/src/app/main/ui/inspect/attributes/variant.cljs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
;; 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.attributes.variant
|
||||||
|
(:require-macros [app.main.style :as stl])
|
||||||
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.logic.variants :as clv]
|
||||||
|
[app.common.types.component :as ctc]
|
||||||
|
[app.common.types.components-list :as ctkl]
|
||||||
|
[app.main.ui.components.copy-button :refer [copy-button]]
|
||||||
|
[app.main.ui.components.title-bar :refer [inspect-title-bar]]
|
||||||
|
[app.util.i18n :refer [tr]]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(mf/defc variant-block*
|
||||||
|
[{:keys [name value]}]
|
||||||
|
[:div {:title value
|
||||||
|
:class (stl/css :variant-row)}
|
||||||
|
[:div {:class (stl/css :global/attr-label)} name]
|
||||||
|
[:div {:class (stl/css :global/attr-value)}
|
||||||
|
[:& copy-button {:data value}
|
||||||
|
[:div {:class (stl/css :button-children)} value]]]])
|
||||||
|
|
||||||
|
|
||||||
|
(mf/defc variant-panel*
|
||||||
|
[{:keys [objects shapes libraries file-id] :as kk} ]
|
||||||
|
(let [shape (->> shapes first)
|
||||||
|
title (cond
|
||||||
|
(ctc/is-variant-container? shape)
|
||||||
|
"inspect.attributes.variant.component"
|
||||||
|
(ctc/main-instance? shape)
|
||||||
|
"inspect.attributes.variant.variant"
|
||||||
|
:else
|
||||||
|
"inspect.attributes.variant.copy")
|
||||||
|
|
||||||
|
properties (mf/with-memo [objects shape]
|
||||||
|
(let [data (dm/get-in libraries [file-id :data])
|
||||||
|
is-container? (ctc/is-variant-container? shape)
|
||||||
|
component (when-not is-container? (ctkl/get-component data (:component-id shape)))]
|
||||||
|
(if is-container?
|
||||||
|
(->> (clv/extract-properties-values data objects (:id shape))
|
||||||
|
(map #(update % :value (partial str/join ", "))))
|
||||||
|
(->> (:variant-properties component)
|
||||||
|
(map #(update % :value (fn [v] (if (str/blank? v) "--" v))))))))]
|
||||||
|
[:div {:class (stl/css :attributes-block)}
|
||||||
|
[:& inspect-title-bar
|
||||||
|
{:title (tr title)
|
||||||
|
:class (stl/css :title-spacing-variant)}]
|
||||||
|
|
||||||
|
(for [[pos property] (map-indexed vector properties)]
|
||||||
|
[:> variant-block* {:key (dm/str "variant-property-" pos) :name (:name property) :value (:value property)}])]))
|
25
frontend/src/app/main/ui/inspect/attributes/variant.scss
Normal file
25
frontend/src/app/main/ui/inspect/attributes/variant.scss
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
@import "refactor/common-refactor.scss";
|
||||||
|
|
||||||
|
.attributes-block {
|
||||||
|
@include flexColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-spacing-variant {
|
||||||
|
@extend .attr-title;
|
||||||
|
}
|
||||||
|
|
||||||
|
.variant-row {
|
||||||
|
@extend .attr-row;
|
||||||
|
height: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-children {
|
||||||
|
@extend .copy-button-children;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
|
[app.common.logic.variants :as clv]
|
||||||
[app.common.types.component :as ctk]
|
[app.common.types.component :as ctk]
|
||||||
[app.common.types.file :as ctf]
|
[app.common.types.file :as ctf]
|
||||||
[app.main.data.helpers :as dsh]
|
[app.main.data.helpers :as dsh]
|
||||||
|
@ -758,23 +759,8 @@
|
||||||
first-variant (get objects (first (:shapes shape)))
|
first-variant (get objects (first (:shapes shape)))
|
||||||
variant-id (:variant-id first-variant)
|
variant-id (:variant-id first-variant)
|
||||||
|
|
||||||
dashes-to-end (mf/use-fn
|
|
||||||
(fn [data]
|
|
||||||
(let [dashes (if (some #(= % "--") data) ["--"] [])]
|
|
||||||
(concat (remove #(= % "--") data) dashes))))
|
|
||||||
|
|
||||||
properties (mf/with-memo [data objects variant-id]
|
properties (mf/with-memo [data objects variant-id]
|
||||||
(->> (dwv/find-related-components data objects variant-id)
|
(clv/extract-properties-values data objects (:id shape)))
|
||||||
(mapcat :variant-properties)
|
|
||||||
(group-by :name)
|
|
||||||
(map-indexed (fn [index [k v]]
|
|
||||||
{:name k
|
|
||||||
:pos index
|
|
||||||
:values (->> v
|
|
||||||
(map #(if (str/empty? (:value %)) "--" (:value %)))
|
|
||||||
distinct
|
|
||||||
dashes-to-end)}))))
|
|
||||||
|
|
||||||
|
|
||||||
menu-open* (mf/use-state false)
|
menu-open* (mf/use-state false)
|
||||||
menu-open? (deref menu-open*)
|
menu-open? (deref menu-open*)
|
||||||
|
@ -860,7 +846,7 @@
|
||||||
(when-not multi?
|
(when-not multi?
|
||||||
[:*
|
[:*
|
||||||
(for [[pos property] (map vector (range) properties)]
|
(for [[pos property] (map vector (range) properties)]
|
||||||
(let [val (str/join ", " (:values property))]
|
(let [val (str/join ", " (:value property))]
|
||||||
[:div {:key (str (:id shape) pos) :class (stl/css :variant-property-row)}
|
[:div {:key (str (:id shape) pos) :class (stl/css :variant-property-row)}
|
||||||
[:> input-with-values* {:name (:name property)
|
[:> input-with-values* {:name (:name property)
|
||||||
:values val
|
:values val
|
||||||
|
|
|
@ -1530,6 +1530,16 @@ msgstr "Shadow"
|
||||||
msgid "inspect.attributes.size"
|
msgid "inspect.attributes.size"
|
||||||
msgstr "Size and position"
|
msgstr "Size and position"
|
||||||
|
|
||||||
|
#: src/app/main/ui/viewer/inspect/attributes/variant.cljs:40
|
||||||
|
msgid "inspect.attributes.variant.variant"
|
||||||
|
msgstr "Variant properties"
|
||||||
|
|
||||||
|
msgid "inspect.attributes.variant.component"
|
||||||
|
msgstr "Component properties"
|
||||||
|
|
||||||
|
msgid "inspect.attributes.variant.copy"
|
||||||
|
msgstr "Copy properties"
|
||||||
|
|
||||||
#: src/app/main/ui/viewer/inspect/attributes/stroke.cljs:52
|
#: src/app/main/ui/viewer/inspect/attributes/stroke.cljs:52
|
||||||
msgid "inspect.attributes.stroke"
|
msgid "inspect.attributes.stroke"
|
||||||
msgstr "Stroke"
|
msgstr "Stroke"
|
||||||
|
|
|
@ -1532,6 +1532,16 @@ msgstr "Sombra"
|
||||||
msgid "inspect.attributes.size"
|
msgid "inspect.attributes.size"
|
||||||
msgstr "Tamaño y posición"
|
msgstr "Tamaño y posición"
|
||||||
|
|
||||||
|
#: src/app/main/ui/viewer/inspect/attributes/variant.cljs:40
|
||||||
|
msgid "inspect.attributes.variant.variant"
|
||||||
|
msgstr "Propiedades de la variante"
|
||||||
|
|
||||||
|
msgid "inspect.attributes.variant.component"
|
||||||
|
msgstr "Propiedades del componente"
|
||||||
|
|
||||||
|
msgid "inspect.attributes.variant.copy"
|
||||||
|
msgstr "Propiedades de la copia"
|
||||||
|
|
||||||
#: src/app/main/ui/viewer/inspect/attributes/stroke.cljs:52
|
#: src/app/main/ui/viewer/inspect/attributes/stroke.cljs:52
|
||||||
msgid "inspect.attributes.stroke"
|
msgid "inspect.attributes.stroke"
|
||||||
msgstr "Borde"
|
msgstr "Borde"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue