-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: figma plugin for palette local variables
- Loading branch information
1 parent
b1c84ac
commit 939b4a6
Showing
31 changed files
with
1,354 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Otter Figma plugin for color palettes in local variables (V1) - User guide | ||
|
||
## Introduction | ||
The Otter Figma plugin helps you manage color palettes in local variables. Follow these steps to use the plugin effectively. | ||
|
||
## Prerequisites | ||
- You'll need the [Color Shades](https://www.figma.com/community/plugin/929607085343688745/color-shades) plugin to generate initial palettes. | ||
|
||
## Steps to use the Otter plugin | ||
|
||
1. **Generate color palettes**: | ||
- Use the Color Shades plugin to create your color palettes. | ||
|
||
 | ||
- Copy the generated UI elements from the Figma page. | ||
|
||
 | ||
The output should have this format: | ||
``` | ||
0 | ||
#F4F7F7 | ||
0.5 | ||
#E4EAEA | ||
1 | ||
#D3DDDC | ||
1.5 | ||
#C3D0CF | ||
2 | ||
#B2C3C1 | ||
3 | ||
#91A8A7 | ||
4 | ||
#708E8C | ||
5 | ||
#4F7471 | ||
6 | ||
#3F5D5A | ||
7 | ||
#2F4644 | ||
8 | ||
#202E2D | ||
8.5 | ||
#182322 | ||
9 | ||
#101717 | ||
9.5 | ||
#080C0B | ||
10 | ||
#000000 | ||
``` | ||
2. **Open the Otter plugin**: | ||
- Launch the Otter plugin in Figma. | ||
|
||
 | ||
|
||
3. **Configure the plugin**: | ||
- Select values from the dropdowns for **Collections**, **Palette name**, and **Mode**. | ||
- Paste the copied values into the **Shades** input area. | ||
- Adjust the filter values if needed (default: **15, 85, 95**). | ||
|
||
4. **Add Variables**: | ||
- Click the **"Add variables"** button to update the local variables with the new shades. | ||
|
||
### Current Limitations | ||
- **Update Only**: Currently, the plugin only supports updating existing variables. Creating new variables is not yet supported. | ||
- **Future Enhancements**: Future versions will support creating new variables and generating palettes directly within the Otter plugin. | ||
|
||
## Conclusion | ||
By following these steps, you can efficiently manage your color palettes in local variables using the Otter Figma plugin. Happy designing! | ||
|
||
If you have any questions or need further assistance, feel free to [reach out](https://github.com/AmadeusITGroup/otter/issues). |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import shared from '../../eslint.shared.config.mjs'; | ||
import local from './eslint.local.config.mjs'; | ||
|
||
export default [ | ||
...shared, | ||
...local | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { | ||
dirname, | ||
} from 'node:path'; | ||
import { | ||
fileURLToPath, | ||
} from 'node:url'; | ||
import globals from 'globals'; | ||
|
||
const __filename = fileURLToPath(import.meta.url); | ||
// __dirname is not defined in ES module scope | ||
const __dirname = dirname(__filename); | ||
|
||
export default [ | ||
{ | ||
name: '@o3r/palette-generator/projects', | ||
languageOptions: { | ||
sourceType: 'module', | ||
parserOptions: { | ||
tsconfigRootDir: __dirname, | ||
project: [ | ||
'tsconfig.build.json', | ||
'tsconfig.build.plugin.json', | ||
'tsconfig.spec.json', | ||
'tsconfig.eslint.json' | ||
] | ||
}, | ||
globals: { | ||
// TODO: support for flat config https://github.com/figma/eslint-plugin-figma-plugins/issues/28 | ||
figma: 'readonly', | ||
__html__: 'readonly' | ||
} | ||
} | ||
}, | ||
{ | ||
name: '@o3r/palette-generator/webpack', | ||
files: ['webpack.config.js'], | ||
languageOptions: { | ||
globals: { | ||
...globals.node, | ||
NodeJS: true, | ||
globalThis: true | ||
} | ||
} | ||
} | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const getJestGlobalConfig = require('../../jest.config.ut').getJestGlobalConfig; | ||
|
||
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */ | ||
module.exports = { | ||
...getJestGlobalConfig(__dirname), | ||
projects: [ | ||
'<rootDir>/testing/jest.config.ut.js' | ||
] | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "Otter Palette Generator", | ||
"id": "1471168859479115202", | ||
"api": "1.0.0", | ||
"main": "src/plugin/code.js", | ||
"capabilities": [], | ||
"enableProposedApi": false, | ||
"documentAccess": "dynamic-page", | ||
"editorType": [ | ||
"figma" | ||
], | ||
"ui": "src/ui/ui.html", | ||
"networkAccess": { | ||
"allowedDomains": [ | ||
"none" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
{ | ||
"name": "@o3r/palette-generator", | ||
"version": "0.0.0-placeholder", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"description": "Figma Plugin for generating palettes and storing them in Local Variables", | ||
"sideEffects": false, | ||
"scripts": { | ||
"nx": "nx", | ||
"ng": "yarn nx", | ||
"build": "yarn nx build o3r-palette-generator", | ||
"build:plugin": "esbuild src/plugin/code.ts --bundle --outfile=dist/src/plugin/code.js", | ||
"build:ui": "tsc -p tsconfig.build.json && webpack", | ||
"postbuild": "yarn cpy './manifest.json' dist" | ||
}, | ||
"dependencies": { | ||
"tslib": "^2.6.2" | ||
}, | ||
"devDependencies": { | ||
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0", | ||
"@figma/eslint-plugin-figma-plugins": "^0.15.0", | ||
"@figma/plugin-typings": "^1.107.0", | ||
"@nx/eslint-plugin": "~20.4.0", | ||
"@nx/jest": "~20.4.0", | ||
"@o3r/build-helpers": "workspace:^", | ||
"@o3r/eslint-plugin": "workspace:^", | ||
"@schematics/angular": "~19.1.0", | ||
"@stylistic/eslint-plugin": "~3.1.0", | ||
"@stylistic/eslint-plugin-ts": "~3.1.0", | ||
"@types/jest": "~29.5.2", | ||
"@types/node": "^20.0.0", | ||
"@typescript-eslint/parser": "~8.24.0", | ||
"angular-eslint": "~19.1.0", | ||
"cpy-cli": "^5.0.0", | ||
"esbuild": "~0.25.0", | ||
"eslint": "~9.20.0", | ||
"eslint-import-resolver-node": "^0.3.9", | ||
"eslint-import-resolver-typescript": "^3.6.3", | ||
"eslint-plugin-import": "^2.31.0", | ||
"eslint-plugin-import-newlines": "^1.4.0", | ||
"eslint-plugin-jest": "~28.11.0", | ||
"eslint-plugin-jsdoc": "~50.6.0", | ||
"eslint-plugin-prefer-arrow": "~1.2.3", | ||
"eslint-plugin-unicorn": "^56.0.0", | ||
"eslint-plugin-unused-imports": "^4.1.4", | ||
"globals": "^15.9.0", | ||
"html-inline-script-webpack-plugin": "^3.1.0", | ||
"html-webpack-plugin": "^5.3.2", | ||
"jest": "~29.7.0", | ||
"jest-environment-jsdom": "~29.7.0", | ||
"jest-junit": "~16.0.0", | ||
"jsonc-eslint-parser": "~2.4.0", | ||
"style-loader": "^3.2.1", | ||
"ts-jest": "~29.2.5", | ||
"ts-loader": "^9.5.2", | ||
"ts-node": "~10.9.2", | ||
"type-fest": "^4.30.1", | ||
"typescript": "~5.7.3", | ||
"typescript-eslint": "~8.24.0", | ||
"url-loader": "^4.1.1", | ||
"webpack": "~5.98.0", | ||
"webpack-cli": "~6.0.0" | ||
}, | ||
"engines": { | ||
"node": "^18.19.1 || ^20.11.1 || >=22.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"name": "o3r-palette-generator", | ||
"$schema": "https://raw.githubusercontent.com/nrwl/nx/master/packages/nx/schemas/project-schema.json", | ||
"projectType": "application", | ||
"sourceRoot": "apps/palette-generator/src", | ||
"prefix": "o3r", | ||
"targets": { | ||
"build": { | ||
"executor": "nx:run-script", | ||
"outputs": ["{projectRoot}/dist/package.json"], | ||
"options": { | ||
"script": "postbuild" | ||
}, | ||
"dependsOn": [ | ||
"build-plugin" | ||
] | ||
}, | ||
"build-plugin": { | ||
"executor": "nx:run-script", | ||
"options": { | ||
"script": "build:plugin" | ||
}, | ||
"outputs": ["{projectRoot}/dist/src"], | ||
"dependsOn": [ | ||
"build-ui" | ||
] | ||
}, | ||
"build-ui": { | ||
"executor": "nx:run-script", | ||
"options": { | ||
"script": "build:ui" | ||
}, | ||
"outputs": ["{projectRoot}/dist/src"] | ||
}, | ||
"lint": {}, | ||
"test": { | ||
"options": { | ||
"passWithNoTests": true | ||
} | ||
} | ||
}, | ||
"tags": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* Represents a mode with an ID and a name. | ||
*/ | ||
interface Mode { | ||
/** The unique identifier for the mode. */ | ||
modeId: string; | ||
/** The name of the mode. */ | ||
name: string; | ||
} | ||
|
||
/** | ||
* Represents the data for variables. | ||
*/ | ||
export interface VariablesData { | ||
/** The name of the palette. */ | ||
paletteName: string; | ||
/** The input for shades. */ | ||
shadesInput: string; | ||
/** The values that will be filtered out, comma separated. */ | ||
filter: string; | ||
/** The ID of the collection. */ | ||
collectionId: string; | ||
/** The ID of the mode. */ | ||
modeId: string; | ||
} | ||
|
||
/** | ||
* Represents a collection with an ID, name, modes, and palettes. | ||
*/ | ||
export interface Collection { | ||
/** The unique identifier for the collection. */ | ||
id: string; | ||
/** The name of the collection. */ | ||
name: string; | ||
/** The modes available in the collection. */ | ||
modes: Mode[]; | ||
/** The palettes available in the collection. */ | ||
palettes: string[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import type { | ||
Collection, | ||
VariablesData, | ||
} from '../contract'; | ||
|
||
/** | ||
* Initializes the plugin by fetching collections and color variables, | ||
* then sends the data to the UI. | ||
*/ | ||
async function initialize() { | ||
const collections = await figma.variables.getLocalVariableCollectionsAsync(); | ||
const colorVars = await figma.variables.getLocalVariablesAsync('COLOR'); | ||
const collectionsForUi: Collection[] = collections.map((collection) => { | ||
const collectionPalettes = Array.from(new Set(colorVars | ||
.filter((v) => v.variableCollectionId === collection.id && v.name.startsWith('color/')) | ||
.map((variable) => variable.name.split('/')[1]))); | ||
return { id: collection.id, name: collection.name, modes: collection.modes, palettes: collectionPalettes }; | ||
}); | ||
figma.showUI(__html__, { width: 400, height: 670 }); | ||
if (collectionsForUi.length > 0) { | ||
figma.ui.postMessage({ type: 'collections', data: collectionsForUi }); | ||
} else { | ||
figma.ui.postMessage({ type: 'no-collections' }); | ||
} | ||
} | ||
|
||
// eslint-disable-next-line unicorn/prefer-add-event-listener -- Figma API | ||
figma.ui.onmessage = async (msg: { type: string; data: any }) => { | ||
const colorVars: { key: string; value: string }[] = []; | ||
if (msg.type === 'store-vars') { | ||
const varData = msg.data as VariablesData; | ||
const excludedKeys = new Set(varData.filter.split(',')); | ||
// shades input come as line seprated values, even lines represent the palette name (0, 0.5 etc) and odd ones the colors in hex format | ||
const shadesInput = varData.shadesInput.split('\n'); | ||
for (let i = 0; i < shadesInput.length; i += 2) { | ||
const key = (Number.parseFloat(shadesInput[i]) * 10).toString().padStart(2, '0'); | ||
if (!excludedKeys.has(key)) { | ||
const value = shadesInput[i + 1]; | ||
colorVars.push({ key, value }); | ||
} | ||
} | ||
const collection = await figma.variables.getVariableCollectionByIdAsync(varData.collectionId); | ||
const variables = await figma.variables.getLocalVariablesAsync(); | ||
for (const colorVar of colorVars) { | ||
const varName = `color/${varData.paletteName}/${colorVar.key}`; | ||
const existingVar = variables.find((variable) => variable.name === varName); | ||
if (existingVar) { | ||
existingVar.setValueForMode(varData.modeId, figma.util.rgb(colorVar.value)); | ||
} else if (collection) { | ||
const newVar = figma.variables.createVariable(varName, collection, 'COLOR'); | ||
newVar.setValueForMode(varData.modeId, figma.util.rgb(colorVar.value)); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
void initialize(); |
Oops, something went wrong.