0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-12 18:18:24 -05:00

🐛 Detect correctly color of outlines and controls of components

This commit is contained in:
Andrés Moya 2023-05-30 16:56:13 +02:00
parent d8861bbf48
commit 9c79c80fd7
6 changed files with 72 additions and 31 deletions

View file

@ -40,7 +40,19 @@
[shape] [shape]
(some? (:main-instance? shape))) (some? (:main-instance? shape)))
(defn is-main-instance? (defn in-component-copy?
"Check if the shape is inside a component non-main instance."
[shape]
(some? (:shape-ref shape)))
(defn in-component-copy-not-root?
"Check if the shape is inside a component non-main instance and
is not the root shape."
[shape]
(and (some? (:shape-ref shape))
(nil? (:component-id shape))))
(defn main-instance-of?
"Check if this shape is the root of the main instance of the given component." "Check if this shape is the root of the main instance of the given component."
[shape-id page-id component] [shape-id page-id component]
(and (= shape-id (:main-instance-id component)) (and (= shape-id (:main-instance-id component))
@ -58,18 +70,6 @@
(and (some? (:component-id shape)) (and (some? (:component-id shape))
(= (:component-file shape) library-id))) (= (:component-file shape) library-id)))
(defn in-component-copy?
"Check if the shape is inside a component non-main instance."
[shape]
(some? (:shape-ref shape)))
(defn in-component-copy-not-root?
"Check if the shape is inside a component non-main instance and
is not the root shape."
[shape]
(and (some? (:shape-ref shape))
(nil? (:component-id shape))))
(defn detach-shape (defn detach-shape
"Remove the links and leave it as a plain shape, detached from any component." "Remove the links and leave it as a plain shape, detached from any component."
[shape] [shape]

View file

@ -109,6 +109,23 @@
:else :else
(get-component-shape objects (get objects (:parent-id shape)) options)))) (get-component-shape objects (get objects (:parent-id shape)) options))))
(defn in-component-main?
"Check if the shape is inside a component non-main instance.
Note that we must iterate on the parents because non-root shapes in
a main component have not any discriminating attribute."
[objects shape]
(let [component-shape (get-component-shape objects shape {:allow-main? true})]
(:main-instance? component-shape)))
(defn in-any-component?
"Check if the shape is part of any component (main or copy), wether it's
head or not."
[objects shape]
(or (ctk/in-component-copy? shape)
(ctk/main-instance? shape)
(in-component-main? objects shape)))
(defn make-component-shape (defn make-component-shape
"Clone the shape and all children. Generate new ids and detach "Clone the shape and all children. Generate new ids and detach
from parent and frame. Update the original shapes to have links from parent and frame. Update the original shapes to have links

View file

@ -109,7 +109,7 @@
(t/is (= (:name p-group) "Group1")) (t/is (= (:name p-group) "Group1"))
(t/is (ctk/instance-of? p-group file-id (:id component1))) (t/is (ctk/instance-of? p-group file-id (:id component1)))
(t/is (not (:main-instance? p-group))) (t/is (not (:main-instance? p-group)))
(t/is (not (ctk/is-main-instance? (:id p-group) file-page-id component1))) (t/is (not (ctk/main-instance-of? (:id p-group) file-page-id component1)))
(t/is (ctk/is-main-of? c-group1 p-group)) (t/is (ctk/is-main-of? c-group1 p-group))
(t/is (= (:name p-shape) "Rect1")) (t/is (= (:name p-shape) "Rect1"))

View file

@ -9,6 +9,8 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.types.container :as ctn]
[app.main.refs :as refs]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.attrs :as attrs]
[app.util.object :as obj] [app.util.object :as obj]
@ -22,7 +24,6 @@
[props] [props]
(let [shape (obj/get props "shape") (let [shape (obj/get props "shape")
zoom (obj/get props "zoom" 1) zoom (obj/get props "zoom" 1)
color (obj/get props "color")
modifier (obj/get props "modifier") modifier (obj/get props "modifier")
shape (gsh/transform-shape shape (:modifiers modifier)) shape (gsh/transform-shape shape (:modifiers modifier))
@ -35,6 +36,13 @@
(or (ex/ignoring (upf/format-path (:content shape))) (or (ex/ignoring (upf/format-path (:content shape)))
""))) "")))
;; Note that we don't use mf/deref to avoid a repaint dependency here
objects (deref refs/workspace-page-objects)
color (if (ctn/in-any-component? objects shape)
"var(--color-component-highlight)"
"var(--color-primary)")
{:keys [x y width height selrect]} shape {:keys [x y width height selrect]} shape
border-radius-attrs (attrs/extract-border-radius shape) border-radius-attrs (attrs/extract-border-radius shape)
@ -78,19 +86,16 @@
::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "zoom" "modifiers"]))]} ::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "zoom" "modifiers"]))]}
[props] [props]
(let [shapes (obj/get props "shapes") (let [shapes (obj/get props "shapes")
zoom (obj/get props "zoom") zoom (obj/get props "zoom")
modifiers (obj/get props "modifiers") modifiers (obj/get props "modifiers")]
color (if (or (> (count shapes) 1) (nil? (:shape-ref (first shapes))))
"var(--color-primary)" "var(--color-component-highlight)")]
(for [shape shapes] (for [shape shapes]
(let [modifier (get modifiers (:id shape))] (let [modifier (get modifiers (:id shape))]
[:& outline {:key (str "outline-" (:id shape)) [:& outline {:key (str "outline-" (:id shape))
:shape shape :shape shape
:modifier modifier :modifier modifier
:zoom zoom :zoom zoom}]))))
:color color}]))))
(defn- show-outline? (defn- show-outline?
[shape] [shape]

View file

@ -11,6 +11,7 @@
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.types.container :as ctn]
[app.common.types.shape :as cts] [app.common.types.shape :as cts]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.refs :as refs] [app.main.refs :as refs]
@ -441,9 +442,13 @@
(let [num (count shapes) (let [num (count shapes)
{:keys [type] :as shape} (first shapes) {:keys [type] :as shape} (first shapes)
color (if (or (> num 1) (nil? (:shape-ref shape))) ;; Note that we don't use mf/deref to avoid a repaint dependency here
selection-rect-color-normal objects (deref refs/workspace-page-objects)
selection-rect-color-component)]
color (if (and (= num 1)
(ctn/in-any-component? objects shape))
selection-rect-color-component
selection-rect-color-normal)]
(cond (cond
(zero? num) (zero? num)
nil nil
@ -481,9 +486,13 @@
(let [num (count shapes) (let [num (count shapes)
{:keys [type] :as shape} (first shapes) {:keys [type] :as shape} (first shapes)
color (if (or (> num 1) (nil? (:shape-ref shape))) ;; Note that we don't use mf/deref to avoid a repaint dependency here
selection-rect-color-normal objects (deref refs/workspace-page-objects)
selection-rect-color-component)]
color (if (and (= num 1)
(ctn/in-any-component? objects shape))
selection-rect-color-component
selection-rect-color-normal)]
(cond (cond
(zero? num) (zero? num)
nil nil

View file

@ -10,6 +10,7 @@
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.types.container :as ctn]
[app.common.types.shape-tree :as ctt] [app.common.types.shape-tree :as ctt]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
@ -98,6 +99,15 @@
#(mf/deferred % ts/raf)]} #(mf/deferred % ts/raf)]}
[{:keys [frame selected? zoom show-artboard-names? show-id? on-frame-enter on-frame-leave on-frame-select]}] [{:keys [frame selected? zoom show-artboard-names? show-id? on-frame-enter on-frame-leave on-frame-select]}]
(let [workspace-read-only? (mf/use-ctx ctx/workspace-read-only?) (let [workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
;; Note that we don't use mf/deref to avoid a repaint dependency here
objects (deref refs/workspace-page-objects)
color (when selected?
(if (ctn/in-any-component? objects frame)
"var(--color-component-highlight)"
"var(--color-primary-dark)"))
on-pointer-down on-pointer-down
(mf/use-callback (mf/use-callback
(mf/deps (:id frame) on-frame-select workspace-read-only?) (mf/deps (:id frame) on-frame-select workspace-read-only?)
@ -106,7 +116,7 @@
(when (= 1 (.-which event)) (when (= 1 (.-which event))
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
(on-frame-select event (:id frame)))))) (on-frame-select event (:id frame))))))
on-double-click on-double-click
(mf/use-callback (mf/use-callback
@ -146,7 +156,7 @@
:width 12 :width 12
:height 12 :height 12
:class "workspace-frame-icon" :class "workspace-frame-icon"
:style {:fill (when selected? "var(--color-primary-dark)")} :style {:fill color}
:visibility (if show-artboard-names? "visible" "hidden")} :visibility (if show-artboard-names? "visible" "hidden")}
[:use {:href "#icon-set-thumbnail"}]]) [:use {:href "#icon-set-thumbnail"}]])
[:text {:x text-pos-x [:text {:x text-pos-x
@ -154,7 +164,7 @@
:width (:width frame) :width (:width frame)
:height 20 :height 20
:class "workspace-frame-label" :class "workspace-frame-label"
:style {:fill (when selected? "var(--color-primary-dark)")} :style {:fill color}
:visibility (if show-artboard-names? "visible" "hidden") :visibility (if show-artboard-names? "visible" "hidden")
:on-pointer-down on-pointer-down :on-pointer-down on-pointer-down
:on-double-click on-double-click :on-double-click on-double-click