mirror of
https://github.com/penpot/penpot.git
synced 2025-10-04 22:17:24 +00:00
🎉 Add variants to plugins API
This commit is contained in:
@@ -10,16 +10,23 @@
|
||||
[app.common.types.components-list :as ctcl]
|
||||
[app.common.types.variant :as ctv]))
|
||||
|
||||
|
||||
(defn find-variant-components
|
||||
"Find a list of the components thet belongs to this variant-id"
|
||||
[data objects variant-id]
|
||||
;; We can't simply filter components, because we need to maintain the order
|
||||
(->> (dm/get-in objects [variant-id :shapes])
|
||||
(map #(dm/get-in objects [% :component-id]))
|
||||
(map #(ctcl/get-component data % true))
|
||||
reverse))
|
||||
|
||||
([data variant-id]
|
||||
(let [page-id (->> data
|
||||
:components
|
||||
vals
|
||||
(filter #(= (:variant-id %) variant-id))
|
||||
first
|
||||
:main-instance-page)
|
||||
objects (dm/get-in data [:pages-index page-id :objects])]
|
||||
(find-variant-components data objects variant-id)))
|
||||
([data objects variant-id]
|
||||
;; We can't simply filter components, because we need to maintain the order
|
||||
(->> (dm/get-in objects [variant-id :shapes])
|
||||
(map #(dm/get-in objects [% :component-id]))
|
||||
(map #(ctcl/get-component data % true))
|
||||
reverse)))
|
||||
|
||||
(defn extract-properties-names
|
||||
[shape data]
|
||||
@@ -28,7 +35,6 @@
|
||||
:variant-properties
|
||||
(map :name)))
|
||||
|
||||
|
||||
(defn extract-properties-values
|
||||
"Get a map of properties associated to their possible values"
|
||||
[data objects variant-id]
|
||||
@@ -50,7 +56,6 @@
|
||||
(get :objects))]
|
||||
(dm/get-in objects [variant-id :shapes]))))
|
||||
|
||||
|
||||
(defn is-secondary-variant?
|
||||
[component data]
|
||||
(let [shapes (get-variant-mains component data)]
|
||||
|
||||
@@ -42,18 +42,21 @@
|
||||
[changes variant-id pos]
|
||||
(let [data (pcb/get-library-data changes)
|
||||
objects (pcb/get-objects changes)
|
||||
related-components (cfv/find-variant-components data objects variant-id)]
|
||||
(reduce (fn [changes component]
|
||||
(let [props (:variant-properties component)
|
||||
props (d/remove-at-index props pos)
|
||||
main-id (:main-instance-id component)
|
||||
name (ctv/properties-to-name props)]
|
||||
(-> changes
|
||||
(pcb/update-component (:id component) #(assoc % :variant-properties props)
|
||||
{:apply-changes-local-library? true})
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name)))))
|
||||
changes
|
||||
related-components)))
|
||||
related-components (cfv/find-variant-components data objects variant-id)
|
||||
props (-> related-components first :variant-properties)]
|
||||
(if (and (seq props) (<= 0 pos) (< pos (count props)))
|
||||
(reduce (fn [changes component]
|
||||
(let [props (:variant-properties component)
|
||||
props (d/remove-at-index props pos)
|
||||
main-id (:main-instance-id component)
|
||||
name (ctv/properties-to-name props)]
|
||||
(-> changes
|
||||
(pcb/update-component (:id component) #(assoc % :variant-properties props)
|
||||
{:apply-changes-local-library? true})
|
||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name)))))
|
||||
changes
|
||||
related-components)
|
||||
changes)))
|
||||
|
||||
|
||||
(defn generate-update-property-value
|
||||
|
||||
@@ -632,7 +632,8 @@
|
||||
|
||||
current-lib-data (get-in libraries [current-library-id :data])
|
||||
|
||||
components (->> (get-in libraries [current-library-id :data :components])
|
||||
components (->> current-lib-data
|
||||
:components
|
||||
vals
|
||||
(remove #(true? (:deleted %)))
|
||||
(remove #(cfv/is-secondary-variant? % current-lib-data))
|
||||
|
||||
@@ -8,12 +8,15 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.variant :as cfv]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.typography :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.plugins :as dp]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
@@ -614,9 +617,7 @@
|
||||
|
||||
(defn get-variant-components
|
||||
[file-id variant-id]
|
||||
(->> (dm/get-in (u/locate-file file-id) [:data :components])
|
||||
(map second)
|
||||
(filter #(= (:variant-id %) variant-id))))
|
||||
(cfv/find-variant-components (-> file-id u/locate-file :data) variant-id))
|
||||
|
||||
(declare lib-component-proxy)
|
||||
|
||||
@@ -640,15 +641,8 @@
|
||||
(set)
|
||||
(apply array)))}
|
||||
|
||||
:errors
|
||||
{:this true
|
||||
:get (fn [_]
|
||||
;; TODO
|
||||
)}
|
||||
|
||||
:currentValues
|
||||
(fn [property]
|
||||
;; TODO: validate input
|
||||
(->> (get-variant-components file-id id)
|
||||
(map
|
||||
(fn [{:keys [variant-properties]}]
|
||||
@@ -658,31 +652,39 @@
|
||||
(set)
|
||||
(apply array)))
|
||||
|
||||
:deleteProperty
|
||||
(fn [_property]
|
||||
;; TODO
|
||||
)
|
||||
|
||||
:findComponents
|
||||
(fn [props]
|
||||
;; TODO: Parse input
|
||||
;; TODO: Probably not the best way to find the components
|
||||
(letfn [(match-props [{:keys [variant-properties]}]
|
||||
(->> (js/Object.keys props)
|
||||
(every? (fn [p]
|
||||
(= (obj/get props p)
|
||||
(-> (d/seek #(= (:name %) p) variant-properties)
|
||||
:value))))))]
|
||||
(->> (get-variant-components file-id id)
|
||||
(filter match-props)
|
||||
(keep :id)
|
||||
(map #(lib-component-proxy plugin-id file-id %))
|
||||
(apply array))))
|
||||
:variantComponents
|
||||
(fn []
|
||||
(->> (get-variant-components file-id id)
|
||||
(map :id)
|
||||
(map #(lib-component-proxy plugin-id file-id %))
|
||||
(apply array)))
|
||||
|
||||
:addVariant
|
||||
(fn []
|
||||
;; TODO
|
||||
)))
|
||||
(st/emit!
|
||||
(ev/event {::ev/name "add-new-variant" ::ev/origin "plugin:add-variant"})
|
||||
(dwv/add-new-variant id)))
|
||||
|
||||
|
||||
:addProperty
|
||||
(fn []
|
||||
(st/emit!
|
||||
(ev/event {::ev/name "add-new-property" ::ev/origin "plugin:add-property"})
|
||||
(dwv/add-new-property id {:property-value "Value 1"})))
|
||||
|
||||
:removeProperty
|
||||
(fn [pos]
|
||||
(st/emit!
|
||||
(ev/event {::ev/name "remove-property" ::ev/origin "plugin:remove-property"})
|
||||
(dwv/remove-property id pos)))
|
||||
|
||||
:renameProperty
|
||||
(fn [pos name]
|
||||
(st/emit!
|
||||
(dwv/update-property-name id pos name {:trigger "plugin:rename-property"})))))
|
||||
|
||||
|
||||
(set! shape/variant-proxy variant-proxy)
|
||||
|
||||
(defn lib-component-proxy? [p]
|
||||
(obj/type-of? p "LibraryComponentProxy"))
|
||||
@@ -837,30 +839,61 @@
|
||||
(when (some? root)
|
||||
(shape/shape-proxy plugin-id file-id (:main-instance-page component) (:id root)))))
|
||||
|
||||
:isVariant
|
||||
(fn []
|
||||
(let [component (u/locate-library-component file-id id)]
|
||||
(ctk/is-variant? component)))
|
||||
|
||||
:variants
|
||||
{:enumerable false
|
||||
:get
|
||||
(fn []
|
||||
(let [component (u/locate-library-component file-id id)]
|
||||
(when (some? (:variant-id component))
|
||||
(when (ctk/is-variant? component)
|
||||
(variant-proxy plugin-id file-id (:variant-id component)))))}
|
||||
|
||||
:variantProps
|
||||
{:get
|
||||
(fn []
|
||||
(let [component (u/locate-library-component file-id id)]
|
||||
(when (some? (:variant-id component))
|
||||
(when (ctk/is-variant? component)
|
||||
(->> (:variant-properties component)
|
||||
(reduce
|
||||
(fn [acc {:keys [name value]}]
|
||||
(obj/set! acc name value))
|
||||
#js {})))))}
|
||||
|
||||
:variantErrors
|
||||
{:get (fn [])}
|
||||
:variantError
|
||||
{:get (fn []
|
||||
(let [file (u/locate-file file-id)
|
||||
component (u/locate-library-component file-id id)
|
||||
root (ctf/get-component-root (:data file) component)]
|
||||
(when (ctk/is-variant? component)
|
||||
(:variant-error root))))}
|
||||
|
||||
:transformInVariant
|
||||
(fn []
|
||||
(let [component (u/locate-library-component file-id id)]
|
||||
(when (and component
|
||||
(not (ctk/is-variant? component)))
|
||||
(st/emit!
|
||||
(ev/event {::ev/name "transform-in-variant" ::ev/origin "plugin:transform-in-variant"})
|
||||
(dwv/transform-in-variant (:main-instance-id component))))))
|
||||
|
||||
:addVariant
|
||||
(fn []
|
||||
(let [component (u/locate-library-component file-id id)]
|
||||
(when (and component
|
||||
(ctk/is-variant? component))
|
||||
(st/emit!
|
||||
(ev/event {::ev/name "add-new-variant" ::ev/origin "plugin:add-variant-from-component"})
|
||||
(dwv/add-new-variant (:main-instance-id component))))))
|
||||
|
||||
:setVariantProperty
|
||||
(fn [_property _value])))
|
||||
(fn [pos value]
|
||||
(st/emit!
|
||||
(ev/event {::ev/name "variant-edit-property-value" ::ev/origin "plugin:edit-property-value"})
|
||||
(dwv/update-property-value id pos value)))))
|
||||
|
||||
(defn library-proxy? [p]
|
||||
(obj/type-of? p "LibraryProxy"))
|
||||
@@ -901,27 +934,14 @@
|
||||
{:this true
|
||||
:get
|
||||
(fn [_]
|
||||
(let [file (u/locate-file file-id)
|
||||
components
|
||||
(concat
|
||||
(->> file
|
||||
:data
|
||||
:components
|
||||
(remove (comp :deleted second))
|
||||
(remove (comp :variant-id second))
|
||||
(map first)
|
||||
(map #(lib-component-proxy plugin-id file-id %)))
|
||||
|
||||
(->> file
|
||||
:data
|
||||
:components
|
||||
(remove (comp :deleted second))
|
||||
(filter (comp :variant-id second))
|
||||
(map second)
|
||||
(group-by :variant-id)
|
||||
;; TODO: This is not the way to locate the variant main component
|
||||
(map (comp :id first second))
|
||||
(map #(lib-component-proxy plugin-id file-id %))))]
|
||||
(let [file (u/locate-file file-id)
|
||||
data (:data file)
|
||||
components (->> data
|
||||
:components
|
||||
(remove (comp :deleted second))
|
||||
(remove (comp #(cfv/is-secondary-variant? % data) second))
|
||||
(map first)
|
||||
(map #(lib-component-proxy plugin-id file-id %)))]
|
||||
(apply array components)))}
|
||||
|
||||
:tokens
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.data.workspace.variants :as dwv]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.flex :as flex]
|
||||
@@ -57,6 +58,8 @@
|
||||
|
||||
(declare shape-proxy)
|
||||
(declare shape-proxy?)
|
||||
;; This is injected from plugin/librraies
|
||||
(def variant-proxy)
|
||||
|
||||
(defn interaction-proxy? [p]
|
||||
(obj/type-of? p "InteractionProxy"))
|
||||
@@ -761,6 +764,8 @@
|
||||
|
||||
|
||||
;; Interactions
|
||||
|
||||
|
||||
:interactions
|
||||
{:this true
|
||||
:get
|
||||
@@ -1234,7 +1239,6 @@
|
||||
(let [guide (u/proxy->ruler-guide value)]
|
||||
(st/emit! (dwgu/remove-guide guide)))))
|
||||
|
||||
|
||||
:applyToken
|
||||
(fn [_property _token]
|
||||
;; TODO
|
||||
@@ -1251,16 +1255,34 @@
|
||||
;; TODO swap component
|
||||
)
|
||||
|
||||
:isVariantCopy
|
||||
:isVariantHead
|
||||
(fn []
|
||||
;; TODO
|
||||
)
|
||||
(let [shape (u/locate-shape file-id page-id id)
|
||||
component (u/locate-library-component file-id (:component-id shape))]
|
||||
(and (ctk/instance-head? shape) (ctk/is-variant? component))))
|
||||
|
||||
:isVariantContainer
|
||||
(fn []
|
||||
(let [shape (u/locate-shape file-id page-id id)]
|
||||
(ctk/is-variant-container? shape)))
|
||||
|
||||
:switchVariant
|
||||
(fn [_property _value]
|
||||
;; TODO validate input
|
||||
;; TODO switch variant
|
||||
))
|
||||
(fn [pos value]
|
||||
(let [shape (u/locate-shape file-id page-id id)
|
||||
component (u/locate-library-component file-id (:component-id shape))]
|
||||
(when (and component (ctk/is-variant? component))
|
||||
(st/emit! (dwv/variants-switch {:shapes [shape] :pos pos :val value})))))
|
||||
|
||||
:combineAsVariants
|
||||
(fn [ids]
|
||||
(let [shape (u/locate-shape file-id page-id id)
|
||||
component (u/locate-library-component file-id (:component-id shape))
|
||||
ids (->> ids
|
||||
(map uuid/uuid)
|
||||
(into #{id}))]
|
||||
(when (and component (not (ctk/is-variant? component)))
|
||||
(st/emit!
|
||||
(dwv/combine-as-variants ids {:trigger "plugin:combine-as-variants"}))))))
|
||||
|
||||
(cond-> (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data))
|
||||
(crc/add-properties!
|
||||
@@ -1377,7 +1399,16 @@
|
||||
(u/display-not-valid :verticalSizing "Plugin doesn't have 'content:write' permission")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-item-v-sizing value})))))})))
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-item-v-sizing value})))))}
|
||||
|
||||
|
||||
{:name "variants"
|
||||
:enumerable false
|
||||
:get
|
||||
(fn [self]
|
||||
(let [shape (-> self u/proxy->shape)]
|
||||
(when (ctk/is-variant-container? shape)
|
||||
(variant-proxy plugin-id file-id (:id shape)))))})))
|
||||
|
||||
(cond-> (cfh/text-shape? data) (text/add-text-props plugin-id))
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
[file-id group name]
|
||||
(let [file (u/locate-file file-id)
|
||||
tokens-lib (->> file :data :tokens-lib)]
|
||||
(cttl/get-theme tokens-lib group name)))
|
||||
#_(cttl/get-theme tokens-lib group name)))
|
||||
|
||||
(defn locate-token-set
|
||||
[file-id set-name]
|
||||
@@ -28,7 +28,7 @@
|
||||
[file-id set-name token-id]
|
||||
(let [file (u/locate-file file-id)
|
||||
tokens-lib (->> file :data :tokens-lib)]
|
||||
(cttl/get-token-in-set tokens-lib set-name token-id)))
|
||||
#_(cttl/get-token-in-set tokens-lib set-name token-id)))
|
||||
|
||||
(defn token-proxy
|
||||
[plugin-id file-id set-name id]
|
||||
@@ -86,9 +86,9 @@
|
||||
(let [file (u/locate-file file-id)
|
||||
tokens-lib (->> file :data :tokens-lib)
|
||||
token-set (cttl/get-set tokens-lib set-name)]
|
||||
(->> (cttl/get-tokens token-set)
|
||||
(map #(token-proxy plugin-id file-id set-name (:id %)))
|
||||
(apply array))))}))
|
||||
#_(->> (cttl/get-tokens token-set)
|
||||
(map #(token-proxy plugin-id file-id set-name (:id %)))
|
||||
(apply array))))}))
|
||||
|
||||
(defn theme-proxy
|
||||
[plugin-id file-id group name]
|
||||
|
||||
Reference in New Issue
Block a user