mirror of
https://github.com/penpot/penpot.git
synced 2025-05-11 00:56:38 +02:00
📚 Merge penpot/penpot-docs repository
This commit is contained in:
parent
3932054ea6
commit
88296480ec
665 changed files with 17621 additions and 0 deletions
8
docs/plugins/api.md
Normal file
8
docs/plugins/api.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
layout: layouts/plugins.njk
|
||||
title: 4. API
|
||||
---
|
||||
|
||||
# Penpot plugins API
|
||||
|
||||
We've got all the documentation you need for the API right <a target="_blank" href="https://penpot-plugins-api-doc.pages.dev/">here</a>.
|
73
docs/plugins/beta-changelog.md
Normal file
73
docs/plugins/beta-changelog.md
Normal file
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
layout: layouts/plugins-no-sidebar.njk
|
||||
---
|
||||
|
||||
# Beta changelog
|
||||
|
||||
### <g-emoji class="g-emoji" alias="boom" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f680.png"><img class="emoji" alt="boom" height="20" width="20" src="https://github.githubassets.com/images/icons/emoji/unicode/1f680.png"></g-emoji> Epics and highlights</code>
|
||||
- This marks the release of version 1.0, and from this point forward, we’ll do our best to avoid making any more breaking changes (or make deprecations backward compatible).
|
||||
- We’ve redone the documentation. You can check the API here:
|
||||
[https://penpot-plugins-api-doc.pages.dev/](https://penpot-plugins-api-doc.pages.dev/)
|
||||
- New samples repository with lots of samples to use the API:
|
||||
[https://github.com/penpot/penpot-plugins-samples](https://github.com/penpot/penpot-plugins-samples)
|
||||
|
||||
### <g-emoji class="g-emoji" alias="boom" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f4a5.png"><img class="emoji" alt="boom" height="20" width="20" src="https://github.githubassets.com/images/icons/emoji/unicode/1f4a5.png"></g-emoji> Breaking changes & Deprecations
|
||||
|
||||
- Changed types names to remove the Penpot prefix. So for example: <code class="language-js">PenpotShape</code> becomes <code class="language-js">Shape</code>; <code class="language-js">PenpotFile</code> becomes <code class="language-js">File</code>, and so on. Check the [API documentation](https://penpot-plugins-api-doc.pages.dev/) for more details.
|
||||
- Changes on the <code class="language-js">penpot.on</code> and <code class="language-js">penpot.off</code> methods.
|
||||
Previously you had to send the original callback to the off method in order to remove an event listener. Now, <code class="language-js">penpot.on</code> will return an *id* that you can pass to the <code class="language-js">penpot.off</code> method in order to remove the listener.
|
||||
|
||||
Previously:
|
||||
```js
|
||||
penpot.on(‘pagechange’, myListener); // Register an event listener
|
||||
penpot.off(‘pagechange’, myListener); // Remove previously registered listener
|
||||
```
|
||||
|
||||
Now:
|
||||
```js
|
||||
const id = penpot.on(‘pagechange’, myListener);
|
||||
penpot.off(id);
|
||||
```
|
||||
|
||||
We’ve deprecated the old behavior in favor of the new one, this means that the behavior will work in the next version, but will be removed further down the line.
|
||||
|
||||
- Change some names to better align with the names in Penpot's UI.
|
||||
- type <code class="language-js">frame</code> is now <code class="language-js">board</code>:
|
||||
- <code class="language-js">PenpotFrame</code> is now <code class="language-js">Board</code>
|
||||
- <code class="language-js">penpot.createFrame</code> changed to <code class="language-js">penpot.createBoard</code>
|
||||
- <code class="language-js">shape.frameX</code> / <code class="language-js">shape.frameY</code> changed to<code class="language-js">shape.boardX</code> / <code class="language-js">shape.boardY</code>
|
||||
- <code class="language-js">PenpotFrameGuideX</code> now <code class="language-js">GuideX</code>
|
||||
- type<code class="language-js">rect</code> is <code class="language-js">rectangle</code>
|
||||
- <code class="language-js">PenpotRectangle</code> is now <code class="language-js">Rectangle</code>
|
||||
- type<code class="language-js">circle</code> is<code class="language-js">ellipse</code>
|
||||
- <code class="language-js">PenpotCircle</code> is now <code class="language-js">Ellipse</code>
|
||||
- <code class="language-js">penpot.createCircle</code> changed to <code class="language-js">penpot.createEllipse</code>
|
||||
- type<code class="language-js">bool</code> is<code class="language-js">boolean</code>
|
||||
- <code class="language-js">PenpotBool</code> is now <code class="language-js">Boolean</code>
|
||||
- Removed the following methods
|
||||
- <code class="language-js">getPage</code>, you can use now the property <code class="language-js">currentPage</code>
|
||||
- <code class="language-js">getFile</code>, you can use now the property <code class="language-js">currentFile</code>
|
||||
- <code class="language-js">getTheme</code>, you can use now the property <code class="language-js">theme</code>
|
||||
- <code class="language-js">getSelected</code>, you can use the property <code class="language-js">selection</code>
|
||||
- <code class="language-js">getSelectedShapes</code>, you can use the property <code class="language-js">selection</code>
|
||||
|
||||
### <g-emoji class="g-emoji" alias="sparkles" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2728.png"><img class="emoji" alt="sparkles" height="20" width="20" src="https://github.githubassets.com/images/icons/emoji/unicode/2728.png"></g-emoji> New features
|
||||
|
||||
- Support for comments
|
||||
- Support for export files
|
||||
- Support for undo blocks
|
||||
- Support for ruler guides
|
||||
- Support for prototype functionality access
|
||||
- New geometry utils:
|
||||
- shape.bounds
|
||||
- shape.center
|
||||
- New events
|
||||
- contentsave
|
||||
- shapechange
|
||||
- Adds property file.pages
|
||||
- Adds parent reference to shape
|
||||
- Add root shape reference to page
|
||||
- Add detach shape to component method
|
||||
- Adds method to createPage and openPage
|
||||
- Adds shape.visible property
|
||||
- Adds method penpot.viewport.zoomToShapes to change the viewport to the shapes.
|
277
docs/plugins/create-a-plugin.md
Normal file
277
docs/plugins/create-a-plugin.md
Normal file
|
@ -0,0 +1,277 @@
|
|||
---
|
||||
layout: layouts/plugins.njk
|
||||
title: 2. Create a Plugin
|
||||
---
|
||||
|
||||
# Create a Plugin
|
||||
|
||||
This guide covers the creation of a Penpot plugin. Penpot offers two ways to kickstart your development:
|
||||
|
||||
1. Using a Template:
|
||||
|
||||
- **Typescript template**: Using the <a target="_blank" href="https://github.com/penpot/penpot-plugin-starter-template">Penpot Plugin Starter Template</a>: A basic template with the required files for quickstarting your plugin. This template uses Typescript and Vite.
|
||||
- **Framework templates**: These templates already have everything you need to start <a target="_blank" href="https://github.com/penpot/plugin-examples">developing a plugin using a JavaScript framework. </a>
|
||||
|
||||
<p class="advice">
|
||||
In case you'll use any of these templates, you can skip to <a href="#2.7.-step-7.-load-the-plugin-in-penpot">step 2.7</a>
|
||||
</p>
|
||||
|
||||
2. Creating a plugin from scratch using a major framework.
|
||||
|
||||
Follow to the next section to understand how to bootstrap a new plugin using one of the three major JavaScript frameworks.
|
||||
|
||||
## 2.1. Step 1. Create a project
|
||||
|
||||
Create your own app with the framework of your choice. See examples for each framework <a target="_blank" href="https://github.com/penpot/plugin-examples"> here </a>
|
||||
|
||||
| Framework | Command | Version\* |
|
||||
| --------- | ----------------------------------------------------------- | --------- |
|
||||
| Angular | ng new plugin-name | 18.0.0 |
|
||||
| React | npm create vite@latest plugin-name -- --template react-ts | 18.2.0 |
|
||||
| Vue | npm create vue@latest | 3.4.21 |
|
||||
|
||||
_\*: version we used in the examples._
|
||||
|
||||
## 2.2. Step 2. Install Penpot libraries
|
||||
|
||||
There are two libraries that can help you with your plugin's development. They are <code class="language-js">@penpot/plugin-styles</code> and <code class="language-js">@penpot/plugin-types</code>.
|
||||
|
||||
### Plugin styles
|
||||
|
||||
<code class="language-js">@penpot/plugin-styles</code> contains styles to help build the UI for Penpot plugins. To check the styles go to <a target="_blank" href="https://penpot-plugins-styles.pages.dev/">Plugin styles</a>.
|
||||
|
||||
```bash
|
||||
npm install @penpot/plugin-styles
|
||||
```
|
||||
|
||||
You can add the styles to your global CSS file.
|
||||
|
||||
```css
|
||||
@import "@penpot/plugin-styles/styles.css";
|
||||
```
|
||||
|
||||
### Plugin types
|
||||
|
||||
<code class="language-js">@penpot/plugin-types</code> contains the typings for the Penpot Plugin API.
|
||||
|
||||
```bash
|
||||
npm install @penpot/plugin-types
|
||||
```
|
||||
|
||||
If you're using typescript, don't forget to add <code class="language-js">@penpot/plugin-types</code> to your typings in your <code class="language-js">tsconfig.json</code>.
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
[...]
|
||||
"typeRoots": ["./node_modules/@types", "./node_modules/@penpot"],
|
||||
"types": ["plugin-types"],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2.3. Step 3. Create a plugin file
|
||||
|
||||
A plugin file is needed to interact with Penpot and its API. You can use either javascript or typescript and it can be placed wherever you like. It normally goes alongside the main files inside the <code class="language-js">src/</code> folder. We highly recommend labeling your creation as <code class="language-js">plugin.js</code> or <code class="language-js">plugin.ts</code>, depending upon your preferred language.
|
||||
|
||||
You can start with something like this:
|
||||
|
||||
```ts
|
||||
penpot.ui.open("Plugin name", "", {
|
||||
width: 500,
|
||||
height: 600,
|
||||
});
|
||||
```
|
||||
|
||||
The sizing values are optional. By default, the plugin will open with a size of 285x540 pixels.
|
||||
|
||||
## 2.4. Step 4. Connect API and plugin interface
|
||||
|
||||
To enable interaction between your plugin and the Penpot API, you'll need to implement message-based communication using JavaScript events. This communication occurs between the main Penpot application and your plugin, which runs in an iframe. The <code class="language-js">window</code> object facilitates this communication by sending and receiving messages between the two.
|
||||
|
||||
### Sending messages from Penpot to your plugin
|
||||
|
||||
To send a message from the Penpot API to your plugin interface, use the following command in <code class="language-js">plugin.ts</code>:
|
||||
|
||||
```js
|
||||
penpot.ui.sendMessage(message);
|
||||
```
|
||||
|
||||
Here, <code class="language-js">message</code> can be any data or instruction you want to pass to your plugin. This message is dispatched from Penpot and is received by your plugin's iframe.
|
||||
|
||||
### Receiving Messages in Your Plugin Interface
|
||||
|
||||
Your plugin can capture incoming messages from Penpot using the <code class="language-js">window</code> object's <code class="language-js">message</code> event. To do this, set up an event listener in your plugin like this:
|
||||
|
||||
```js
|
||||
window.addEventListener("message", (event) => {
|
||||
// Handle the incoming message
|
||||
console.log(event.data);
|
||||
});
|
||||
```
|
||||
|
||||
The<code class="language-js">event.data</code> object contains the message sent from Penpot. You can use this data to update your plugin's interface or trigger specific actions within your plugin.
|
||||
|
||||
### Two-Way Communication
|
||||
|
||||
This setup allows for two-way communication between Penpot and your plugin. Penpot can send messages to your plugin, and your plugin can respond or send messages back to Penpot using the same<code class="language-js">postMessage</code> API. For example:
|
||||
|
||||
```js
|
||||
// Sending a message back to Penpot from your plugin
|
||||
parent.postMessage(responseMessage, targetOrigin);
|
||||
```
|
||||
|
||||
-<code class="language-js">responseMessage</code> is the data you want to send back to Penpot.
|
||||
-<code class="language-js">targetOrigin</code> should be the origin of the Penpot application to ensure messages are only sent to the intended recipient. You can use<code class="language-js">'*'</code> to allow all.
|
||||
|
||||
### Summary
|
||||
|
||||
By using these message-based events, any data retrieved through the Penpot API can be communicated to and from your plugin interface seamlessly.
|
||||
|
||||
For more detailed information, refer to the [Penpot Plugins API Documentation](https://penpot-plugins-api-doc.pages.dev/).
|
||||
|
||||
## 2.5. Step 5. Build the plugin file
|
||||
|
||||
<div class="advice">
|
||||
<p>This step is only for local serving.
|
||||
For a detailed guide about building and deploying you can check the documentation at <a target="_blank" href="/plugins/deployment/">Deployment</a> </p>
|
||||
<p>You can skip this step if working exclusively with JavaScript by simply moving <code class="language-text">plugin.js</code> to your <code class="language-text">public/</code> directory.</p>
|
||||
</div>
|
||||
|
||||
If you wish to run your plugin locally and test it live you need to make your plugin file reachable. Right now, your <code class="language-js">plugin.ts</code> file is somewhere in the <code class="language-js">src/</code> folder, and you can't access it through <code class="language-js">http:\/\/localhost:XXXX/plugin.js</code>.
|
||||
|
||||
You can achieve this through multiple solutions, but we offer two simple ways of doing so. Of course, you can come up with your own.
|
||||
|
||||
#### Vite
|
||||
|
||||
If you're using Vite you can simply edit the configuration file and add the build to your <code class="language-js">vite.config.ts</code>.
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
[...]
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
plugin: "src/plugin.ts",
|
||||
index: "./index.html",
|
||||
},
|
||||
output: {
|
||||
entryFileNames: "[name].js",
|
||||
},
|
||||
},
|
||||
},
|
||||
preview: {
|
||||
port: XXXX,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
And then add the following scripts to your <code class="language-js">package.json</code>:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"dev": "vite build --watch & vite preview",
|
||||
"build": "tsc && vite build",
|
||||
[...]
|
||||
}
|
||||
```
|
||||
|
||||
#### Esbuild
|
||||
|
||||
```bash
|
||||
$ npm i -D esbuild # install as dev dependency
|
||||
```
|
||||
|
||||
Now you can use esbuild to parse and move your plugin file.
|
||||
|
||||
```bash
|
||||
esbuild your-folder/plugin.ts --minify --outfile=your-folder/public/plugin.js
|
||||
```
|
||||
|
||||
You can add it to your <code class="language-js">package.json</code> scripts so you don't need to manually re-run the build:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"start": "npm run build:plugin && ng serve",
|
||||
"build:plugin": "esbuild your-folder/plugin.ts --minify --outfile=your-folder/public/plugin.js"
|
||||
[...]
|
||||
},
|
||||
```
|
||||
|
||||
Keep in mind that you'll need to build again your plugin file if you modify it mid-serve.
|
||||
|
||||
## 2.6. Step 6. Configure the manifest file
|
||||
|
||||
Now that everything is in place you need a <code class="language-js">manifest.json</code> file to provide Penpot with your plugin data. Remember to make it reachable by placing it in the <code class="language-js">public/</code> folder.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Plugin name",
|
||||
"description": "Plugin description",
|
||||
"code": "/plugin.js",
|
||||
"icon": "/icon.png",
|
||||
"permissions": [
|
||||
"content:read",
|
||||
"content:write",
|
||||
"library:read",
|
||||
"library:write",
|
||||
"user:read",
|
||||
"comment:read",
|
||||
"comment:write",
|
||||
"allow:downloads"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Icon
|
||||
|
||||
The plugin icon must be an image file. All image formats are valid, so you can use whichever format works best for your needs. Although there is no specific size requirement, it is recommended that the icon be 56x56 pixels in order to ensure its optimal appearance across all devices.
|
||||
|
||||
### Types of permissions
|
||||
|
||||
- <code class="language-js">content:read</code>: Allows reading of content-related data. Grants read access to all endpoints and operations dealing with content. Typical use cases: viewing shapes, pages, or other design elements in a project; accessing the properties and settings of content within the application.
|
||||
|
||||
- <code class="language-js">content:write</code>: Allows writing or modifying content-related data. Grants write access to all endpoints and operations dealing with content modifications, except those marked as read-only. Typical use cases: adding, updating, or deleting shapes and elements in a design; uploading media or other assets to the project.
|
||||
|
||||
- <code class="language-js">user:read</code>: Allows reading of user-related data. Grants read access to all endpoints and operations dealing with user data. Typical use cases: viewing user profiles and their associated information or listing active users in a particular context or project.
|
||||
|
||||
- <code class="language-js">library:read</code>: Allows reading of library-related data and assets. Grants read access to all endpoints and operations dealing with the library context. Typical use cases: accessing shared design elements and components from a library or viewing the details and properties of library assets.
|
||||
|
||||
- <code class="language-js">library:write</code>: Allows writing or modifying library-related data and assets. Grants write access to all endpoints and operations dealing with library modifications. Typical use cases: adding new components or assets to the library or updating or removing existing library elements.
|
||||
|
||||
- <code class="language-js">comment:read</code>: Allows reading of comment-related data. Grants read access to all endpoints and operations dealing with comments.
|
||||
Typical use cases: viewing comments on pages; accessing feedback or annotations provided by collaborators in the project.
|
||||
|
||||
- <code class="language-js">comment:write</code>: Allows writing or modifying comment-related data. Grants write access to all endpoints and operations dealing with creating, replying, or deleting comments.
|
||||
Typical use cases: adding new comments to pages; deleting existing comments; replying to comments within the project's context.
|
||||
|
||||
- <code class="language-js">allow:downloads</code>: Allows downloading of the project file. Grants access to endpoints and operations that enable the downloading of the entire project file.
|
||||
Typical use cases: downloading the full project file for backup or sharing.
|
||||
|
||||
_Note: Write permissions automatically includes its corresponding read permission (e.g.,<code class="language-js">content:write</code> includes <code class="language-js">content:read</code>) because reading is required to perform write or modification actions._
|
||||
|
||||
## 2.7. Step 7. Load the Plugin in Penpot
|
||||
|
||||
<p class="advice"><b>Serving an application:</b> This refers to making your application accessible over a network, typically for testing or development purposes. <br><br>When using a tool like <a href="https://www.npmjs.com/package/live-server" target="_blank">live-server</a>, a local web server is created on your machine, which serves your application files over HTTP. Most modern frameworks offer their own methods for serving applications, and there are build tools like Vite and Webpack that can handle this process as well. </p>
|
||||
|
||||
**You don't need to deploy your plugin just to test it**. Locally serving your plugin is compatible with <code class="language-js">https:\/\/penpot.app/</code>. However, be mindful of potential CORS (Cross-Origin Resource Sharing) issues. To avoid these, ensure your plugin includes the appropriate cross-origin headers. (Find more info about this at the <a target="_blank" href="/plugins/deployment/">Deployment step</a>)
|
||||
|
||||
Serving your plugin will generate a URL that looks something like <code class="language-js">http:\/\/localhost:XXXX</code>, where <code class="language-js">XXXX</code> represents the port number on which the plugin is served. Ensure that both <code class="language-js">http:\/\/localhost:XXXX/manifest.json</code> and <code class="language-js">http:\/\/localhost:XXXX/plugin.js</code> are accessible. If these files are inside a specific folder, the URL should be adjusted accordingly (e.g., <code class="language-js">http:\/\/localhost:XXXX/folder/manifest.json</code>).
|
||||
|
||||
Once your plugin is served you are ready to load it into Penpot. You can use the shortcut <code class="language-js">Ctrl + Alt + P</code> to open the Plugin Manager modal. In this modal, provide the URL to your plugin's manifest file (e.g., <code class="language-js">http:\/\/localhost:XXXX/manifest.json</code>) for installation. If everything is set up correctly, the plugin will be installed, and you can launch it whenever needed.
|
||||
|
||||
You can also open the Plugin manager modal via:
|
||||
|
||||
- Menu
|
||||
<figure>
|
||||
<video title="Open plugin manager from penpot menu" muted="" playsinline="" controls="" width="100%" poster="/img/plugins/plugins-menu.png" height="auto">
|
||||
<source src="/img/plugins/plugins-menu.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
- Toolbar
|
||||
<figure>
|
||||
<video title="Open plugin manager from penpot toolbar" muted="" playsinline="" controls="" width="100%" poster="/img/plugins/plugins-toolbar.png" height="auto">
|
||||
<source src="/img/plugins/plugins-toolbar.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
218
docs/plugins/deployment.md
Normal file
218
docs/plugins/deployment.md
Normal file
|
@ -0,0 +1,218 @@
|
|||
---
|
||||
layout: layouts/plugins.njk
|
||||
title: 3. Deployment
|
||||
---
|
||||
|
||||
# Deployment
|
||||
|
||||
When it comes to deploying your plugin there are several platforms to choose from. Each platform has its unique features and benefits, so the choice depends on you.
|
||||
|
||||
In this guide you will found some options for static sites that have free plans.
|
||||
|
||||
## 3.1. Building your project
|
||||
|
||||
The building may vary between frameworks but if you had previously configured your scripts in <code class="language-bash">package.json</code>, <code class="language-bash">npm run build</code> should work.
|
||||
|
||||
The resulting build should be located somewhere in the <code class="language-bash">dist/</code> folder, maybe somewhere else if you have configured so.
|
||||
|
||||
Be wary that some framework's builders can add additional folders like <code class="language-bash">apps/project-name/</code>, <code class="language-bash">project-name/</code> or <code class="language-bash">browser/</code>.
|
||||
|
||||
Examples:
|
||||
|
||||

|
||||

|
||||
|
||||
## 3.2. Netlify
|
||||
|
||||
### Create an account
|
||||
|
||||
You need a Netlify account if you don't already have one. You can <a target="_blank" href="https://app.netlify.com/signup">sign up</a> with Github, GItlab, BItbucket or via email and password.
|
||||
|
||||
### CORS issues
|
||||
|
||||
To avoid these issues you can add a <code class="language-bash">_headers</code> file to your plugin. Place it in the <code class="language-bash">public/</code> folder or alongside the main files.
|
||||
|
||||
```js
|
||||
/*
|
||||
Access-Control-Allow-Origin: *
|
||||
```
|
||||
|
||||
### Connect to Git
|
||||
|
||||
Netlify allows you to import an existing project from GitHub, GitLab, Bitbucket or Azure DevOps.
|
||||
|
||||
- <a target="_blank" href="https://docs.netlify.com/configure-builds/overview/">Configure builds</a>.
|
||||
|
||||
#### How to deploy
|
||||
|
||||
<figure>
|
||||
<video title="Deploy your plugin with Netlify using GitHub" muted="" playsinline="" controls="" width="100%" poster="/img/plugins/deploy-netlify-repo.png" height="auto">
|
||||
<source src="/img/plugins/deploy-netlify-repo.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
1. Go to <a target="_blank" href="https://app.netlify.com/start">Start</a> and connect with your repository. Allow Netlify to be installed in either all your projects or just the selected ones.
|
||||
|
||||

|
||||
|
||||
2. Configure your build settings. Netlify auto-detects your framework and offers a basic configuration. This is usually enough.
|
||||
|
||||

|
||||
|
||||
3. Deploy your plugin.
|
||||
|
||||
### Drag and drop
|
||||
|
||||
Netlify offers a simple drag and drop method. Check <a target="_blank" href="https://app.netlify.com/drop">Netlify Drop</a>.
|
||||
|
||||
#### How to deploy
|
||||
|
||||
<figure>
|
||||
<video title="Deploy your plugin with Netlify using drag and drop" muted="" playsinline="" controls="" width="100%" poster="/img/plugins/deploy-netlify-dragdrop.png" height="auto">
|
||||
<source src="/img/plugins/deploy-netlify-dragdrop.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
1. Build your project
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
2. Go to <a target="_blank" href="https://app.netlify.com/drop">Netlify Drop</a>.
|
||||
|
||||
3. Drag and drop the build folder into Netlify Sites. Dropping the whole dist may not work, you should drop the folder where the main files are located.
|
||||
|
||||
4. Done!
|
||||
|
||||
## 3.3. Cloudflare
|
||||
|
||||
### Create an account
|
||||
|
||||
You need a Cloudflare account if you don't already have one. You can <a target="_blank" href="https://dash.cloudflare.com/sign-up">sign up</a> via email and password.
|
||||
|
||||
### CORS issues
|
||||
|
||||
To avoid these issues you can add a <code class="language-bash">_headers</code> file to your plugin. Place it in the <code class="language-bash">public/</code> folder or alongside the main files.
|
||||
|
||||
```js
|
||||
/*
|
||||
Access-Control-Allow-Origin: *
|
||||
```
|
||||
|
||||
### Connect to Git
|
||||
|
||||
Cloudflare allows you to import an existing project from GitHub or GitLab.
|
||||
|
||||
- <a target="_blank" href="https://developers.cloudflare.com/pages/get-started/git-integration/">Git integration</a>
|
||||
|
||||
#### How to deploy
|
||||
|
||||
<figure>
|
||||
<video title="Deploy your plugin with Cloudflare using GitHub" muted="" playsinline="" controls="" width="100%" poster="/img/plugins/deploy-cloudflare-repo.png" height="auto">
|
||||
<source src="/img/plugins/deploy-cloudflare-repo.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
|
||||
1. Go to Workers & Pages > Create > Page > Connect to git
|
||||
|
||||
2. Select a repository. Allow Cloudflare to be installed in either all your projects or just the selected ones.
|
||||
|
||||

|
||||
|
||||
4. Configure your build settings.
|
||||
|
||||

|
||||
|
||||
5. Save and deploy.
|
||||
|
||||
### Direct upload
|
||||
|
||||
You can directly upload your plugin folder.
|
||||
|
||||
- <a target="_blank" href="https://developers.cloudflare.com/pages/get-started/direct-upload/">Direct upload</a>
|
||||
|
||||
#### How to deploy
|
||||
|
||||
<figure>
|
||||
<video title="Deploy your plugin with Cloudflare using drag and drop" muted="" playsinline="" controls="" width="100%" poster="/img/plugins/deploy-netlify-dragdrop.png" height="auto">
|
||||
<source src="/img/plugins/deploy-netlify-dragdrop.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
1. Build your plugin.
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
2. Go to Workers & Pages > Create > Page > Upload assets.
|
||||
|
||||
3. Create a new page.
|
||||
|
||||

|
||||
|
||||
4. Upload your plugin files. You can drag and drop or select the folder.
|
||||
|
||||

|
||||
|
||||
5. Deploy site.
|
||||
|
||||
## 3.4. Surge
|
||||
|
||||
Surge provides a CLI tool for easy deployment.
|
||||
|
||||
- <a target="_blank" href="https://surge.sh/help/getting-started-with-surge">Getting Started</a>.
|
||||
|
||||
### CORS issues
|
||||
|
||||
To avoid these issues you can add a <code class="language-bash">CORS</code> file to your plugin. Place it in the <code class="language-bash">public/</code> folder or alongside the main files.
|
||||
|
||||
The <code class="language-bash">CORS</code> can contain a <code class="language-bash">*</code> for any domain, or a list of specific domains.
|
||||
|
||||
Check <a target="_blank" href="https://surge.sh/help/enabling-cross-origin-resource-sharing">Enabling Cross-Origin Resources sharing</a>.
|
||||
|
||||
### How to deploy
|
||||
|
||||
1. Install surge CLI globally and log into your account or create one.
|
||||
|
||||
```bash
|
||||
npm install --global surge
|
||||
surge login
|
||||
# or
|
||||
surge signup
|
||||
```
|
||||
|
||||
2. Create a CORS file to allow all sites.
|
||||
|
||||
```bash
|
||||
echo '*' > public/CORS
|
||||
```
|
||||
|
||||
3. Build your project.
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
4. Start surge deployment
|
||||
|
||||
```bash
|
||||
surge
|
||||
|
||||
# Your plugin build folder
|
||||
project: /home/user/example-plugin/dist/
|
||||
|
||||
# your domain, surge offers a free .surge.sh domain and free ssl
|
||||
domain: https://example-plugin-penpot.surge.sh
|
||||
|
||||
upload: [====================] 100% eta: 0.0s (10 files, 305761 bytes)
|
||||
CDN: [====================] 100%
|
||||
encryption: *.surge.sh, surge.sh (346 days)
|
||||
IP: XXX.XXX.XXX.XXX
|
||||
|
||||
Success! - Published to example-plugin-penpot.surge.sh
|
||||
```
|
||||
|
||||
5. Done!
|
128
docs/plugins/examples-templates.md
Normal file
128
docs/plugins/examples-templates.md
Normal file
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
layout: layouts/plugins.njk
|
||||
title: 5. Examples and templates
|
||||
---
|
||||
|
||||
# Examples and templates
|
||||
|
||||
## 5.1. Examples
|
||||
|
||||
We've put together a handy list of some of the most common actions you can perform in penpot, and we've also included a helpful example for each one. We hope this makes it easier for you to create your plugins!
|
||||
|
||||
<p class="advice">
|
||||
If you just want to get to the examples, you can go straight to the repository <a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main">here</a>
|
||||
</p>
|
||||
|
||||
### Create a shape
|
||||
|
||||
One of the most basic things you can do in design is create a shape. It's really simple. In this example, we'll show you how to make a rectangle, but you can use the same principles to make other shapes. This makes it easy for you to add different shapes to your design, which is great for building more complex elements and layouts.
|
||||
|
||||
```js
|
||||
// just replace
|
||||
penpot.createRectangle();
|
||||
|
||||
// for one of these other options:
|
||||
penpot.createEllipse();
|
||||
penpot.createPath();
|
||||
penpot.createBoard();
|
||||
```
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/create-shape">Shape example</a>
|
||||
|
||||
### Create a text
|
||||
|
||||
You'll learn how to insert text and explore a variety of styling options to customize it to your exact preferences. You'll discover how to adjust font, size, color, and more to create visually engaging text elements. You can also apply multiple styles within a single text string by styling different sections individually, giving you even greater control over your text design and allowing for creative, dynamic typographic effects.
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/create-text">Text example</a>
|
||||
|
||||
### Group and ungroup shapes
|
||||
|
||||
It's really important to keep your layers organized if you want to keep your workflow clean and efficient. Grouping shapes together makes it much easier to manage and manipulate multiple elements as a single unit. This not only makes your design process much more streamlined, but it also helps you maintain a structured and organized layer hierarchy. When you need to make individual adjustments, you can easily ungroup these shapes, which gives you flexibility while keeping your workspace tidy and well-organized.
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/group-ungroup">Group and ungroup example</a>
|
||||
|
||||
### Create flex layout
|
||||
|
||||
Flex Layout makes it simple to create designs that adapt and respond to different screens and devices. It automatically adjusts the positioning and sizing of content and containers, so you can resize, align, and distribute elements without any manual intervention.
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/create-flexlayout">Flex layout example</a>
|
||||
|
||||
### Create grid layout
|
||||
|
||||
Grid Layout lets you create flexible designs that automatically adapt to different screen sizes and content changes. You can easily resize, fit, and fill content and containers with this feature, so you don't have to make manual adjustments and you get a seamless, responsive design experience.
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/create-gridlayout">Grid layout example</a>
|
||||
|
||||
### Create a component
|
||||
|
||||
Using components is a great way to reuse objects or groups of objects, making sure everything looks the same and works well across your designs. This example shows you how to create a component, which lets you make your workflow easier by defining reusable design elements.
|
||||
|
||||
<p class="advice">
|
||||
Just a friendly reminder that it's important to have the <b>library permissions</b> in the <code class="language-bash">manifest.json</code>.
|
||||
</p>
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/components-library">Components example</a>
|
||||
|
||||
### Create a colors library
|
||||
|
||||
Having quick access to your go-to colors and fonts can really help you work more efficiently, letting you build a solid set of assets with minimal effort. In this example, you'll see how to add a color to your library, so you'll have instant access whenever you need it. The same goes for typography assets—just replace createColor with createTypography. This flexibility means your most commonly used design elements are always at your fingertips, ready to enhance your creative workflow.
|
||||
|
||||
<p class="advice">
|
||||
Just a friendly reminder that it's important to have the <b>library permissions</b> in the <code class="language-bash">manifest.json</code>.
|
||||
</p>
|
||||
|
||||
```js
|
||||
// just replace
|
||||
penpot.library.local.createColor();
|
||||
|
||||
// for
|
||||
penpot.library.local.createTypography();
|
||||
```
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/colors-library">Colors library example</a>
|
||||
|
||||
### Theme
|
||||
|
||||
Penpot has dark and light modes, and you can easily add this to your plugin so your interface adapts to both themes. When you add theme support, your plugin will automatically sync with Penpot's interface settings, so the user experience is consistent no matter which mode is selected. This makes your plugin look better and also ensures it stays in line with Penpot's overall design.
|
||||
|
||||
Just a heads-up: if you use the <a target="_blank" href="https://penpot-plugins-styles.pages.dev/">plugin-styles library</a>, many elements will automatically adapt to dark or light mode without any extra effort from you. However, if you need to customize specific elements, be sure to use the selectors provided in the <code class="language-bash">styles.css</code> of the example.
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/theme">Theme example</a>
|
||||
|
||||
### Use of third party API
|
||||
|
||||
Often, we want to make our plugins better by adding external libraries, new features, and functionalities. Here's an example of how to use the Picsum library. It shows how you can use third-party APIs to make your plugin development better. Use this as a reference to explore how you can add external resources to your projects.
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/third-party-api">Third party API example</a>
|
||||
|
||||
### Interactive prototype
|
||||
|
||||
With the ability to create an interactive prototype, you can turn your design from a static layout into a dynamic, navigable experience. This lets users interact with the design in a more seamless way and gives them a better preview of the final product.
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/create-interactive-prototype">Interactive prototype example</a>
|
||||
|
||||
### Add ruler guides
|
||||
|
||||
Ruler guides are great for aligning elements exactly where you want them. Check out how to add horizontal and vertical guides to your page or boards. This makes it easier to keep your design looking the same from one place to the next.
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/create-ruler-guides">Ruler guides example</a>
|
||||
|
||||
### Create a comment
|
||||
|
||||
Comments are a great way for designers and team members to give each other feedback on a design right away. This example shows how to add comments to specific parts of a design, which makes it easier for everyone to work together and improve their workflow.
|
||||
|
||||
<p class="advice">
|
||||
Just a friendly reminder that it's important to have the <b>comment permissions</b> in the <code class="language-bash">manifest.json</code>.
|
||||
</p>
|
||||
|
||||
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/create-comments">Comments example</a>
|
||||
|
||||
|
||||
## 5.2. Templates
|
||||
|
||||
As we mentioned in the <a target="_blank" href="/plugins/create-a-plugin/">Create a plugin</a> section, we've got two great options for you to get started with your plugin.
|
||||
The first is a basic **Typescript** template with all the essential structure you'll need.
|
||||
The second is the same, but uses one of the most popular frameworks like **Angular, Vue, or React**. We've included links to the repositories below:
|
||||
|
||||
- <a target="_blank" href="https://github.com/penpot/penpot-plugin-starter-template">Plugin Starter Template with plain Typescript</a><br>
|
||||
- <a target="_blank" href="https://github.com/penpot/plugin-examples">Plugin Starter Template using a framework</a>
|
72
docs/plugins/faq.md
Normal file
72
docs/plugins/faq.md
Normal file
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
layout: layouts/plugins.njk
|
||||
title: 6. FAQ
|
||||
---
|
||||
|
||||
# FAQ
|
||||
|
||||
### Which Node version should I use?
|
||||
|
||||
Currently we are using the v22.2.0
|
||||
|
||||
### Should I create my plugin for dark and light themes?
|
||||
|
||||
It’s not obligatory but keep in mind that the containing modal will change colors automatically to match Penpot’s theme. Check this <a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/theme">example</a> on how to apply dark and light themes to your plugin.
|
||||
|
||||
### Should I always host my plugin?
|
||||
|
||||
By the time being any and all plugins must be hosted independently and outside the Penpot environment. Check the <a target="_blank" href="/plugins/deployment/">documentation</a> for a guide on how to deploy your plugin on some deployment services like Netlify or Cloudflare.
|
||||
|
||||
### Is there any way to export my figma plugins to penpot?
|
||||
|
||||
No. The feature set of figma and penpot are not the same so it’s not compatible.
|
||||
|
||||
### What is the recommended size for my plugin icon?
|
||||
|
||||
You can make it any size since it will be automatically adjusted to 56x56 px in the plugin manager modal. Just make sure to keep it square size.
|
||||
|
||||
### Are there any naming conventions for the plugin name?
|
||||
|
||||
The name of the plugin should be short and followed by the suffix ‘-plugins’, like ‘shape-remover-plugin’.
|
||||
|
||||
### Which framework do you recommend for creating the plugin?
|
||||
|
||||
Any framework you are familiar with would be a good choice. Our examples are in vue, angular and react. Check the <a target="_blank" href="/plugins/create-a-plugin/">documentation</a>
|
||||
|
||||
### Is it necessary to use the plugin styles library?
|
||||
|
||||
The plugin <a target="_blank" href="https://www.npmjs.com/package/@penpot/plugin-styles">styles library</a> is not obligatory, although we recommend its use because it'll help you with the dark and light theming and to maintain the Penpot look-and-feel.
|
||||
|
||||
### Is the API ready to use the prototyping features?
|
||||
|
||||
Absolutely! You can definitely create flows and interactions in the same elements as in the interface, like frames, shapes, and groups. Just check out the API documentation for the methods: createFlow, addInteraction, or removeInteraction. And if you need more help, you can always check out the <a target="_blank" href="https://penpot-plugins-api-doc.pages.dev/interfaces/PenpotFlow">PenpotFlow</a> or <a target="_blank" href="https://penpot-plugins-api-doc.pages.dev/interfaces/PenpotInteraction">PenpotInteraction</a> interfaces.
|
||||
|
||||
### Are there any security or quality criteria I should be aware of?
|
||||
|
||||
There are no set requirements. However, we can recommend the use of <a target="_blank" href="https://typescript-eslint.io/">eslint</a> or <a target="_blank" href="https://prettier.io/">prettier</a>, which is what we use.
|
||||
|
||||
### Is it necessary to create plugins with a UI?
|
||||
|
||||
No, it’s completely optional, in fact, we have an example of a plugin without UI. Try the plugin using this url to install it: <code class="language-js">https:\/\/create-palette-penpot-plugin.pages.dev/assets/manifest.json</code> or check the code <a target="_blank" href="https://github.com/penpot/penpot-plugins/tree/main/apps/create-palette-plugin">here</a>
|
||||
|
||||
### Can I create components?
|
||||
|
||||
Yes, it is possible to create components using:
|
||||
|
||||
```js
|
||||
createComponent(shapes: Shape[]): LibraryComponent;
|
||||
```
|
||||
|
||||
Take a look at the Penpot Library methods in the <a target="_blank" href="https://penpot-plugins-api-doc.pages.dev/interfaces/Library">API documentation</a> or this <a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/components-library">simple example</a>.
|
||||
|
||||
### Is there a place where I can share my plugin?
|
||||
|
||||
You will be able to share your plugin with the <a target="_blank" href="https://community.penpot.app/">Penpot community</a>. In the future, we plan to create a place where we will publish the plugins we know about, but this is still something we have to define.
|
||||
|
||||
### My plugin works on my local machine, but I couldn’t install it on Penpot. What could be the problem?
|
||||
|
||||
The url you that you need to provide in the plugin manager should look <a target="_blank" href="/plugins/create-a-plugin/#2.6.-step-6.-configure-the-manifest-file">like this</a>: <code class="language-bash">https:\/\/yourdomain.com/assents/manifest.json</code>
|
||||
|
||||
### Where can I get support if I find a bug or an unexpected behavior?
|
||||
|
||||
You can report a problem or request support at <a href="mailto:support@penpot.app">support@penpot.app</a>.
|
199
docs/plugins/getting-started.md
Normal file
199
docs/plugins/getting-started.md
Normal file
|
@ -0,0 +1,199 @@
|
|||
---
|
||||
layout: layouts/plugins.njk
|
||||
title: 1. Getting started
|
||||
---
|
||||
|
||||
# Getting started
|
||||
|
||||
## 1.1. Introduction
|
||||
|
||||
Welcome to Penpot Plugins!
|
||||
|
||||
Plugins are the perfect tool to easily extend Penpot's functionality, you can automate repetitive tasks, add new features and much more.
|
||||
|
||||
Plugins can be created with your favorite framework or with not framework at all. Feel free to use whatever you want because Plugins are independent from Penpot's code and therefore you don't need any extra knowledge.
|
||||
|
||||
The plugins will be hosted outside Penpot, and each creator need to host theirs.
|
||||
|
||||
## 1.2. Pre-requisites
|
||||
|
||||
- Basic experience with Penpot.
|
||||
- Basic experience with JavaScript, HTML and CSS.
|
||||
- Node and npm (<a target="_blank" href="https://nodejs.org/en/learn/getting-started/how-to-install-nodejs">How to install Node.js</a>).
|
||||
- A text editor, ideally an IDE like <a target="_blank" href="https://code.visualstudio.com">Visual Studio Code</a> or similar.
|
||||
|
||||
Nice to have:
|
||||
|
||||
- Git basic knowledge.
|
||||
- A Github account or a similar service to host and share your plugin code.
|
||||
- TypeScript basic knowledge.
|
||||
- Experience with any front framework (angular, react, vue...) for complex user interfaces.
|
||||
- A hosting service of your choice for plugin's deployment.
|
||||
|
||||
## 1.3. Installation
|
||||
|
||||
With the plugins system enabled, you need to go to any project to open the plugin manager.
|
||||
|
||||
You can open the plugin manager in any project via:
|
||||
|
||||
##### Shortcut
|
||||
|
||||
| Linux and Windows | macOS |
|
||||
| ----------------------------------------- | -------------------------------------- |
|
||||
| <kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>P</kbd> | <kbd>⌘</kbd><kbd>Alt</kbd><kbd>P</kbd> |
|
||||
|
||||
##### Menu
|
||||
|
||||
<figure>
|
||||
<video title="Open plugin manager from penpot menu" muted="" playsinline="" controls="" width="100%" poster="/img/plugins/plugins-menu.png" height="auto">
|
||||
<source src="/img/plugins/plugins-menu.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
##### Toolbar
|
||||
|
||||
<figure>
|
||||
<video title="Open plugin manager from penpot toolbar" muted="" playsinline="" controls="" width="100%" poster="/img/plugins/plugins-toolbar.png" height="auto">
|
||||
<source src="/img/plugins/plugins-toolbar.mp4" type="video/mp4">
|
||||
</video>
|
||||
</figure>
|
||||
|
||||
The plugin manager looks like this:
|
||||
|
||||

|
||||
|
||||
You need to provide the plugin's manifest URL for the installation. If there are no issues the plugin will be installed and then you would be able to open it whenever you like.
|
||||
|
||||
### Examples
|
||||
|
||||
| Name | URL |
|
||||
| ------------- | ------------------------------------------------------------------- |
|
||||
| Lorem Ipsum | https://lorem-ipsum-penpot-plugin.pages.dev/assets/manifest.json |
|
||||
| Contrast | https://contrast-penpot-plugin.pages.dev/assets/manifest.json |
|
||||
| Feather icons | https://icons-penpot-plugin.pages.dev/assets/manifest.json |
|
||||
| Tables | https://table-penpot-plugin.pages.dev/assets/manifest.json |
|
||||
| Color palette | https://create-palette-penpot-plugin.pages.dev/assets/manifest.json |
|
||||
| Rename layers | https://rename-layers-penpot-plugin.pages.dev/assets/manifest.json |
|
||||
|
||||
## 1.4. Plugin's basics
|
||||
|
||||
### How does it work?
|
||||
|
||||
Penpot's plugin system allows you to add new features to the platform through independent modules called plugins. These plugins run separately from the main Penpot app, inside iframes, which are like small, isolated browser windows within the app.
|
||||
|
||||
Plugins communicate with Penpot by sending and receiving messages through the iframe.
|
||||
|
||||
@startuml
|
||||
|
||||
skinparam state {
|
||||
BackgroundColor transparent
|
||||
BorderColor black
|
||||
ArrowColor black
|
||||
}
|
||||
|
||||
Penpot_App -down-> WebComponent
|
||||
WebComponent -up-> Penpot_App : Write / Read
|
||||
WebComponent : - Create API
|
||||
WebComponent : - Create sandbox (ses)
|
||||
WebComponent : - Read plugin manifest
|
||||
WebComponent : - Run plugin code
|
||||
WebComponent -right-> Plugin_code
|
||||
Plugin_code : penpot.ui.open('Example plugin', '');
|
||||
Plugin_code :
|
||||
Plugin_code : penpot.ui.onMessage((message) => {
|
||||
Plugin_code : console.log('iframe message', message);
|
||||
Plugin_code : });
|
||||
Plugin_code -right-> Iframe
|
||||
Iframe -left-> Plugin_code
|
||||
Iframe : <button type="button" data-appearance="primary">
|
||||
Iframe : Send plugin message
|
||||
Iframe : </button>
|
||||
Iframe :
|
||||
Iframe : <script type="text/javascript">
|
||||
Iframe : document.querySelector('button').addEventListener(() => {
|
||||
Iframe: parent.postMessage('test', '*');
|
||||
Iframe : });
|
||||
Iframe : </script>
|
||||
|
||||
CSS_Library -down-> Iframe
|
||||
External_API -up-> Iframe
|
||||
Iframe -down-> External_API
|
||||
|
||||
@enduml
|
||||
|
||||
### What is manifest.json file?
|
||||
|
||||
The <code class="language-js">manifest.json</code> file contains the basic information about the plugin. It defines the plugin's name, description, the main code file, and the permissions it requires. The structure of the <code class="language-js">manifest.json</code> file looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Your plugin name",
|
||||
"description": "Your plugin description",
|
||||
"code": "plugin.js",
|
||||
"icon": "Your icon",
|
||||
"permissions": [
|
||||
"content:read",
|
||||
"content:write",
|
||||
"library:read",
|
||||
"library:write",
|
||||
"user:read",
|
||||
"comment:read",
|
||||
"comment:write",
|
||||
"allow:downloads"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Properties
|
||||
|
||||
- **Name and description**: your plugin's basic information, which will be displayed in the plugin manager modal.
|
||||
- **Code**: your plugin's file location. It needs to be compiled to JavaScript and reachable.
|
||||
- **Icon**: your plugin's icon, which will be also displayed in the plugin manager modal. It'll be a <code class="language-js"><img src=""></code> tag so you can use whichever image format works better for you. **It's recommended to use a 56x56 pixel icon for the best appearance on all devices**.
|
||||
- **Permissions**: your plugin's permissions, which allow access to different parts of the Penpot API.
|
||||
|
||||
#### Types of permissions
|
||||
|
||||
- <code class="language-js">content:read</code>: Allows reading of content-related data. Grants read access to all endpoints and operations dealing with content. Typical use cases: viewing shapes, pages, or other design elements in a project; accessing the properties and settings of content within the application.
|
||||
|
||||
- <code class="language-js">content:write</code>: Allows writing or modifying content-related data. Grants write access to all endpoints and operations dealing with content modifications, except those marked as read-only. Typical use cases: adding, updating, or deleting shapes and elements in a design; uploading media or other assets to the project.
|
||||
|
||||
- <code class="language-js">user:read</code>: Allows reading of user-related data. Grants read access to all endpoints and operations dealing with user data. Typical use cases: viewing user profiles and their associated information or listing active users in a particular context or project.
|
||||
|
||||
- <code class="language-js">library:read</code>: Allows reading of library-related data and assets. Grants read access to all endpoints and operations dealing with the library context. Typical use cases: accessing shared design elements and components from a library or viewing the details and properties of library assets.
|
||||
|
||||
- <code class="language-js">library:write</code>: Allows writing or modifying library-related data and assets. Grants write access to all endpoints and operations dealing with library modifications. Typical use cases: adding new components or assets to the library or updating or removing existing library elements.
|
||||
|
||||
- <code class="language-js">comment:read</code>: Allows reading of comment-related data. Grants read access to all endpoints and operations dealing with comments.
|
||||
Typical use cases: viewing comments on pages; accessing feedback or annotations provided by collaborators in the project.
|
||||
|
||||
- <code class="language-js">comment:write</code>: Allows writing or modifying comment-related data. Grants write access to all endpoints and operations dealing with creating, replying, or deleting comments.
|
||||
Typical use cases: adding new comments to pages; deleting existing comments; replying to comments within the project's context.
|
||||
|
||||
- <code class="language-js">allow:downloads</code>: Allows downloading of the project file. Grants access to endpoints and operations that enable the downloading of the entire project file.
|
||||
Typical use cases: downloading the full project file for backup or sharing.
|
||||
|
||||
_Note: Write permissions automatically includes its corresponding read permission (e.g., <code class="language-js">content:write</code> includes <code class="language-js">content:read</code>) because reading is required to perform write or modification actions._
|
||||
|
||||
### What are plugin.ts and plugin.js files?
|
||||
|
||||
The <code class="language-js">plugin.ts</code> file is where you write code to interact with the Penpot API using TypeScript. This file is then compiled into <code class="language-js">plugin.js</code> which is the final JavaScript code that runs the plugin. You don't write <code class="language-js">plugin.js</code> directly; it's generated from the <code class="language-js">plugin.ts</code> file.
|
||||
|
||||
<p class="advice">
|
||||
<b>This is also the only file where you can use the Penpot object.</b> Do not try to use the Penpot object in your plugin interface scripts.
|
||||
</p>
|
||||
|
||||
You can check some samples in:
|
||||
|
||||
- <a href="https://github.com/penpot/penpot-plugins-samples/" target="_blank">Penpot plugin samples.</a>
|
||||
|
||||
### What is TypeScript?
|
||||
|
||||
You may have noticed that we're using TypeScript in our plugin files, but what is it, and why?
|
||||
|
||||
TypeScript is like JavaScript with extra rules. These rules help you catch mistakes early, before you run your code. It makes your code more reliable and easier to manage, especially in big projects.
|
||||
|
||||
We're using TypeScript to make working with the Penpot API easier, as it provides autocompletion and instant access to documentation. However, even with TypeScript’s powerful features, you'll still need to include the <code class="language-js">@penpot/plugin-types</code> npm package, which contains the typings for the Penpot Plugin API. This ensures that TypeScript can fully understand and work with the API.
|
||||
|
||||

|
||||
|
||||
You can install the package in any project with <code class="language-js">npm install @penpot/plugin-types</code>. You can check the details in [@penpot/plugin-types package](https://www.npmjs.com/package/@penpot/plugin-types).
|
48
docs/plugins/index.njk
Normal file
48
docs/plugins/index.njk
Normal file
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
layout: layouts/plugins-home.njk
|
||||
title: Plugins
|
||||
eleventyNavigation:
|
||||
key: Plugins
|
||||
order: 5
|
||||
---
|
||||
|
||||
<h1 class="main-title">Plugins</h1>
|
||||
|
||||
<ul class="help-sections">
|
||||
<li class="illus illus-getting-started">
|
||||
<a href="/plugins/getting-started/">
|
||||
<h2>Getting started →</h2>
|
||||
<p>Learn the basics, including introduction, pre-requisites, installation, and plugin fundamentals.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-create-plugin">
|
||||
<a href="/plugins/create-a-plugin/">
|
||||
<h2>Create a plugin →</h2>
|
||||
<p>How to report bugs, add translations and more.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-deployment">
|
||||
<a href="/plugins/deployment">
|
||||
<h2>Deployment →</h2>
|
||||
<p>Discover different methods and steps to deploy your plugin.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-api">
|
||||
<a href="/plugins/api/">
|
||||
<h2>API →</h2>
|
||||
<p>Access detailed documentation on the plugins API for integration and development.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-examples">
|
||||
<a href="/plugins/examples-templates/">
|
||||
<h2>Examples and templates →</h2>
|
||||
<p>Find examples and starter templates in different frameworks.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="illus illus-faq">
|
||||
<a href="/plugins/faq/">
|
||||
<h2>FAQs →</h2>
|
||||
<p>Get quick answers to common questions and troubleshooting tips.</p>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
Loading…
Add table
Add a link
Reference in a new issue