diff --git a/frontend/src/app/plugins/api.cljs b/frontend/src/app/plugins/api.cljs index adf18684a..790197e64 100644 --- a/frontend/src/app/plugins/api.cljs +++ b/frontend/src/app/plugins/api.cljs @@ -205,7 +205,7 @@ (createShapeFromSvg [_ svg-string] (cond - (not (string? svg-string)) + (or (not (string? svg-string)) (empty? svg-string)) (u/display-not-valid :createShapeFromSvg svg-string) :else diff --git a/frontend/src/app/plugins/library.cljs b/frontend/src/app/plugins/library.cljs index de163e8b5..eb47da713 100644 --- a/frontend/src/app/plugins/library.cljs +++ b/frontend/src/app/plugins/library.cljs @@ -14,6 +14,7 @@ [app.common.record :as cr] [app.common.schema :as sm] [app.common.types.color :as ctc] + [app.common.types.file :as ctf] [app.common.types.typography :as ctt] [app.common.uuid :as uuid] [app.main.data.workspace :as dw] @@ -630,7 +631,19 @@ :else (let [component (u/proxy->library-component self) value (dm/str value " / " (:name component))] - (st/emit! (dwl/rename-component id value)))))})) + (st/emit! (dwl/rename-component id value)))))} + + {:name "mainInstance" + :get + (fn [self] + (let [file-id (obj/get self "$file") + file (u/locate-file file-id) + component (u/proxy->library-component self) + root (ctf/get-component-root (:data file) component)] + (when (some? root) + (shape/shape-proxy plugin-id file-id (:main-instance-page component) (:id root)))))})) + +(set! shape/lib-component-proxy lib-component-proxy) (deftype Library [$plugin $id] Object diff --git a/frontend/src/app/plugins/shape.cljs b/frontend/src/app/plugins/shape.cljs index 44cc2af73..df6b8d123 100644 --- a/frontend/src/app/plugins/shape.cljs +++ b/frontend/src/app/plugins/shape.cljs @@ -18,6 +18,9 @@ [app.common.spec :as us] [app.common.svg.path.legacy-parser2 :as spp] [app.common.text :as txt] + [app.common.types.component :as ctk] + [app.common.types.container :as ctn] + [app.common.types.file :as ctf] [app.common.types.grid :as ctg] [app.common.types.shape :as cts] [app.common.types.shape.blur :as ctsb] @@ -43,6 +46,7 @@ [cuerdas.core :as str])) (def lib-typography-proxy? nil) +(def lib-component-proxy nil) (deftype TextRange [$plugin $file $page $id start end] Object @@ -466,7 +470,39 @@ :else (let [typography (u/proxy->library-typography typography)] - (st/emit! (dwt/apply-typography #{$id} typography $file))))))) + (st/emit! (dwt/apply-typography #{$id} typography $file)))))) + + ;; COMPONENTS + (isComponentInstance + [self] + (let [shape (u/proxy->shape self) + file-id (obj/get self "$file") + page-id (obj/get self "$page") + objects (u/locate-objects file-id page-id)] + (ctn/in-any-component? objects shape))) + + (isComponentMainInstance + [self] + (let [shape (u/proxy->shape self) + file-id (obj/get self "$file") + page-id (obj/get self "$page") + objects (u/locate-objects file-id page-id)] + (ctn/inside-component-main? objects shape))) + + (isComponentCopyInstance + [self] + (let [shape (u/proxy->shape self)] + (ctk/in-component-copy? shape))) + + (isComponentRoot + [self] + (let [shape (u/proxy->shape self)] + (ctk/instance-root? shape))) + + (isComponentHead + [self] + (let [shape (u/proxy->shape self)] + (ctk/instance-head? shape)))) (crc/define-properties! ShapeProxy @@ -951,7 +987,60 @@ id (obj/get self "$id") objects (u/locate-objects file-id page-id)] (when (ctl/grid-layout-immediate-child-id? objects id) - (grid/layout-cell-proxy plugin-id file-id page-id id))))}) + (grid/layout-cell-proxy plugin-id file-id page-id id))))} + + ;; Components + {:name "componentRefShape" + :get + (fn [self] + (let [file-id (obj/get self "$file") + page-id (obj/get self "$page") + objects (u/locate-objects file-id page-id) + shape (u/proxy->shape self)] + (when (ctn/in-any-component? objects shape) + (let [plugin-id (obj/get self "$plugin") + [root component] (u/locate-component objects shape) + component-page-id (:main-instance-page component) + component-file (u/locate-file (:component-file root)) + ref-shape (ctf/get-ref-shape (:data component-file) component shape)] + (when (and (not (:deleted component)) (some? ref-shape) (some? component-file)) + (shape-proxy plugin-id (:id component-file) component-page-id (:id ref-shape)))))))} + + {:name "componentRoot" + :get + (fn [self] + (let [file-id (obj/get self "$file") + page-id (obj/get self "$page") + objects (u/locate-objects file-id page-id) + shape (u/proxy->shape self)] + (when (ctn/in-any-component? objects shape) + (let [plugin-id (obj/get self "$plugin") + [root component] (u/locate-component objects shape)] + (shape-proxy plugin-id (:component-file root) (:main-instance-page component) (:id root))))))} + + {:name "componentHead" + :get + (fn [self] + (let [file-id (obj/get self "$file") + objects (u/locate-objects file-id page-id) + shape (u/proxy->shape self)] + (when (ctn/in-any-component? objects shape) + (let [plugin-id (obj/get self "$plugin") + page-id (obj/get self "$page") + head (ctn/get-head-shape (u/locate-objects file-id page-id) shape)] + (shape-proxy plugin-id file-id page-id (:id head))))))} + + {:name "component" + :get + (fn [self] + (let [file-id (obj/get self "$file") + page-id (obj/get self "$page") + objects (u/locate-objects file-id page-id) + shape (u/proxy->shape self)] + (when (ctn/in-any-component? objects shape) + (let [plugin-id (obj/get self "$plugin") + [root component] (u/locate-component objects shape)] + (lib-component-proxy plugin-id (:component-file root) (:id component))))))}) (cond-> (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data)) (crc/add-properties! diff --git a/frontend/src/app/plugins/utils.cljs b/frontend/src/app/plugins/utils.cljs index 87fb3abb3..da600d447 100644 --- a/frontend/src/app/plugins/utils.cljs +++ b/frontend/src/app/plugins/utils.cljs @@ -10,6 +10,8 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.spec :as us] + [app.common.types.container :as ctn] + [app.common.types.file :as ctf] [app.common.uuid :as uuid] [app.main.store :as st] [app.util.object :as obj] @@ -62,6 +64,14 @@ (let [{:keys [profile-id]} (locate-presence session-id)] (dm/get-in @st/state [:users profile-id]))) +(defn locate-component + [objects shape] + (let [current-file-id (:current-file-id @st/state) + workspace-data (:workspace-data @st/state) + workspace-libraries (:workspace-libraries @st/state) + root (ctn/get-instance-root objects shape)] + [root (ctf/resolve-component root {:id current-file-id :data workspace-data} workspace-libraries {:include-deleted? true})])) + (defn proxy->file [proxy] (let [id (obj/get proxy "$id")]