mirror of
https://github.com/penpot/penpot.git
synced 2026-01-09 23:09:01 -05:00
Compare commits
1 Commits
nitrate-mo
...
hiru-plugi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bea0f9d124 |
@@ -19,7 +19,7 @@ In the `apps` folder you'll find some examples that use the libraries mentioned
|
||||
- example-styles: to run this example you should run
|
||||
|
||||
```
|
||||
npm run start:styles-example
|
||||
pnpm run start:styles-example
|
||||
```
|
||||
|
||||
Open in your browser: `http://localhost:4202/`
|
||||
@@ -28,8 +28,8 @@ Open in your browser: `http://localhost:4202/`
|
||||
|
||||
This guide will help you launch a Penpot plugin from the penpot-plugins repository. Before proceeding, ensure that you have Penpot running locally by following the [setup instructions](https://help.penpot.app/technical-guide/developer/devenv/).
|
||||
|
||||
In the terminal, navigate to the **penpot-plugins** repository and run `npm install` to install the required dependencies.
|
||||
Then, run `npm start` to launch the plugins wrapper.
|
||||
In the terminal, navigate to the **penpot-plugins** repository and run `pnpm install` to install the required dependencies.
|
||||
Then, run `pnpm run start` to launch the plugins wrapper.
|
||||
|
||||
After installing the dependencies, choose a plugin to launch. You can either run one of the provided examples or create your own (see "Creating a plugin from scratch" below).
|
||||
To launch a plugin, Open a new terminal tab and run the appropriate startup script for the chosen plugin.
|
||||
@@ -38,7 +38,7 @@ For instance, to launch the Contrast plugin, use the following command:
|
||||
|
||||
```
|
||||
// for the contrast plugin
|
||||
npm run start:plugin:contrast
|
||||
pnpm run start:plugin:contrast
|
||||
```
|
||||
|
||||
Finally, open in your browser the specific port. In this specific example would be `http://localhost:4302`
|
||||
@@ -49,21 +49,22 @@ A table listing the available plugins and their corresponding startup commands i
|
||||
|
||||
| Plugin | Description | PORT | Start command | Manifest URL |
|
||||
| ----------------------- | ----------------------------------------------------------- | ---- | ------------------------------------- | ------------------------------------------ |
|
||||
| poc-state-plugin | Sandbox plugin to test new plugins api functionality | 4301 | npm run start:plugin:poc-state | http://localhost:4301/assets/manifest.json |
|
||||
| contrast-plugin | Sample plugin that gives you color contrast information | 4302 | npm run start:plugin:contrast | http://localhost:4302/assets/manifest.json |
|
||||
| icons-plugin | Tool to add icons from [Feather](https://feathericons.com/) | 4303 | npm run start:plugin:icons | http://localhost:4303/assets/manifest.json |
|
||||
| lorem-ipsum-plugin | Generate Lorem ipsum text | 4304 | npm run start:plugin:loremipsum | http://localhost:4304/assets/manifest.json |
|
||||
| create-palette-plugin | Creates a board with all the palette colors | 4305 | npm run start:plugin:palette | http://localhost:4305/assets/manifest.json |
|
||||
| table-plugin | Create or import table | 4306 | npm run start:table-plugin | http://localhost:4306/assets/manifest.json |
|
||||
| rename-layers-plugin | Rename layers in bulk | 4307 | npm run start:plugin:renamelayers | http://localhost:4307/assets/manifest.json |
|
||||
| colors-to-tokens-plugin | Generate tokens JSON file | 4308 | npm run start:plugin:colors-to-tokens | http://localhost:4308/assets/manifest.json |
|
||||
| poc-state-plugin | Sandbox plugin to test new plugins api functionality | 4301 | pnpm run start:plugin:poc-state | http://localhost:4301/assets/manifest.json |
|
||||
| contrast-plugin | Sample plugin that gives you color contrast information | 4302 | pnpm run start:plugin:contrast | http://localhost:4302/assets/manifest.json |
|
||||
| icons-plugin | Tool to add icons from [Feather](https://feathericons.com/) | 4303 | pnpm run start:plugin:icons | http://localhost:4303/assets/manifest.json |
|
||||
| lorem-ipsum-plugin | Generate Lorem ipsum text | 4304 | pnpm run start:plugin:loremipsum | http://localhost:4304/assets/manifest.json |
|
||||
| create-palette-plugin | Creates a board with all the palette colors | 4305 | pnpm run start:plugin:palette | http://localhost:4305/assets/manifest.json |
|
||||
| table-plugin | Create or import table | 4306 | pnpm run start:table-plugin | http://localhost:4306/assets/manifest.json |
|
||||
| rename-layers-plugin | Rename layers in bulk | 4307 | pnpm run start:plugin:renamelayers | http://localhost:4307/assets/manifest.json |
|
||||
| colors-to-tokens-plugin | Generate tokens JSON file | 4308 | pnpm run start:plugin:colors-to-tokens | http://localhost:4308/assets/manifest.json |
|
||||
| poc-tokens-plugin | Sandbox plugin to test tokens functionality | 4309 | pnpm run start:plugin:poc-tokens | http://localhost:4309/assets/manifest.json |
|
||||
|
||||
## Web Apps
|
||||
|
||||
| App | Description | PORT | Start command | URL |
|
||||
| --------------- | ----------------------------------------------------------------- | ---- | -------------------------------- | ---------------------- |
|
||||
| plugins-runtime | Runtime for the plugins subsystem | 4200 | npm run start:app:runtime | |
|
||||
| example-styles | Showcase of some of the Penpot styles that can be used in plugins | 4201 | npm run start:app:styles-example | http://localhost:4201/ |
|
||||
| plugins-runtime | Runtime for the plugins subsystem | 4200 | pnpm run start:app:runtime | |
|
||||
| example-styles | Showcase of some of the Penpot styles that can be used in plugins | 4201 | pnpm run start:app:styles-example | http://localhost:4201/ |
|
||||
|
||||
## Creating a plugin from scratch
|
||||
|
||||
|
||||
51
plugins/apps/poc-tokens-plugin/eslint.config.js
Normal file
51
plugins/apps/poc-tokens-plugin/eslint.config.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import baseConfig from '../../eslint.config.js';
|
||||
import { compat } from '../../eslint.base.config.js';
|
||||
|
||||
export default [
|
||||
...baseConfig,
|
||||
...compat
|
||||
.config({
|
||||
extends: [
|
||||
'plugin:@nx/angular',
|
||||
'plugin:@angular-eslint/template/process-inline-templates',
|
||||
],
|
||||
})
|
||||
.map((config) => ({
|
||||
...config,
|
||||
files: ['**/*.ts'],
|
||||
rules: {
|
||||
'@angular-eslint/directive-selector': [
|
||||
'error',
|
||||
{
|
||||
type: 'attribute',
|
||||
prefix: 'app',
|
||||
style: 'camelCase',
|
||||
},
|
||||
],
|
||||
'@angular-eslint/component-selector': [
|
||||
'error',
|
||||
{
|
||||
type: 'element',
|
||||
prefix: 'app',
|
||||
style: 'kebab-case',
|
||||
},
|
||||
],
|
||||
},
|
||||
})),
|
||||
...compat
|
||||
.config({ extends: ['plugin:@nx/angular-template'] })
|
||||
.map((config) => ({
|
||||
...config,
|
||||
files: ['**/*.html'],
|
||||
rules: {},
|
||||
})),
|
||||
{ ignores: ['**/assets/*.js'] },
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: './tsconfig.*?.json',
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
79
plugins/apps/poc-tokens-plugin/project.json
Normal file
79
plugins/apps/poc-tokens-plugin/project.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "poc-tokens-plugin",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"sourceRoot": "apps/poc-tokens-plugin/src",
|
||||
"tags": ["type:plugin"],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@angular-devkit/build-angular:application",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/apps/poc-tokens-plugin",
|
||||
"index": "apps/poc-tokens-plugin/src/index.html",
|
||||
"browser": "apps/poc-tokens-plugin/src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "apps/poc-tokens-plugin/tsconfig.app.json",
|
||||
"assets": [
|
||||
"apps/poc-tokens-plugin/src/favicon.ico",
|
||||
"apps/poc-tokens-plugin/src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"libs/plugins-styles/src/lib/styles.css",
|
||||
"apps/poc-tokens-plugin/src/styles.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"optimization": {
|
||||
"scripts": true,
|
||||
"styles": true,
|
||||
"fonts": false
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production",
|
||||
"dependsOn": ["buildPlugin"]
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "poc-tokens-plugin:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "poc-tokens-plugin:build:development",
|
||||
"port": 4309,
|
||||
"host": "0.0.0.0"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"executor": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "poc-tokens-plugin:build"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
127
plugins/apps/poc-tokens-plugin/src/app/app.component.css
Normal file
127
plugins/apps/poc-tokens-plugin/src/app/app.component.css
Normal file
@@ -0,0 +1,127 @@
|
||||
/* @import "@penpot/plugin-styles/styles.css"; */
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.title-l {
|
||||
margin: var(--spacing-16) 0;
|
||||
}
|
||||
|
||||
.columns {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
flex-grow: 1;
|
||||
margin-block-end: var(--spacing-16);
|
||||
}
|
||||
|
||||
.panels {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
padding: 0 var(--spacing-8);
|
||||
}
|
||||
|
||||
.panel {
|
||||
padding: var(--spacing-8);
|
||||
display: flex;
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.panel:not(:first-child) {
|
||||
border-block-start: 1px solid var(--df-secondary);
|
||||
padding-block-start: var(--spacing-16);
|
||||
}
|
||||
|
||||
.panel-heading,
|
||||
.token-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-inline-end: var(--spacing-8);
|
||||
}
|
||||
|
||||
.panel-heading p,
|
||||
.token-group span {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.panel-heading button,
|
||||
.token-group button {
|
||||
background: none;
|
||||
padding: var(--spacing-4) calc(var(--spacing-12) / 2);
|
||||
}
|
||||
|
||||
.panel-heading button:focus,
|
||||
.token-group button:focus {
|
||||
padding: calc(var(--spacing-4) - 2px) calc(var(--spacing-12) / 2 - 2px);
|
||||
}
|
||||
|
||||
.panel-item button {
|
||||
opacity: 0;
|
||||
margin-inline-end: var(--spacing-8);
|
||||
padding: var(--spacing-4) calc(var(--spacing-12) / 2);
|
||||
}
|
||||
|
||||
.panel-item button:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.panel-item button:focus {
|
||||
opacity: 1;
|
||||
padding: calc(var(--spacing-4) - 2px) calc(var(--spacing-12) / 2 - 2px);
|
||||
}
|
||||
|
||||
.panel ul {
|
||||
/* flex-grow: 1; */
|
||||
overflow-y: auto;
|
||||
padding-inline-end: var(--spacing-8);
|
||||
}
|
||||
|
||||
.panel-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.panel-item span {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.set-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.set-item.selected {
|
||||
background-color: var(--db-quaternary);
|
||||
}
|
||||
|
||||
.set-item:hover {
|
||||
color: var(--da-primary);
|
||||
background-color: var(--db-secondary);
|
||||
}
|
||||
|
||||
.token-group:not(:first-child) {
|
||||
margin-top: var(--spacing-8);
|
||||
}
|
||||
|
||||
.token-group {
|
||||
border-block-end: 1px solid var(--df-secondary);
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.token-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.token-item:hover {
|
||||
color: var(--da-primary);
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
144
plugins/apps/poc-tokens-plugin/src/app/app.component.html
Normal file
144
plugins/apps/poc-tokens-plugin/src/app/app.component.html
Normal file
@@ -0,0 +1,144 @@
|
||||
<div class="container">
|
||||
<p class="title-l">Design tokens plugin POC</p>
|
||||
|
||||
<div class="columns">
|
||||
<div class="panels">
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<p class="headline-m">THEMES</p>
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
(click)="addTheme()"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul data-handler="themes-list">
|
||||
@for (theme of themes; track theme.id) {
|
||||
<li class="body-m panel-item theme-item">
|
||||
<span>{{ theme.group }} / {{ theme.name }}</span>
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
(click)="renameTheme(theme.id, theme.name)"
|
||||
>
|
||||
🖊️
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
(click)="deleteTheme(theme.id)"
|
||||
>
|
||||
❌
|
||||
</button>
|
||||
<div class="checkbox-container">
|
||||
<input
|
||||
class="checkbox-input"
|
||||
type="checkbox"
|
||||
id="checkbox1"
|
||||
[checked]="isThemeActive(theme.id)"
|
||||
(change)="toggleTheme(theme.id)"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<p class="headline-m">SETS</p>
|
||||
<button type="button" data-appearance="secondary" (click)="addSet()">
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul data-handler="sets-list">
|
||||
@for (set of sets; track set.id) {
|
||||
<li
|
||||
class="body-m panel-item set-item"
|
||||
[class.selected]="set.id === currentSetId"
|
||||
>
|
||||
<span (click)="loadTokens(set.id)">
|
||||
{{ set.name }}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
(click)="renameSet(set.id, set.name)"
|
||||
>
|
||||
🖊️
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
(click)="deleteSet(set.id)"
|
||||
>
|
||||
❌
|
||||
</button>
|
||||
<div class="checkbox-container">
|
||||
<input
|
||||
class="checkbox-input"
|
||||
type="checkbox"
|
||||
id="checkbox1"
|
||||
[checked]="isSetActive(set.id)"
|
||||
(change)="toggleSet(set.id)"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panels">
|
||||
<div class="panel">
|
||||
<p class="headline-m">TOKENS</p>
|
||||
|
||||
<ul data-handler="tokens-list">
|
||||
@for (group of tokenGroups; track group[0]) {
|
||||
<li class="body-m token-group">
|
||||
<span>{{ group[0] }}</span>
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
(click)="addToken(group[0])"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</li>
|
||||
@for (token of group[1]; track token.id) {
|
||||
<li
|
||||
class="body-m panel-item token-item"
|
||||
(click)="applyToken(token.id)"
|
||||
>
|
||||
<span>{{ token.name }}</span>
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
(click)="renameToken(token.id, token.name)"
|
||||
>
|
||||
🖊️
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
(click)="deleteToken(token.id)"
|
||||
>
|
||||
❌
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<button type="button" data-appearance="primary" (click)="loadLibrary()">
|
||||
Load
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
290
plugins/apps/poc-tokens-plugin/src/app/app.component.ts
Normal file
290
plugins/apps/poc-tokens-plugin/src/app/app.component.ts
Normal file
@@ -0,0 +1,290 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { fromEvent, map, filter, take, merge } from 'rxjs';
|
||||
import { PluginMessageEvent, PluginUIEvent } from '../model';
|
||||
|
||||
type TokenTheme = {
|
||||
id: string;
|
||||
name: string;
|
||||
group: string;
|
||||
description: string;
|
||||
active: boolean;
|
||||
};
|
||||
|
||||
type TokenSet = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
active: boolean;
|
||||
};
|
||||
|
||||
type Token = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
type TokensGroup = [string, Token[]];
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
host: {
|
||||
'[attr.data-theme]': 'theme()',
|
||||
},
|
||||
})
|
||||
export class AppComponent {
|
||||
public route = inject(ActivatedRoute);
|
||||
|
||||
public messages$ = fromEvent<MessageEvent<PluginMessageEvent>>(
|
||||
window,
|
||||
'message',
|
||||
);
|
||||
|
||||
public initialTheme$ = this.route.queryParamMap.pipe(
|
||||
map((params) => params.get('theme')),
|
||||
filter((theme) => !!theme),
|
||||
take(1),
|
||||
);
|
||||
|
||||
public theme = toSignal(
|
||||
merge(
|
||||
this.initialTheme$,
|
||||
this.messages$.pipe(
|
||||
filter((event) => event.data.type === 'theme'),
|
||||
map((event) => {
|
||||
return event.data.content;
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
public themes: TokenTheme[] = [];
|
||||
public sets: TokenSet[] = [];
|
||||
public tokenGroups: TokensGroup[] = [];
|
||||
public currentSetId: string | undefined = undefined;
|
||||
|
||||
constructor() {
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data.type === 'set-themes') {
|
||||
this.#setThemes(event.data.themesData);
|
||||
} else if (event.data.type === 'set-sets') {
|
||||
this.#setSets(event.data.setsData);
|
||||
} else if (event.data.type === 'set-tokens') {
|
||||
this.#setTokens(event.data.tokenGroupsData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadLibrary() {
|
||||
this.#sendMessage({ type: 'load-library' });
|
||||
}
|
||||
|
||||
loadTokens(setId: string) {
|
||||
this.currentSetId = setId;
|
||||
this.#sendMessage({ type: 'load-tokens', setId });
|
||||
}
|
||||
|
||||
addTheme() {
|
||||
this.#sendMessage({
|
||||
type: 'add-theme',
|
||||
themeGroup: this.#randomString(),
|
||||
themeName: this.#randomString(),
|
||||
});
|
||||
}
|
||||
|
||||
addSet() {
|
||||
this.#sendMessage({ type: 'add-set', setName: this.#randomString() });
|
||||
}
|
||||
|
||||
addToken(tokenType: string) {
|
||||
let tokenValue;
|
||||
switch (tokenType) {
|
||||
case 'borderRadius':
|
||||
tokenValue = 25;
|
||||
break;
|
||||
case 'shadow':
|
||||
tokenValue = [
|
||||
{
|
||||
color: '#123456',
|
||||
inset: 'false',
|
||||
offsetX: '6',
|
||||
offsetY: '6',
|
||||
spread: '0',
|
||||
blur: '4',
|
||||
},
|
||||
];
|
||||
break;
|
||||
case 'color':
|
||||
tokenValue = '#fabada';
|
||||
break;
|
||||
case 'dimension':
|
||||
tokenValue = 100;
|
||||
break;
|
||||
case 'fontFamilies':
|
||||
tokenValue = ['Source Sans Pro', 'Sans serif'];
|
||||
break;
|
||||
case 'fontSizes':
|
||||
tokenValue = 24;
|
||||
break;
|
||||
case 'fontWeights':
|
||||
tokenValue = 'bold';
|
||||
break;
|
||||
case 'letterSpacing':
|
||||
tokenValue = 0.5;
|
||||
break;
|
||||
case 'number':
|
||||
tokenValue = 33;
|
||||
break;
|
||||
case 'opacity':
|
||||
tokenValue = 0.6;
|
||||
break;
|
||||
case 'rotation':
|
||||
tokenValue = 45;
|
||||
break;
|
||||
case 'sizing':
|
||||
tokenValue = 200;
|
||||
break;
|
||||
case 'spacing':
|
||||
tokenValue = 16;
|
||||
break;
|
||||
case 'borderWidth':
|
||||
tokenValue = 3;
|
||||
break;
|
||||
case 'textCase':
|
||||
tokenValue = 'lowercase';
|
||||
break;
|
||||
case 'textDecoration':
|
||||
tokenValue = 'underline';
|
||||
break;
|
||||
case 'typography':
|
||||
tokenValue = {
|
||||
fontFamilies: ['Acme', 'Arial', 'Sans Serif'],
|
||||
fontSizes: '36',
|
||||
letterSpacing: '0.8',
|
||||
textCase: 'uppercase',
|
||||
textDecoration: 'none',
|
||||
fontWeights: '600',
|
||||
lineHeight: '1.5',
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.currentSetId && tokenValue) {
|
||||
this.#sendMessage({
|
||||
type: 'add-token',
|
||||
setId: this.currentSetId,
|
||||
tokenType,
|
||||
tokenName: this.#randomString(),
|
||||
tokenValue,
|
||||
});
|
||||
} else {
|
||||
console.log('Invalid token type');
|
||||
}
|
||||
}
|
||||
|
||||
renameTheme(themeId: string, themeName: string) {
|
||||
const newName = prompt('Rename theme', themeName);
|
||||
if (newName && newName !== '') {
|
||||
this.#sendMessage({ type: 'rename-theme', themeId, newName });
|
||||
}
|
||||
}
|
||||
|
||||
renameSet(setId: string, setName: string) {
|
||||
const newName = prompt('Rename set', setName);
|
||||
if (newName && newName !== '') {
|
||||
this.#sendMessage({ type: 'rename-set', setId, newName });
|
||||
}
|
||||
}
|
||||
|
||||
renameToken(tokenId: string, tokenName: string) {
|
||||
const newName = prompt('Rename token', tokenName);
|
||||
if (this.currentSetId && newName && newName !== '') {
|
||||
this.#sendMessage({
|
||||
type: 'rename-token',
|
||||
setId: this.currentSetId,
|
||||
tokenId,
|
||||
newName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
deleteTheme(themeId: string) {
|
||||
this.#sendMessage({ type: 'delete-theme', themeId });
|
||||
}
|
||||
|
||||
deleteSet(setId: string) {
|
||||
this.#sendMessage({ type: 'delete-set', setId });
|
||||
}
|
||||
|
||||
deleteToken(tokenId: string) {
|
||||
if (this.currentSetId) {
|
||||
this.#sendMessage({
|
||||
type: 'delete-token',
|
||||
setId: this.currentSetId,
|
||||
tokenId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isThemeActive(themeId: string) {
|
||||
for (const theme of this.themes) {
|
||||
if (theme.id === themeId) {
|
||||
return theme.active;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
toggleTheme(themeId: string) {
|
||||
this.#sendMessage({ type: 'toggle-theme', themeId });
|
||||
}
|
||||
|
||||
isSetActive(setId: string) {
|
||||
for (const set of this.sets) {
|
||||
if (set.id === setId) {
|
||||
return set.active;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
toggleSet(setId: string) {
|
||||
this.#sendMessage({ type: 'toggle-set', setId });
|
||||
}
|
||||
|
||||
applyToken(tokenId: string) {
|
||||
if (this.currentSetId) {
|
||||
this.#sendMessage({
|
||||
type: 'apply-token',
|
||||
setId: this.currentSetId,
|
||||
tokenId,
|
||||
// attributes: ['stroke-color'] // Uncomment to choose attribute to apply
|
||||
}); // (incompatible attributes will have no effect)
|
||||
}
|
||||
}
|
||||
|
||||
#sendMessage(message: PluginUIEvent) {
|
||||
parent.postMessage(message, '*');
|
||||
}
|
||||
|
||||
#setThemes(themes: TokenTheme[]) {
|
||||
this.themes = themes;
|
||||
}
|
||||
|
||||
#setSets(sets: TokenSet[]) {
|
||||
this.sets = sets;
|
||||
}
|
||||
|
||||
#setTokens(tokenGroups: TokensGroup[]) {
|
||||
this.tokenGroups = tokenGroups;
|
||||
}
|
||||
|
||||
#randomString() {
|
||||
// Generate a big random number and convert it to string using base 36
|
||||
// (the number of letters in the ascii alphabet)
|
||||
return Math.floor(Math.random() * Date.now()).toString(36);
|
||||
}
|
||||
}
|
||||
11
plugins/apps/poc-tokens-plugin/src/app/app.config.ts
Normal file
11
plugins/apps/poc-tokens-plugin/src/app/app.config.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(routes),
|
||||
],
|
||||
};
|
||||
3
plugins/apps/poc-tokens-plugin/src/app/app.routes.ts
Normal file
3
plugins/apps/poc-tokens-plugin/src/app/app.routes.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { Routes } from '@angular/router';
|
||||
|
||||
export const routes: Routes = [];
|
||||
1
plugins/apps/poc-tokens-plugin/src/assets/CORS
Normal file
1
plugins/apps/poc-tokens-plugin/src/assets/CORS
Normal file
@@ -0,0 +1 @@
|
||||
*
|
||||
2
plugins/apps/poc-tokens-plugin/src/assets/_headers
Normal file
2
plugins/apps/poc-tokens-plugin/src/assets/_headers
Normal file
@@ -0,0 +1,2 @@
|
||||
/*
|
||||
Access-Control-Allow-Origin: *
|
||||
BIN
plugins/apps/poc-tokens-plugin/src/assets/favicon.ico
Normal file
BIN
plugins/apps/poc-tokens-plugin/src/assets/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
plugins/apps/poc-tokens-plugin/src/assets/icon.png
Normal file
BIN
plugins/apps/poc-tokens-plugin/src/assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
14
plugins/apps/poc-tokens-plugin/src/assets/manifest.json
Normal file
14
plugins/apps/poc-tokens-plugin/src/assets/manifest.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Design tokens plugin POC",
|
||||
"description": "This is a plugin to try Design Tokens in Penpot API",
|
||||
"code": "/assets/plugin.js",
|
||||
"permissions": [
|
||||
"page:read",
|
||||
"content:read",
|
||||
"file:read",
|
||||
"selection:read",
|
||||
"content:write",
|
||||
"library:read",
|
||||
"library:write"
|
||||
]
|
||||
}
|
||||
13
plugins/apps/poc-tokens-plugin/src/index.html
Normal file
13
plugins/apps/poc-tokens-plugin/src/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Angular example plugin</title>
|
||||
<base href="/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
||||
7
plugins/apps/poc-tokens-plugin/src/main.ts
Normal file
7
plugins/apps/poc-tokens-plugin/src/main.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
import { AppComponent } from './app/app.component';
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||
console.error(err),
|
||||
);
|
||||
112
plugins/apps/poc-tokens-plugin/src/model.ts
Normal file
112
plugins/apps/poc-tokens-plugin/src/model.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import { TokenProperty } from '@penpot/plugin-types';
|
||||
|
||||
/**
|
||||
* This file contains the typescript interfaces for the plugin events.
|
||||
*/
|
||||
|
||||
// Events sent from the ui to the plugin
|
||||
|
||||
export interface LoadLibraryEvent {
|
||||
type: 'load-library';
|
||||
}
|
||||
|
||||
export interface LoadTokensEvent {
|
||||
type: 'load-tokens';
|
||||
setId: string;
|
||||
}
|
||||
|
||||
export interface AddThemeEvent {
|
||||
type: 'add-theme';
|
||||
themeGroup: string;
|
||||
themeName: string;
|
||||
}
|
||||
|
||||
export interface AddSetEvent {
|
||||
type: 'add-set';
|
||||
setName: string;
|
||||
}
|
||||
|
||||
export interface AddTokenEvent {
|
||||
type: 'add-token';
|
||||
setId: string;
|
||||
tokenType: string;
|
||||
tokenName: string;
|
||||
tokenValue: unknown;
|
||||
}
|
||||
|
||||
export interface RenameThemeEvent {
|
||||
type: 'rename-theme';
|
||||
themeId: string;
|
||||
newName: string;
|
||||
}
|
||||
|
||||
export interface RenameSetEvent {
|
||||
type: 'rename-set';
|
||||
setId: string;
|
||||
newName: string;
|
||||
}
|
||||
|
||||
export interface RenameTokenEvent {
|
||||
type: 'rename-token';
|
||||
setId: string;
|
||||
tokenId: string;
|
||||
newName: string;
|
||||
}
|
||||
|
||||
export interface DeleteThemeEvent {
|
||||
type: 'delete-theme';
|
||||
themeId: string;
|
||||
}
|
||||
|
||||
export interface DeleteSetEvent {
|
||||
type: 'delete-set';
|
||||
setId: string;
|
||||
}
|
||||
|
||||
export interface DeleteTokenEvent {
|
||||
type: 'delete-token';
|
||||
setId: string;
|
||||
tokenId: string;
|
||||
}
|
||||
|
||||
export interface ToggleThemeEvent {
|
||||
type: 'toggle-theme';
|
||||
themeId: string;
|
||||
}
|
||||
|
||||
export interface ToggleSetEvent {
|
||||
type: 'toggle-set';
|
||||
setId: string;
|
||||
}
|
||||
|
||||
export interface ApplyTokenEvent {
|
||||
type: 'apply-token';
|
||||
setId: string;
|
||||
tokenId: string;
|
||||
attributes?: TokenProperty[];
|
||||
}
|
||||
|
||||
export type PluginUIEvent =
|
||||
| LoadLibraryEvent
|
||||
| LoadTokensEvent
|
||||
| AddThemeEvent
|
||||
| AddSetEvent
|
||||
| AddTokenEvent
|
||||
| RenameThemeEvent
|
||||
| RenameSetEvent
|
||||
| RenameTokenEvent
|
||||
| DeleteThemeEvent
|
||||
| DeleteSetEvent
|
||||
| DeleteTokenEvent
|
||||
| ToggleThemeEvent
|
||||
| ToggleSetEvent
|
||||
| ApplyTokenEvent;
|
||||
|
||||
// Events sent from the plugin to the ui
|
||||
|
||||
export interface ThemePluginEvent {
|
||||
type: 'theme';
|
||||
content: string;
|
||||
}
|
||||
|
||||
export type PluginMessageEvent = ThemePluginEvent;
|
||||
246
plugins/apps/poc-tokens-plugin/src/plugin.ts
Normal file
246
plugins/apps/poc-tokens-plugin/src/plugin.ts
Normal file
@@ -0,0 +1,246 @@
|
||||
import type { PluginMessageEvent, PluginUIEvent } from './model.js';
|
||||
import { TokenType, TokenProperty } from '@penpot/plugin-types';
|
||||
|
||||
penpot.ui.open('Design Tokens test', `?theme=${penpot.theme}`, {
|
||||
width: 1000,
|
||||
height: 800,
|
||||
});
|
||||
|
||||
penpot.on('themechange', (theme) => {
|
||||
sendMessage({ type: 'theme', content: theme });
|
||||
});
|
||||
|
||||
penpot.ui.onMessage<PluginUIEvent>(async (message) => {
|
||||
if (message.type === 'load-library') {
|
||||
loadLibrary();
|
||||
} else if (message.type === 'load-tokens') {
|
||||
loadTokens(message.setId);
|
||||
} else if (message.type === 'add-theme') {
|
||||
addTheme(message.themeGroup, message.themeName);
|
||||
} else if (message.type === 'add-set') {
|
||||
addSet(message.setName);
|
||||
} else if (message.type === 'add-token') {
|
||||
addToken(
|
||||
message.setId,
|
||||
message.tokenType,
|
||||
message.tokenName,
|
||||
message.tokenValue,
|
||||
);
|
||||
} else if (message.type === 'rename-theme') {
|
||||
renameTheme(message.themeId, message.newName);
|
||||
} else if (message.type === 'rename-set') {
|
||||
renameSet(message.setId, message.newName);
|
||||
} else if (message.type === 'rename-token') {
|
||||
renameToken(message.setId, message.tokenId, message.newName);
|
||||
} else if (message.type === 'delete-theme') {
|
||||
deleteTheme(message.themeId);
|
||||
} else if (message.type === 'delete-set') {
|
||||
deleteSet(message.setId);
|
||||
} else if (message.type === 'delete-token') {
|
||||
deleteToken(message.setId, message.tokenId);
|
||||
} else if (message.type === 'toggle-theme') {
|
||||
toggleTheme(message.themeId);
|
||||
} else if (message.type === 'toggle-set') {
|
||||
toggleSet(message.setId);
|
||||
} else if (message.type === 'apply-token') {
|
||||
applyToken(message.setId, message.tokenId, message.attributes);
|
||||
}
|
||||
});
|
||||
|
||||
function sendMessage(message: PluginMessageEvent) {
|
||||
penpot.ui.sendMessage(message);
|
||||
}
|
||||
|
||||
function loadLibrary() {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
|
||||
const themes = tokensCatalog.themes;
|
||||
|
||||
const themesData = themes.map((theme) => {
|
||||
return {
|
||||
id: theme.id,
|
||||
group: theme.group,
|
||||
name: theme.name,
|
||||
active: theme.active,
|
||||
};
|
||||
});
|
||||
|
||||
penpot.ui.sendMessage({
|
||||
source: 'penpot',
|
||||
type: 'set-themes',
|
||||
themesData,
|
||||
});
|
||||
|
||||
const sets = tokensCatalog.sets;
|
||||
|
||||
const setsData = sets.map((set) => {
|
||||
return {
|
||||
id: set.id,
|
||||
name: set.name,
|
||||
active: set.active,
|
||||
};
|
||||
});
|
||||
|
||||
penpot.ui.sendMessage({
|
||||
source: 'penpot',
|
||||
type: 'set-sets',
|
||||
setsData,
|
||||
});
|
||||
}
|
||||
|
||||
function loadTokens(setId: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.getSetById(setId);
|
||||
const tokensByType = set?.tokensByType;
|
||||
|
||||
const tokenGroupsData = [];
|
||||
if (tokensByType) {
|
||||
for (const group of tokensByType) {
|
||||
const type = group[0];
|
||||
const tokens = group[1];
|
||||
tokenGroupsData.push([
|
||||
type,
|
||||
tokens.map((token) => {
|
||||
return {
|
||||
id: token.id,
|
||||
name: token.name,
|
||||
description: token.description,
|
||||
};
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
penpot.ui.sendMessage({
|
||||
source: 'penpot',
|
||||
type: 'set-tokens',
|
||||
tokenGroupsData,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addTheme(themeGroup: string, themeName: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const theme = tokensCatalog?.addTheme(themeGroup, themeName);
|
||||
if (theme) {
|
||||
loadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
function addSet(setName: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.addSet(setName);
|
||||
if (set) {
|
||||
loadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
function addToken(
|
||||
setId: string,
|
||||
tokenType: string,
|
||||
tokenName: string,
|
||||
tokenValue: unknown,
|
||||
) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.getSetById(setId);
|
||||
const token = set?.addToken(tokenType as TokenType, tokenName, tokenValue);
|
||||
if (token) {
|
||||
loadTokens(setId);
|
||||
}
|
||||
}
|
||||
|
||||
function renameTheme(themeId: string, newName: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const theme = tokensCatalog?.getThemeById(themeId);
|
||||
if (theme) {
|
||||
theme.name = newName;
|
||||
loadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
function renameSet(setId: string, newName: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.getSetById(setId);
|
||||
if (set) {
|
||||
set.name = newName;
|
||||
loadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
function renameToken(setId: string, tokenId: string, newName: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.getSetById(setId);
|
||||
const token = set?.getTokenById(tokenId);
|
||||
if (token) {
|
||||
token.name = newName;
|
||||
loadTokens(setId);
|
||||
}
|
||||
}
|
||||
|
||||
function deleteTheme(themeId: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const theme = tokensCatalog?.getThemeById(themeId);
|
||||
if (theme) {
|
||||
theme.remove();
|
||||
loadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
function deleteSet(setId: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.getSetById(setId);
|
||||
if (set) {
|
||||
set.remove();
|
||||
loadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
function deleteToken(setId: string, tokenId: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.getSetById(setId);
|
||||
const token = set?.getTokenById(tokenId);
|
||||
if (token) {
|
||||
token.remove();
|
||||
loadTokens(setId);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleTheme(themeId: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const theme = tokensCatalog?.getThemeById(themeId);
|
||||
if (theme) {
|
||||
theme.toggleActive();
|
||||
loadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSet(setId: string) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.getSetById(setId);
|
||||
if (set) {
|
||||
set.toggleActive();
|
||||
loadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
function applyToken(
|
||||
setId: string,
|
||||
tokenId: string,
|
||||
attributes: TokenProperty[] | undefined,
|
||||
) {
|
||||
const tokensCatalog = penpot.library.local.tokens;
|
||||
const set = tokensCatalog?.getSetById(setId);
|
||||
const token = set?.getTokenById(tokenId);
|
||||
|
||||
if (token) {
|
||||
token.applyToSelected(attributes);
|
||||
}
|
||||
|
||||
// Alternatve way
|
||||
//
|
||||
// const selection = penpot.selection;
|
||||
// if (token && selection) {
|
||||
// for (const shape of selection) {
|
||||
// shape.applyToken(token, attributes);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
23
plugins/apps/poc-tokens-plugin/src/styles.css
Normal file
23
plugins/apps/poc-tokens-plugin/src/styles.css
Normal file
@@ -0,0 +1,23 @@
|
||||
/* @import "@penpot/plugin-styles/styles.css"; */
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
line-height: 1.5;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-block-start: var(--spacing-12);
|
||||
}
|
||||
|
||||
.title-l {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.headline-l {
|
||||
margin-block-start: var(--spacing-8);
|
||||
}
|
||||
10
plugins/apps/poc-tokens-plugin/tsconfig.app.json
Normal file
10
plugins/apps/poc-tokens-plugin/tsconfig.app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": []
|
||||
},
|
||||
"files": ["src/main.ts"],
|
||||
"include": ["src/**/*.d.ts"],
|
||||
"exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
}
|
||||
7
plugins/apps/poc-tokens-plugin/tsconfig.editor.json
Normal file
7
plugins/apps/poc-tokens-plugin/tsconfig.editor.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"compilerOptions": {
|
||||
"types": ["node"]
|
||||
}
|
||||
}
|
||||
33
plugins/apps/poc-tokens-plugin/tsconfig.json
Normal file
33
plugins/apps/poc-tokens-plugin/tsconfig.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"useDefineForClassFields": false,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.editor.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.plugin.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
}
|
||||
8
plugins/apps/poc-tokens-plugin/tsconfig.plugin.json
Normal file
8
plugins/apps/poc-tokens-plugin/tsconfig.plugin.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"types": []
|
||||
},
|
||||
"files": ["src/plugin.ts"],
|
||||
"include": ["../../libs/plugin-types/index.d.ts"]
|
||||
}
|
||||
1068
plugins/libs/plugin-types/index.d.ts
vendored
1068
plugins/libs/plugin-types/index.d.ts
vendored
File diff suppressed because it is too large
Load Diff
27170
plugins/package-lock.json
generated
27170
plugins/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
||||
"start:plugin:table": "nx run table-plugin:init",
|
||||
"start:plugin:renamelayers": "nx run rename-layers-plugin:init",
|
||||
"start:plugin:colors-to-tokens": "nx run colors-to-tokens-plugin:init",
|
||||
"start:plugin:poc-tokens": "nx run poc-tokens-plugin:init",
|
||||
"build": "nx build plugins-runtime --emptyOutDir=true",
|
||||
"build:plugins": "nx run-many -t build --parallel -p tag:type:plugin --exclude=poc-state-plugin",
|
||||
"build:styles-example": "nx run example-styles:build",
|
||||
|
||||
Reference in New Issue
Block a user