mirror of
https://github.com/penpot/penpot.git
synced 2025-08-02 16:48:39 +02:00
🎉 Add variations POC
This commit is contained in:
parent
91fa39705d
commit
3268225941
24 changed files with 751 additions and 124 deletions
|
@ -52,7 +52,8 @@
|
|||
"plugins/runtime"
|
||||
"design-tokens/v1"
|
||||
"text-editor/v2"
|
||||
"render-wasm/v1"})
|
||||
"render-wasm/v1"
|
||||
"variants/v1"})
|
||||
|
||||
;; A set of features enabled by default
|
||||
(def default-features
|
||||
|
@ -111,6 +112,7 @@
|
|||
:feature-design-tokens "design-tokens/v1"
|
||||
:feature-text-editor-v2 "text-editor/v2"
|
||||
:feature-render-wasm "render-wasm/v1"
|
||||
:feature-variants "variants/v1"
|
||||
nil))
|
||||
|
||||
(defn migrate-legacy-features
|
||||
|
|
|
@ -861,7 +861,6 @@
|
|||
|
||||
(defn move-token-set-group-before
|
||||
[changes {:keys [from-path to-path before-path before-group? prev-before-path prev-before-group?]}]
|
||||
(prn prev-before-path prev-before-group?)
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :move-token-set-group-before
|
||||
:from-path from-path
|
||||
|
@ -971,31 +970,37 @@
|
|||
(apply-changes-local)))))
|
||||
|
||||
(defn update-component
|
||||
[changes id update-fn]
|
||||
(assert-library! changes)
|
||||
(let [library-data (::library-data (meta changes))
|
||||
prev-component (get-in library-data [:components id])
|
||||
new-component (update-fn prev-component)]
|
||||
(if prev-component
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :mod-component
|
||||
:id id
|
||||
:name (:name new-component)
|
||||
:path (:path new-component)
|
||||
:main-instance-id (:main-instance-id new-component)
|
||||
:main-instance-page (:main-instance-page new-component)
|
||||
:annotation (:annotation new-component)
|
||||
:objects (:objects new-component) ;; this won't exist in components-v2 (except for deleted components)
|
||||
:modified-at (:modified-at new-component)})
|
||||
(update :undo-changes conj {:type :mod-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)
|
||||
:annotation (:annotation prev-component)
|
||||
:objects (:objects prev-component)}))
|
||||
changes)))
|
||||
([changes id update-fn]
|
||||
(let [library-data (::library-data (meta changes))
|
||||
prev-component (get-in library-data [:components id])]
|
||||
(update-component changes id prev-component update-fn)))
|
||||
([changes id prev-component update-fn]
|
||||
(assert-library! changes)
|
||||
(let [new-component (update-fn prev-component)]
|
||||
(if prev-component
|
||||
(-> changes
|
||||
(update :redo-changes conj {:type :mod-component
|
||||
:id id
|
||||
:name (:name new-component)
|
||||
:path (:path new-component)
|
||||
:main-instance-id (:main-instance-id new-component)
|
||||
:main-instance-page (:main-instance-page new-component)
|
||||
:annotation (:annotation new-component)
|
||||
:variant-id (:variant-id new-component)
|
||||
:variant-properties (:variant-properties new-component)
|
||||
:objects (:objects new-component) ;; this won't exist in components-v2 (except for deleted components)
|
||||
:modified-at (:modified-at new-component)})
|
||||
(update :undo-changes conj {:type :mod-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)
|
||||
:annotation (:annotation prev-component)
|
||||
:variant-id (:variant-id prev-component)
|
||||
:variant-properties (:variant-properties prev-component)
|
||||
:objects (:objects prev-component)}))
|
||||
changes))))
|
||||
|
||||
(defn delete-component
|
||||
[changes id page-id]
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
|
||||
(defn generate-duplicate-component
|
||||
"Create a new component copied from the one with the given id."
|
||||
[changes library component-id components-v2]
|
||||
[changes library component-id new-component-id components-v2]
|
||||
(let [component (ctkl/get-component (:data library) component-id)
|
||||
new-name (:name component)
|
||||
|
||||
|
@ -160,7 +160,7 @@
|
|||
(ctf/get-component-page (:data library) component))
|
||||
|
||||
new-component-id (when components-v2
|
||||
(uuid/next))
|
||||
new-component-id)
|
||||
|
||||
[new-component-shape new-component-shapes ; <- null in components-v2
|
||||
new-main-instance-shape new-main-instance-shapes]
|
||||
|
@ -181,6 +181,7 @@
|
|||
(:id main-instance-page)
|
||||
(:annotation component)))))
|
||||
|
||||
|
||||
(defn generate-instantiate-component
|
||||
"Generate changes to create a new instance from a component."
|
||||
([changes objects file-id component-id position page libraries]
|
||||
|
|
62
common/src/app/common/logic/variants.cljc
Normal file
62
common/src/app/common/logic/variants.cljc
Normal file
|
@ -0,0 +1,62 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
(ns app.common.logic.variants
|
||||
(:require
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
|
||||
(defn properties-to-name
|
||||
[properties]
|
||||
(->> properties
|
||||
(map :value)
|
||||
(str/join ", ")))
|
||||
|
||||
(defn generate-update-property-name
|
||||
[changes related-components pos new-name]
|
||||
(reduce (fn [changes component]
|
||||
(pcb/update-component
|
||||
changes (:id component)
|
||||
#(assoc-in % [:variant-properties pos :name] new-name)))
|
||||
changes
|
||||
related-components))
|
||||
|
||||
|
||||
(defn generate-remove-property
|
||||
[changes related-components pos]
|
||||
(reduce (fn [changes component]
|
||||
(let [props (:variant-properties component)
|
||||
props (vec (concat (subvec props 0 pos) (subvec props (inc pos))))
|
||||
main-id (:main-instance-id component)
|
||||
name (properties-to-name props)]
|
||||
(-> changes
|
||||
(pcb/update-component (:id component) #(assoc % :variant-properties props))
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name)))))
|
||||
changes
|
||||
related-components))
|
||||
|
||||
|
||||
(defn generate-update-property-value
|
||||
[changes component-id main-id pos value name]
|
||||
(-> changes
|
||||
(pcb/update-component component-id #(assoc-in % [:variant-properties pos :value] value))
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name))))
|
||||
|
||||
(defn generate-add-new-property
|
||||
[changes related-components property-name]
|
||||
(let [[_ changes]
|
||||
(reduce (fn [[num changes] component]
|
||||
(let [props (-> (or (:variant-properties component) [])
|
||||
(conj {:name property-name :value (str "Value" num)}))
|
||||
main-id (:main-instance-id component)
|
||||
variant-name (properties-to-name props)]
|
||||
[(inc num)
|
||||
(-> changes
|
||||
(pcb/update-component (:id component) #(assoc % :variant-properties props))
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name variant-name)))]))
|
||||
[1 changes]
|
||||
related-components)]
|
||||
changes))
|
|
@ -215,6 +215,19 @@
|
|||
(and (= shape-id (:main-instance-id component))
|
||||
(= page-id (:main-instance-page component))))
|
||||
|
||||
|
||||
(defn is-variant?
|
||||
"Check if this shape or component is a variant component"
|
||||
[item]
|
||||
(some? (:variant-id item)))
|
||||
|
||||
|
||||
(defn is-variant-container?
|
||||
"Check if this shape is a variant container"
|
||||
[shape]
|
||||
(:is-variant-container shape))
|
||||
|
||||
|
||||
(defn set-touched-group
|
||||
[touched group]
|
||||
(when group
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
(wrap-object-fn)))))))
|
||||
|
||||
(defn mod-component
|
||||
[file-data {:keys [id name path main-instance-id main-instance-page objects annotation modified-at]}]
|
||||
[file-data {:keys [id name path main-instance-id main-instance-page objects annotation variant-id variant-properties modified-at]}]
|
||||
(let [wrap-objects-fn cfeat/*wrap-with-objects-map-fn*]
|
||||
(d/update-in-when file-data [:components id]
|
||||
(fn [component]
|
||||
|
@ -76,10 +76,22 @@
|
|||
(assoc :annotation annotation)
|
||||
|
||||
(nil? annotation)
|
||||
(dissoc :annotation))
|
||||
(dissoc :annotation)
|
||||
|
||||
(some? variant-id)
|
||||
(assoc :variant-id variant-id)
|
||||
|
||||
(nil? variant-id)
|
||||
(dissoc :variant-id)
|
||||
|
||||
(some? variant-properties)
|
||||
(assoc :variant-properties variant-properties)
|
||||
|
||||
(nil? variant-properties)
|
||||
(dissoc :variant-properties))
|
||||
diff (set/difference
|
||||
(ctk/diff-components component new-comp)
|
||||
#{:annotation :modified-at})] ;; The set of properties that doesn't mark a component as touched
|
||||
#{:annotation :modified-at :variant-id :variant-properties})] ;; The set of properties that doesn't mark a component as touched
|
||||
|
||||
(if (empty? diff)
|
||||
new-comp
|
||||
|
|
|
@ -406,7 +406,7 @@
|
|||
(cond-> new-shape
|
||||
:always
|
||||
(-> (gsh/move delta)
|
||||
(dissoc :touched))
|
||||
(dissoc :touched :variant-id :variant-name))
|
||||
|
||||
(and main-instance? root?)
|
||||
(assoc :main-instance true)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.uuid :as uuid]
|
||||
[clojure.test :as t]))
|
||||
|
||||
(t/use-fixtures :each thi/test-fixture)
|
||||
|
@ -288,6 +289,7 @@
|
|||
changes (cll/generate-duplicate-component (pcb/empty-changes)
|
||||
file
|
||||
(:id component)
|
||||
(uuid/next)
|
||||
true)
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue