mirror of
https://github.com/penpot/penpot-plugins.git
synced 2025-04-15 16:31:36 -05:00
feat: colors to tokens export plugin
This commit is contained in:
parent
815181d20a
commit
7f8a011037
25 changed files with 1886 additions and 9 deletions
19
README.md
19
README.md
|
@ -47,15 +47,16 @@ A table listing the available plugins and their corresponding startup commands i
|
|||
|
||||
## Sample plugins
|
||||
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
||||
## Web Apps
|
||||
|
||||
|
|
51
apps/colors-to-tokens-plugin/eslint.config.js
Normal file
51
apps/colors-to-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
apps/colors-to-tokens-plugin/project.json
Normal file
79
apps/colors-to-tokens-plugin/project.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"name": "colors-to-tokens-plugin",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"sourceRoot": "apps/colors-to-tokens-plugin/src",
|
||||
"tags": ["type:plugin"],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@angular-devkit/build-angular:application",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/apps/colors-to-tokens-plugin",
|
||||
"index": "apps/colors-to-tokens-plugin/src/index.html",
|
||||
"browser": "apps/colors-to-tokens-plugin/src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "apps/colors-to-tokens-plugin/tsconfig.app.json",
|
||||
"assets": [
|
||||
"apps/colors-to-tokens-plugin/src/favicon.ico",
|
||||
"apps/colors-to-tokens-plugin/src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"libs/plugins-styles/src/lib/styles.css",
|
||||
"apps/colors-to-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": "colors-to-tokens-plugin:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "colors-to-tokens-plugin:build:development",
|
||||
"host": "0.0.0.0",
|
||||
"port": 4308
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"executor": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "colors-to-tokens-plugin:build"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
87
apps/colors-to-tokens-plugin/src/app/app.component.css
Normal file
87
apps/colors-to-tokens-plugin/src/app/app.component.css
Normal file
|
@ -0,0 +1,87 @@
|
|||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-24);
|
||||
padding-top: var(--spacing-36);
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--foreground-primary);
|
||||
}
|
||||
|
||||
.description {
|
||||
padding-bottom: var(--spacing-4);
|
||||
|
||||
a {
|
||||
color: var(--accent-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.title,
|
||||
.description {
|
||||
text-wrap: pretty;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: var(--spacing-8);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.download-btn {
|
||||
display: flex;
|
||||
gap: var(--spacing-4);
|
||||
align-items: center;
|
||||
|
||||
app-svg {
|
||||
--svg-stroke-color: var(--background-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.restart-btn {
|
||||
display: flex;
|
||||
gap: var(--spacing-4);
|
||||
align-items: center;
|
||||
|
||||
app-svg {
|
||||
--svg-stroke-color: var(--foreground-secondary);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
app-svg {
|
||||
--svg-stroke-color: var(--accent-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Override default button appearance */
|
||||
.download-btn[data-appearance='primary']:is(button):disabled {
|
||||
color: var(--background-secondary);
|
||||
background-color: var(--accent-primary-muted);
|
||||
border: 2px solid var(--accent-primary-muted);
|
||||
|
||||
app-svg {
|
||||
--svg-stroke-color: var(--background-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.success {
|
||||
display: flex;
|
||||
background-color: var(--success-950);
|
||||
border-radius: var(--spacing-8);
|
||||
border: 1px solid var(--success-500);
|
||||
color: var(--app-white);
|
||||
gap: var(--spacing-8);
|
||||
padding: var(--spacing-8);
|
||||
|
||||
app-svg {
|
||||
--svg-stroke-color: var(--success-500);
|
||||
}
|
||||
}
|
||||
|
||||
.download-note {
|
||||
padding: 0 var(--spacing-8);
|
||||
text-align: center;
|
||||
}
|
168
apps/colors-to-tokens-plugin/src/app/app.component.ts
Normal file
168
apps/colors-to-tokens-plugin/src/app/app.component.ts
Normal file
|
@ -0,0 +1,168 @@
|
|||
import { Component, effect, inject, linkedSignal } from '@angular/core';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import type {
|
||||
PluginMessageEvent,
|
||||
PluginUIEvent,
|
||||
ThemePluginEvent,
|
||||
SetColorsPluginEvent,
|
||||
} from '../model';
|
||||
import { filter, fromEvent, map, merge, take } from 'rxjs';
|
||||
import { transformToToken } from './utils/transform-to-token';
|
||||
import { SvgComponent } from './components/svg.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
imports: [SvgComponent],
|
||||
template: `
|
||||
<h1 class="title title-m">Convert your colors assets to Design Tokens</h1>
|
||||
<p class="description body-m">
|
||||
A Penpot plugin to generate a JSON file with your color styles in a
|
||||
<a target="_blank" href="https://tr.designtokens.org/format/"
|
||||
>Design Token Standard format</a
|
||||
>.
|
||||
</p>
|
||||
@if (result()) {
|
||||
<div class="success body-s">
|
||||
<app-svg name="tick" />
|
||||
Colors convertered to tokens successfully!
|
||||
</div>
|
||||
}
|
||||
<div class="actions">
|
||||
@if (result()) {
|
||||
<button
|
||||
type="button"
|
||||
data-appearance="secondary"
|
||||
class="restart-btn"
|
||||
(click)="restart()"
|
||||
>
|
||||
<app-svg name="reload" />
|
||||
Restart
|
||||
</button>
|
||||
} @else {
|
||||
<button type="button" (click)="convert()" data-appearance="primary">
|
||||
Convert colors
|
||||
</button>
|
||||
}
|
||||
|
||||
<button
|
||||
(click)="handleDownload()"
|
||||
class="download-btn"
|
||||
type="button"
|
||||
data-appearance="primary"
|
||||
[attr.disabled]="result() ? null : true"
|
||||
>
|
||||
<app-svg name="download" />
|
||||
Download
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- @if (result()) {
|
||||
<p class="body-m download-note">
|
||||
Now you can modify and import it (link to help center)
|
||||
</p>
|
||||
} -->
|
||||
`,
|
||||
styleUrl: './app.component.css',
|
||||
host: {
|
||||
'[attr.data-theme]': 'theme()',
|
||||
},
|
||||
})
|
||||
export class AppComponent {
|
||||
route = inject(ActivatedRoute);
|
||||
messages$ = fromEvent<MessageEvent<PluginMessageEvent>>(window, 'message');
|
||||
|
||||
initialTheme$ = this.route.queryParamMap.pipe(
|
||||
map((params) => params.get('theme')),
|
||||
filter((theme) => !!theme),
|
||||
take(1),
|
||||
);
|
||||
|
||||
theme = toSignal(
|
||||
merge(
|
||||
this.initialTheme$,
|
||||
this.messages$.pipe(
|
||||
filter(
|
||||
(event): event is MessageEvent<ThemePluginEvent> =>
|
||||
event.data.type === 'theme',
|
||||
),
|
||||
map((event) => {
|
||||
return event.data.content;
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
#result = toSignal(
|
||||
this.messages$.pipe(
|
||||
filter(
|
||||
(event): event is MessageEvent<SetColorsPluginEvent> =>
|
||||
event.data.type === 'set-colors',
|
||||
),
|
||||
map((event) => {
|
||||
if (event.data.colors) {
|
||||
try {
|
||||
const tokens = transformToToken(event.data.colors);
|
||||
|
||||
return {
|
||||
tokens,
|
||||
name: event.data.fileName,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}),
|
||||
),
|
||||
{
|
||||
initialValue: null,
|
||||
},
|
||||
);
|
||||
|
||||
result = linkedSignal(() => this.#result());
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
if (this.result()) {
|
||||
this.#sendMessage({
|
||||
type: 'resize',
|
||||
width: 410,
|
||||
height: 340,
|
||||
});
|
||||
} else {
|
||||
this.#sendMessage({ type: 'reset' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#sendMessage(message: PluginUIEvent): void {
|
||||
parent.postMessage(message, '*');
|
||||
}
|
||||
|
||||
convert(): void {
|
||||
this.#sendMessage({ type: 'get-colors' });
|
||||
}
|
||||
|
||||
restart(): void {
|
||||
this.result.set(null);
|
||||
}
|
||||
|
||||
handleDownload() {
|
||||
const fileTokens = this.#result();
|
||||
if (!fileTokens) return;
|
||||
|
||||
const blob = new Blob([JSON.stringify(fileTokens.tokens)], {
|
||||
type: 'text/json',
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = fileTokens.name + '-tokens.json';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
}
|
6
apps/colors-to-tokens-plugin/src/app/app.config.ts
Normal file
6
apps/colors-to-tokens-plugin/src/app/app.config.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { ApplicationConfig } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideRouter([])],
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
:host {
|
||||
display: block;
|
||||
|
||||
--svg-stroke-color: transparent;
|
||||
--svg-fill-color: transparent;
|
||||
|
||||
inline-size: var(--spacing-16);
|
||||
block-size: var(--spacing-16);
|
||||
}
|
||||
|
||||
svg {
|
||||
stroke: var(--svg-stroke-color);
|
||||
fill: var(--svg-fill-color);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
import { Component, input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-svg',
|
||||
template: `
|
||||
@switch (name()) {
|
||||
@case ('tick') {
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="1154.667 712.01 14.666 11.333"
|
||||
>
|
||||
<path d="m1167.333 714.01-7.333 7.333-3.333-3.333" />
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
d="m1167.333 714.01-7.333 7.333-3.333-3.333"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
@case ('download') {
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="859 710.01 16 16"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
d="M873 720.01v2.667a1.335 1.335 0 0 1-1.333 1.333h-9.334a1.335 1.335 0 0 1-1.333-1.333v-2.667m2.667-3.333L867 720.01m0 0 3.333-3.333M867 720.01v-8"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
@case ('reload') {
|
||||
<svg
|
||||
viewBox="0 0 16 16"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M2.4 8a6 6 0 1 1 1.758 4.242M2.4 8l2.1-2zm0 0L1 5.5z"></path>
|
||||
</svg>
|
||||
}
|
||||
}
|
||||
`,
|
||||
styleUrl: './svg.component.css',
|
||||
})
|
||||
export class SvgComponent {
|
||||
name = input.required<'tick' | 'download' | 'reload'>();
|
||||
}
|
|
@ -0,0 +1,498 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`transform colors to tokens 1`] = `
|
||||
{
|
||||
"colors": {
|
||||
"blue": {
|
||||
"050": {
|
||||
"$type": "color",
|
||||
"$value": "#ebf8ff",
|
||||
},
|
||||
"100": {
|
||||
"$type": "color",
|
||||
"$value": "#bee3f8",
|
||||
},
|
||||
"650": {
|
||||
"$type": "color",
|
||||
"$value": "#2a4365",
|
||||
},
|
||||
"700": {
|
||||
"$type": "color",
|
||||
"$value": "#2c5282",
|
||||
},
|
||||
"900": {
|
||||
"$type": "color",
|
||||
"$value": "#1a365d",
|
||||
},
|
||||
},
|
||||
"gray": {
|
||||
"100": {
|
||||
"$type": "color",
|
||||
"$value": "#edf2f7",
|
||||
},
|
||||
"200": {
|
||||
"$type": "color",
|
||||
"$value": "#e2e8f0",
|
||||
},
|
||||
"400": {
|
||||
"$type": "color",
|
||||
"$value": "#a0aec0",
|
||||
},
|
||||
"600": {
|
||||
"$type": "color",
|
||||
"$value": "#4a5568",
|
||||
},
|
||||
"700": {
|
||||
"$type": "color",
|
||||
"$value": "#2d3748",
|
||||
},
|
||||
"800": {
|
||||
"$type": "color",
|
||||
"$value": "#1a202c",
|
||||
},
|
||||
},
|
||||
"green": {
|
||||
"050": {
|
||||
"$type": "color",
|
||||
"$value": "#f0fff4",
|
||||
},
|
||||
"100": {
|
||||
"$type": "color",
|
||||
"$value": "#c6f6d5",
|
||||
},
|
||||
"300": {
|
||||
"$type": "color",
|
||||
"$value": "#68d391",
|
||||
},
|
||||
"500": {
|
||||
"$type": "color",
|
||||
"$value": "#38a169",
|
||||
},
|
||||
"600": {
|
||||
"$type": "color",
|
||||
"$value": "#2f855a",
|
||||
},
|
||||
"700": {
|
||||
"$type": "color",
|
||||
"$value": "#276749",
|
||||
},
|
||||
"800": {
|
||||
"$type": "color",
|
||||
"$value": "#22543d",
|
||||
},
|
||||
},
|
||||
"pink": {
|
||||
"100": {
|
||||
"$type": "color",
|
||||
"$value": "#fed7e2",
|
||||
},
|
||||
},
|
||||
"purple": {
|
||||
"100": {
|
||||
"$type": "color",
|
||||
"$value": "#e9d8fd",
|
||||
},
|
||||
"300": {
|
||||
"$type": "color",
|
||||
"$value": "#b794f4",
|
||||
},
|
||||
"500": {
|
||||
"$type": "color",
|
||||
"$value": "#805ad5",
|
||||
},
|
||||
},
|
||||
"red": {
|
||||
"100": {
|
||||
"$type": "color",
|
||||
"$value": "#FED7D7",
|
||||
},
|
||||
"300": {
|
||||
"$type": "color",
|
||||
"$value": "#FC8181",
|
||||
},
|
||||
"500": {
|
||||
"$type": "color",
|
||||
"$value": "#e53e3e",
|
||||
},
|
||||
"600": {
|
||||
"$type": "color",
|
||||
"$value": "#c53030",
|
||||
},
|
||||
"800": {
|
||||
"$type": "color",
|
||||
"$value": "#822727",
|
||||
},
|
||||
},
|
||||
"shadow": {
|
||||
"dark": {
|
||||
"$type": "color",
|
||||
"$value": "#00000069",
|
||||
},
|
||||
"light": {
|
||||
"$type": "color",
|
||||
"$value": "#00000016",
|
||||
},
|
||||
"mid": {
|
||||
"$type": "color",
|
||||
"$value": "#00000060",
|
||||
},
|
||||
},
|
||||
"white": {
|
||||
"$type": "color",
|
||||
"$value": "#ffffff",
|
||||
},
|
||||
"yellow": {
|
||||
"050": {
|
||||
"$type": "color",
|
||||
"$value": "#fffff0",
|
||||
},
|
||||
"100": {
|
||||
"$type": "color",
|
||||
"$value": "#fefcbf",
|
||||
},
|
||||
"200": {
|
||||
"$type": "color",
|
||||
"$value": "#faf089",
|
||||
},
|
||||
"700": {
|
||||
"$type": "color",
|
||||
"$value": "#975a16",
|
||||
},
|
||||
"800": {
|
||||
"$type": "color",
|
||||
"$value": "#744210",
|
||||
},
|
||||
},
|
||||
},
|
||||
"ui/darkmode": {
|
||||
"dm": {
|
||||
"background": {
|
||||
"blue": {
|
||||
"$type": "color",
|
||||
"$value": "#1a365d",
|
||||
},
|
||||
"green": {
|
||||
"$type": "color",
|
||||
"$value": "#1c4532",
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#5f370e",
|
||||
},
|
||||
},
|
||||
"button": {
|
||||
"blue": {
|
||||
"$type": "color",
|
||||
"$value": "#2b6cb0",
|
||||
},
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#4a5568",
|
||||
},
|
||||
"green": {
|
||||
"$type": "color",
|
||||
"$value": "#2f855a",
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#975a16",
|
||||
},
|
||||
"yellow[DONTUSE]": {
|
||||
"$type": "color",
|
||||
"$value": "#fefcbf",
|
||||
},
|
||||
},
|
||||
"card": {
|
||||
"background": {
|
||||
"$type": "color",
|
||||
"$value": "#2d3748",
|
||||
},
|
||||
},
|
||||
"chart": {
|
||||
"accent": {
|
||||
"$type": "color",
|
||||
"$value": "#9f7aea",
|
||||
"alt": {
|
||||
"$type": "color",
|
||||
"$value": "#ecc94b",
|
||||
},
|
||||
},
|
||||
"background": {
|
||||
"$type": "color",
|
||||
"$value": "#4a5568",
|
||||
},
|
||||
"green": {
|
||||
"$type": "color",
|
||||
"$value": "#38a169",
|
||||
},
|
||||
"red": {
|
||||
"$type": "color",
|
||||
"$value": "#e53e3e",
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#ecc94b",
|
||||
},
|
||||
},
|
||||
"dashboard": {
|
||||
"background": {
|
||||
"$type": "color",
|
||||
"$value": "#1a202c",
|
||||
},
|
||||
},
|
||||
"footer": {
|
||||
"$type": "color",
|
||||
"$value": "#1a202c",
|
||||
},
|
||||
"icon": {
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#e2e8f0",
|
||||
},
|
||||
"secondary": {
|
||||
"$type": "color",
|
||||
"$value": "#718096",
|
||||
},
|
||||
},
|
||||
"input": {
|
||||
"$type": "color",
|
||||
"$value": "#4a5568",
|
||||
},
|
||||
"label": {
|
||||
"$type": "color",
|
||||
"$value": "#a0aec0",
|
||||
},
|
||||
"sidebar": {
|
||||
"$type": "color",
|
||||
"$value": "#171923",
|
||||
},
|
||||
"text": {
|
||||
"blue": {
|
||||
"$type": "color",
|
||||
"$value": "#63b3ed",
|
||||
},
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#a0aec0",
|
||||
},
|
||||
"emphasis": {
|
||||
"$type": "color",
|
||||
"$value": "#edf2f7",
|
||||
},
|
||||
"green": {
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#68d391",
|
||||
},
|
||||
"emphasis": {
|
||||
"$type": "color",
|
||||
"$value": "#9ae6b4",
|
||||
},
|
||||
},
|
||||
"red": {
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#f56565",
|
||||
},
|
||||
"emphasis": {
|
||||
"$type": "color",
|
||||
"$value": "#FC8181",
|
||||
},
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#faf089",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"ui/lightmode": {
|
||||
"lm": {
|
||||
"axis": {
|
||||
"line": {
|
||||
"$type": "color",
|
||||
"$value": "#a0aec0",
|
||||
},
|
||||
},
|
||||
"background": {
|
||||
"blue": {
|
||||
"$type": "color",
|
||||
"$value": "#ebf8ff",
|
||||
},
|
||||
"green": {
|
||||
"$type": "color",
|
||||
"$value": "#f0fff4",
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#fffff0",
|
||||
},
|
||||
},
|
||||
"bar": {
|
||||
"line": {
|
||||
"$type": "color",
|
||||
"$value": "#a0aec040",
|
||||
},
|
||||
},
|
||||
"button": {
|
||||
"$type": "color",
|
||||
"$value": "#E2E8F0",
|
||||
"active": {
|
||||
"$type": "color",
|
||||
"$value": "#a0aec0",
|
||||
},
|
||||
"blue": {
|
||||
"$type": "color",
|
||||
"$value": "#bee3f8",
|
||||
},
|
||||
"green": {
|
||||
"$type": "color",
|
||||
"$value": "#c6f6d5",
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#fefcbf",
|
||||
},
|
||||
},
|
||||
"card": {
|
||||
"background": {
|
||||
"$type": "color",
|
||||
"$value": "#ffffff",
|
||||
},
|
||||
},
|
||||
"chart": {
|
||||
"accent": {
|
||||
"$type": "color",
|
||||
"$value": "#b794f4",
|
||||
"alt": {
|
||||
"$type": "color",
|
||||
"$value": "#faf089",
|
||||
},
|
||||
},
|
||||
"background": {
|
||||
"$type": "color",
|
||||
"$value": "#E2E8F0",
|
||||
},
|
||||
"green": {
|
||||
"$type": "color",
|
||||
"$value": "#68d391",
|
||||
},
|
||||
"red": {
|
||||
"$type": "color",
|
||||
"$value": "#FC8181",
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#faf089",
|
||||
},
|
||||
},
|
||||
"dashboard": {
|
||||
"background": {
|
||||
"$type": "color",
|
||||
"$value": "#EDF2F7",
|
||||
},
|
||||
},
|
||||
"footer": {
|
||||
"$type": "color",
|
||||
"$value": "#e2e8f0",
|
||||
},
|
||||
"icon": {
|
||||
"blue": {
|
||||
"$type": "color",
|
||||
"$value": "#2a4365",
|
||||
},
|
||||
"blue1": {
|
||||
"$type": "color",
|
||||
"$value": "#bee3f8",
|
||||
},
|
||||
"blue2": {
|
||||
"$type": "color",
|
||||
"$value": "#0000ff",
|
||||
},
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#A0AEC0",
|
||||
},
|
||||
"green": {
|
||||
"$type": "color",
|
||||
"$value": "#276749",
|
||||
},
|
||||
"red": {
|
||||
"$type": "color",
|
||||
"$value": "#c53030",
|
||||
},
|
||||
"secondary": {
|
||||
"$type": "color",
|
||||
"$value": "#e2e8f0",
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#744210",
|
||||
},
|
||||
},
|
||||
"input": {
|
||||
"$type": "color",
|
||||
"$value": "#EDF2F7",
|
||||
},
|
||||
"label": {
|
||||
"$type": "color",
|
||||
"$value": "#4a5568",
|
||||
},
|
||||
"placeholder": {
|
||||
"$type": "color",
|
||||
"$value": "#718096",
|
||||
},
|
||||
"shadow": {
|
||||
"$type": "color",
|
||||
"$value": "#00000020",
|
||||
},
|
||||
"sidebar": {
|
||||
"$type": "color",
|
||||
"$value": "#1a202c",
|
||||
},
|
||||
"text": {
|
||||
"blue": {
|
||||
"$type": "color",
|
||||
"$value": "#2a4365",
|
||||
},
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#2d3748",
|
||||
},
|
||||
"emphasis": {
|
||||
"$type": "color",
|
||||
"$value": "#000000",
|
||||
},
|
||||
"green": {
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#22543d",
|
||||
},
|
||||
"emphasis": {
|
||||
"$type": "color",
|
||||
"$value": "#38a169",
|
||||
},
|
||||
},
|
||||
"red": {
|
||||
"default": {
|
||||
"$type": "color",
|
||||
"$value": "#822727",
|
||||
},
|
||||
"emphasis": {
|
||||
"$type": "color",
|
||||
"$value": "#e53e3e",
|
||||
},
|
||||
},
|
||||
"secondary": {
|
||||
"$type": "color",
|
||||
"$value": "#718096",
|
||||
},
|
||||
"yellow": {
|
||||
"$type": "color",
|
||||
"$value": "#744210",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
|
@ -0,0 +1,654 @@
|
|||
import { expect, test } from 'vitest';
|
||||
import { transformToToken } from './transform-to-token';
|
||||
|
||||
const initColors = [
|
||||
{
|
||||
name: 'dm chart yellow',
|
||||
color: '#ecc94b',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'dm text blue',
|
||||
color: '#63b3ed',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'green 700',
|
||||
color: '#276749',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm text green emphasis',
|
||||
color: '#9ae6b4',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm icon blue',
|
||||
color: '#2a4365',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm card background',
|
||||
color: '#ffffff',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'gray 600',
|
||||
color: '#4a5568',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'yellow 200',
|
||||
color: '#faf089',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm button',
|
||||
color: '#E2E8F0',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'green 300',
|
||||
color: '#68d391',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm chart red',
|
||||
color: '#e53e3e',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'gray 400',
|
||||
color: '#a0aec0',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm dashboard background',
|
||||
color: '#EDF2F7',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm text yellow',
|
||||
color: '#744210',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'pink 100',
|
||||
color: '#fed7e2',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm text secondary',
|
||||
color: '#718096',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'blue 900',
|
||||
color: '#1a365d',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'green 800',
|
||||
color: '#22543d',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'red 300',
|
||||
color: '#FC8181',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm button yellow',
|
||||
color: '#fefcbf',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm text red emphasis',
|
||||
color: '#e53e3e',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm chart green',
|
||||
color: '#38a169',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm placeholder',
|
||||
color: '#718096',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'purple 500',
|
||||
color: '#805ad5',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm chart yellow',
|
||||
color: '#faf089',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'shadow light',
|
||||
color: '#000000',
|
||||
opacity: 0.16078432,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm footer',
|
||||
color: '#1a202c',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'red 800',
|
||||
color: '#822727',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm text blue',
|
||||
color: '#2a4365',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'purple 300',
|
||||
color: '#b794f4',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'purple 100',
|
||||
color: '#e9d8fd',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm background blue',
|
||||
color: '#1a365d',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'dm text red default',
|
||||
color: '#f56565',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'gray 700',
|
||||
color: '#2d3748',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm button blue',
|
||||
color: '#bee3f8',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm icon default',
|
||||
color: '#e2e8f0',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'green 600',
|
||||
color: '#2f855a',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'yellow 100',
|
||||
color: '#fefcbf',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'blue 100',
|
||||
color: '#bee3f8',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm background yellow',
|
||||
color: '#5f370e',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'blue 650',
|
||||
color: '#2a4365',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm text green default',
|
||||
color: '#68d391',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm bar line',
|
||||
color: '#a0aec0',
|
||||
opacity: 0.4,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm background green',
|
||||
color: '#1c4532',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'dm button blue',
|
||||
color: '#2b6cb0',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'gray 100',
|
||||
color: '#edf2f7',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm button yellow',
|
||||
color: '#975a16',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
/* 3 different blue colors in the same path */
|
||||
{
|
||||
name: 'lm icon blue',
|
||||
color: '#bee3f8',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm icon blue',
|
||||
color: '#0000ff',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm text default',
|
||||
color: '#2d3748',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm icon red',
|
||||
color: '#c53030',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm text green default',
|
||||
color: '#22543d',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm icon green',
|
||||
color: '#276749',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'shadow dark',
|
||||
color: '#000000',
|
||||
opacity: 0.69803923,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm chart background',
|
||||
color: '#E2E8F0',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'yellow 050',
|
||||
color: '#fffff0',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'green 100',
|
||||
color: '#c6f6d5',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm sidebar',
|
||||
color: '#1a202c',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm label',
|
||||
color: '#a0aec0',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'green 050',
|
||||
color: '#f0fff4',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm button green',
|
||||
color: '#2f855a',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm label',
|
||||
color: '#4a5568',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm button active',
|
||||
color: '#a0aec0',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm icon secondary',
|
||||
color: '#718096',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'dm chart background',
|
||||
color: '#4a5568',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm axis line',
|
||||
color: '#a0aec0',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm button yellow[DONTUSE]',
|
||||
color: '#fefcbf',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'dm sidebar',
|
||||
color: '#171923',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'dm text emphasis',
|
||||
color: '#edf2f7',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm chart green',
|
||||
color: '#68d391',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm background blue',
|
||||
color: '#ebf8ff',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'red 100',
|
||||
color: '#FED7D7',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm text default',
|
||||
color: '#a0aec0',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'red 500',
|
||||
color: '#e53e3e',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'yellow 800',
|
||||
color: '#744210',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'blue 050',
|
||||
color: '#ebf8ff',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'gray 800',
|
||||
color: '#1a202c',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm background yellow',
|
||||
color: '#fffff0',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm chart accent',
|
||||
color: '#9f7aea',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm shadow',
|
||||
color: '#000000',
|
||||
opacity: 0.2,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm text red emphasis',
|
||||
color: '#FC8181',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'dm input',
|
||||
color: '#4a5568',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'dm chart accent alt',
|
||||
color: '#ecc94b',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm button green',
|
||||
color: '#c6f6d5',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'red 600',
|
||||
color: '#c53030',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm icon secondary',
|
||||
color: '#e2e8f0',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm text yellow',
|
||||
color: '#faf089',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'green 500',
|
||||
color: '#38a169',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'shadow mid',
|
||||
color: '#000000',
|
||||
opacity: 0.6,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm text green emphasis',
|
||||
color: '#38a169',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'blue 700',
|
||||
color: '#2c5282',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm text red default',
|
||||
color: '#822727',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm footer',
|
||||
color: '#e2e8f0',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm text emphasis',
|
||||
color: '#000000',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm card background',
|
||||
color: '#2d3748',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm chart accent',
|
||||
color: '#b794f4',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'white',
|
||||
color: '#ffffff',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'dm button default',
|
||||
color: '#4a5568',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm input',
|
||||
color: '#EDF2F7',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm chart accent alt',
|
||||
color: '#faf089',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'gray 200',
|
||||
color: '#e2e8f0',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm icon yellow',
|
||||
color: '#744210',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'dm dashboard background',
|
||||
color: '#1a202c',
|
||||
opacity: 1,
|
||||
path: 'ui / dark mode',
|
||||
},
|
||||
{
|
||||
name: 'lm icon default',
|
||||
color: '#A0AEC0',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'yellow 700',
|
||||
color: '#975a16',
|
||||
opacity: 1,
|
||||
path: 'colors',
|
||||
},
|
||||
{
|
||||
name: 'lm background green',
|
||||
color: '#f0fff4',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
{
|
||||
name: 'lm chart red',
|
||||
color: '#FC8181',
|
||||
opacity: 1,
|
||||
path: 'ui / light mode',
|
||||
},
|
||||
];
|
||||
|
||||
test('transform colors to tokens', () => {
|
||||
const result = transformToToken(initColors);
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
import { LibraryColor } from '@penpot/plugin-types';
|
||||
import { TokenStructure } from '../../model';
|
||||
|
||||
export function transformToToken(colors: LibraryColor[]) {
|
||||
const result: TokenStructure = {};
|
||||
|
||||
colors.forEach((data) => {
|
||||
const currentOpacity = data.opacity ?? 1;
|
||||
const opacity = currentOpacity < 1 ? Math.floor(currentOpacity * 100) : '';
|
||||
const value = `${data.color}${opacity}`;
|
||||
const names: string[] = data.name.split(' ');
|
||||
|
||||
const key: string = data.path.replace(' \\/ ', '/').replace(/ /g, '');
|
||||
|
||||
if (!result[key]) {
|
||||
result[key] = {};
|
||||
}
|
||||
|
||||
const props = [key, ...names];
|
||||
let acc = result;
|
||||
|
||||
props.forEach((prop, index) => {
|
||||
if (!acc[prop]) {
|
||||
acc[prop] = {};
|
||||
}
|
||||
|
||||
if (index === props.length - 1) {
|
||||
let propIndex = 1;
|
||||
const initialProp = prop;
|
||||
|
||||
while (acc[prop]?.$value) {
|
||||
prop = `${initialProp}${propIndex}`;
|
||||
propIndex++;
|
||||
}
|
||||
|
||||
acc[prop] = {
|
||||
$value: value,
|
||||
$type: 'color',
|
||||
};
|
||||
}
|
||||
|
||||
acc = acc[prop] as TokenStructure;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
BIN
apps/colors-to-tokens-plugin/src/assets/icon.png
Normal file
BIN
apps/colors-to-tokens-plugin/src/assets/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
7
apps/colors-to-tokens-plugin/src/assets/manifest.json
Normal file
7
apps/colors-to-tokens-plugin/src/assets/manifest.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "Colors to Tokens",
|
||||
"description": "Generate a design tokens file from a list of colors",
|
||||
"code": "/assets/plugin.js",
|
||||
"icon": "/assets/icon.png",
|
||||
"permissions": ["content:read", "library:read", "allow:downloads"]
|
||||
}
|
12
apps/colors-to-tokens-plugin/src/index.html
Normal file
12
apps/colors-to-tokens-plugin/src/index.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>colors-to-tokens-plugin</title>
|
||||
<base href="/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
7
apps/colors-to-tokens-plugin/src/main.ts
Normal file
7
apps/colors-to-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)
|
||||
);
|
42
apps/colors-to-tokens-plugin/src/model.ts
Normal file
42
apps/colors-to-tokens-plugin/src/model.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { LibraryColor } from '@penpot/plugin-types';
|
||||
|
||||
export interface Token {
|
||||
$value: string;
|
||||
$type: string;
|
||||
}
|
||||
|
||||
export type TokenStructure = {
|
||||
[key: string]: Token | TokenStructure;
|
||||
};
|
||||
|
||||
export interface GETColorsPluginUIEvent {
|
||||
type: 'get-colors';
|
||||
}
|
||||
|
||||
export interface ResetPluginUIEvent {
|
||||
type: 'reset';
|
||||
}
|
||||
|
||||
export interface ResizePluginUIEvent {
|
||||
type: 'resize';
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
export type PluginUIEvent =
|
||||
| GETColorsPluginUIEvent
|
||||
| ResizePluginUIEvent
|
||||
| ResetPluginUIEvent;
|
||||
|
||||
export interface ThemePluginEvent {
|
||||
type: 'theme';
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface SetColorsPluginEvent {
|
||||
type: 'set-colors';
|
||||
colors: LibraryColor[] | null;
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
export type PluginMessageEvent = ThemePluginEvent | SetColorsPluginEvent;
|
50
apps/colors-to-tokens-plugin/src/plugin.ts
Normal file
50
apps/colors-to-tokens-plugin/src/plugin.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import type { PluginMessageEvent, PluginUIEvent } from './model.js';
|
||||
|
||||
const defaultSize = {
|
||||
width: 410,
|
||||
height: 280,
|
||||
};
|
||||
|
||||
penpot.ui.open('COLORS TO TOKENS', `?theme=${penpot.theme}`, {
|
||||
width: defaultSize.width,
|
||||
height: defaultSize.height,
|
||||
});
|
||||
|
||||
penpot.on('themechange', (theme) => {
|
||||
sendMessage({ type: 'theme', content: theme });
|
||||
});
|
||||
|
||||
penpot.ui.onMessage<PluginUIEvent>((message) => {
|
||||
if (message.type === 'get-colors') {
|
||||
const colors = penpot.library.local.colors.filter(
|
||||
(color) => !color.gradient,
|
||||
);
|
||||
|
||||
const fileName = penpot.currentFile?.name ?? 'Untitled';
|
||||
|
||||
sendMessage({
|
||||
type: 'set-colors',
|
||||
colors,
|
||||
fileName,
|
||||
});
|
||||
} else if (message.type === 'resize') {
|
||||
if (
|
||||
penpot.ui.size?.width === defaultSize.width &&
|
||||
penpot.ui.size?.height === defaultSize.height
|
||||
) {
|
||||
resize(message.width, message.height);
|
||||
}
|
||||
} else if (message.type === 'reset') {
|
||||
resize(defaultSize.width, defaultSize.height);
|
||||
}
|
||||
});
|
||||
|
||||
function resize(width: number, height: number) {
|
||||
if ('resize' in penpot.ui) {
|
||||
(penpot as any).ui.resize(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
function sendMessage(message: PluginMessageEvent) {
|
||||
penpot.ui.sendMessage(message);
|
||||
}
|
0
apps/colors-to-tokens-plugin/src/styles.css
Normal file
0
apps/colors-to-tokens-plugin/src/styles.css
Normal file
10
apps/colors-to-tokens-plugin/tsconfig.app.json
Normal file
10
apps/colors-to-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": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
}
|
7
apps/colors-to-tokens-plugin/tsconfig.editor.json
Normal file
7
apps/colors-to-tokens-plugin/tsconfig.editor.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"compilerOptions": {
|
||||
"types": []
|
||||
}
|
||||
}
|
33
apps/colors-to-tokens-plugin/tsconfig.json
Normal file
33
apps/colors-to-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
apps/colors-to-tokens-plugin/tsconfig.plugin.json
Normal file
8
apps/colors-to-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"]
|
||||
}
|
26
apps/colors-to-tokens-plugin/tsconfig.spec.json
Normal file
26
apps/colors-to-tokens-plugin/tsconfig.spec.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
"vitest/importMeta",
|
||||
"vite/client",
|
||||
"node",
|
||||
"vitest"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"vitest.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
21
apps/colors-to-tokens-plugin/vite.config.ts
Normal file
21
apps/colors-to-tokens-plugin/vite.config.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
root: __dirname,
|
||||
cacheDir: '../node_modules/.vite/colors-to-tokens-plugin',
|
||||
test: {
|
||||
watch: false,
|
||||
globals: true,
|
||||
cache: {
|
||||
dir: '../node_modules/.vitest',
|
||||
},
|
||||
environment: 'jsdom',
|
||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
reporters: ['default'],
|
||||
coverage: {
|
||||
reportsDirectory: '../coverage/colors-to-tokens-plugin',
|
||||
provider: 'v8',
|
||||
},
|
||||
},
|
||||
});
|
|
@ -15,6 +15,7 @@
|
|||
"start:plugin:palette": "npx nx run create-palette-plugin:build --watch & npx nx run create-palette-plugin:preview",
|
||||
"start:plugin:table": "npx nx run table-plugin:init",
|
||||
"start:plugin:renamelayers": "npx nx run rename-layers-plugin:init",
|
||||
"start:plugin:colors-to-tokens": "npx nx run colors-to-tokens-plugin:init",
|
||||
"build": "npx nx build plugins-runtime --emptyOutDir=true",
|
||||
"build:plugins": "npx nx run-many -t build --parallel -p tag:type:plugin --exclude=poc-state-plugin",
|
||||
"build:styles-example": "npx nx run example-styles:build",
|
||||
|
|
Loading…
Add table
Reference in a new issue