mirror of
https://github.com/penpot/penpot.git
synced 2025-05-25 18:36:12 +02:00
✨ New apis for plugins
This commit is contained in:
parent
d6de1fdbdf
commit
3ca5b13e27
7 changed files with 613 additions and 92 deletions
|
@ -101,6 +101,7 @@
|
||||||
(fn []
|
(fn []
|
||||||
(->> (http/send! {:method :get
|
(->> (http/send! {:method :get
|
||||||
:uri plugin-url
|
:uri plugin-url
|
||||||
|
:omit-default-headers true
|
||||||
:response-type :json})
|
:response-type :json})
|
||||||
(rx/map :body)
|
(rx/map :body)
|
||||||
(rx/subs!
|
(rx/subs!
|
||||||
|
|
|
@ -154,4 +154,4 @@
|
||||||
{:name "currentPage" :get #(.getPage ^js %)}
|
{:name "currentPage" :get #(.getPage ^js %)}
|
||||||
{:name "selection" :get #(.getSelectedShapes ^js %)}
|
{:name "selection" :get #(.getSelectedShapes ^js %)}
|
||||||
{:name "viewport" :get #(.getViewport ^js %)}
|
{:name "viewport" :get #(.getViewport ^js %)}
|
||||||
{:name "library" :get (fn [_] (library/create-library-subcontext))}))
|
{:name "library" :get (fn [_] (library/library-subcontext))}))
|
||||||
|
|
282
frontend/src/app/plugins/flex.cljs
Normal file
282
frontend/src/app/plugins/flex.cljs
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
;; 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.plugins.flex
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.record :as crc]
|
||||||
|
[app.common.spec :as us]
|
||||||
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
|
[app.main.data.workspace.transforms :as dwt]
|
||||||
|
[app.main.store :as st]
|
||||||
|
[app.plugins.utils :as utils :refer [proxy->shape]]
|
||||||
|
[app.util.object :as obj]
|
||||||
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
(deftype FlexLayout [$file $page $id]
|
||||||
|
Object
|
||||||
|
(remove
|
||||||
|
[_]
|
||||||
|
(st/emit! (dwsl/remove-layout #{$id})))
|
||||||
|
|
||||||
|
(appendChild
|
||||||
|
[_ child]
|
||||||
|
(let [child-id (obj/get child "$id")]
|
||||||
|
(st/emit! (dwt/move-shapes-to-frame #{child-id} $id nil nil)
|
||||||
|
(ptk/data-event :layout/update {:ids [$id]})))))
|
||||||
|
|
||||||
|
(defn flex-layout-proxy
|
||||||
|
[file-id page-id id]
|
||||||
|
(-> (FlexLayout. file-id page-id id)
|
||||||
|
(crc/add-properties!
|
||||||
|
{:name "$id" :enumerable false}
|
||||||
|
{:name "$file" :enumerable false}
|
||||||
|
{:name "$page" :enumerable false}
|
||||||
|
|
||||||
|
{:name "dir"
|
||||||
|
:get #(-> % proxy->shape :layout-flex-dir d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/flex-direction-types value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-flex-dir value})))))}
|
||||||
|
|
||||||
|
{:name "alignItems"
|
||||||
|
:get #(-> % proxy->shape :layout-align-items d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/align-items-types value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value})))))}
|
||||||
|
|
||||||
|
{:name "alignContent"
|
||||||
|
:get #(-> % proxy->shape :layout-align-content d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/align-content-types value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value})))))}
|
||||||
|
|
||||||
|
{:name "justifyItems"
|
||||||
|
:get #(-> % proxy->shape :layout-justify-items d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/justify-items-types value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value})))))}
|
||||||
|
|
||||||
|
{:name "justifyContent"
|
||||||
|
:get #(-> % proxy->shape :layout-justify-content d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/justify-content-types value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value})))))}
|
||||||
|
|
||||||
|
{:name "rowGap"
|
||||||
|
:get #(-> % proxy->shape :layout-gap :row-gap)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:row-gap value}})))))}
|
||||||
|
|
||||||
|
{:name "columnGap"
|
||||||
|
:get #(-> % proxy->shape :layout-gap :column-gap)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:column-gap value}})))))}
|
||||||
|
|
||||||
|
{:name "verticalPadding"
|
||||||
|
:get #(-> % proxy->shape :layout-padding :p1)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value :p3 value}})))))}
|
||||||
|
|
||||||
|
{:name "horizontalPadding"
|
||||||
|
:get #(-> % proxy->shape :layout-padding :p2)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value :p4 value}})))))}
|
||||||
|
|
||||||
|
|
||||||
|
{:name "topPadding"
|
||||||
|
:get #(-> % proxy->shape :layout-padding :p1)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value}})))))}
|
||||||
|
|
||||||
|
{:name "rightPadding"
|
||||||
|
:get #(-> % proxy->shape :layout-padding :p2)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value}})))))}
|
||||||
|
|
||||||
|
{:name "bottomPadding"
|
||||||
|
:get #(-> % proxy->shape :layout-padding :p3)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p3 value}})))))}
|
||||||
|
|
||||||
|
{:name "leftPadding"
|
||||||
|
:get #(-> % proxy->shape :layout-padding :p4)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
||||||
|
|
||||||
|
|
||||||
|
(deftype LayoutChildProxy [$file $page $id])
|
||||||
|
|
||||||
|
(defn layout-child-proxy
|
||||||
|
[file-id page-id id]
|
||||||
|
(-> (LayoutChildProxy. file-id page-id id)
|
||||||
|
(crc/add-properties!
|
||||||
|
{:name "$id" :enumerable false}
|
||||||
|
{:name "$file" :enumerable false}
|
||||||
|
{:name "$page" :enumerable false}
|
||||||
|
|
||||||
|
{:name "absolute"
|
||||||
|
:get #(-> % proxy->shape :layout-item-absolute boolean)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (boolean? value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-item-absolute value})))))}
|
||||||
|
|
||||||
|
{:name "zIndex"
|
||||||
|
:get #(-> % proxy->shape :layout-item-z-index (d/nilv 0))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-z-index value})))))}
|
||||||
|
|
||||||
|
{:name "horizontalSizing"
|
||||||
|
:get #(-> % proxy->shape :layout-item-h-sizing (d/nilv :fix) d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/item-h-sizing-types value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-h-sizing value})))))}
|
||||||
|
|
||||||
|
{:name "verticalSizing"
|
||||||
|
:get #(-> % proxy->shape :layout-item-v-sizing (d/nilv :fix) d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/item-v-sizing-types value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-v-sizing value})))))}
|
||||||
|
|
||||||
|
{:name "alignSelf"
|
||||||
|
:get #(-> % proxy->shape :layout-item-align-self (d/nilv :auto) d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/item-align-self-types value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-align-self value})))))}
|
||||||
|
|
||||||
|
{:name "verticalMargin"
|
||||||
|
:get #(-> % proxy->shape :layout-item-margin :m1 (d/nilv 0))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m1 value :m3 value}})))))}
|
||||||
|
|
||||||
|
{:name "horizontalMargin"
|
||||||
|
:get #(-> % proxy->shape :layout-item-margin :m2 (d/nilv 0))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m2 value :m4 value}})))))}
|
||||||
|
|
||||||
|
{:name "topMargin"
|
||||||
|
:get #(-> % proxy->shape :layout-item-margin :m1 (d/nilv 0))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m1 value}})))))}
|
||||||
|
|
||||||
|
{:name "rightMargin"
|
||||||
|
:get #(-> % proxy->shape :layout-item-margin :m2 (d/nilv 0))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m2 value}})))))}
|
||||||
|
|
||||||
|
{:name "bottomMargin"
|
||||||
|
:get #(-> % proxy->shape :layout-item-margin :m3 (d/nilv 0))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m3 value}})))))}
|
||||||
|
|
||||||
|
{:name "leftMargin"
|
||||||
|
:get #(-> % proxy->shape :layout-item-margin :m4 (d/nilv 0))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m4 value}})))))}
|
||||||
|
|
||||||
|
{:name "maxWidth"
|
||||||
|
:get #(-> % proxy->shape :layout-item-max-w)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-max-w value})))))}
|
||||||
|
|
||||||
|
{:name "minWidth"
|
||||||
|
:get #(-> % proxy->shape :layout-item-min-w)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-min-w value})))))}
|
||||||
|
|
||||||
|
{:name "maxHeight"
|
||||||
|
:get #(-> % proxy->shape :layout-item-max-h)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-max-h value})))))}
|
||||||
|
|
||||||
|
{:name "minHeight"
|
||||||
|
:get #(-> % proxy->shape :layout-item-min-h)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(when (us/safe-number? value)
|
||||||
|
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-min-h value})))))})))
|
|
@ -13,7 +13,7 @@
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
[app.main.data.workspace.transforms :as dwt]
|
[app.main.data.workspace.transforms :as dwt]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.utils :as utils :refer [proxy->shape]]
|
[app.plugins.utils :as utils :refer [proxy->shape locate-shape]]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -196,3 +196,93 @@
|
||||||
(let [id (obj/get self "$id")]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
||||||
|
|
||||||
|
(deftype GridCellProxy [$file $page $id])
|
||||||
|
|
||||||
|
(defn layout-cell-proxy
|
||||||
|
[file-id page-id id]
|
||||||
|
(letfn [(locate-cell [_]
|
||||||
|
(let [shape (locate-shape file-id page-id id)
|
||||||
|
parent (locate-shape file-id page-id (:parent-id shape))]
|
||||||
|
(ctl/get-cell-by-shape-id parent id)))]
|
||||||
|
|
||||||
|
(-> (GridCellProxy. file-id page-id id)
|
||||||
|
(crc/add-properties!
|
||||||
|
{:name "$id" :enumerable false}
|
||||||
|
{:name "$file" :enumerable false}
|
||||||
|
{:name "$page" :enumerable false}
|
||||||
|
|
||||||
|
{:name "row"
|
||||||
|
:get #(-> % locate-cell :row)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
cell (locate-cell self)]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:row value})))))}
|
||||||
|
|
||||||
|
{:name "rowSpan"
|
||||||
|
:get #(-> % locate-cell :row-span)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
cell (locate-cell self)]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:row-span value})))))}
|
||||||
|
|
||||||
|
{:name "column"
|
||||||
|
:get #(-> % locate-cell :column)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
cell (locate-cell self)]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:column value})))))}
|
||||||
|
|
||||||
|
{:name "columnSpan"
|
||||||
|
:get #(-> % locate-cell :column-span)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
cell (locate-cell self)]
|
||||||
|
(when (us/safe-int? value)
|
||||||
|
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:column-span value})))))}
|
||||||
|
|
||||||
|
{:name "areaName"
|
||||||
|
:get #(-> % locate-cell :area-name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
cell (locate-cell self)]
|
||||||
|
(when (string? value)
|
||||||
|
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:area-name value})))))}
|
||||||
|
|
||||||
|
{:name "position"
|
||||||
|
:get #(-> % locate-cell :position d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
cell (locate-cell self)
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? ctl/grid-position-types value)
|
||||||
|
(st/emit! (dwsl/change-cells-mode (:parent-id shape) #{(:id cell)} value)))))}
|
||||||
|
|
||||||
|
{:name "alignSelf"
|
||||||
|
:get #(-> % locate-cell :align-self d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
value (keyword value)
|
||||||
|
cell (locate-cell self)]
|
||||||
|
(when (contains? ctl/grid-cell-align-self-types value)
|
||||||
|
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:align-self value})))))}
|
||||||
|
|
||||||
|
{:name "justifySelf"
|
||||||
|
:get #(-> % locate-cell :justify-self d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
value (keyword value)
|
||||||
|
cell (locate-cell self)]
|
||||||
|
(when (contains? ctl/grid-cell-justify-self-types value)
|
||||||
|
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:justify-self value})))))}))))
|
||||||
|
|
|
@ -7,71 +7,134 @@
|
||||||
(ns app.plugins.library
|
(ns app.plugins.library
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.record :as cr]
|
[app.common.record :as cr]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.utils :as utils :refer [get-data]]
|
[app.plugins.utils :as u]))
|
||||||
[app.util.object :as obj]))
|
|
||||||
|
|
||||||
(defn get-library-info
|
(deftype LibraryColorProxy [$file $id]
|
||||||
([self attr]
|
Object
|
||||||
(let [lib-id (get-data self :id)
|
|
||||||
current-file-id (:current-file-id @st/state)]
|
|
||||||
(if (= lib-id current-file-id)
|
|
||||||
(dm/get-in @st/state [:workspace-file attr])
|
|
||||||
(dm/get-in @st/state [:workspace-libraries lib-id attr]))))
|
|
||||||
|
|
||||||
([self attr mapfn]
|
(asFill [_]
|
||||||
(-> (get-library-info self attr)
|
(let [color (u/locate-library-color $file $id)]
|
||||||
(mapfn))))
|
(u/to-js
|
||||||
|
(d/without-nils
|
||||||
|
{:fill-color (:color color)
|
||||||
|
:fill-opacity (:opacity color)
|
||||||
|
:fill-color-gradient (:gradient color)
|
||||||
|
:fill-color-ref-file $file
|
||||||
|
:fill-color-ref-id $id
|
||||||
|
:fill-image (:image color)}))))
|
||||||
|
|
||||||
(defn get-library-data
|
(asStroke [_]
|
||||||
([self attr]
|
(let [color (u/locate-library-color $file $id)]
|
||||||
(let [lib-id (get-data self :id)
|
(u/to-js
|
||||||
current-file-id (:current-file-id @st/state)]
|
(d/without-nils
|
||||||
(if (= lib-id current-file-id)
|
{:stroke-color (:color color)
|
||||||
(dm/get-in @st/state [:workspace-data attr])
|
:stroke-opacity (:opacity color)
|
||||||
(dm/get-in @st/state [:workspace-libraries lib-id :data attr]))))
|
:stroke-color-gradient (:gradient color)
|
||||||
|
:stroke-color-ref-file $file
|
||||||
|
:stroke-color-ref-id $id
|
||||||
|
:stroke-image (:image color)
|
||||||
|
:stroke-style :solid
|
||||||
|
:stroke-alignment :inner})))))
|
||||||
|
|
||||||
([self attr mapfn]
|
(defn lib-color-proxy
|
||||||
(-> (get-library-data self attr)
|
[file-id id]
|
||||||
(mapfn))))
|
(assert (uuid? file-id))
|
||||||
|
(assert (uuid? id))
|
||||||
|
|
||||||
(defn- array-to-js
|
|
||||||
[value]
|
|
||||||
(.freeze
|
|
||||||
js/Object
|
|
||||||
(apply array (->> value (map utils/to-js)))))
|
|
||||||
|
|
||||||
(deftype Library [_data]
|
|
||||||
Object)
|
|
||||||
|
|
||||||
(defn create-library
|
|
||||||
[data]
|
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(Library. data)
|
(LibraryColorProxy. file-id id)
|
||||||
{:name "_data"
|
{:name "$file" :enumerable false}
|
||||||
:enumerable false}
|
{:name "$id" :enumerable false}
|
||||||
|
{:name "id" :get (fn [_] (dm/str id))}
|
||||||
{:name "id"
|
|
||||||
:get (fn [self]
|
|
||||||
(str (:id (obj/get self "_data"))))}
|
|
||||||
|
|
||||||
{:name "name"
|
{:name "name"
|
||||||
:get (fn [self]
|
:get #(-> % u/proxy->library-color :name)}
|
||||||
(get-library-info self :name))}
|
|
||||||
|
{:name "color"
|
||||||
|
:get #(-> % u/proxy->library-color :color)}
|
||||||
|
|
||||||
|
{:name "opacity"
|
||||||
|
:get #(-> % u/proxy->library-color :opacity)}
|
||||||
|
|
||||||
|
{:name "gradient"
|
||||||
|
:get #(-> % u/proxy->library-color :gradient u/to-js)}
|
||||||
|
|
||||||
|
{:name "image"
|
||||||
|
:get #(-> % u/proxy->library-color :image u/to-js)}))
|
||||||
|
|
||||||
|
(deftype LibraryTypographyProxy [$file $id]
|
||||||
|
Object)
|
||||||
|
|
||||||
|
(defn lib-typography-proxy
|
||||||
|
[file-id id]
|
||||||
|
(assert (uuid? file-id))
|
||||||
|
(assert (uuid? id))
|
||||||
|
|
||||||
|
(cr/add-properties!
|
||||||
|
(LibraryTypographyProxy. file-id id)
|
||||||
|
{:name "$file" :enumerable false}
|
||||||
|
{:name "$id" :enumerable false}
|
||||||
|
{:name "id" :get (fn [_] (dm/str id))}
|
||||||
|
{:name "name"
|
||||||
|
:get #(-> % u/proxy->library-typography :name)}))
|
||||||
|
|
||||||
|
(deftype LibraryComponentProxy [$file $id]
|
||||||
|
Object)
|
||||||
|
|
||||||
|
(defn lib-component-proxy
|
||||||
|
[file-id id]
|
||||||
|
(assert (uuid? file-id))
|
||||||
|
(assert (uuid? id))
|
||||||
|
|
||||||
|
(cr/add-properties!
|
||||||
|
(LibraryComponentProxy. file-id id)
|
||||||
|
{:name "$file" :enumerable false}
|
||||||
|
{:name "$id" :enumerable false}
|
||||||
|
{:name "id" :get (fn [_] (dm/str id))}
|
||||||
|
{:name "name"
|
||||||
|
:get #(-> % u/proxy->library-component :name)}))
|
||||||
|
|
||||||
|
(deftype Library [$id]
|
||||||
|
Object)
|
||||||
|
|
||||||
|
(defn library-proxy
|
||||||
|
[file-id]
|
||||||
|
(assert (uuid? file-id) "File id not valid")
|
||||||
|
|
||||||
|
(cr/add-properties!
|
||||||
|
(Library. file-id)
|
||||||
|
{:name "$file" :enumerable false}
|
||||||
|
|
||||||
|
{:name "id"
|
||||||
|
:get #(-> % u/proxy->file :id str)}
|
||||||
|
|
||||||
|
{:name "name"
|
||||||
|
:get #(-> % u/proxy->file :name)}
|
||||||
|
|
||||||
{:name "colors"
|
{:name "colors"
|
||||||
:get (fn [self]
|
:get
|
||||||
(array-to-js (get-library-data self :colors vals)))}
|
(fn [_]
|
||||||
|
(let [file (u/locate-file file-id)
|
||||||
|
colors (->> file :data :colors keys (map #(lib-color-proxy file-id %)))]
|
||||||
|
(apply array colors)))}
|
||||||
|
|
||||||
{:name "typographies"
|
{:name "typographies"
|
||||||
:get (fn [self]
|
:get
|
||||||
(array-to-js (get-library-data self :typographies vals)))}
|
(fn [_]
|
||||||
|
(let [file (u/locate-file file-id)
|
||||||
|
typographies (->> file :data :typographies keys (map #(lib-typography-proxy file-id %)))]
|
||||||
|
(apply array typographies)))}
|
||||||
|
|
||||||
{:name "components"
|
{:name "components"
|
||||||
:get (fn [self]
|
:get
|
||||||
(array-to-js (get-library-data self :components vals)))}))
|
(fn [_]
|
||||||
|
(let [file (u/locate-file file-id)
|
||||||
|
components (->> file :data :componentes keys (map #(lib-component-proxy file-id %)))]
|
||||||
|
(apply array components)))}))
|
||||||
|
|
||||||
(deftype PenpotLibrarySubcontext []
|
(deftype PenpotLibrarySubcontext []
|
||||||
Object
|
Object
|
||||||
|
@ -80,17 +143,15 @@
|
||||||
|
|
||||||
(find [_]))
|
(find [_]))
|
||||||
|
|
||||||
(defn create-library-subcontext
|
(defn library-subcontext
|
||||||
[]
|
[]
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(PenpotLibrarySubcontext.)
|
(PenpotLibrarySubcontext.)
|
||||||
{:name "local" :get
|
{:name "local" :get
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [file (get @st/state :workspace-file)
|
(library-proxy (:current-file-id @st/state)))}
|
||||||
data (get @st/state :workspace-data)]
|
|
||||||
(create-library (assoc file :data data))))}
|
|
||||||
|
|
||||||
{:name "connected" :get
|
{:name "connected" :get
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [libraries (get @st/state :workspace-libraries)]
|
(let [libraries (get @st/state :workspace-libraries)]
|
||||||
(apply array (->> libraries vals (map create-library)))))}))
|
(apply array (->> libraries vals (map library-proxy)))))}))
|
||||||
|
|
|
@ -13,14 +13,16 @@
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.text :as txt]
|
[app.common.text :as txt]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.main.data.workspace :as udw]
|
[app.main.data.workspace :as udw]
|
||||||
[app.main.data.workspace.changes :as dwc]
|
[app.main.data.workspace.changes :as dwc]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[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.store :as st]
|
[app.main.store :as st]
|
||||||
|
[app.plugins.flex :as flex]
|
||||||
[app.plugins.grid :as grid]
|
[app.plugins.grid :as grid]
|
||||||
[app.plugins.utils :as utils :refer [locate-shape proxy->shape array-to-js]]
|
[app.plugins.utils :as utils :refer [locate-objects locate-shape proxy->shape array-to-js]]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(declare shape-proxy)
|
(declare shape-proxy)
|
||||||
|
@ -62,7 +64,8 @@
|
||||||
;; Only for frames
|
;; Only for frames
|
||||||
(addFlexLayout
|
(addFlexLayout
|
||||||
[_]
|
[_]
|
||||||
(st/emit! (dwsl/create-layout-from-id $id :flex :from-frame? true :calculate-params? false)))
|
(st/emit! (dwsl/create-layout-from-id $id :flex :from-frame? true :calculate-params? false))
|
||||||
|
(grid/grid-layout-proxy $file $page $id))
|
||||||
|
|
||||||
(addGridLayout
|
(addGridLayout
|
||||||
[_]
|
[_]
|
||||||
|
@ -309,7 +312,27 @@
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (obj/get self "$id")
|
(let [id (obj/get self "$id")
|
||||||
value (mapv #(utils/from-js %) value)]
|
value (mapv #(utils/from-js %) value)]
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :strokes value)))))})
|
(st/emit! (dwc/update-shapes [id] #(assoc % :strokes value)))))}
|
||||||
|
|
||||||
|
{:name "layoutChild"
|
||||||
|
:get
|
||||||
|
(fn [self]
|
||||||
|
(let [file-id (obj/get self "$file")
|
||||||
|
page-id (obj/get self "$page")
|
||||||
|
id (obj/get self "$id")
|
||||||
|
objects (locate-objects file-id page-id)]
|
||||||
|
(when (ctl/any-layout-immediate-child-id? objects id)
|
||||||
|
(flex/layout-child-proxy file-id page-id id))))}
|
||||||
|
|
||||||
|
{:name "layoutCell"
|
||||||
|
:get
|
||||||
|
(fn [self]
|
||||||
|
(let [file-id (obj/get self "$file")
|
||||||
|
page-id (obj/get self "$page")
|
||||||
|
id (obj/get self "$id")
|
||||||
|
objects (locate-objects file-id page-id)]
|
||||||
|
(when (ctl/grid-layout-immediate-child-id? objects id)
|
||||||
|
(grid/layout-cell-proxy file-id page-id id))))})
|
||||||
|
|
||||||
(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!
|
||||||
|
@ -334,21 +357,40 @@
|
||||||
(when (= :grid layout)
|
(when (= :grid layout)
|
||||||
(grid/grid-layout-proxy file-id page-id id))))}
|
(grid/grid-layout-proxy file-id page-id id))))}
|
||||||
|
|
||||||
|
{:name "flex"
|
||||||
|
:get
|
||||||
|
(fn [self]
|
||||||
|
(let [layout (-> self proxy->shape :layout)
|
||||||
|
file-id (obj/get self "$file")
|
||||||
|
page-id (obj/get self "$page")
|
||||||
|
id (obj/get self "$id")]
|
||||||
|
(when (= :flex layout)
|
||||||
|
(flex/flex-layout-proxy file-id page-id id))))}
|
||||||
|
|
||||||
{:name "guides"
|
{:name "guides"
|
||||||
:get #(-> % proxy->shape :grids array-to-js)
|
:get #(-> % proxy->shape :grids array-to-js)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (obj/get self "$id")
|
(let [id (obj/get self "$id")
|
||||||
value (mapv #(utils/from-js %) value)]
|
value (mapv #(utils/from-js %) value)]
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :grids value)))))})
|
(st/emit! (dwc/update-shapes [id] #(assoc % :grids value)))))}
|
||||||
|
|
||||||
;; TODO: Flex properties
|
{:name "horizontalSizing"
|
||||||
#_(crc/add-properties!
|
:get #(-> % proxy->shape :layout-item-h-sizing (d/nilv :fix) d/name)
|
||||||
{:name "flex"
|
:set
|
||||||
:get
|
(fn [self value]
|
||||||
(fn [self]
|
(let [id (obj/get self "$id")
|
||||||
(let [layout (-> self proxy->shape :layout)]
|
value (keyword value)]
|
||||||
(when (= :flex layout)
|
(when (contains? #{:fix :auto} value)
|
||||||
(flex-layout-proxy (proxy->shape self)))))})))
|
(st/emit! (dwsl/update-layout #{id} {:layout-item-h-sizing value})))))}
|
||||||
|
|
||||||
|
{:name "verticalSizing"
|
||||||
|
:get #(-> % proxy->shape :layout-item-v-sizing (d/nilv :fix) d/name)
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? #{:fix :auto} value)
|
||||||
|
(st/emit! (dwsl/update-layout #{id} {:layout-item-v-sizing value})))))})))
|
||||||
|
|
||||||
(cond-> (not (cfh/frame-shape? data))
|
(cond-> (not (cfh/frame-shape? data))
|
||||||
(-> (obj/unset! "addGridLayout")
|
(-> (obj/unset! "addGridLayout")
|
||||||
|
|
|
@ -29,11 +29,30 @@
|
||||||
(assert (uuid? id) "Page not valid uuid")
|
(assert (uuid? id) "Page not valid uuid")
|
||||||
(dm/get-in (locate-file file-id) [:data :pages-index id]))
|
(dm/get-in (locate-file file-id) [:data :pages-index id]))
|
||||||
|
|
||||||
|
(defn locate-objects
|
||||||
|
[file-id page-id]
|
||||||
|
(:objects (locate-page file-id page-id)))
|
||||||
|
|
||||||
(defn locate-shape
|
(defn locate-shape
|
||||||
[file-id page-id id]
|
[file-id page-id id]
|
||||||
(assert (uuid? id) "Shape not valid uuid")
|
(assert (uuid? id) "Shape not valid uuid")
|
||||||
(dm/get-in (locate-page file-id page-id) [:objects id]))
|
(dm/get-in (locate-page file-id page-id) [:objects id]))
|
||||||
|
|
||||||
|
(defn locate-library-color
|
||||||
|
[file-id id]
|
||||||
|
(assert (uuid? id) "Color not valid uuid")
|
||||||
|
(dm/get-in (locate-file file-id) [:data :colors id]))
|
||||||
|
|
||||||
|
(defn locate-library-typography
|
||||||
|
[file-id id]
|
||||||
|
(assert (uuid? id) "Typography not valid uuid")
|
||||||
|
(dm/get-in (locate-file file-id) [:data :typographies id]))
|
||||||
|
|
||||||
|
(defn locate-library-component
|
||||||
|
[file-id id]
|
||||||
|
(assert (uuid? id) "Component not valid uuid")
|
||||||
|
(dm/get-in (locate-file file-id) [:data :components id]))
|
||||||
|
|
||||||
(defn proxy->file
|
(defn proxy->file
|
||||||
[proxy]
|
[proxy]
|
||||||
(let [id (obj/get proxy "$id")]
|
(let [id (obj/get proxy "$id")]
|
||||||
|
@ -52,6 +71,24 @@
|
||||||
id (obj/get proxy "$id")]
|
id (obj/get proxy "$id")]
|
||||||
(locate-shape file-id page-id id)))
|
(locate-shape file-id page-id id)))
|
||||||
|
|
||||||
|
(defn proxy->library-color
|
||||||
|
[proxy]
|
||||||
|
(let [file-id (obj/get proxy "$file")
|
||||||
|
id (obj/get proxy "$id")]
|
||||||
|
(locate-library-color file-id id)))
|
||||||
|
|
||||||
|
(defn proxy->library-typography
|
||||||
|
[proxy]
|
||||||
|
(let [file-id (obj/get proxy "$file")
|
||||||
|
id (obj/get proxy "$id")]
|
||||||
|
(locate-library-color file-id id)))
|
||||||
|
|
||||||
|
(defn proxy->library-component
|
||||||
|
[proxy]
|
||||||
|
(let [file-id (obj/get proxy "$file")
|
||||||
|
id (obj/get proxy "$id")]
|
||||||
|
(locate-library-color file-id id)))
|
||||||
|
|
||||||
(defn get-data
|
(defn get-data
|
||||||
([self attr]
|
([self attr]
|
||||||
(-> (obj/get self "_data")
|
(-> (obj/get self "_data")
|
||||||
|
@ -81,27 +118,35 @@
|
||||||
|
|
||||||
(defn from-js
|
(defn from-js
|
||||||
"Converts the object back to js"
|
"Converts the object back to js"
|
||||||
([obj]
|
[obj]
|
||||||
(from-js obj identity))
|
(when (some? obj)
|
||||||
([obj vfn]
|
(let [process-node
|
||||||
(let [ret (js->clj obj {:keyword-fn (fn [k] (str/camel (name k)))})]
|
(fn process-node [node]
|
||||||
(reduce-kv
|
(reduce-kv
|
||||||
(fn [m k v]
|
(fn [m k v]
|
||||||
(let [k (keyword (str/kebab k))
|
(let [k (keyword (str/kebab k))
|
||||||
v (cond (map? v)
|
v (cond (map? v)
|
||||||
(from-js v)
|
(process-node v)
|
||||||
|
|
||||||
|
(vector? v)
|
||||||
|
(mapv process-node v)
|
||||||
|
|
||||||
(and (string? v) (re-matches us/uuid-rx v))
|
(and (string? v) (re-matches us/uuid-rx v))
|
||||||
(uuid/uuid v)
|
(uuid/uuid v)
|
||||||
|
|
||||||
:else (vfn k v))]
|
(= k :type)
|
||||||
|
(keyword v)
|
||||||
|
|
||||||
|
:else v)]
|
||||||
(assoc m k v)))
|
(assoc m k v)))
|
||||||
{}
|
{}
|
||||||
ret))))
|
node))]
|
||||||
|
(process-node (js->clj obj)))))
|
||||||
|
|
||||||
(defn to-js
|
(defn to-js
|
||||||
"Converts to javascript an camelize the keys"
|
"Converts to javascript an camelize the keys"
|
||||||
[obj]
|
[obj]
|
||||||
|
(when (some? obj)
|
||||||
(let [result
|
(let [result
|
||||||
(reduce-kv
|
(reduce-kv
|
||||||
(fn [m k v]
|
(fn [m k v]
|
||||||
|
@ -111,7 +156,7 @@
|
||||||
(assoc m (str/camel (name k)) v)))
|
(assoc m (str/camel (name k)) v)))
|
||||||
{}
|
{}
|
||||||
obj)]
|
obj)]
|
||||||
(clj->js result)))
|
(clj->js result))))
|
||||||
|
|
||||||
(defn array-to-js
|
(defn array-to-js
|
||||||
[value]
|
[value]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue