-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ulf Schuster
committed
Jun 27, 2023
0 parents
commit d6ae39c
Showing
8 changed files
with
326 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Node | ||
*.log | ||
*.log.* | ||
node_modules | ||
|
||
out/ | ||
dist/ | ||
code.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,15 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"type": "chrome", | ||
"request": "launch", | ||
"name": "Launch Chrome against localhost", | ||
"url": "http://localhost:8080", | ||
"webRoot": "${workspaceFolder}" | ||
} | ||
] | ||
} |
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,26 @@ | ||
GitHub Copilot: Sure, here's a possible repository description for this Figma plugin: | ||
|
||
# Figma Spacing and Typography Plugin | ||
|
||
This is a plugin for Figma that helps you update the spacing and typography of your designs. It replaces padding, gap, and font size values in selected frames and text nodes, using a set of predefined rules. The plugin also loads all the fonts used in the text nodes asynchronously, to ensure that the new font sizes are applied correctly. | ||
|
||
## Features | ||
|
||
- Replace padding, gap, and font size values in selected frames and text nodes | ||
- Load all fonts used in the text nodes asynchronously | ||
- Apply a set of predefined rules to calculate the new values | ||
- Show an error message if no frame is selected or no text nodes are found | ||
- Notify the user when the spacings and font sizes have been updated successfully | ||
|
||
## Usage | ||
|
||
To use the plugin, select a frame that contains nodes with padding, gap, or font size values that you want to update. Then, run the plugin from the Figma menu or using the keyboard shortcut. The plugin will replace the values in all the selected nodes, and notify you when the process is complete. | ||
|
||
## Installation | ||
|
||
To install the plugin, download the source code from this repository and open it in Figma. Then, go to the Plugins menu, select "Development" > "Create Plugin", and choose the "manifest.json" file from the source code folder. Finally, click "Create Plugin" and the plugin will be installed in your Figma account. | ||
|
||
## License | ||
|
||
This plugin is licensed under the MIT License. See the LICENSE file for more information. | ||
|
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,199 @@ | ||
// Function for loading all fonts used in a text node | ||
const loadFonts = async (textNode: TextNode) => { | ||
// Get an array of all the font names used in the text node | ||
const fontNames = textNode.getRangeAllFontNames(0, textNode.characters.length); | ||
|
||
// Load all the fonts asynchronously | ||
await Promise.all(fontNames.map(figma.loadFontAsync)); | ||
}; | ||
|
||
// Define the new line heights as an array | ||
const skipLineHeights = false; | ||
|
||
// Get the selected frame | ||
const selectedFrame = figma.currentPage.selection[0] as FrameNode; | ||
|
||
if (selectedFrame) { | ||
const nodesToReplace = []; | ||
|
||
// Find all nodes with padding, gap, or font size values to replace | ||
function findNodesToReplace(node: BaseNode) { | ||
if ('paddingLeft' in node || 'paddingRight' in node || 'paddingTop' in node || 'paddingBottom' in node || 'itemSpacing' in node || 'gridStyleId' in node) { | ||
nodesToReplace.push(node); | ||
} | ||
|
||
if ('children' in node) { | ||
node.children.forEach(child => findNodesToReplace(child)); | ||
} | ||
} | ||
|
||
findNodesToReplace(selectedFrame); | ||
|
||
// Replace padding and gap values in all nodes | ||
nodesToReplace.forEach(node => { | ||
if ('paddingLeft' in node) { | ||
node.paddingLeft = replacePaddingValue(node.paddingLeft); | ||
} | ||
|
||
if ('paddingRight' in node) { | ||
node.paddingRight = replacePaddingValue(node.paddingRight); | ||
} | ||
|
||
if ('paddingTop' in node) { | ||
node.paddingTop = replacePaddingValue(node.paddingTop); | ||
} | ||
|
||
if ('paddingBottom' in node) { | ||
node.paddingBottom = replacePaddingValue(node.paddingBottom); | ||
} | ||
|
||
if ('itemSpacing' in node) { | ||
node.itemSpacing = replacePaddingValue(node.itemSpacing); | ||
} | ||
|
||
if ('gridStyleId' in node) { | ||
node.gridStyleId = replacePaddingValue(node.gridStyleId); | ||
} | ||
}); | ||
|
||
// Replace font sizes and line heights in all text nodes | ||
const textNodes = selectedFrame.findAll(node => node.type === "TEXT") as TextNode[]; | ||
if (textNodes.length === 0) { | ||
// Show an error message if no text nodes are found | ||
figma.notify("Spacings updated successfully."); | ||
figma.closePlugin(); | ||
} else { | ||
// Keep track of the number of fonts that are still loading | ||
let numFontsLoading = 0; | ||
|
||
textNodes.forEach(async textNode => { | ||
// Load all fonts used in the text node | ||
numFontsLoading++; | ||
await loadFonts(textNode); | ||
|
||
// Replace font size in the text node | ||
const oldFontSize = textNode.fontSize; | ||
const newFontSize = getNewFontSize(oldFontSize); | ||
textNode.fontSize = newFontSize; | ||
|
||
// Replace line height in the text node | ||
if (textNode.lineHeight.unit === "PIXELS") { | ||
const lineHeight = textNode.lineHeight.value; | ||
const newLineHeight = getNewLineHeight(lineHeight); | ||
textNode.lineHeight = { unit: "PIXELS", value: newLineHeight }; | ||
} | ||
// Reset the line height of the text node to "auto" | ||
if (skipLineHeights === true) { | ||
textNode.lineHeight = { unit: "AUTO" }; | ||
} | ||
|
||
// Decrement the count of fonts that are still loading | ||
numFontsLoading--; | ||
if (numFontsLoading === 0) { | ||
// Close the plugin when all fonts have finished loading | ||
figma.notify("Font sizes and spacings updated successfully."); | ||
figma.closePlugin(); | ||
} | ||
}); | ||
} | ||
} else { | ||
// Show an error message if no frame is selected | ||
figma.notify("Please select a frame."); | ||
figma.closePlugin(); | ||
} | ||
|
||
function replacePaddingValue(value: number): number { | ||
const paddingValuesToReplace = getPaddingValuesToReplace(); | ||
const paddingNewValues = paddingValuesToReplace.map(getNewPaddingValue); | ||
const index = paddingValuesToReplace.indexOf(value); | ||
if (index !== -1) { | ||
return paddingNewValues[index]; | ||
} | ||
return value; | ||
} | ||
|
||
function getPaddingValuesToReplace(): number[] { | ||
const paddingValuesToReplace = new Set<number>(); | ||
const nodesToCheck = [selectedFrame]; | ||
while (nodesToCheck.length > 0) { | ||
const node = nodesToCheck.pop(); | ||
if ('paddingLeft' in node) { | ||
paddingValuesToReplace.add(node.paddingLeft); | ||
} | ||
if ('paddingRight' in node) { | ||
paddingValuesToReplace.add(node.paddingRight); | ||
} | ||
if ('paddingTop' in node) { | ||
paddingValuesToReplace.add(node.paddingTop); | ||
} | ||
if ('paddingBottom' in node) { | ||
paddingValuesToReplace.add(node.paddingBottom); | ||
} | ||
if ('itemSpacing' in node) { | ||
paddingValuesToReplace.add(node.itemSpacing); | ||
} | ||
if ('gridStyleId' in node) { | ||
paddingValuesToReplace.add(node.gridStyleId); | ||
} | ||
if ('children' in node) { | ||
nodesToCheck.push(...node.children); | ||
} | ||
} | ||
return Array.from(paddingValuesToReplace); | ||
} | ||
|
||
function getNewPaddingValue(oldValue: number): number { | ||
switch (true) { | ||
case (oldValue <= 16): | ||
return oldValue; | ||
case (oldValue <= 24): | ||
return Math.floor(oldValue / 16) * 14; | ||
case (oldValue <= 32): | ||
return Math.floor(oldValue / 16) * 12; | ||
case (oldValue <= 48): | ||
return Math.floor(oldValue / 16) * 10; | ||
case (oldValue <= 80): | ||
return Math.floor(oldValue / 16) * 8; | ||
case (oldValue <= 128): | ||
return Math.floor(oldValue / 16) * 6; | ||
default: | ||
return Math.floor(oldValue / 16) * 4; | ||
} | ||
} | ||
|
||
function getNewLineHeight(oldValue: number): number { | ||
switch (true) { | ||
case (oldValue <= 16): | ||
return oldValue; | ||
case (oldValue <= 24): | ||
case (oldValue <= 32): | ||
return Math.floor(oldValue / 16) * 14; | ||
case (oldValue <= 48): | ||
return Math.floor(oldValue / 16) * 12; | ||
case (oldValue <= 80): | ||
return Math.floor(oldValue / 16) * 10; | ||
case (oldValue <= 128): | ||
case (oldValue <= 256): | ||
return Math.floor(oldValue / 16) * 8; | ||
default: | ||
return Math.floor(oldValue / 16) * 4; | ||
} | ||
} | ||
function getNewFontSize(oldValue: number): number { | ||
switch (true) { | ||
case (oldValue <= 16): | ||
return oldValue; | ||
case (oldValue <= 24): | ||
case (oldValue <= 32): | ||
return Math.floor(oldValue / 16) * 14; | ||
case (oldValue <= 48): | ||
return Math.floor(oldValue / 16) * 12; | ||
case (oldValue <= 80): | ||
return Math.floor(oldValue / 16) * 10; | ||
case (oldValue <= 128): | ||
case (oldValue <= 256): | ||
return Math.floor(oldValue / 16) * 8; | ||
default: | ||
return Math.floor(oldValue / 16) * 4; | ||
} | ||
} |
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,16 @@ | ||
{ | ||
"name": "Responsive Replacer Dynamic", | ||
"id": "1252632497510105166", | ||
"api": "1.0.0", | ||
"main": "code.js", | ||
"capabilities": [], | ||
"enableProposedApi": false, | ||
"editorType": [ | ||
"figma" | ||
], | ||
"networkAccess": { | ||
"allowedDomains": [ | ||
"none" | ||
] | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,16 @@ | ||
{ | ||
"name": "Responsive Replacer Dynamic", | ||
"version": "1.0.0", | ||
"description": "Your Figma Plugin", | ||
"main": "code.js", | ||
"scripts": { | ||
"build": "tsc -p tsconfig.json", | ||
"watch": "npm run build -- --watch" | ||
}, | ||
"author": "", | ||
"license": "", | ||
"devDependencies": { | ||
"@figma/plugin-typings": "^1.65.0", | ||
"typescript": "*" | ||
} | ||
} |
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,11 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es6", | ||
"lib": ["es6"], | ||
"strict": true, | ||
"typeRoots": [ | ||
"./node_modules/@types", | ||
"./node_modules/@figma" | ||
] | ||
} | ||
} |