Skip to content

Instantly share code, notes, and snippets.

@alexjlockwood
Last active September 12, 2023 12:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexjlockwood/3167fc7c47c337a3ce04ec6bfffda72b to your computer and use it in GitHub Desktop.
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 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