🔧 Read component shapes from pages

This commit is contained in:
Andrés Moya 2023-03-07 12:03:38 +01:00
parent a4dd5fccff
commit 0711fa700b
21 changed files with 588 additions and 403 deletions

View file

@ -8,6 +8,7 @@
"A version parsing helper."
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
@ -664,9 +665,10 @@
[_ shapes]
(ctn/make-component-instance page
component
(:id file)
(:data file)
(gpt/point main-instance-x
main-instance-y)
true
{:main-instance? true
:force-id main-instance-id})]
(as-> file $
@ -701,12 +703,15 @@
component (ctkl/get-component (:data file) component-id)
;; main-instance-id (:main-instance-id component)
components-v2 (dm/get-in file [:options :components-v2])
[shape shapes]
(ctn/make-component-instance page
component
(:id file)
(gpt/point x
y)
components-v2
#_{:main-instance? true
:force-id main-instance-id})]

View file

@ -15,6 +15,7 @@
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.types.components-list :as ctkl]
[app.common.types.file :as ctf]
[app.common.uuid :as uuid]))
@ -598,13 +599,14 @@
(update :redo-changes
(fn [redo-changes]
(-> redo-changes
(conj {:type :add-component
:id id
:path path
:name name
:main-instance-id main-instance-id
:main-instance-page main-instance-page
:shapes new-shapes})
(conj (cond-> {:type :add-component
:id id
:path path
:name name
:main-instance-id main-instance-id
:main-instance-page main-instance-page}
(some? new-shapes) ;; this will be null in components-v2
(assoc :shapes new-shapes)))
(into (map mk-change) updated-shapes))))
(update :undo-changes
(fn [undo-changes]
@ -640,8 +642,9 @@
(defn delete-component
[changes id components-v2]
(assert-library changes)
(let [library-data (::library-data (meta changes))
prev-component (get-in library-data [:components id])]
(let [library-data (::library-data (meta changes))
component (ctkl/get-component library-data id)
shapes (ctf/get-component-shapes library-data component)]
(-> changes
(update :redo-changes conj {:type :del-component
:id id})
@ -655,11 +658,11 @@
:always
(d/preconj {:type :add-component
:id id
:name (:name prev-component)
:path (:path prev-component)
:main-instance-id (:main-instance-id prev-component)
:main-instance-page (:main-instance-page prev-component)
:shapes (vals (:objects prev-component))})))))))
:name (:name component)
:path (:path component)
:main-instance-id (:main-instance-id component)
:main-instance-page (:main-instance-page component)
:shapes shapes})))))))
(defn restore-component
[changes id]

View file

@ -153,8 +153,8 @@
(s/coll-of ::cts/shape))
(defmethod change-spec :add-component [_]
(s/keys :req-un [::id ::name :internal.changes.add-component/shapes]
:opt-un [::path]))
(s/keys :req-un [::id ::name]
:opt-un [::path :internal.changes.add-component/shapes]))
(defmethod change-spec :mod-component [_]
(s/keys :req-un [::id]

View file

@ -270,25 +270,6 @@
[shape group]
((or (:touched shape) #{}) group))
(defn get-component
"Retrieve a component from libraries, if no library-id is provided, we
iterate over all libraries and find the component on it."
([libraries component-id]
(some #(-> % :data :components (get component-id)) (vals libraries)))
([libraries library-id component-id]
(get-in libraries [library-id :data :components component-id])))
(defn get-component-shape
"Get the parent shape linked to a component for this shape, if any"
[objects shape]
(if-not (:shape-ref shape)
nil
(if (:component-id shape)
shape
(if-let [parent-id (:parent-id shape)]
(get-component-shape objects (get objects parent-id))
nil))))
(defn get-root-shape
"Get the root shape linked to a component for this shape, if any."
[objects shape]

View file

@ -34,6 +34,7 @@
(and (= shape-id (:main-instance-id component))
(= page-id (:main-instance-page component))))
;; Obsolete in components-v2
(defn get-component-root
[component]
(get-in component [:objects (:id component)]))
@ -45,12 +46,12 @@
(= (:component-file shape) library-id)))
(defn in-component-instance?
"Check if the shape is inside a component instance."
"Check if the shape is inside a component non-main instance."
[shape]
(some? (:shape-ref shape)))
(defn in-component-instance-not-root?
"Check if the shape is inside a component instance and
"Check if the shape is inside a component non-main instance and
is not the root shape."
[shape]
(and (some? (:shape-ref shape))

View file

@ -23,11 +23,13 @@
(assoc-in [:components id]
{:id id
:name name
:path path
:objects (->> shapes
(d/index-by :id)
(wrap-object-fn))})
:path path})
(not components-v2)
(assoc-in [:components id :objects]
(->> shapes
(d/index-by :id)
(wrap-object-fn)))
components-v2
(update-in [:components id] assoc
:main-instance-id main-instance-id
@ -60,4 +62,3 @@
(defn delete-component
[file-data component-id]
(update file-data :components dissoc component-id))

View file

@ -11,6 +11,7 @@
[app.common.geom.shapes :as gsh]
[app.common.pages.common :as common]
[app.common.spec :as us]
[app.common.types.pages-list :as ctpl]
[app.common.types.shape-tree :as ctst]
[clojure.spec.alpha :as s]))
@ -62,6 +63,17 @@
[container shape-id f]
(update-in container [:objects shape-id] f))
(defn get-component-shape
"Get the parent shape linked to a component for this shape, if any"
[objects shape]
(if-not (:shape-ref shape)
nil
(if (:component-id shape)
shape
(if-let [parent-id (:parent-id shape)]
(get-component-shape objects (get objects parent-id))
nil))))
(defn make-component-shape
"Clone the shape and all children. Generate new ids and detach
from parent and frame. Update the original shapes to have links
@ -117,15 +129,22 @@
[new-root-shape (map remap-frame-id new-shapes) updated-shapes]))
(defn make-component-instance
"Clone the shapes of the component, generating new names and ids, and linking
"Generate a new instance of the component inside the given container.
Clone the shapes of the component, generating new names and ids, and linking
each new shape to the corresponding one of the component. Place the new instance
coordinates in the given position."
([container component component-file-id position]
(make-component-instance container component component-file-id position {}))
([container component library-data position components-v2]
(make-component-instance container component library-data position components-v2 {}))
([container component component-file-id position
([container component library-data position components-v2
{:keys [main-instance? force-id] :or {main-instance? false force-id nil}}]
(let [component-shape (get-shape component (:id component))
(let [component-page (when components-v2
(ctpl/get-page library-data (:main-instance-page component)))
component-shape (if components-v2
(-> (get-shape component-page (:main-instance-id component))
(assoc :parent-id nil))
(get-shape component (:id component)))
orig-pos (gpt/point (:x component-shape) (:y component-shape))
delta (gpt/subtract position orig-pos)
@ -147,20 +166,20 @@
(vswap! frame-ids-map assoc (:id original-shape) (:id new-shape)))
(cond-> new-shape
true
:always
(-> (gsh/move delta)
(dissoc :touched))
(dissoc :touched :main-instance?))
(nil? (:shape-ref original-shape))
(assoc :shape-ref (:id original-shape))
(nil? (:parent-id original-shape))
(assoc :component-id (:id original-shape)
:component-file component-file-id
(assoc :component-id (:id component)
:component-file (:id library-data)
:component-root? true
:name new-name)
(and (nil? (:parent-id original-shape)) main-instance?)
(and (nil? (:parent-id original-shape)) main-instance? components-v2)
(assoc :main-instance? true)
(some? (:parent-id original-shape))
@ -169,7 +188,7 @@
[new-shape new-shapes _]
(ctst/clone-object component-shape
nil
(get component :objects)
(if components-v2 (:objects component-page) (:objects component))
update-new-shape
(fn [object _] object)
force-id)
@ -177,10 +196,10 @@
;; If frame-id points to a shape inside the component, remap it to the
;; corresponding new frame shape. If not, set it to the destination frame.
;; Also fix empty parent-id.
remap-frame-id (fn [shape]
(as-> shape $
(update $ :frame-id #(get @frame-ids-map % frame-id))
(update $ :parent-id #(or % (:frame-id $)))))]
remap-frame-id (fn [shape]
(as-> shape $
(update $ :frame-id #(get @frame-ids-map % frame-id))
(update $ :parent-id #(or % (:frame-id $)))))]
[new-shape (map remap-frame-id new-shapes)])))

View file

@ -6,27 +6,27 @@
(ns app.common.types.file
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.features :as ffeat]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.pages.common :refer [file-version]]
[app.common.pages.helpers :as cph]
[app.common.types.color :as ctc]
[app.common.types.colors-list :as ctcl]
[app.common.types.component :as ctk]
[app.common.types.components-list :as ctkl]
[app.common.types.container :as ctn]
[app.common.types.file.media-object :as ctfm]
[app.common.types.page :as ctp]
[app.common.types.pages-list :as ctpl]
[app.common.types.shape-tree :as ctst]
[app.common.types.typographies-list :as ctyl]
[app.common.types.typography :as cty]
[app.common.uuid :as uuid]
[clojure.spec.alpha :as s]
[cuerdas.core :as str]))
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.features :as ffeat]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.pages.common :refer [file-version]]
[app.common.pages.helpers :as cph]
[app.common.types.color :as ctc]
[app.common.types.colors-list :as ctcl]
[app.common.types.component :as ctk]
[app.common.types.components-list :as ctkl]
[app.common.types.container :as ctn]
[app.common.types.file.media-object :as ctfm]
[app.common.types.page :as ctp]
[app.common.types.pages-list :as ctpl]
[app.common.types.shape-tree :as ctst]
[app.common.types.typographies-list :as ctyl]
[app.common.types.typography :as cty]
[app.common.uuid :as uuid]
[clojure.spec.alpha :as s]
[cuerdas.core :as str]))
;; Specs
@ -116,6 +116,75 @@
([libraries library-id component-id]
(ctkl/get-component (dm/get-in libraries [library-id :data]) component-id)))
(defn get-component-library
"Retrieve the library the component belongs to."
[libraries instance-root]
(get libraries (:component-file instance-root)))
(defn get-component-page
"Retrieve the page where the main instance of the component resides."
[file-data component]
(ctpl/get-page file-data (:main-instance-page component)))
(defn get-component-container
"Retrieve the container that holds the component shapes (the page in components-v2
or the component itself in v1)"
[file-data component]
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
(if components-v2
(let [component-page (get-component-page file-data component)]
(cph/make-container component-page :page))
(cph/make-container component :component))))
(defn get-component-root
"Retrieve the root shape of the component."
[file-data component]
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
(if components-v2
(-> file-data
(get-component-page component)
(ctn/get-shape (:main-instance-id component)))
(ctk/get-component-root component))))
(defn get-component-shapes
"Retrieve all shapes of the component"
[file-data component]
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
(if components-v2
(let [instance-page (get-component-page file-data component)]
(cph/get-children-with-self (:objects instance-page) (:main-instance-id component)))
(vals (:objects component)))))
(defn get-component-shape
"Retrieve one shape in the component."
[file-data component shape-id]
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
(if components-v2
(let [component-page (get-component-page file-data component)]
(ctn/get-shape component-page shape-id))
(dm/get-in component [:objects shape-id]))))
(defn get-ref-shape
"Retrieve the shape in the component that is referenced by the
instance shape."
[file-data component shape]
(when (:shape-ref shape)
(get-component-shape file-data component (:shape-ref shape))))
(defn load-component-objects
"Add an :objects property to the component, with only the shapes that belong to it"
[file-data component]
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
(if components-v2
(let [component-page (get-component-page file-data component)
page-objects (:objects component-page)
objects (->> (cons (:main-instance-id component)
(cph/get-children-ids page-objects (:main-instance-id component)))
(map #(get page-objects %))
(d/index-by :id))]
(assoc component :objects objects))
component)))
(defn delete-component
"Delete a component and store it to be able to be recovered later.
@ -123,26 +192,29 @@
([file-data component-id]
(delete-component file-data component-id false))
([file-data component-id skip-undelete?]
(let [components-v2 (dm/get-in file-data [:options :components-v2])
([file-data component-id _skip-undelete?]
(let [_components-v2 (dm/get-in file-data [:options :components-v2])
add-to-deleted-components
(fn [file-data]
(let [component (ctkl/get-component file-data component-id)]
(if (some? component)
(let [page (ctpl/get-page file-data (:main-instance-page component))
main-instance (ctn/get-shape page (:main-instance-id component))
component (assoc component
:main-instance-x (:x main-instance) ; An instance root is always a group,
:main-instance-y (:y main-instance))] ; so it will have :x and :y
(when (nil? main-instance)
(throw (ex-info "Cannot delete the main instance before the component" {:component-id component-id})))
(assoc-in file-data [:deleted-components component-id] component))
file-data)))]
;; TODO: replace :deleted-components with a :deleted? flag in normal shapes
;; see task https://tree.taiga.io/project/penpot/task/4998
;;
;; add-to-deleted-components
;; (fn [file-data]
;; (let [component (ctkl/get-component file-data component-id)]
;; (if (some? component)
;; (let [main-instance (get-component-root file-data component)
;; component (assoc component
;; :main-instance-x (:x main-instance) ; An instance root is always a group,
;; :main-instance-y (:y main-instance))] ; or a frame, so it will have :x and :y
;; (when (nil? main-instance)
;; (throw (ex-info "Cannot delete the main instance before the component" {:component-id component-id})))
;; (assoc-in file-data [:deleted-components component-id] component))
;; file-data)))
]
(cond-> file-data
(and components-v2 (not skip-undelete?))
(add-to-deleted-components)
;; (and components-v2 (not skip-undelete?))
;; (add-to-deleted-components)
:always
(ctkl/delete-component component-id)))))
@ -243,8 +315,9 @@
[(ctpl/add-page file-data library-page) (:id library-page) (gpt/point 0 0)]))))
(defn migrate-to-components-v2
"If there is any component in the file library, add a new 'Library backup' and generate
main instances for all components there. Mark the file with the :components-v2 option."
"If there is any component in the file library, add a new 'Library backup', generate
main instances for all components there and remove shapes from library components.
Mark the file with the :components-v2 option."
[file-data]
(let [components (ctkl/components-seq file-data)]
(if (or (empty? components)
@ -262,8 +335,9 @@
[new-shape new-shapes]
(ctn/make-component-instance page
component
(:id file-data)
file-data
position
false
{:main-instance? true})
add-shapes
@ -281,9 +355,10 @@
update-component
(fn [component]
(assoc component
:main-instance-id (:id new-shape)
:main-instance-page page-id))]
(-> component
(assoc :main-instance-id (:id new-shape)
:main-instance-page page-id)
(dissoc :objects)))]
(-> file-data
(ctpl/update-page page-id add-shapes)
@ -292,9 +367,9 @@
add-instance-grid
(fn [file-data components]
(let [position-seq (ctst/generate-shape-grid
(map ctk/get-component-root components)
start-pos
grid-gap)]
(map (partial get-component-root file-data) components)
start-pos
grid-gap)]
(loop [file-data file-data
components-seq (seq components)
position-seq position-seq]
@ -311,7 +386,7 @@
(assoc-in [:options :components-v2] true))))))
(defn- absorb-components
[file-data used-components]
[file-data used-components library-data]
(let [grid-gap 50
; Search for the library page. If not exists, create it.
@ -326,10 +401,17 @@
[main-instance-shape main-instance-shapes]
(ctn/make-component-instance page
component
(:id file-data)
library-data
position
(dm/get-in file-data [:options :components-v2])
{:main-instance? true})
main-instance-shapes
(map #(cond-> %
(some? (:component-file %))
(assoc :component-file (:id file-data)))
main-instance-shapes)
; Add all shapes of the main instance to the library page
add-main-instance-shapes
(fn [page]
@ -353,7 +435,7 @@
:path (:path component)
:main-instance-id (:id main-instance-shape)
:main-instance-page page-id
:shapes (vals (:objects component))}))
:shapes (get-component-shapes library-data component)}))
; Change all existing instances to point to the local file
remap-instances
@ -378,9 +460,9 @@
add-component-grid
(fn [data used-components]
(let [position-seq (ctst/generate-shape-grid
(map #(ctk/get-component-root (first %)) used-components)
start-pos
grid-gap)]
(map #(get-component-root library-data (first %)) used-components)
start-pos
grid-gap)]
(loop [data data
components-seq (seq used-components)
position-seq position-seq]
@ -410,9 +492,9 @@
remap-shape))
%
shapes)))]
(as-> file-data $
(ctcl/add-color $ color)
(reduce remap-shapes $ usages))))]
(as-> file-data $
(ctcl/add-color $ color)
(reduce remap-shapes $ usages))))]
(reduce absorb-color
file-data
@ -434,9 +516,9 @@
remap-shape))
%
shapes)))]
(as-> file-data $
(ctyl/add-typography $ typography)
(reduce remap-shapes $ usages))))]
(as-> file-data $
(ctyl/add-typography $ typography)
(reduce remap-shapes $ usages))))]
(reduce absorb-typography
file-data
@ -452,7 +534,7 @@
(cond-> file-data
(d/not-empty? used-components)
(absorb-components used-components)
(absorb-components used-components library-data)
(d/not-empty? used-colors)
(absorb-colors used-colors)
@ -477,69 +559,82 @@
root (d/seek #(nil? (:parent-id %)) (vals objects))]
(letfn [(show-shape [shape-id level objects]
(let [shape (get objects shape-id)]
(println (str/pad (str (str/repeat " " level)
(:name shape)
(when (seq (:touched shape)) "*")
(when show-ids (str/format " <%s>" (:id shape))))
{:length 20
:type :right})
(show-component shape objects))
(when show-touched
(when (seq (:touched shape))
(println (str (str/repeat " " level)
" "
(str (:touched shape)))))
(when (:remote-synced? shape)
(println (str (str/repeat " " level)
" (remote-synced)"))))
(when (:shapes shape)
(dorun (for [shape-id (:shapes shape)]
(show-shape shape-id (inc level) objects))))))
(let [shape (get objects shape-id)]
(println (str/pad (str (str/repeat " " level)
(when (:main-instance? shape) "{")
(:name shape)
(when (:main-instance? shape) "}")
(when (seq (:touched shape)) "*")
(when show-ids (str/format " <%s>" (:id shape))))
{:length 20
:type :right})
(show-component-info shape objects))
(when show-touched
(when (seq (:touched shape))
(println (str (str/repeat " " level)
" "
(str (:touched shape)))))
(when (:remote-synced? shape)
(println (str (str/repeat " " level)
" (remote-synced)"))))
(when (:shapes shape)
(dorun (for [shape-id (:shapes shape)]
(show-shape shape-id (inc level) objects))))))
(show-component [shape objects]
(if (nil? (:shape-ref shape))
""
(let [root-shape (cph/get-component-shape objects shape)
component-id (when root-shape (:component-id root-shape))
component-file-id (when root-shape (:component-file root-shape))
component-file (when component-file-id (get libraries component-file-id nil))
component (when component-id
(if component-file
(dm/get-in component-file [:data :components component-id])
(get components component-id)))
component-shape (when (and component (:shape-ref shape))
(dm/get-in component [:objects (:shape-ref shape)]))]
(str/format " %s--> %s%s%s"
(cond (:component-root? shape) "#"
(:component-id shape) "@"
:else "-")
(when component-file (str/format "<%s> " (:name component-file)))
(or (:name component-shape) "?")
(if (or (:component-root? shape)
(nil? (:component-id shape))
true)
""
(let [component-id (:component-id shape)
component-file-id (:component-file shape)
component-file (when component-file-id (get libraries component-file-id nil))
component (if component-file
(dm/get-in component-file [:data :components component-id])
(get components component-id))]
(str/format " (%s%s)"
(when component-file (str/format "<%s> " (:name component-file)))
(:name component))))))))]
(show-component-info [shape objects]
(if (nil? (:shape-ref shape))
(if (:component-root? shape) " #" "")
(let [root-shape (ctn/get-component-shape objects shape)
component-id (when root-shape (:component-id root-shape))
component-file-id (when root-shape (:component-file root-shape))
component-file (when component-file-id (get libraries component-file-id nil))
component (when component-id
(if component-file
(dm/get-in component-file [:data :components component-id])
(get components component-id)))
component-shape (when component
(if component-file
(get-ref-shape (:data component-file) component shape)
(get-ref-shape file-data component shape)))]
(println "[Page]")
(str/format " %s--> %s%s%s"
(cond (:component-root? shape) "#"
(:component-id shape) "@"
:else "-")
(when component-file (str/format "<%s> " (:name component-file)))
(or (:name component-shape) "?")
(if (or (:component-root? shape)
(nil? (:component-id shape))
true)
""
(let [component-id (:component-id shape)
component-file-id (:component-file shape)
component-file (when component-file-id (get libraries component-file-id nil))
component (if component-file
(dm/get-in component-file [:data :components component-id])
(get components component-id))]
(str/format " (%s%s)"
(when component-file (str/format "<%s> " (:name component-file)))
(:name component))))))))
(show-component-instance [component]
(let [page (get-component-page file-data component)
root (get-component-root file-data component)]
(if-not show-ids
(println (str " [" (:name page) "] / " (:name root)))
(do
(println (str " " (:name page) (str/format " <%s>" (:id page))))
(println (str " " (:name root) (str/format " <%s>" (:id root))))))))]
(println (str "[Page: " (:name page) "]"))
(show-shape (:id root) 0 objects)
(dorun (for [component (vals components)]
(do
(println)
(println (str/format "[%s]" (:name component))
(when show-ids
(str/format " (main: %s/%s)"
(:main-instance-page component)
(:main-instance-id component))))
(show-shape (:id component) 0 (:objects component)))))))))
(println (str/format "[%s]" (:name component)))
(when (:objects component)
(show-shape (:id component) 0 (:objects component)))
(when (:main-instance-page component)
(show-component-instance component)))))))))

View file

@ -359,4 +359,3 @@
(iterate next-pos
(with-meta start-pos
{:counter 0}))))

View file

@ -9,7 +9,8 @@
[clojure.test :as t]
[app.common.pages.helpers :as cph]
[app.common.types.component :as ctk]
[app.common.types.container :as ctn]))
[app.common.types.container :as ctn]
[app.common.types.file :as ctf]))
;; ---- Helpers to manage libraries and synchronization
@ -81,7 +82,7 @@
[page root-inst-id libraries]
(let [root-inst (ctn/get-shape page root-inst-id)
component (cph/get-component libraries (:component-id root-inst))
component (ctf/get-component libraries (:component-id root-inst))
shapes-inst (cph/get-children-with-self (:objects page) root-inst-id)
shapes-main (cph/get-children-with-self (:objects component) (:shape-ref root-inst))
@ -90,10 +91,10 @@
main-exists? (fn [shape]
(let [component-shape
(cph/get-component-shape (:objects page) shape)
(ctn/get-component-shape (:objects page) shape)
component
(cph/get-component libraries (:component-id component-shape))
(ctf/get-component libraries (:component-id component-shape))
main-shape
(ctn/get-shape component (:shape-ref shape))]
@ -117,7 +118,7 @@
[page root-inst-id libraries]
(let [root-inst (ctn/get-shape page root-inst-id)
component (cph/get-component libraries (:component-id root-inst))
component (ctf/get-component libraries (:component-id root-inst))
shapes-inst (cph/get-children-with-self (:objects page) root-inst-id)
shapes-main (cph/get-children-with-self (:objects component) (:shape-ref root-inst))
@ -126,10 +127,10 @@
main-exists? (fn [shape]
(let [component-shape
(cph/get-component-shape (:objects page) shape)
(ctn/get-component-shape (:objects page) shape)
component
(cph/get-component libraries (:component-id component-shape))
(ctf/get-component libraries (:component-id component-shape))
main-shape
(ctn/get-shape component (:shape-ref shape))]
@ -144,7 +145,7 @@
(defn resolve-component
"Get the component with the given id and all its shapes."
[page component-id libraries]
(let [component (cph/get-component libraries component-id)
(let [component (ctf/get-component libraries component-id)
root-main (ctk/get-component-root component)
shapes-main (cph/get-children-with-self (:objects component) (:id root-main))]

View file

@ -102,8 +102,9 @@
(let [[instance-shape instance-shapes]
(ctn/make-component-instance (ctpl/get-page file-data page-id)
(ctkl/get-component (:data library) component-id)
(:id library)
(gpt/point 0 0))]
(:data library)
(gpt/point 0 0)
true)]
(swap! idmap assoc label (:id instance-shape))
(-> file-data