mirror of
https://github.com/penpot/penpot.git
synced 2025-05-08 23:35:53 +02:00
✨ Reusable shape container refactor
This commit is contained in:
parent
5e299551b7
commit
57c93f80e2
7 changed files with 123 additions and 155 deletions
|
@ -27,8 +27,7 @@
|
||||||
[app.main.ui.shapes.rect :as rect]
|
[app.main.ui.shapes.rect :as rect]
|
||||||
[app.main.ui.shapes.text :as text]
|
[app.main.ui.shapes.text :as text]
|
||||||
[app.main.ui.shapes.group :as group]
|
[app.main.ui.shapes.group :as group]
|
||||||
[app.main.ui.shapes.gradients :as grad]
|
[app.main.ui.shapes.shape :refer [shape-container]]))
|
||||||
[app.main.ui.context :as muc]))
|
|
||||||
|
|
||||||
(def ^:private default-color "#E8E9EA") ;; $color-canvas
|
(def ^:private default-color "#E8E9EA") ;; $color-canvas
|
||||||
|
|
||||||
|
@ -57,14 +56,9 @@
|
||||||
(mf/fnc frame-wrapper
|
(mf/fnc frame-wrapper
|
||||||
[{:keys [shape] :as props}]
|
[{:keys [shape] :as props}]
|
||||||
(let [childs (mapv #(get objects %) (:shapes shape))
|
(let [childs (mapv #(get objects %) (:shapes shape))
|
||||||
shape (geom/transform-shape shape)
|
shape (geom/transform-shape shape)]
|
||||||
render-id (mf/use-memo #(str (uuid/next)))]
|
[:> shape-container {:shape shape}
|
||||||
[:& (mf/provider muc/render-ctx) {:value render-id}
|
[:& frame-shape {:shape shape :childs childs}]]))))
|
||||||
[:g.frame
|
|
||||||
[:defs
|
|
||||||
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
|
|
||||||
[:& frame-shape {:shape shape :childs childs}]]]))))
|
|
||||||
|
|
||||||
(defn group-wrapper-factory
|
(defn group-wrapper-factory
|
||||||
[objects]
|
[objects]
|
||||||
|
@ -86,14 +80,8 @@
|
||||||
frame-wrapper (mf/use-memo (mf/deps objects) #(frame-wrapper-factory objects))]
|
frame-wrapper (mf/use-memo (mf/deps objects) #(frame-wrapper-factory objects))]
|
||||||
(when (and shape (not (:hidden shape)))
|
(when (and shape (not (:hidden shape)))
|
||||||
(let [shape (geom/transform-shape frame shape)
|
(let [shape (geom/transform-shape frame shape)
|
||||||
opts #js {:shape shape}
|
opts #js {:shape shape}]
|
||||||
render-id (mf/use-memo #(str (uuid/next)))]
|
[:> shape-container {:shape shape}
|
||||||
[:& (mf/provider muc/render-ctx) {:value render-id}
|
|
||||||
[:g {:filter (filters/filter-str (str "filter_" render-id) shape)}
|
|
||||||
[:defs
|
|
||||||
[:& filters/filters {:shape shape}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
|
|
||||||
(case (:type shape)
|
(case (:type shape)
|
||||||
:curve [:> path/path-shape opts]
|
:curve [:> path/path-shape opts]
|
||||||
:text [:> text/text-shape opts]
|
:text [:> text/text-shape opts]
|
||||||
|
@ -104,7 +92,7 @@
|
||||||
:circle [:> circle/circle-shape opts]
|
:circle [:> circle/circle-shape opts]
|
||||||
:frame [:> frame-wrapper {:shape shape}]
|
:frame [:> frame-wrapper {:shape shape}]
|
||||||
:group [:> group-wrapper {:shape shape :frame frame}]
|
:group [:> group-wrapper {:shape shape :frame frame}]
|
||||||
nil)]])))))
|
nil)])))))
|
||||||
|
|
||||||
(mf/defc page-svg
|
(mf/defc page-svg
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
|
|
|
@ -7,5 +7,33 @@
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2020 UXBOX Labs SL
|
;; Copyright (c) 2020 UXBOX Labs SL
|
||||||
|
|
||||||
(ns app.main.ui.shapes.shape)
|
(ns app.main.ui.shapes.shape
|
||||||
|
(:require
|
||||||
|
[rumext.alpha :as mf]
|
||||||
|
[app.util.object :as obj]
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.ui.shapes.filters :as filters]
|
||||||
|
[app.main.ui.shapes.gradients :as grad]
|
||||||
|
[app.main.ui.context :as muc]))
|
||||||
|
|
||||||
|
(mf/defc shape-container
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
|
||||||
|
(let [shape (unchecked-get props "shape")
|
||||||
|
children (unchecked-get props "children")
|
||||||
|
render-id (mf/use-memo #(str (uuid/next)))
|
||||||
|
filter-id (str "filter_" render-id)
|
||||||
|
group-props (-> props
|
||||||
|
(obj/clone)
|
||||||
|
(obj/without ["shape" "children"])
|
||||||
|
(obj/set! "className" "shape")
|
||||||
|
(obj/set! "filter" (filters/filter-str filter-id shape)))]
|
||||||
|
[:& (mf/provider muc/render-ctx) {:value render-id}
|
||||||
|
[:> :g group-props
|
||||||
|
[:defs
|
||||||
|
[:& filters/filters {:shape shape :filter-id filter-id}]
|
||||||
|
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
||||||
|
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
|
||||||
|
|
||||||
|
children]]))
|
||||||
|
|
|
@ -30,9 +30,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 geom]
|
[app.common.geom.shapes :as geom]
|
||||||
[app.common.uuid :as uuid]
|
[app.main.ui.shapes.shape :refer [shape-container]]))
|
||||||
[app.main.ui.shapes.gradients :as grad]
|
|
||||||
[app.main.ui.context :as muc]))
|
|
||||||
|
|
||||||
(defn on-mouse-down
|
(defn on-mouse-down
|
||||||
[event {:keys [interactions] :as shape}]
|
[event {:keys [interactions] :as shape}]
|
||||||
|
@ -57,18 +55,11 @@
|
||||||
|
|
||||||
on-mouse-down (mf/use-callback
|
on-mouse-down (mf/use-callback
|
||||||
(mf/deps shape)
|
(mf/deps shape)
|
||||||
#(on-mouse-down % shape))
|
#(on-mouse-down % shape))]
|
||||||
|
|
||||||
render-id (mf/use-memo #(str (uuid/next)))]
|
[:> shape-container {:shape shape
|
||||||
|
:on-mouse-down on-mouse-down
|
||||||
[:& (mf/provider muc/render-ctx) {:value render-id}
|
:cursor (when (:interactions shape) "pointer")}
|
||||||
[:g.shape {:on-mouse-down on-mouse-down
|
|
||||||
:cursor (when (:interactions shape) "pointer")
|
|
||||||
:filter (filters/filter-str (str "filter_" render-id) shape)}
|
|
||||||
[:defs
|
|
||||||
[:& filters/filters {:shape shape}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
|
|
||||||
[:& component {:shape shape
|
[:& component {:shape shape
|
||||||
:frame frame
|
:frame frame
|
||||||
:childs childs
|
:childs childs
|
||||||
|
@ -81,7 +72,7 @@
|
||||||
:fill "#31EFB8"
|
:fill "#31EFB8"
|
||||||
:stroke "#31EFB8"
|
:stroke "#31EFB8"
|
||||||
:stroke-width 1
|
:stroke-width 1
|
||||||
:fill-opacity 0.2}])]])))
|
:fill-opacity 0.2}])])))
|
||||||
|
|
||||||
(defn frame-wrapper
|
(defn frame-wrapper
|
||||||
[shape-container show-interactions?]
|
[shape-container show-interactions?]
|
||||||
|
|
|
@ -14,14 +14,11 @@
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.keyboard :as kbd]
|
[app.main.ui.keyboard :as kbd]
|
||||||
[app.main.ui.shapes.filters :as filters]
|
|
||||||
[app.main.ui.shapes.gradients :as grad]
|
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.common.uuid :as uuid]
|
|
||||||
[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 geom]
|
[app.common.geom.shapes :as geom]
|
||||||
[app.main.ui.context :as muc]))
|
[app.main.ui.shapes.shape :refer [shape-container]]))
|
||||||
|
|
||||||
(defn- on-mouse-down
|
(defn- on-mouse-down
|
||||||
[event {:keys [id type] :as shape}]
|
[event {:keys [id type] :as shape}]
|
||||||
|
@ -73,18 +70,11 @@
|
||||||
#(on-mouse-down % shape))
|
#(on-mouse-down % shape))
|
||||||
on-context-menu (mf/use-callback
|
on-context-menu (mf/use-callback
|
||||||
(mf/deps shape)
|
(mf/deps shape)
|
||||||
#(on-context-menu % shape))
|
#(on-context-menu % shape))]
|
||||||
render-id (mf/use-memo #(str (uuid/next)))]
|
|
||||||
|
|
||||||
[:& (mf/provider muc/render-ctx) {:value render-id}
|
[:> shape-container {:shape shape
|
||||||
[:g.shape {:on-mouse-down on-mouse-down
|
:on-mouse-down on-mouse-down
|
||||||
:on-context-menu on-context-menu
|
:on-context-menu on-context-menu}
|
||||||
:filter (filters/filter-str (str "filter_" render-id) shape)}
|
[:& component {:shape shape}]])))
|
||||||
[:defs
|
|
||||||
[:& filters/filters {:shape shape}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
|
|
||||||
|
|
||||||
[:& component {:shape shape}]]])))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,13 @@
|
||||||
[app.main.ui.workspace.shapes.common :as common]
|
[app.main.ui.workspace.shapes.common :as common]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.ui.shapes.frame :as frame]
|
[app.main.ui.shapes.frame :as frame]
|
||||||
[app.main.ui.shapes.gradients :as grad]
|
|
||||||
[app.main.ui.shapes.filters :as filters]
|
|
||||||
[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 geom]
|
[app.common.geom.shapes :as geom]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
[app.main.ui.context :as muc]
|
[app.main.ui.shapes.shape :refer [shape-container]]))
|
||||||
[app.common.uuid :as uuid]))
|
|
||||||
|
|
||||||
(defn- frame-wrapper-factory-equals?
|
(defn- frame-wrapper-factory-equals?
|
||||||
[np op]
|
[np op]
|
||||||
|
@ -115,9 +112,7 @@
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps (:id shape))
|
(mf/deps (:id shape))
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (dws/change-hover-state (:id shape) false))))
|
(st/emit! (dws/change-hover-state (:id shape) false))))]
|
||||||
|
|
||||||
render-id (mf/use-memo #(str (uuid/next)))]
|
|
||||||
|
|
||||||
(when-not (:hidden shape)
|
(when-not (:hidden shape)
|
||||||
[:g {:class (when selected? "selected")
|
[:g {:class (when selected? "selected")
|
||||||
|
@ -130,14 +125,8 @@
|
||||||
:on-double-click on-double-click
|
:on-double-click on-double-click
|
||||||
:on-mouse-down on-mouse-down}]
|
:on-mouse-down on-mouse-down}]
|
||||||
|
|
||||||
[:& (mf/provider muc/render-ctx) {:value render-id}
|
[:> shape-container {:shape shape}
|
||||||
[:g.frame {:filter (filters/filter-str (str "filter_" render-id) shape)}
|
|
||||||
[:defs
|
|
||||||
[:& filters/filters {:shape shape}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
|
|
||||||
|
|
||||||
[:& frame-shape
|
[:& frame-shape
|
||||||
{:shape shape
|
{:shape shape
|
||||||
:childs children}]]]])))))
|
:childs children}]]])))))
|
||||||
|
|
||||||
|
|
|
@ -11,22 +11,19 @@
|
||||||
(:require
|
(:require
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.util.dom :as dom]
|
||||||
|
[app.util.timers :as ts]
|
||||||
|
[app.main.streams :as ms]
|
||||||
[app.main.constants :as c]
|
[app.main.constants :as c]
|
||||||
[app.main.data.workspace :as dw]
|
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
[app.main.data.workspace :as dw]
|
||||||
|
[app.main.data.workspace.drawing :as dr]
|
||||||
[app.main.ui.keyboard :as kbd]
|
[app.main.ui.keyboard :as kbd]
|
||||||
[app.main.ui.shapes.path :as path]
|
[app.main.ui.shapes.path :as path]
|
||||||
[app.main.ui.shapes.filters :as filters]
|
[app.main.ui.shapes.filters :as filters]
|
||||||
[app.main.ui.shapes.gradients :as grad]
|
[app.main.ui.shapes.shape :refer [shape-container]]
|
||||||
[app.main.ui.workspace.shapes.common :as common]
|
[app.main.ui.workspace.shapes.common :as common]))
|
||||||
[app.main.data.workspace.drawing :as dr]
|
|
||||||
[app.util.dom :as dom]
|
|
||||||
[app.main.streams :as ms]
|
|
||||||
[app.util.timers :as ts]
|
|
||||||
[app.common.uuid :as uuid]
|
|
||||||
[app.main.ui.shapes.gradients :as grad]
|
|
||||||
[app.main.ui.context :as muc]))
|
|
||||||
|
|
||||||
(mf/defc path-wrapper
|
(mf/defc path-wrapper
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
|
@ -46,20 +43,13 @@
|
||||||
(do
|
(do
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(st/emit! (dw/start-edition-mode (:id shape)))))))
|
(st/emit! (dw/start-edition-mode (:id shape)))))))]
|
||||||
|
|
||||||
render-id (mf/use-memo #(str (uuid/next)))]
|
[:> shape-container {:shape shape
|
||||||
|
:on-double-click on-double-click
|
||||||
[:& (mf/provider muc/render-ctx) {:value render-id}
|
|
||||||
[:g.shape {:on-double-click on-double-click
|
|
||||||
:on-mouse-down on-mouse-down
|
:on-mouse-down on-mouse-down
|
||||||
:on-context-menu on-context-menu
|
:on-context-menu on-context-menu}
|
||||||
:filter (filters/filter-str (str "filter_" render-id) shape)}
|
|
||||||
[:defs
|
|
||||||
[:& filters/filters {:shape shape}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
|
|
||||||
|
|
||||||
[:& path/path-shape {:shape shape
|
[:& path/path-shape {:shape shape
|
||||||
:background? true}]]]))
|
:background? true}]]))
|
||||||
|
|
||||||
|
|
|
@ -9,35 +9,34 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.shapes.text
|
(ns app.main.ui.workspace.shapes.text
|
||||||
(:require
|
(:require
|
||||||
[cuerdas.core :as str]
|
["slate" :as slate]
|
||||||
|
["slate-react" :as rslate]
|
||||||
[goog.events :as events]
|
[goog.events :as events]
|
||||||
[goog.object :as gobj]
|
[goog.object :as gobj]
|
||||||
|
[cuerdas.core :as str]
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
|
[beicon.core :as rx]
|
||||||
|
[app.util.color :as color]
|
||||||
|
[app.util.dom :as dom]
|
||||||
|
[app.util.text :as ut]
|
||||||
|
[app.util.object :as obj]
|
||||||
|
[app.util.color :as uc]
|
||||||
|
[app.util.timers :as timers]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.geom.shapes :as geom]
|
||||||
|
[app.main.refs :as refs]
|
||||||
|
[app.main.store :as st]
|
||||||
|
[app.main.fonts :as fonts]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.data.workspace.texts :as dwt]
|
[app.main.data.workspace.texts :as dwt]
|
||||||
[app.main.refs :as refs]
|
|
||||||
[app.main.store :as st]
|
|
||||||
[app.main.ui.cursors :as cur]
|
[app.main.ui.cursors :as cur]
|
||||||
[app.main.ui.workspace.shapes.common :as common]
|
[app.main.ui.workspace.shapes.common :as common]
|
||||||
[app.main.ui.shapes.text :as text]
|
[app.main.ui.shapes.text :as text]
|
||||||
[app.main.ui.keyboard :as kbd]
|
[app.main.ui.keyboard :as kbd]
|
||||||
[app.main.ui.context :as muc]
|
[app.main.ui.context :as muc]
|
||||||
[app.main.ui.shapes.filters :as filters]
|
[app.main.ui.shapes.filters :as filters]
|
||||||
[app.main.fonts :as fonts]
|
[app.main.ui.shapes.shape :refer [shape-container]])
|
||||||
[app.util.color :as color]
|
|
||||||
[app.util.dom :as dom]
|
|
||||||
[app.util.text :as ut]
|
|
||||||
[app.common.geom.shapes :as geom]
|
|
||||||
[app.util.object :as obj]
|
|
||||||
[app.util.color :as uc]
|
|
||||||
[app.util.timers :as timers]
|
|
||||||
["slate" :as slate]
|
|
||||||
["slate-react" :as rslate]
|
|
||||||
[app.common.uuid :as uuid]
|
|
||||||
[app.main.ui.shapes.gradients :as grad]
|
|
||||||
[app.main.ui.context :as muc])
|
|
||||||
(:import
|
(:import
|
||||||
goog.events.EventType
|
goog.events.EventType
|
||||||
goog.events.KeyCodes))
|
goog.events.KeyCodes))
|
||||||
|
@ -81,9 +80,7 @@
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(when selected?
|
(when selected?
|
||||||
(st/emit! (dw/start-edition-mode (:id shape)))))
|
(st/emit! (dw/start-edition-mode (:id shape)))))]
|
||||||
|
|
||||||
render-id (mf/use-memo #(str (uuid/next)))]
|
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps shape edition selected? current-transform)
|
(mf/deps shape edition selected? current-transform)
|
||||||
|
@ -91,19 +88,14 @@
|
||||||
selected?
|
selected?
|
||||||
(not edition?)
|
(not edition?)
|
||||||
(not embed-resources?)
|
(not embed-resources?)
|
||||||
(nil? current-transform))]
|
(nil? current-transform))
|
||||||
(timers/schedule #(reset! render-editor check?)))))
|
result (timers/schedule #(reset! render-editor check?))]
|
||||||
|
#(rx/dispose! result))))
|
||||||
|
|
||||||
[:& (mf/provider muc/render-ctx) {:value render-id}
|
[:> shape-container {:shape shape
|
||||||
[:g.shape {:on-double-click on-double-click
|
:on-double-click on-double-click
|
||||||
:on-mouse-down on-mouse-down
|
:on-mouse-down on-mouse-down
|
||||||
:on-context-menu on-context-menu
|
:on-context-menu on-context-menu}
|
||||||
:filter (filters/filter-str (str "filter_" render-id) shape)}
|
|
||||||
[:defs
|
|
||||||
[:& filters/filters {:shape shape}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
|
|
||||||
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
|
|
||||||
[:*
|
|
||||||
(when @render-editor
|
(when @render-editor
|
||||||
[:g {:opacity 0
|
[:g {:opacity 0
|
||||||
:style {:pointer-events "none"}}
|
:style {:pointer-events "none"}}
|
||||||
|
@ -114,7 +106,7 @@
|
||||||
(if edition?
|
(if edition?
|
||||||
[:& text-shape-edit {:shape shape}]
|
[:& text-shape-edit {:shape shape}]
|
||||||
[:& text/text-shape {:shape shape
|
[:& text/text-shape {:shape shape
|
||||||
:selected? selected?}])]]]))
|
:selected? selected?}])]))
|
||||||
|
|
||||||
;; --- Text Editor Rendering
|
;; --- Text Editor Rendering
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue