mirror of
https://github.com/penpot/penpot.git
synced 2025-08-01 16:38:35 +02:00
Merge pull request #6606 from penpot/niwinz-develop-fixes-2
✨ Fix several issues on penpot library
This commit is contained in:
commit
08aeb93710
18 changed files with 200 additions and 184 deletions
|
@ -10,15 +10,21 @@
|
||||||
(: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.features :as cfeat]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.files.changes :as ch]
|
[app.common.files.changes :as ch]
|
||||||
|
;; [app.common.features :as cfeat]
|
||||||
|
[app.common.files.helpers :as cph]
|
||||||
[app.common.files.migrations :as fmig]
|
[app.common.files.migrations :as fmig]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.svg :as csvg]
|
[app.common.svg :as csvg]
|
||||||
|
[app.common.time :as dt]
|
||||||
[app.common.types.color :as types.color]
|
[app.common.types.color :as types.color]
|
||||||
|
[app.common.types.component :as types.comp]
|
||||||
|
[app.common.types.container :as types.cont]
|
||||||
[app.common.types.file :as types.file]
|
[app.common.types.file :as types.file]
|
||||||
[app.common.types.page :as types.page]
|
[app.common.types.page :as types.page]
|
||||||
|
[app.common.types.path :as types.path]
|
||||||
[app.common.types.shape :as types.shape]
|
[app.common.types.shape :as types.shape]
|
||||||
[app.common.types.typography :as types.typography]
|
[app.common.types.typography :as types.typography]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
@ -293,7 +299,7 @@
|
||||||
|
|
||||||
(defn close-group
|
(defn close-group
|
||||||
[state]
|
[state]
|
||||||
(let [group-id (-> state :parent-stack peek)
|
(let [group-id (-> state ::parent-stack peek)
|
||||||
group (get-shape state group-id)
|
group (get-shape state group-id)
|
||||||
children (->> (get group :shapes)
|
children (->> (get group :shapes)
|
||||||
(into [] (keep (partial get-shape state)))
|
(into [] (keep (partial get-shape state)))
|
||||||
|
@ -329,6 +335,35 @@
|
||||||
(commit-change state change :add-container true)))]
|
(commit-change state change :add-container true)))]
|
||||||
(update state ::parent-stack pop))))
|
(update state ::parent-stack pop))))
|
||||||
|
|
||||||
|
(defn- update-bool-style-properties
|
||||||
|
[bool-shape objects]
|
||||||
|
(let [xform
|
||||||
|
(comp
|
||||||
|
(map (d/getf objects))
|
||||||
|
(remove cph/frame-shape?)
|
||||||
|
(remove types.comp/is-variant?)
|
||||||
|
(remove (partial types.cont/has-any-copy-parent? objects)))
|
||||||
|
|
||||||
|
children
|
||||||
|
(->> (get bool-shape :shapes)
|
||||||
|
(into [] xform)
|
||||||
|
(not-empty))]
|
||||||
|
|
||||||
|
(when-not children
|
||||||
|
(ex/raise :type :validation
|
||||||
|
:code :empty-children
|
||||||
|
:hint "expected a group with at least one shape for creating a bool"))
|
||||||
|
|
||||||
|
(let [head (if (= type :difference)
|
||||||
|
(first children)
|
||||||
|
(last children))
|
||||||
|
fills (if (and (contains? head :svg-attrs) (empty? (:fills head)))
|
||||||
|
types.path/default-bool-fills
|
||||||
|
(get head :fills))]
|
||||||
|
(-> bool-shape
|
||||||
|
(assoc :fills fills)
|
||||||
|
(assoc :stroks (get head :strokes))))))
|
||||||
|
|
||||||
(defn add-bool
|
(defn add-bool
|
||||||
[state params]
|
[state params]
|
||||||
(let [{:keys [group-id type]}
|
(let [{:keys [group-id type]}
|
||||||
|
@ -337,32 +372,40 @@
|
||||||
group
|
group
|
||||||
(get-shape state group-id)
|
(get-shape state group-id)
|
||||||
|
|
||||||
children
|
objects
|
||||||
(->> (get group :shapes)
|
(get-current-objects state)
|
||||||
(not-empty))]
|
|
||||||
|
|
||||||
(assert (some? children) "expect group to have at least 1 element")
|
bool
|
||||||
|
(-> group
|
||||||
|
(assoc :type :bool)
|
||||||
|
(assoc :bool-type type)
|
||||||
|
(update-bool-style-properties objects)
|
||||||
|
(types.path/update-bool-shape objects))
|
||||||
|
|
||||||
(let [objects (get-current-objects state)
|
selrect
|
||||||
bool (-> group
|
(get bool :selrect)
|
||||||
(assoc :type :bool)
|
|
||||||
(gsh/update-bool objects))
|
|
||||||
change {:type :mod-obj
|
|
||||||
:id (:id bool)
|
|
||||||
:operations
|
|
||||||
[{:type :set :attr :content :val (:content bool) :ignore-touched true}
|
|
||||||
{:type :set :attr :type :val :bool :ignore-touched true}
|
|
||||||
{:type :set :attr :bool-type :val type :ignore-touched true}
|
|
||||||
{:type :set :attr :selrect :val (:selrect bool) :ignore-touched true}
|
|
||||||
{:type :set :attr :points :val (:points bool) :ignore-touched true}
|
|
||||||
{:type :set :attr :x :val (-> bool :selrect :x) :ignore-touched true}
|
|
||||||
{:type :set :attr :y :val (-> bool :selrect :y) :ignore-touched true}
|
|
||||||
{:type :set :attr :width :val (-> bool :selrect :width) :ignore-touched true}
|
|
||||||
{:type :set :attr :height :val (-> bool :selrect :height) :ignore-touched true}]}]
|
|
||||||
|
|
||||||
(-> state
|
operations
|
||||||
(commit-change change :add-container true)
|
[{:type :set :attr :content :val (:content bool) :ignore-touched true}
|
||||||
(assoc ::last-id group-id)))))
|
{:type :set :attr :type :val :bool :ignore-touched true}
|
||||||
|
{:type :set :attr :bool-type :val type :ignore-touched true}
|
||||||
|
{:type :set :attr :selrect :val selrect :ignore-touched true}
|
||||||
|
{:type :set :attr :points :val (:points bool) :ignore-touched true}
|
||||||
|
{:type :set :attr :x :val (get selrect :x) :ignore-touched true}
|
||||||
|
{:type :set :attr :y :val (get selrect :y) :ignore-touched true}
|
||||||
|
{:type :set :attr :width :val (get selrect :width) :ignore-touched true}
|
||||||
|
{:type :set :attr :height :val (get selrect :height) :ignore-touched true}
|
||||||
|
{:type :set :attr :fills :val (:fills bool) :ignore-touched true}
|
||||||
|
{:type :set :attr :strokes :val (:strokes bool) :ignore-touched true}]
|
||||||
|
|
||||||
|
change
|
||||||
|
{:type :mod-obj
|
||||||
|
:id (:id bool)
|
||||||
|
:operations operations}]
|
||||||
|
|
||||||
|
(-> state
|
||||||
|
(commit-change change :add-container true)
|
||||||
|
(assoc ::last-id group-id))))
|
||||||
|
|
||||||
(defn add-shape
|
(defn add-shape
|
||||||
[state params]
|
[state params]
|
||||||
|
@ -533,6 +576,7 @@
|
||||||
:size (get blob :size)})
|
:size (get blob :size)})
|
||||||
(update ::file-media assoc id
|
(update ::file-media assoc id
|
||||||
{:id id
|
{:id id
|
||||||
|
:created-at (dt/now)
|
||||||
:name name
|
:name name
|
||||||
:width width
|
:width width
|
||||||
:height height
|
:height height
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
[app.common.types.grid :as ctg]
|
[app.common.types.grid :as ctg]
|
||||||
[app.common.types.page :as ctp]
|
[app.common.types.page :as ctp]
|
||||||
[app.common.types.pages-list :as ctpl]
|
[app.common.types.pages-list :as ctpl]
|
||||||
|
[app.common.types.path :as path]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
|
@ -744,7 +745,7 @@
|
||||||
group
|
group
|
||||||
|
|
||||||
(= :bool (:type group))
|
(= :bool (:type group))
|
||||||
(gsh/update-bool group objects)
|
(path/update-bool-shape group objects)
|
||||||
|
|
||||||
(:masked-group group)
|
(:masked-group group)
|
||||||
(->> (map lookup children)
|
(->> (map lookup children)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.types.component :as ctk]
|
[app.common.types.component :as ctk]
|
||||||
[app.common.types.file :as ctf]
|
[app.common.types.file :as ctf]
|
||||||
|
[app.common.types.path :as path]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.types.tokens-lib :as ctob]
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
@ -685,10 +686,10 @@
|
||||||
(empty? children) ;; a parent with no children will be deleted,
|
(empty? children) ;; a parent with no children will be deleted,
|
||||||
nil ;; so it does not need resize
|
nil ;; so it does not need resize
|
||||||
|
|
||||||
(= (:type parent) :bool)
|
(cfh/bool-shape? parent)
|
||||||
(gsh/update-bool parent objects)
|
(path/update-bool-shape parent objects)
|
||||||
|
|
||||||
(= (:type parent) :group)
|
(cfh/group-shape? parent)
|
||||||
;; FIXME: this functions should be
|
;; FIXME: this functions should be
|
||||||
;; normalized in the same way as
|
;; normalized in the same way as
|
||||||
;; update-bool in order to make all
|
;; update-bool in order to make all
|
||||||
|
|
|
@ -164,7 +164,6 @@
|
||||||
(dm/export gtr/calculate-geometry)
|
(dm/export gtr/calculate-geometry)
|
||||||
(dm/export gtr/update-group-selrect)
|
(dm/export gtr/update-group-selrect)
|
||||||
(dm/export gtr/update-mask-selrect)
|
(dm/export gtr/update-mask-selrect)
|
||||||
(dm/export gtr/update-bool)
|
|
||||||
(dm/export gtr/apply-transform)
|
(dm/export gtr/apply-transform)
|
||||||
(dm/export gtr/transform-shape)
|
(dm/export gtr/transform-shape)
|
||||||
(dm/export gtr/transform-selrect)
|
(dm/export gtr/transform-selrect)
|
||||||
|
|
|
@ -456,13 +456,6 @@
|
||||||
(assoc :flip-x (-> mask :flip-x))
|
(assoc :flip-x (-> mask :flip-x))
|
||||||
(assoc :flip-y (-> mask :flip-y)))))
|
(assoc :flip-y (-> mask :flip-y)))))
|
||||||
|
|
||||||
(defn update-bool
|
|
||||||
"Calculates the selrect+points for the boolean shape"
|
|
||||||
[shape objects]
|
|
||||||
(let [content (path/calc-bool-content shape objects)
|
|
||||||
shape (assoc shape :content content)]
|
|
||||||
(path/update-geometry shape)))
|
|
||||||
|
|
||||||
;; FIXME: revisit
|
;; FIXME: revisit
|
||||||
(defn update-shapes-geometry
|
(defn update-shapes-geometry
|
||||||
[objects ids]
|
[objects ids]
|
||||||
|
@ -477,7 +470,7 @@
|
||||||
(update-mask-selrect shape children)
|
(update-mask-selrect shape children)
|
||||||
|
|
||||||
(cfh/bool-shape? shape)
|
(cfh/bool-shape? shape)
|
||||||
(update-bool shape objects)
|
(path/update-bool-shape shape objects)
|
||||||
|
|
||||||
(cfh/group-shape? shape)
|
(cfh/group-shape? shape)
|
||||||
(update-group-selrect shape children)
|
(update-group-selrect shape children)
|
||||||
|
|
|
@ -22,6 +22,14 @@
|
||||||
|
|
||||||
#?(:clj (set! *warn-on-reflection* true))
|
#?(:clj (set! *warn-on-reflection* true))
|
||||||
|
|
||||||
|
(def ^:cosnt bool-group-style-properties bool/group-style-properties)
|
||||||
|
(def ^:const bool-style-properties bool/style-properties)
|
||||||
|
(def ^:const default-bool-fills bool/default-fills)
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; TRANSFORMATIONS
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn content?
|
(defn content?
|
||||||
[o]
|
[o]
|
||||||
(impl/path-data? o))
|
(impl/path-data? o))
|
||||||
|
@ -197,6 +205,13 @@
|
||||||
(-> (calc-bool-content* shape objects)
|
(-> (calc-bool-content* shape objects)
|
||||||
(impl/path-data)))
|
(impl/path-data)))
|
||||||
|
|
||||||
|
(defn update-bool-shape
|
||||||
|
"Calculates the selrect+points for the boolean shape"
|
||||||
|
[shape objects]
|
||||||
|
(let [content (calc-bool-content shape objects)
|
||||||
|
shape (assoc shape :content content)]
|
||||||
|
(update-geometry shape)))
|
||||||
|
|
||||||
(defn shape-with-open-path?
|
(defn shape-with-open-path?
|
||||||
[shape]
|
[shape]
|
||||||
(let [svg? (contains? shape :svg-attrs)
|
(let [svg? (contains? shape :svg-attrs)
|
||||||
|
|
|
@ -18,28 +18,13 @@
|
||||||
(def default-fills
|
(def default-fills
|
||||||
[{:fill-color clr/black}])
|
[{:fill-color clr/black}])
|
||||||
|
|
||||||
(def style-group-properties
|
(def group-style-properties
|
||||||
[:shadow :blur])
|
#{:shadow :blur})
|
||||||
|
|
||||||
|
;; FIXME: revisit
|
||||||
(def style-properties
|
(def style-properties
|
||||||
(into style-group-properties
|
(into group-style-properties
|
||||||
[:fill-color
|
[:fills :strokes]))
|
||||||
:fill-opacity
|
|
||||||
:fill-color-gradient
|
|
||||||
:fill-color-ref-file
|
|
||||||
:fill-color-ref-id
|
|
||||||
:fill-image
|
|
||||||
:fills
|
|
||||||
:stroke-color
|
|
||||||
:stroke-color-ref-file
|
|
||||||
:stroke-color-ref-id
|
|
||||||
:stroke-opacity
|
|
||||||
:stroke-style
|
|
||||||
:stroke-width
|
|
||||||
:stroke-alignment
|
|
||||||
:stroke-cap-start
|
|
||||||
:stroke-cap-end
|
|
||||||
:strokes]))
|
|
||||||
|
|
||||||
(defn add-previous
|
(defn add-previous
|
||||||
([content]
|
([content]
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.types.component :as ctc]
|
[app.common.types.component :as ctc]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
|
[app.common.types.path :as path]
|
||||||
[app.common.types.path.bool :as bool]
|
[app.common.types.path.bool :as bool]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
@ -35,7 +36,7 @@
|
||||||
head
|
head
|
||||||
(cond-> head
|
(cond-> head
|
||||||
(and (contains? head :svg-attrs) (empty? (:fills head)))
|
(and (contains? head :svg-attrs) (empty? (:fills head)))
|
||||||
(assoc :fills bool/default-fills))
|
(assoc :fills path/default-bool-fills))
|
||||||
|
|
||||||
shape
|
shape
|
||||||
{:id shape-id
|
{:id shape-id
|
||||||
|
@ -48,12 +49,26 @@
|
||||||
|
|
||||||
shape
|
shape
|
||||||
(-> shape
|
(-> shape
|
||||||
(merge (select-keys head bool/style-properties))
|
(merge (select-keys head path/bool-style-properties))
|
||||||
(cts/setup-shape)
|
(cts/setup-shape)
|
||||||
(gsh/update-bool objects))]
|
(path/update-bool-shape objects))]
|
||||||
|
|
||||||
[shape (cph/get-position-on-parent objects (:id head))]))
|
[shape (cph/get-position-on-parent objects (:id head))]))
|
||||||
|
|
||||||
|
(defn- group->bool
|
||||||
|
[type group objects]
|
||||||
|
(let [shapes (->> (:shapes group)
|
||||||
|
(map (d/getf objects)))
|
||||||
|
head (if (= type :difference) (first shapes) (last shapes))
|
||||||
|
head (cond-> head
|
||||||
|
(and (contains? head :svg-attrs) (empty? (:fills head)))
|
||||||
|
(assoc :fills path/default-bool-fills))]
|
||||||
|
(-> group
|
||||||
|
(assoc :type :bool)
|
||||||
|
(assoc :bool-type type)
|
||||||
|
(merge (select-keys head bool/style-properties))
|
||||||
|
(path/update-bool-shape objects))))
|
||||||
|
|
||||||
(defn create-bool
|
(defn create-bool
|
||||||
[type & {:keys [ids force-shape-id]}]
|
[type & {:keys [ids force-shape-id]}]
|
||||||
|
|
||||||
|
@ -101,20 +116,6 @@
|
||||||
(rx/of (dch/commit-changes changes)
|
(rx/of (dch/commit-changes changes)
|
||||||
(dws/select-shapes (d/ordered-set shape-id)))))))))
|
(dws/select-shapes (d/ordered-set shape-id)))))))))
|
||||||
|
|
||||||
(defn group->bool
|
|
||||||
[type group objects]
|
|
||||||
(let [shapes (->> (:shapes group)
|
|
||||||
(map (d/getf objects)))
|
|
||||||
head (if (= type :difference) (first shapes) (last shapes))
|
|
||||||
head (cond-> head
|
|
||||||
(and (contains? head :svg-attrs) (empty? (:fills head)))
|
|
||||||
(assoc :fills bool/default-fills))]
|
|
||||||
(-> group
|
|
||||||
(assoc :type :bool)
|
|
||||||
(assoc :bool-type type)
|
|
||||||
(merge (select-keys head bool/style-properties))
|
|
||||||
(gsh/update-bool objects))))
|
|
||||||
|
|
||||||
(defn group-to-bool
|
(defn group-to-bool
|
||||||
[shape-id type]
|
[shape-id type]
|
||||||
(ptk/reify ::group-to-bool
|
(ptk/reify ::group-to-bool
|
||||||
|
@ -130,7 +131,7 @@
|
||||||
(-> shape
|
(-> shape
|
||||||
(assoc :type :group)
|
(assoc :type :group)
|
||||||
(dissoc :bool-type)
|
(dissoc :bool-type)
|
||||||
(d/without-keys bool/style-group-properties)
|
(d/without-keys path/bool-group-style-properties)
|
||||||
(gsh/update-group-selrect
|
(gsh/update-group-selrect
|
||||||
(mapv (d/getf objects)
|
(mapv (d/getf objects)
|
||||||
(:shapes shape)))))
|
(:shapes shape)))))
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 1.0.2
|
||||||
|
|
||||||
|
- Fix incorrect boolean type assignation
|
||||||
|
- Fix fill and stroke handling on boolean shape creation
|
||||||
|
- Add sample-bool.js to the playground directory
|
||||||
|
- Fix compatibility issue on file media with penpot 2.7.x
|
||||||
|
|
||||||
## 1.0.1
|
## 1.0.1
|
||||||
|
|
||||||
- Make the library generate a .penpot file compatible with penpot 2.7.x
|
- Make the library generate a .penpot file compatible with penpot 2.7.x
|
||||||
|
|
|
@ -52,7 +52,7 @@ await penpot.exportStream(context, writable);
|
||||||
Build the library:
|
Build the library:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn run build
|
./scripts/build
|
||||||
```
|
```
|
||||||
|
|
||||||
Login on npm:
|
Login on npm:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@penpot/library",
|
"name": "@penpot/library",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"author": "Kaleidos INC",
|
"author": "Kaleidos INC",
|
||||||
"packageManager": "yarn@4.9.1+sha512.f95ce356460e05be48d66401c1ae64ef84d163dd689964962c6888a9810865e39097a5e9de748876c2e0bf89b232d583c33982773e9903ae7a76257270986538",
|
"packageManager": "yarn@4.9.1+sha512.f95ce356460e05be48d66401c1ae64ef84d163dd689964962c6888a9810865e39097a5e9de748876c2e0bf89b232d583c33982773e9903ae7a76257270986538",
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
import * as penpot from "#self";
|
|
||||||
import { createWriteStream } from 'fs';
|
|
||||||
import { Writable } from "stream";
|
|
||||||
|
|
||||||
// Example of creating component and instance out of order
|
|
||||||
|
|
||||||
(async function() {
|
|
||||||
const context = penpot.createBuildContext();
|
|
||||||
|
|
||||||
{
|
|
||||||
context.addFile({name: "Test File 1"});
|
|
||||||
context.addPage({name: "Foo Page"})
|
|
||||||
|
|
||||||
const mainBoardId = context.genId();
|
|
||||||
const mainRectId = context.genId();
|
|
||||||
|
|
||||||
// First create instance (just for with the purpose of teaching
|
|
||||||
// that it can be done, without putting that under obligation to
|
|
||||||
// do it in this order or the opposite)
|
|
||||||
|
|
||||||
context.addBoard({
|
|
||||||
name: "Board Instance 1",
|
|
||||||
x: 700,
|
|
||||||
y: 0,
|
|
||||||
width: 500,
|
|
||||||
height: 300,
|
|
||||||
shapeRef: mainBoardId,
|
|
||||||
touched: ["name-group"]
|
|
||||||
})
|
|
||||||
|
|
||||||
context.addRect({
|
|
||||||
name: "Rect Instance 1",
|
|
||||||
x: 800,
|
|
||||||
y: 20,
|
|
||||||
width:100,
|
|
||||||
height:200,
|
|
||||||
shapeRef: mainRectId,
|
|
||||||
touched: ["name-group"]
|
|
||||||
});
|
|
||||||
|
|
||||||
// this function call takes the current board from context, but it
|
|
||||||
// also can be passed as parameter on an explicit way if you
|
|
||||||
// prefer
|
|
||||||
context.addComponentInstance({
|
|
||||||
componentId: "00000000-0000-0000-0000-000000000001"
|
|
||||||
});
|
|
||||||
|
|
||||||
context.closeBoard();
|
|
||||||
|
|
||||||
// Then, create the main instance
|
|
||||||
context.addBoard({
|
|
||||||
id: mainBoardId,
|
|
||||||
name: "Board",
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: 500,
|
|
||||||
height: 300,
|
|
||||||
})
|
|
||||||
|
|
||||||
context.addRect({
|
|
||||||
id: mainRectId,
|
|
||||||
name: "Rect 1",
|
|
||||||
x: 20,
|
|
||||||
y: 20,
|
|
||||||
width:100,
|
|
||||||
height:200,
|
|
||||||
});
|
|
||||||
|
|
||||||
context.addComponent({
|
|
||||||
componentId: "00000000-0000-0000-0000-000000000001",
|
|
||||||
name: "Component 1",
|
|
||||||
});
|
|
||||||
|
|
||||||
context.closeBoard();
|
|
||||||
context.closeFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Create a file stream to write the zip to
|
|
||||||
const output = createWriteStream('sample-with-components.zip');
|
|
||||||
// Wrap Node's stream in a WHATWG WritableStream
|
|
||||||
const writable = Writable.toWeb(output);
|
|
||||||
await penpot.exportStream(context, writable);
|
|
||||||
}
|
|
||||||
|
|
||||||
})().catch((cause) => {
|
|
||||||
console.error(cause);
|
|
||||||
|
|
||||||
const causeExplain = cause.explain;
|
|
||||||
if (causeExplain) {
|
|
||||||
console.log("EXPLAIN:")
|
|
||||||
console.error(cause.explain);
|
|
||||||
}
|
|
||||||
|
|
||||||
// const innerCause = cause.cause;
|
|
||||||
// if (innerCause) {
|
|
||||||
// console.log("INNER:");
|
|
||||||
// console.error(innerCause);
|
|
||||||
// }
|
|
||||||
process.exit(-1);
|
|
||||||
}).finally(() => {
|
|
||||||
process.exit(0);
|
|
||||||
})
|
|
58
library/playground/sample-bool.js
Normal file
58
library/playground/sample-bool.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import * as penpot from "#self";
|
||||||
|
import { writeFile, readFile } from "fs/promises";
|
||||||
|
|
||||||
|
(async function () {
|
||||||
|
const context = penpot.createBuildContext();
|
||||||
|
|
||||||
|
{
|
||||||
|
context.addFile({ name: "Test File 1" });
|
||||||
|
context.addPage({ name: "Foo Page" });
|
||||||
|
|
||||||
|
const groupId = context.addGroup({
|
||||||
|
name: "Bool Group"
|
||||||
|
})
|
||||||
|
|
||||||
|
context.addRect({
|
||||||
|
name: "Rect 1",
|
||||||
|
x: 20,
|
||||||
|
y: 20,
|
||||||
|
width:100,
|
||||||
|
height:100,
|
||||||
|
});
|
||||||
|
|
||||||
|
context.addRect({
|
||||||
|
name: "Rect 2",
|
||||||
|
x: 90,
|
||||||
|
y: 90,
|
||||||
|
width:100,
|
||||||
|
height:100,
|
||||||
|
fills: [{fillColor: "#fabada", fillOpacity:1}]
|
||||||
|
});
|
||||||
|
|
||||||
|
context.closeGroup();
|
||||||
|
context.addBool({
|
||||||
|
groupId: groupId,
|
||||||
|
type: "union"
|
||||||
|
});
|
||||||
|
|
||||||
|
context.closeBoard();
|
||||||
|
context.closeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let result = await penpot.exportAsBytes(context);
|
||||||
|
await writeFile("sample-bool.zip", result);
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
.catch((cause) => {
|
||||||
|
console.error(cause);
|
||||||
|
|
||||||
|
const innerCause = cause.cause;
|
||||||
|
if (innerCause) {
|
||||||
|
console.error("Inner cause:", innerCause);
|
||||||
|
}
|
||||||
|
process.exit(-1);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
process.exit(0);
|
||||||
|
});
|
12
library/scripts/build
Executable file
12
library/scripts/build
Executable file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# NOTE: this script should be called from the parent directory to
|
||||||
|
# properly work.
|
||||||
|
|
||||||
|
export CURRENT_VERSION=$(node -p "require('./package.json').version");
|
||||||
|
export NODE_ENV=production;
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
yarn run build
|
||||||
|
|
||||||
|
sed -i -re "s/\%version\%/$CURRENT_VERSION/g" target/library/penpot.js
|
|
@ -41,6 +41,9 @@
|
||||||
(def ^:private encode-component
|
(def ^:private encode-component
|
||||||
(sm/encoder types.component/schema:component sm/json-transformer))
|
(sm/encoder types.component/schema:component sm/json-transformer))
|
||||||
|
|
||||||
|
(def encode-file-media
|
||||||
|
(sm/encoder types.file/schema:media sm/json-transformer))
|
||||||
|
|
||||||
(def encode-color
|
(def encode-color
|
||||||
(sm/encoder types.color/schema:color sm/json-transformer))
|
(sm/encoder types.color/schema:color sm/json-transformer))
|
||||||
|
|
||||||
|
@ -175,6 +178,7 @@
|
||||||
[(str "files/" (:file-id file-media) "/media/" file-media-id ".json")
|
[(str "files/" (:file-id file-media) "/media/" file-media-id ".json")
|
||||||
(delay (-> file-media
|
(delay (-> file-media
|
||||||
(dissoc :file-id)
|
(dissoc :file-id)
|
||||||
|
(encode-file-media)
|
||||||
(json/encode)))]))))))
|
(json/encode)))]))))))
|
||||||
|
|
||||||
(defn- generate-manifest-procs
|
(defn- generate-manifest-procs
|
||||||
|
@ -186,8 +190,7 @@
|
||||||
:features (:features file)})))
|
:features (:features file)})))
|
||||||
params {:type "penpot/export-files"
|
params {:type "penpot/export-files"
|
||||||
:version 1
|
:version 1
|
||||||
;; FIXME: set proper placeholder for replacement on build
|
:generated-by "penpot-library/%version%"
|
||||||
:generated-by "penpot-lib/develop"
|
|
||||||
:files files
|
:files files
|
||||||
:relations []}]
|
:relations []}]
|
||||||
["manifest.json" (delay (json/encode params))]))
|
["manifest.json" (delay (json/encode params))]))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue