mirror of
https://github.com/penpot/penpot.git
synced 2026-05-28 11:23:42 +00:00
✨ Add variants to plugins API
This commit is contained in:
parent
38c3b2eaba
commit
04542e1e66
5975
backend/hs_err_pid595.log
Normal file
5975
backend/hs_err_pid595.log
Normal file
File diff suppressed because one or more lines are too long
10795
backend/replay_pid595.log
Normal file
10795
backend/replay_pid595.log
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,16 +10,23 @@
|
|||||||
[app.common.types.components-list :as ctcl]
|
[app.common.types.components-list :as ctcl]
|
||||||
[app.common.types.variant :as ctv]))
|
[app.common.types.variant :as ctv]))
|
||||||
|
|
||||||
|
|
||||||
(defn find-variant-components
|
(defn find-variant-components
|
||||||
"Find a list of the components thet belongs to this variant-id"
|
"Find a list of the components thet belongs to this variant-id"
|
||||||
[data objects variant-id]
|
([data variant-id]
|
||||||
;; We can't simply filter components, because we need to maintain the order
|
(let [page-id (->> data
|
||||||
(->> (dm/get-in objects [variant-id :shapes])
|
:components
|
||||||
(map #(dm/get-in objects [% :component-id]))
|
vals
|
||||||
(map #(ctcl/get-component data % true))
|
(filter #(= (:variant-id %) variant-id))
|
||||||
reverse))
|
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
|
(defn extract-properties-names
|
||||||
[shape data]
|
[shape data]
|
||||||
@ -28,7 +35,6 @@
|
|||||||
:variant-properties
|
:variant-properties
|
||||||
(map :name)))
|
(map :name)))
|
||||||
|
|
||||||
|
|
||||||
(defn extract-properties-values
|
(defn extract-properties-values
|
||||||
"Get a map of properties associated to their possible values"
|
"Get a map of properties associated to their possible values"
|
||||||
[data objects variant-id]
|
[data objects variant-id]
|
||||||
@ -50,7 +56,6 @@
|
|||||||
(get :objects))]
|
(get :objects))]
|
||||||
(dm/get-in objects [variant-id :shapes]))))
|
(dm/get-in objects [variant-id :shapes]))))
|
||||||
|
|
||||||
|
|
||||||
(defn is-secondary-variant?
|
(defn is-secondary-variant?
|
||||||
[component data]
|
[component data]
|
||||||
(let [shapes (get-variant-mains component data)]
|
(let [shapes (get-variant-mains component data)]
|
||||||
|
|||||||
@ -42,18 +42,21 @@
|
|||||||
[changes variant-id pos]
|
[changes variant-id pos]
|
||||||
(let [data (pcb/get-library-data changes)
|
(let [data (pcb/get-library-data changes)
|
||||||
objects (pcb/get-objects changes)
|
objects (pcb/get-objects changes)
|
||||||
related-components (cfv/find-variant-components data objects variant-id)]
|
related-components (cfv/find-variant-components data objects variant-id)
|
||||||
(reduce (fn [changes component]
|
props (-> related-components first :variant-properties)]
|
||||||
(let [props (:variant-properties component)
|
(if (and (seq props) (<= 0 pos) (< pos (count props)))
|
||||||
props (d/remove-at-index props pos)
|
(reduce (fn [changes component]
|
||||||
main-id (:main-instance-id component)
|
(let [props (:variant-properties component)
|
||||||
name (ctv/properties-to-name props)]
|
props (d/remove-at-index props pos)
|
||||||
(-> changes
|
main-id (:main-instance-id component)
|
||||||
(pcb/update-component (:id component) #(assoc % :variant-properties props)
|
name (ctv/properties-to-name props)]
|
||||||
{:apply-changes-local-library? true})
|
(-> changes
|
||||||
(pcb/update-shapes [main-id] #(assoc % :variant-name name)))))
|
(pcb/update-component (:id component) #(assoc % :variant-properties props)
|
||||||
changes
|
{:apply-changes-local-library? true})
|
||||||
related-components)))
|
(pcb/update-shapes [main-id] #(assoc % :variant-name name)))))
|
||||||
|
changes
|
||||||
|
related-components)
|
||||||
|
changes)))
|
||||||
|
|
||||||
|
|
||||||
(defn generate-update-property-value
|
(defn generate-update-property-value
|
||||||
|
|||||||
@ -670,7 +670,8 @@
|
|||||||
(ctkl/components-seq current-lib-data))
|
(ctkl/components-seq current-lib-data))
|
||||||
(update-vals count)))
|
(update-vals count)))
|
||||||
|
|
||||||
components (->> (get-in libraries [current-library-id :data :components])
|
components (->> current-lib-data
|
||||||
|
:components
|
||||||
vals
|
vals
|
||||||
(remove #(true? (:deleted %)))
|
(remove #(true? (:deleted %)))
|
||||||
(remove #(cfv/is-secondary-variant? % current-lib-data))
|
(remove #(cfv/is-secondary-variant? % current-lib-data))
|
||||||
|
|||||||
@ -5,16 +5,18 @@
|
|||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.plugins.library
|
(ns app.plugins.library
|
||||||
"RPC for plugins runtime."
|
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.files.variant :as cfv]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.types.color :as clr]
|
[app.common.types.color :as clr]
|
||||||
|
[app.common.types.component :as ctk]
|
||||||
[app.common.types.file :as ctf]
|
[app.common.types.file :as ctf]
|
||||||
[app.common.types.typography :as ctt]
|
[app.common.types.typography :as ctt]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.plugins :as dp]
|
[app.main.data.plugins :as dp]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.texts :as dwt]
|
[app.main.data.workspace.texts :as dwt]
|
||||||
@ -612,6 +614,85 @@
|
|||||||
(let [typography (u/locate-library-typography file-id id)]
|
(let [typography (u/locate-library-typography file-id id)]
|
||||||
(apply array (keys (dm/get-in typography [:plugin-data (keyword "shared" namespace)]))))))))
|
(apply array (keys (dm/get-in typography [:plugin-data (keyword "shared" namespace)]))))))))
|
||||||
|
|
||||||
|
(defn get-variant-components
|
||||||
|
[file-id variant-id]
|
||||||
|
(cfv/find-variant-components (-> file-id u/locate-file :data) variant-id))
|
||||||
|
|
||||||
|
(declare lib-component-proxy)
|
||||||
|
|
||||||
|
(defn variant-proxy
|
||||||
|
[plugin-id file-id id]
|
||||||
|
|
||||||
|
(obj/reify {:name "VariantProxy"}
|
||||||
|
:$plugin {:enumerable false :get (constantly plugin-id)}
|
||||||
|
:$file {:enumerable false :get (constantly file-id)}
|
||||||
|
:$id {:enumerable false :get (constantly id)}
|
||||||
|
|
||||||
|
:id {:get (fn [_] (dm/str id))}
|
||||||
|
:libraryId {:get (fn [_] (dm/str file-id))}
|
||||||
|
|
||||||
|
:properties
|
||||||
|
{:this true
|
||||||
|
:get (fn [_]
|
||||||
|
(->> (get-variant-components file-id id)
|
||||||
|
(mapcat :variant-properties)
|
||||||
|
(keep :name)
|
||||||
|
(set)
|
||||||
|
(apply array)))}
|
||||||
|
|
||||||
|
:currentValues
|
||||||
|
(fn [property]
|
||||||
|
(->> (get-variant-components file-id id)
|
||||||
|
(map
|
||||||
|
(fn [{:keys [variant-properties]}]
|
||||||
|
(->> variant-properties
|
||||||
|
(d/seek #(= (:name %) property)))))
|
||||||
|
(keep :value)
|
||||||
|
(set)
|
||||||
|
(apply array)))
|
||||||
|
|
||||||
|
:variantComponents
|
||||||
|
(fn []
|
||||||
|
(->> (get-variant-components file-id id)
|
||||||
|
(map :id)
|
||||||
|
(map #(lib-component-proxy plugin-id file-id %))
|
||||||
|
(apply array)))
|
||||||
|
|
||||||
|
:addVariant
|
||||||
|
(fn []
|
||||||
|
(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]
|
||||||
|
(if (not (nat-int? pos))
|
||||||
|
(u/display-not-valid :pos pos)
|
||||||
|
(st/emit!
|
||||||
|
(ev/event {::ev/name "remove-property" ::ev/origin "plugin:remove-property"})
|
||||||
|
(dwv/remove-property id pos))))
|
||||||
|
|
||||||
|
:renameProperty
|
||||||
|
(fn [pos name]
|
||||||
|
(cond
|
||||||
|
(not (nat-int? pos))
|
||||||
|
(u/display-not-valid :pos pos)
|
||||||
|
|
||||||
|
(not (string? name))
|
||||||
|
(u/display-not-valid :name name)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit!
|
||||||
|
(dwv/update-property-name id pos name {:trigger "plugin:rename-property"}))))))
|
||||||
|
|
||||||
|
(set! shape/variant-proxy variant-proxy)
|
||||||
|
|
||||||
(defn lib-component-proxy? [p]
|
(defn lib-component-proxy? [p]
|
||||||
(obj/type-of? p "LibraryComponentProxy"))
|
(obj/type-of? p "LibraryComponentProxy"))
|
||||||
|
|
||||||
@ -763,7 +844,71 @@
|
|||||||
component (u/locate-library-component file-id id)
|
component (u/locate-library-component file-id id)
|
||||||
root (ctf/get-component-root (:data file) component)]
|
root (ctf/get-component-root (:data file) component)]
|
||||||
(when (some? root)
|
(when (some? root)
|
||||||
(shape/shape-proxy plugin-id file-id (:main-instance-page component) (:id 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 (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 (ctk/is-variant? component)
|
||||||
|
(->> (:variant-properties component)
|
||||||
|
(reduce
|
||||||
|
(fn [acc {:keys [name value]}]
|
||||||
|
(obj/set! acc name value))
|
||||||
|
#js {})))))}
|
||||||
|
|
||||||
|
: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 [pos value]
|
||||||
|
(cond
|
||||||
|
(not (nat-int? pos))
|
||||||
|
(u/display-not-valid :pos pos)
|
||||||
|
|
||||||
|
(not (string? name))
|
||||||
|
(u/display-not-valid :name name)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(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]
|
(defn library-proxy? [p]
|
||||||
(obj/type-of? p "LibraryProxy"))
|
(obj/type-of? p "LibraryProxy"))
|
||||||
@ -804,11 +949,12 @@
|
|||||||
{:this true
|
{:this true
|
||||||
:get
|
:get
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [file (u/locate-file file-id)
|
(let [file (u/locate-file file-id)
|
||||||
components (->> file
|
data (:data file)
|
||||||
:data
|
components (->> data
|
||||||
:components
|
:components
|
||||||
(remove (comp :deleted second))
|
(remove (comp :deleted second))
|
||||||
|
(remove (comp #(cfv/is-secondary-variant? % data) second))
|
||||||
(map first)
|
(map first)
|
||||||
(map #(lib-component-proxy plugin-id file-id %)))]
|
(map #(lib-component-proxy plugin-id file-id %)))]
|
||||||
(apply array components)))}
|
(apply array components)))}
|
||||||
|
|||||||
@ -42,6 +42,7 @@
|
|||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.data.workspace.texts :as dwt]
|
[app.main.data.workspace.texts :as dwt]
|
||||||
|
[app.main.data.workspace.variants :as dwv]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.flex :as flex]
|
[app.plugins.flex :as flex]
|
||||||
@ -58,6 +59,8 @@
|
|||||||
|
|
||||||
(declare shape-proxy)
|
(declare shape-proxy)
|
||||||
(declare shape-proxy?)
|
(declare shape-proxy?)
|
||||||
|
;; This is injected from plugin/librraies
|
||||||
|
(def variant-proxy nil)
|
||||||
|
|
||||||
(defn interaction-proxy? [p]
|
(defn interaction-proxy? [p]
|
||||||
(obj/type-of? p "InteractionProxy"))
|
(obj/type-of? p "InteractionProxy"))
|
||||||
@ -771,9 +774,7 @@
|
|||||||
#(interaction-proxy plugin-id file-id page-id id %)
|
#(interaction-proxy plugin-id file-id page-id id %)
|
||||||
(range 0 (count interactions)))))}
|
(range 0 (count interactions)))))}
|
||||||
|
|
||||||
|
|
||||||
;; Methods
|
;; Methods
|
||||||
|
|
||||||
:resize
|
:resize
|
||||||
(fn [width height]
|
(fn [width height]
|
||||||
(cond
|
(cond
|
||||||
@ -1221,7 +1222,46 @@
|
|||||||
|
|
||||||
:else
|
:else
|
||||||
(let [guide (u/proxy->ruler-guide value)]
|
(let [guide (u/proxy->ruler-guide value)]
|
||||||
(st/emit! (dwgu/remove-guide guide))))))
|
(st/emit! (dwgu/remove-guide guide)))))
|
||||||
|
|
||||||
|
:isVariantHead
|
||||||
|
(fn []
|
||||||
|
(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 [pos value]
|
||||||
|
(cond
|
||||||
|
(not (nat-int? pos))
|
||||||
|
(u/display-not-valid :pos pos)
|
||||||
|
|
||||||
|
(not (string? value))
|
||||||
|
(u/display-not-valid :value value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(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]
|
||||||
|
(if (or (not (seq ids)) (not (every? uuid/parse* ids)))
|
||||||
|
(u/display-not-valid :ids 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))
|
(cond-> (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data))
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
@ -1338,7 +1378,15 @@
|
|||||||
(u/display-not-valid :verticalSizing "Plugin doesn't have 'content:write' permission")
|
(u/display-not-valid :verticalSizing "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
:else
|
: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))
|
(cond-> (cfh/text-shape? data) (text/add-text-props plugin-id))
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user