mirror of
https://github.com/penpot/penpot.git
synced 2025-06-06 09:41:43 +02:00
🎉 Create reusable components
This commit is contained in:
parent
8396357f36
commit
5e585201d3
17 changed files with 515 additions and 168 deletions
|
@ -22,6 +22,7 @@
|
|||
[app.config :as cfg]
|
||||
[app.main.constants :as c]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.notifications :as dwn]
|
||||
[app.main.data.workspace.persistence :as dwp]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
|
@ -1266,70 +1267,19 @@
|
|||
;; GROUPS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn group-shape
|
||||
[id frame-id selected selection-rect]
|
||||
{:id id
|
||||
:type :group
|
||||
:name (name (gensym "Group-"))
|
||||
:shapes []
|
||||
:frame-id frame-id
|
||||
:x (:x selection-rect)
|
||||
:y (:y selection-rect)
|
||||
:width (:width selection-rect)
|
||||
:height (:height selection-rect)})
|
||||
|
||||
(def group-selected
|
||||
(ptk/reify ::group-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [id (uuid/next)
|
||||
page-id (:current-page-id state)
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
items (->> selected
|
||||
(map #(get objects %))
|
||||
(filter #(not= :frame (:type %)))
|
||||
(map #(assoc % ::index (cph/position-on-parent (:id %) objects)))
|
||||
(sort-by ::index))]
|
||||
|
||||
(when (not-empty items)
|
||||
(let [selrect (geom/selection-rect items)
|
||||
frame-id (-> items first :frame-id)
|
||||
parent-id (-> items first :parent-id)
|
||||
group (-> (group-shape id frame-id selected selrect)
|
||||
(geom/setup selrect))
|
||||
|
||||
index (::index (first items))
|
||||
|
||||
rchanges [{:type :add-obj
|
||||
:id id
|
||||
:page-id page-id
|
||||
:frame-id frame-id
|
||||
:parent-id parent-id
|
||||
:obj group
|
||||
:index index}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id id
|
||||
:shapes (->> items
|
||||
(map :id)
|
||||
(into #{})
|
||||
(vec))}]
|
||||
|
||||
uchanges
|
||||
(reduce (fn [res obj]
|
||||
(conj res {:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:parent-id obj)
|
||||
:index (::index obj)
|
||||
:shapes [(:id obj)]}))
|
||||
[]
|
||||
items)
|
||||
|
||||
uchanges (conj uchanges {:type :del-obj :id id :page-id page-id})]
|
||||
|
||||
shapes (dws/shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [[group rchanges uchanges]
|
||||
(dws/prepare-create-group page-id shapes "Group-" false)]
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dws/select-shapes (d/ordered-set id)))))))))
|
||||
(dws/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
(def ungroup-selected
|
||||
(ptk/reify ::ungroup-selected
|
||||
|
@ -1342,34 +1292,11 @@
|
|||
group (get objects group-id)]
|
||||
(when (and (= 1 (count selected))
|
||||
(= (:type group) :group))
|
||||
(let [shapes (:shapes group)
|
||||
parent-id (cph/get-parent group-id objects)
|
||||
parent (get objects parent-id)
|
||||
index-in-parent (->> (:shapes parent)
|
||||
(map-indexed vector)
|
||||
(filter #(#{group-id} (second %)))
|
||||
(ffirst))
|
||||
rchanges [{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id parent-id
|
||||
:shapes shapes
|
||||
:index index-in-parent}]
|
||||
uchanges [{:type :add-obj
|
||||
:page-id page-id
|
||||
:id group-id
|
||||
:frame-id (:frame-id group)
|
||||
:obj (assoc group :shapes [])}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id group-id
|
||||
:shapes shapes}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id parent-id
|
||||
:shapes [group-id]
|
||||
:index index-in-parent}]]
|
||||
(let [[rchanges uchanges]
|
||||
(dws/prepare-remove-group page-id group objects)]
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Interactions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -1512,6 +1439,7 @@
|
|||
"+" #(st/emit! (increase-zoom nil))
|
||||
"-" #(st/emit! (decrease-zoom nil))
|
||||
"ctrl+g" #(st/emit! group-selected)
|
||||
"ctrl+k" #(st/emit! dwl/add-component)
|
||||
"shift+g" #(st/emit! ungroup-selected)
|
||||
"shift+0" #(st/emit! reset-zoom)
|
||||
"shift+1" #(st/emit! zoom-to-fit-all)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
|
@ -68,7 +69,7 @@
|
|||
(rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}))))))
|
||||
|
||||
(defn delete-color
|
||||
[{:keys [id] :as color}]
|
||||
[{:keys [id] :as params}]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::delete-color
|
||||
ptk/WatchEvent
|
||||
|
@ -94,7 +95,7 @@
|
|||
|
||||
|
||||
(defn delete-media
|
||||
[{:keys [id] :as media}]
|
||||
[{:keys [id] :as params}]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::delete-media
|
||||
ptk/WatchEvent
|
||||
|
@ -106,3 +107,118 @@
|
|||
:object prev}]
|
||||
(rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}))))))
|
||||
|
||||
(declare clone-shape)
|
||||
|
||||
(def add-component
|
||||
(ptk/reify ::add-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
shapes (dws/shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [;; If the selected shape is a group, we can use it. If not,
|
||||
;; we need to create a group before creating the component.
|
||||
[group rchanges uchanges]
|
||||
(if (and (= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
[(first shapes) [] []]
|
||||
(dws/prepare-create-group page-id shapes "Component-" true))
|
||||
|
||||
[new-shape new-shapes updated-shapes]
|
||||
(clone-shape group nil objects)
|
||||
|
||||
rchanges (conj rchanges
|
||||
{:type :add-component
|
||||
:id (:id new-shape)
|
||||
:name (:name new-shape)
|
||||
:new-shapes new-shapes})
|
||||
|
||||
rchanges (into rchanges
|
||||
(map (fn [updated-shape]
|
||||
{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id updated-shape)
|
||||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val (:component-id updated-shape)}]})
|
||||
updated-shapes))
|
||||
|
||||
uchanges (conj uchanges
|
||||
{:type :del-component
|
||||
:id (:id new-shape)})
|
||||
|
||||
uchanges (into uchanges
|
||||
(map (fn [updated-shape]
|
||||
{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id updated-shape)
|
||||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val nil}]})
|
||||
updated-shapes))]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dws/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
(defn- clone-shape
|
||||
"Clone the shape and all children. Generate new ids and detach
|
||||
from parent and frame. Update the original shapes to have links
|
||||
to the new ones."
|
||||
[shape parent-id objects]
|
||||
(let [new-id (uuid/next)]
|
||||
(if (nil? (:shapes shape))
|
||||
|
||||
; TODO: unify this case with the empty child-ids case.
|
||||
(let [new-shape (assoc shape
|
||||
:id new-id
|
||||
:parent-id parent-id
|
||||
:frame-id nil)]
|
||||
[new-shape
|
||||
[new-shape]
|
||||
[(assoc shape :component-id (:id new-shape))]])
|
||||
|
||||
(loop [child-ids (seq (:shapes shape))
|
||||
new-children []
|
||||
updated-children []]
|
||||
|
||||
(if (empty? child-ids)
|
||||
(let [new-shape (assoc shape
|
||||
:id new-id
|
||||
:parent-id parent-id
|
||||
:frame-id nil
|
||||
:shapes (map :id new-children))]
|
||||
[new-shape
|
||||
(conj new-children new-shape)
|
||||
(conj updated-children
|
||||
(assoc shape :component-id (:id new-shape)))])
|
||||
|
||||
(let [child-id (first child-ids)
|
||||
child (get objects child-id)
|
||||
|
||||
[new-child new-child-shapes updated-child-shapes]
|
||||
(clone-shape child new-id objects)]
|
||||
|
||||
(recur
|
||||
(next child-ids)
|
||||
(into new-children new-child-shapes)
|
||||
(into updated-children updated-child-shapes))))))))
|
||||
|
||||
(defn delete-component
|
||||
[{:keys [id] :as params}]
|
||||
(ptk/reify ::delete-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [component (get-in state [:workspace-data :components id])
|
||||
|
||||
rchanges [{:type :del-component
|
||||
:id id}]
|
||||
|
||||
uchanges [{:type :add-component
|
||||
:id id
|
||||
:name (:name component)
|
||||
:new-shapes (:objects component)}]]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
|
|
|
@ -183,6 +183,86 @@
|
|||
(rx/of deselect-all (select-shape (:id selected))))))))
|
||||
|
||||
|
||||
;; --- Group shapes
|
||||
|
||||
(defn shapes-for-grouping
|
||||
[objects selected]
|
||||
(->> selected
|
||||
(map #(get objects %))
|
||||
(filter #(not= :frame (:type %)))
|
||||
(map #(assoc % ::index (cph/position-on-parent (:id %) objects)))
|
||||
(sort-by ::index)))
|
||||
|
||||
(defn- make-group
|
||||
[shapes prefix keep-name]
|
||||
(let [selrect (geom/selection-rect shapes)
|
||||
frame-id (-> shapes first :frame-id)
|
||||
parent-id (-> shapes first :parent-id)
|
||||
group-name (if (and keep-name (= (count shapes) 1))
|
||||
(:name (first shapes))
|
||||
(name (gensym prefix)))]
|
||||
(-> (cp/make-minimal-group frame-id selrect group-name)
|
||||
(geom/setup selrect)
|
||||
(assoc :shapes (map :id shapes)))))
|
||||
|
||||
(defn prepare-create-group
|
||||
[page-id shapes prefix keep-name]
|
||||
(let [group (make-group shapes prefix keep-name)
|
||||
rchanges [{:type :add-obj
|
||||
:id (:id group)
|
||||
:page-id page-id
|
||||
:frame-id (:frame-id (first shapes))
|
||||
:parent-id (:parent-id (first shapes))
|
||||
:obj group
|
||||
:index (::index (first shapes))}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:id group)
|
||||
:shapes (map :id shapes)}]
|
||||
|
||||
uchanges (conj
|
||||
(map (fn [obj] {:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:parent-id obj)
|
||||
:index (::index obj)
|
||||
:shapes [(:id obj)]})
|
||||
shapes)
|
||||
{:type :del-obj
|
||||
:id (:id group)
|
||||
:page-id page-id})]
|
||||
[group rchanges uchanges]))
|
||||
|
||||
(defn prepare-remove-group
|
||||
[page-id group objects]
|
||||
(let [shapes (:shapes group)
|
||||
parent-id (cph/get-parent (:id group) objects)
|
||||
parent (get objects parent-id)
|
||||
index-in-parent (->> (:shapes parent)
|
||||
(map-indexed vector)
|
||||
(filter #(#{(:id group)} (second %)))
|
||||
(ffirst))
|
||||
rchanges [{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id parent-id
|
||||
:shapes shapes
|
||||
:index index-in-parent}]
|
||||
uchanges [{:type :add-obj
|
||||
:page-id page-id
|
||||
:id (:id group)
|
||||
:frame-id (:frame-id group)
|
||||
:obj (assoc group :shapes [])}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id (:id group)
|
||||
:shapes shapes}
|
||||
{:type :mov-objects
|
||||
:page-id page-id
|
||||
:parent-id parent-id
|
||||
:shapes [(:id group)]
|
||||
:index index-in-parent}]]
|
||||
[rchanges uchanges]))
|
||||
|
||||
|
||||
;; --- Duplicate Shapes
|
||||
(declare prepare-duplicate-change)
|
||||
(declare prepare-duplicate-frame-change)
|
||||
|
|
|
@ -156,3 +156,35 @@
|
|||
:xmlnsXlink "http://www.w3.org/1999/xlink"
|
||||
:xmlns "http://www.w3.org/2000/svg"}
|
||||
[:& wrapper {:shape frame :view-box vbox}]]))
|
||||
|
||||
;; TODO: unify with frame-svg?
|
||||
(mf/defc component-svg
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [objects group zoom] :or {zoom 1} :as props}]
|
||||
(let [modifier (-> (gpt/point (:x group) (:y group))
|
||||
(gpt/negate)
|
||||
(gmt/translate-matrix))
|
||||
|
||||
group-id (:id group)
|
||||
|
||||
modifier-ids (concat [group-id] (cph/get-children group-id objects))
|
||||
update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)
|
||||
objects (reduce update-fn objects modifier-ids)
|
||||
group (assoc-in group [:modifiers :displacement] modifier)
|
||||
|
||||
width (* (:width group) zoom)
|
||||
height (* (:height group) zoom)
|
||||
vbox (str "0 0 " (:width group 0)
|
||||
" " (:height group 0))
|
||||
wrapper (mf/use-memo
|
||||
(mf/deps objects)
|
||||
#(group-wrapper-factory objects))]
|
||||
|
||||
[:svg {:view-box vbox
|
||||
:width width
|
||||
:height height
|
||||
:version "1.1"
|
||||
:xmlnsXlink "http://www.w3.org/1999/xlink"
|
||||
:xmlns "http://www.w3.org/2000/svg"}
|
||||
[:& wrapper {:shape group :view-box vbox}]]))
|
||||
|
||||
|
|
|
@ -67,4 +67,4 @@
|
|||
|
||||
(defn ^:export dump-objects []
|
||||
(let [page-id (get @state :current-page-id)]
|
||||
(logjs "state" (get-in @state [:workspace-data page-id :objects]))))
|
||||
(logjs "state" (get-in @state [:workspace-data :pages-index page-id :objects]))))
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
(def chat (icon-xref :chat))
|
||||
(def circle (icon-xref :circle))
|
||||
(def close (icon-xref :close))
|
||||
(def component (icon-xref :component))
|
||||
(def copy (icon-xref :copy))
|
||||
(def curve (icon-xref :curve))
|
||||
(def download (icon-xref :download))
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.ui.hooks :refer [use-rxsub]]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]))
|
||||
|
||||
|
@ -59,7 +60,8 @@
|
|||
do-lock-shape #(st/emit! (dw/update-shape-flags id {:blocked true}))
|
||||
do-unlock-shape #(st/emit! (dw/update-shape-flags id {:blocked false}))
|
||||
do-create-group #(st/emit! dw/group-selected)
|
||||
do-remove-group #(st/emit! dw/ungroup-selected)]
|
||||
do-remove-group #(st/emit! dw/ungroup-selected)
|
||||
do-add-component #(st/emit! dwl/add-component)]
|
||||
[:*
|
||||
[:& menu-entry {:title "Copy"
|
||||
:shortcut "Ctrl + c"
|
||||
|
@ -101,13 +103,17 @@
|
|||
[:& menu-entry {:title "Hide"
|
||||
:on-click do-hide-shape}])
|
||||
|
||||
|
||||
|
||||
(if (:blocked shape)
|
||||
[:& menu-entry {:title "Unlock"
|
||||
:on-click do-unlock-shape}]
|
||||
[:& menu-entry {:title "Lock"
|
||||
:on-click do-lock-shape}])
|
||||
|
||||
[:& menu-separator]
|
||||
[:& menu-entry {:title "Create component"
|
||||
:shortcut "Ctrl + K"
|
||||
:on-click do-add-component}]
|
||||
|
||||
[:& menu-separator]
|
||||
[:& menu-entry {:title "Delete"
|
||||
:shortcut "Supr"
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
[app.common.geom.shapes :as geom]
|
||||
[app.common.media :as cm]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages-helpers :as cph]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cfg]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -21,6 +22,7 @@
|
|||
[app.main.data.colors :as dc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.exports :as exports]
|
||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||
[app.main.ui.components.file-uploader :refer [file-uploader]]
|
||||
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
|
@ -38,6 +40,62 @@
|
|||
[okulary.core :as l]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc components-box
|
||||
[{:keys [file-id local? components] :as props}]
|
||||
(let [state (mf/use-state {:menu-open false
|
||||
:top nil
|
||||
:left nil
|
||||
:component-id nil})
|
||||
on-delete
|
||||
(mf/use-callback
|
||||
(mf/deps state)
|
||||
(fn []
|
||||
(let [params {:id (:component-id @state)}]
|
||||
(st/emit! (dwl/delete-component params)))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-callback
|
||||
(fn [component-id]
|
||||
(fn [event]
|
||||
(when local?
|
||||
(let [pos (dom/get-client-position event)
|
||||
top (:y pos)
|
||||
left (- (:x pos) 20)]
|
||||
(dom/prevent-default event)
|
||||
(swap! state assoc :menu-open true
|
||||
:top top
|
||||
:left left
|
||||
:component-id component-id))))))
|
||||
|
||||
on-drag-start
|
||||
(mf/use-callback
|
||||
(fn [path event]
|
||||
(dnd/set-data! event "text/uri-list" (cfg/resolve-media-path path))
|
||||
(dnd/set-allowed-effect! event "move")))]
|
||||
|
||||
[:div.asset-group
|
||||
[:div.group-title
|
||||
(tr "workspace.assets.components")
|
||||
[:span (str "\u00A0(") (count components) ")"]] ;; Unicode 00A0 is non-breaking space
|
||||
[:div.group-grid.big
|
||||
(for [component components]
|
||||
[:div.grid-cell {:key (:id component)
|
||||
:draggable true
|
||||
:on-context-menu (on-context-menu (:id component))
|
||||
:on-drag-start (partial on-drag-start (:path component))}
|
||||
[:& exports/component-svg {:group (get-in component [:objects (:id component)])
|
||||
:objects (:objects component)}]
|
||||
[:div.cell-name (:name component)]])
|
||||
|
||||
(when local?
|
||||
[:& context-menu
|
||||
{:selectable false
|
||||
:show (:menu-open @state)
|
||||
:on-close #(swap! state assoc :menu-open false)
|
||||
:top (:top @state)
|
||||
:left (:left @state)
|
||||
:options [[(tr "workspace.assets.delete") on-delete]]}])]]))
|
||||
|
||||
(mf/defc graphics-box
|
||||
[{:keys [file-id local? objects open? on-open on-close] :as props}]
|
||||
(let [input-ref (mf/use-ref nil)
|
||||
|
@ -126,7 +184,6 @@
|
|||
:left (:left @state)
|
||||
:options [[(tr "workspace.assets.delete") on-delete]]}])])]))
|
||||
|
||||
|
||||
(mf/defc color-item
|
||||
[{:keys [color local? locale file-id] :as props}]
|
||||
(let [rename? (= (:color-for-rename @refs/workspace-local) (:id color))
|
||||
|
@ -287,32 +344,45 @@
|
|||
(vals (get-in state [:workspace-libraries id :data :media])))))
|
||||
st/state =))
|
||||
|
||||
(defn file-components-ref
|
||||
[id]
|
||||
(l/derived (fn [state]
|
||||
(let [wfile (:workspace-file state)]
|
||||
(if (= (:id wfile) id)
|
||||
(vals (get-in wfile [:data :components]))
|
||||
(vals (get-in state [:workspace-libraries id :data :components])))))
|
||||
st/state =))
|
||||
|
||||
(defn apply-filters
|
||||
[coll filters]
|
||||
(filter (fn [item]
|
||||
(or (matches-search (:name item "!$!") (:term filters))
|
||||
(matches-search (:value item "!$!") (:term filters))))
|
||||
coll))
|
||||
(->> coll
|
||||
(filter (fn [item]
|
||||
(or (matches-search (:name item "!$!") (:term filters))
|
||||
(matches-search (:value item "!$!") (:term filters)))))
|
||||
(sort-by #(str/lower (:name %)))))
|
||||
|
||||
(mf/defc file-library
|
||||
[{:keys [file local? open? filters locale] :as props}]
|
||||
(let [open? (mf/use-state open?)
|
||||
shared? (:is-shared file)
|
||||
router (mf/deref refs/router)
|
||||
toggle-open #(swap! open? not)
|
||||
(let [open? (mf/use-state open?)
|
||||
shared? (:is-shared file)
|
||||
router (mf/deref refs/router)
|
||||
toggle-open #(swap! open? not)
|
||||
|
||||
toggles (mf/use-state #{:graphics :colors})
|
||||
|
||||
url (rt/resolve router :workspace
|
||||
{:project-id (:project-id file)
|
||||
:file-id (:id file)}
|
||||
{:page-id (get-in file [:data :pages 0])})
|
||||
url (rt/resolve router :workspace
|
||||
{:project-id (:project-id file)
|
||||
:file-id (:id file)}
|
||||
{:page-id (get-in file [:data :pages 0])})
|
||||
|
||||
colors-ref (mf/use-memo (mf/deps (:id file)) #(file-colors-ref (:id file)))
|
||||
colors (apply-filters (mf/deref colors-ref) filters)
|
||||
colors-ref (mf/use-memo (mf/deps (:id file)) #(file-colors-ref (:id file)))
|
||||
colors (apply-filters (mf/deref colors-ref) filters)
|
||||
|
||||
media-ref (mf/use-memo (mf/deps (:id file)) #(file-media-ref (:id file)))
|
||||
media (apply-filters (mf/deref media-ref) filters)]
|
||||
media-ref (mf/use-memo (mf/deps (:id file)) #(file-media-ref (:id file)))
|
||||
media (apply-filters (mf/deref media-ref) filters)
|
||||
|
||||
components-ref (mf/use-memo (mf/deps (:id file)) #(file-components-ref (:id file)))
|
||||
components (apply-filters (mf/deref components-ref) filters)]
|
||||
|
||||
[:div.tool-window
|
||||
[:div.tool-window-bar
|
||||
|
@ -332,15 +402,23 @@
|
|||
[:a {:href (str "#" url) :target "_blank"} i/chain]]])]
|
||||
|
||||
(when @open?
|
||||
(let [show-graphics? (and (or (= (:box filters) :all)
|
||||
(= (:box filters) :graphics))
|
||||
(or (> (count media) 0)
|
||||
(str/empty? (:term filters))))
|
||||
show-colors? (and (or (= (:box filters) :all)
|
||||
(= (:box filters) :colors))
|
||||
(or (> (count colors) 0)
|
||||
(str/empty? (:term filters))))]
|
||||
(let [show-components? (and (or (= (:box filters) :all)
|
||||
(= (:box filters) :components))
|
||||
(or (> (count components) 0)
|
||||
(str/empty? (:term filters))))
|
||||
show-graphics? (and (or (= (:box filters) :all)
|
||||
(= (:box filters) :graphics))
|
||||
(or (> (count media) 0)
|
||||
(str/empty? (:term filters))))
|
||||
show-colors? (and (or (= (:box filters) :all)
|
||||
(= (:box filters) :colors))
|
||||
(or (> (count colors) 0)
|
||||
(str/empty? (:term filters))))]
|
||||
[:div.tool-window-content
|
||||
(when show-components?
|
||||
[:& components-box {:file-id (:id file)
|
||||
:local? local?
|
||||
:components components}])
|
||||
(when show-graphics?
|
||||
[:& graphics-box {:file-id (:id file)
|
||||
:local? local?
|
||||
|
@ -357,10 +435,11 @@
|
|||
:on-open #(swap! toggles conj :colors)
|
||||
:on-close #(swap! toggles disj :colors)}])
|
||||
|
||||
(when (and (not show-graphics?) (not show-colors?))
|
||||
(when (and (not show-components?) (not show-graphics?) (not show-colors?))
|
||||
[:div.asset-group
|
||||
[:div.group-title (t locale "workspace.assets.not-found")]])]))]))
|
||||
|
||||
|
||||
(mf/defc assets-toolbox
|
||||
[{:keys [team-id file] :as props}]
|
||||
(let [libraries (mf/deref refs/workspace-libraries)
|
||||
|
|
|
@ -43,7 +43,9 @@
|
|||
:rect i/box
|
||||
:curve i/curve
|
||||
:text i/text
|
||||
:group i/folder
|
||||
:group (if (nil? (:component-id shape))
|
||||
i/folder
|
||||
i/component)
|
||||
nil))
|
||||
|
||||
;; --- Layer Name
|
||||
|
@ -186,6 +188,7 @@
|
|||
[:li {:on-context-menu on-context-menu
|
||||
:ref dref
|
||||
:class (dom/classnames
|
||||
:component (not (nil? (:component-id item)))
|
||||
:dnd-over (= (:over dprops) :center)
|
||||
:dnd-over-top (= (:over dprops) :top)
|
||||
:dnd-over-bot (= (:over dprops) :bot)
|
||||
|
@ -285,7 +288,16 @@
|
|||
|
||||
(defn- strip-objects
|
||||
[objects]
|
||||
(let [strip-data #(select-keys % [:id :name :blocked :hidden :shapes :type :content :parent-id :metadata])]
|
||||
(let [strip-data #(select-keys % [:id
|
||||
:name
|
||||
:blocked
|
||||
:hidden
|
||||
:shapes
|
||||
:type
|
||||
:content
|
||||
:parent-id
|
||||
:component-id
|
||||
:metadata])]
|
||||
(persistent!
|
||||
(reduce-kv (fn [res id obj]
|
||||
(assoc! res id (strip-data obj)))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue