diff --git a/common/src/app/common/logic/libraries.cljc b/common/src/app/common/logic/libraries.cljc index f5bf33de5..2919d9670 100644 --- a/common/src/app/common/logic/libraries.cljc +++ b/common/src/app/common/logic/libraries.cljc @@ -1859,20 +1859,26 @@ (assoc change :component-id (:id container)))) (defn generate-add-component-changes - [changes root objects file-id page-id] + [changes root objects file-id page-id variant-props] (let [name (:name root) + variant-id (when (ctk/is-variant? root) (:parent-id root)) + props (when (ctk/is-variant? root) (get variant-props (:component-id root))) + [path name] (cfh/parse-path-name name) [root-shape updated-shapes] (ctn/convert-shape-in-component root objects file-id) - changes (-> changes - (pcb/add-component (:id root-shape) - path - name - updated-shapes - (:id root) - page-id))] + changes (-> changes + (pcb/add-component (:id root-shape) + path + name + updated-shapes + (:id root) + page-id + nil + variant-id + props))] [root-shape changes])) (defn generate-add-component @@ -1927,7 +1933,7 @@ objects' (assoc objects (:id root) root) - [root-shape changes] (generate-add-component-changes changes root objects' file-id page-id) + [root-shape changes] (generate-add-component-changes changes root objects' file-id page-id nil) changes (pcb/update-shapes changes old-root-ids @@ -2193,9 +2199,11 @@ (defn generate-duplicate-shape-change ([changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id] - (generate-duplicate-shape-change changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id (:frame-id obj) (:parent-id obj) false false true)) + (generate-duplicate-shape-change changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id (:frame-id obj) (:parent-id obj) false false true nil)) + ([changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id variant-props] + (generate-duplicate-shape-change changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id (:frame-id obj) (:parent-id obj) false false true variant-props)) - ([changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id frame-id parent-id duplicating-component? child? remove-swap-slot?] + ([changes objects page unames update-unames! ids ids-map obj delta level-delta libraries library-data file-id frame-id parent-id duplicating-component? child? remove-swap-slot? variant-props] (cond (nil? obj) changes @@ -2231,7 +2239,7 @@ regenerate-component (fn [changes shape] - (let [[_ changes] (generate-add-component-changes changes shape objects file-id (:id page))] + (let [[_ changes] (generate-add-component-changes changes shape objects file-id (:id page) variant-props)] changes)) new-obj @@ -2270,7 +2278,13 @@ (d/update-when :interactions #(ctsi/remap-interactions % ids-map objects)) (cond-> (ctl/grid-layout? obj) - (ctl/remap-grid-cells ids-map))) + (ctl/remap-grid-cells ids-map)) + + (cond-> (ctk/is-variant-container? parent) + (assoc :variant-id parent-id)) + + (cond-> (not (ctk/is-variant-container? parent)) + (dissoc :variant-id))) new-obj (cond-> new-obj (not duplicating-component?) @@ -2318,14 +2332,15 @@ ;; only remove swap slot of children when the current shape ;; is not a subinstance head nor a instance root (not subinstance-head?) - (not instance-root?)))) + (not instance-root?)) + variant-props)) changes (map (d/getf objects) (:shapes obj))))))) (defn generate-duplicate-changes "Prepare objects to duplicate: generate new id, give them unique names, move to the desired position, and recalculate parents and frames as needed." - [changes all-objects page ids delta libraries library-data file-id] + [changes all-objects page ids delta libraries library-data file-id & {:keys [variant-props]}] (let [shapes (map (d/getf all-objects) ids) unames (volatile! (cfh/get-used-names (:objects page))) update-unames! (fn [new-name] (vswap! unames conj new-name)) @@ -2352,7 +2367,8 @@ nil libraries library-data - file-id) + file-id + variant-props) changes)) ;; We need to check the changes to get the ids-map diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index de80d24e7..8817dafd9 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1374,15 +1374,31 @@ (assoc obj ::images images)))) (rx/of obj)))) + (collect-variants [state shape] + (let [page-id (:current-page-id state) + data (dsh/lookup-file-data state) + objects (-> (dsh/get-page data page-id) + (get :objects)) + + components (cfv/find-variant-components data objects (:id shape))] + (into {} (map (juxt :id :variant-properties) components)))) + + ;; Collects all the items together and split images into a ;; separated data structure for a more easy paste process. - (collect-data [result {:keys [id ::images] :as item}] + ;; Also collects the variant properties of the copied variants + (collect-data [state result {:keys [id ::images] :as item}] (cond-> result :always (update :objects assoc id (dissoc item ::images)) (some? images) - (update :images into images))) + (update :images into images) + + (ctc/is-variant-container? item) + (update :variant-properties merge (collect-variants state item)))) + + (maybe-translate [shape objects parent-frame-id] (if (= parent-frame-id uuid/zero) @@ -1467,7 +1483,7 @@ (fn [resolve reject] (->> (rx/from shapes) (rx/merge-map (partial prepare-object objects frame-id)) - (rx/reduce collect-data initial) + (rx/reduce (partial collect-data state) initial) (rx/map (partial sort-selected state)) (rx/map (partial advance-copies state selected)) (rx/map #(t/encode-str % {:type :json-verbose})) @@ -1482,7 +1498,7 @@ ;; https://caniuse.com/?search=ClipboardItem (->> (rx/from shapes) (rx/merge-map (partial prepare-object objects frame-id)) - (rx/reduce collect-data initial) + (rx/reduce (partial collect-data state) initial) (rx/map (partial sort-selected state)) (rx/map (partial advance-copies state selected)) (rx/map #(t/encode-str % {:type :json-verbose})) @@ -2070,6 +2086,9 @@ objects (:objects pdata) + variant-props (:variant-properties pdata) + + position (deref ms/mouse-position) ;; Calculate position for the pasted elements @@ -2101,7 +2120,8 @@ (gslg/get-drop-cell frame-id all-objects position)) changes (-> (pcb/empty-changes it) - (cll/generate-duplicate-changes all-objects page selected delta libraries ldata file-id) + (cll/generate-duplicate-changes all-objects page selected delta + libraries ldata file-id {:variant-props variant-props}) (pcb/amend-changes (partial process-rchange media-idx)) (pcb/amend-changes (partial change-add-obj-index objects selected index)))