0
Fork 0
mirror of https://github.com/penpot/penpot-exporter-figma-plugin.git synced 2024-12-21 21:23:06 -05:00
penpot-exporter-figma-plugin/DEV_GUIDE.md
Jordi Sala Morales 308fa93625
Update packages and add linters (#1)
* Configure linters

* Move to older eslint config, add stylelint, correct configuration for editorconfig

* simplify packages

* improve eslint config

* Fix typescript

* remove line

* github workflow

* package-lock.json

* lint fix

* make plugin compatible with Figma

* Add stylelint to ci

---------

Co-authored-by: Alex Sánchez <alejandro@runroom.com>
2024-04-08 11:43:30 +02:00

3.6 KiB

Developer guide

The plugin relies in penpot.js library. It contains a subset of Penpot frontend app, transpiled into javascript to be used from js code (this was easy since the frontend is written in ClojureScript, that has direct translation to javascript).

Basically, it exports the createFile function and the File data type, that represents a Penpot file as it resides in memory inside the frontend app. It has function to create pages and their content, and also an export function that generates and downloads a .zip archive with the Penpot file as svg documents in Penpot annotated format, that you can import directly into Penpot.

You can see the source of the library at Penpot repo.

To see a general description of the data types used in the functions you can see the data model. Their full specifications are in the common types module.

Those types are defined in Clojure spec format. For those unfamiliar with the syntax, here is a small basic guide:

(s/def ::name string?)
(s/def ::id uuid?)

A parameter or attribute called name is of type string, and id is an uuid string (e.g. "000498f3-27fc-8000-8988-ca7d52f46843").

(s/def ::stroke-alignment #{:center :inner :outer})

stroke-alignment is of an enumerated type, and the valid values are "center", "inner" and "outer".

(ns app.common.types.shape
  (:require
   [app.common.spec :as us]
   ...))

(s/def ::line-height ::us/safe-number)

line-height is of the type safe-number, defined in app.common.spec namespace, that here is imported with the name us (a safe number is a integer or floating point number, with a value not too big or small).

(s/def ::page
  (s/keys :req-un [::id ::name ::objects ::options]))

page is an object with four required arguments: id, name, objects and options, whose types have to be defined above.

(s/def ::column
  (s/keys :req-un [::color]
          :opt-un [::size
                   ::type
                   ::item-length
                   ::margin
                   ::gutter]))

column has one required attribute color and five optional ones size, type, item-length, margin and gutter.

(s/def ::children
  (s/coll-of ::content
             :kind vector?
             :min-count 1))

children is a collection (implemented as a vector) of objects of type content, and must have a minimun lenght of 1.

(defmulti animation-spec :animation-type)

(defmethod animation-spec :dissolve [_]
  (s/keys :req-un [::duration
                   ::easing]))

(defmethod animation-spec :slide [_]
  (s/keys :req-un [::duration
                   ::easing
                   ::way
                   ::direction
                   ::offset-effect]))

(defmethod animation-spec :push [_]
  (s/keys :req-un [::duration
                   ::easing
                   ::direction]))

(s/def ::animation
  (s/multi-spec animation-spec ::animation-type))

This is probably the most complex construct. animation is a multi schema object. It has an attribute called animation-type and the rest of the fields depend on its value. For example, if animation-type is "dissolve", the object must also have a duration and an easing attribute.

Other constructs should be more or less auto explicative with this guide and the clojure.spec manual linked above.