Last active
September 12, 2023 12:49
-
-
Save alexjlockwood/3167fc7c47c337a3ce04ec6bfffda72b to your computer and use it in GitHub Desktop.
This plugin recurses every layer in every page of the current figma file, and detaches color styles that are backed by a single bound color variable.
This file contains hidden or 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 plugin recurses every layer in every page of the current figma file, and detaches | |
// color styles that are backed by a single bound color variable. | |
(function main() { | |
recurseLayerHierarchy(figma.root, false); | |
figma.closePlugin(); | |
})(); | |
function recurseLayerHierarchy(node: BaseNode, isChildOfInstanceNode: boolean) { | |
if (node.type === 'INSTANCE') { | |
// For instance nodes, we will only detach styles that have been | |
// explicitly overriden by designers. Any non-overridden styles | |
// should be detached in the main component, which will automatically | |
// propogate back to this instance node. This approach ensures we don't | |
// introduce unnecessary overrides in the instance. | |
node.overrides.forEach(({ id, overriddenFields }) => { | |
const overriddenFieldsSet = new Set(overriddenFields); | |
if (overriddenFieldsSet.has('fillStyleId') || overriddenFieldsSet.has('strokeStyleId')) { | |
const overriddenNode = figma.getNodeById(id); | |
if (overriddenNode) { | |
detachFillAndStrokeStyles(overriddenNode); | |
} | |
} | |
}); | |
} else if (!isChildOfInstanceNode) { | |
detachFillAndStrokeStyles(node); | |
} | |
if ('children' in node) { | |
node.children.forEach((child: PageNode | SceneNode) => { | |
recurseLayerHierarchy(child, node.type === 'INSTANCE' || isChildOfInstanceNode); | |
}); | |
} | |
} | |
/** | |
* Detaches the fill and stroke styles if they are backed by a single | |
* solid paint bound variable. When this is done, the color styles in the | |
* Figma UI will be replaced by the color variable instead. | |
*/ | |
function detachFillAndStrokeStyles(node: BaseNode) { | |
if ( | |
'fillStyleId' in node && | |
node.fillStyleId !== '' && | |
node.fillStyleId !== figma.mixed && | |
node.fills !== figma.mixed && | |
node.fills.length === 1 && | |
node.fills[0].type === 'SOLID' && | |
node.fills[0].boundVariables?.color !== undefined | |
) { | |
node.fillStyleId = ''; | |
} | |
if ( | |
'strokeStyleId' in node && | |
node.strokeStyleId !== '' && | |
node.strokes.length === 1 && | |
node.strokes[0].type === 'SOLID' && | |
node.strokes[0].boundVariables?.color !== undefined | |
) { | |
node.strokeStyleId = ''; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment