🎉 Add variants to plugins API

This commit is contained in:
Pablo Alba
2025-10-01 18:21:15 +02:00
parent 0ef66432d4
commit 3566b9ec00
6 changed files with 155 additions and 95 deletions

View File

@@ -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)]

View File

@@ -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

View File

@@ -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))

View File

@@ -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

View File

@@ -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))

View File

@@ -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]