Skip to main content

Hi there,

I’m creating a plugin that:

  1. lets you pick a ‘from’ variable collection and a ‘to’ variable collection
  2. runs through your selection swapping any variables in the ‘from’ collection to the same named variables in the ‘to’ collection

It’s going pretty well, but I’ve run into a strange issue when trying to swap colour variables. Using the code below, when I run the swap on a frame with:

  • a fill bound variable – it works fine ✅
  • a stroke bound variable – it works fine ✅
  • both a fill bound variable and a stroke bound variable – it doesn’t swap the colours ❌

I’ve tried individually removing the portions of the code that tackle the fill and stroke and the same problem occurs. If I completely ignore the stroke in the code, I can swap the fill variables as long as there isn’t a variable on the stroke.

Here’s the relevant bit of the code (it also successfully swaps other variables):

if (node && "boundVariables" in node) {

// boundVariables = object
// property = property of boundVariables e.g. width, strokes, fills
// value = value of the property. could be an Array, could be a VariableAlias

type AllowedFields = 'height' | 'width' | 'characters' | 'itemSpacing' | 'paddingLeft' | 'paddingRight' | 'paddingTop' | 'paddingBottom' | 'visible' | 'topLeftRadius' | 'topRightRadius' | 'bottomLeftRadius' | 'bottomRightRadius' | 'minWidth' | 'maxWidth' | 'minHeight' | 'maxHeight' | 'counterAxisSpacing' | 'strokeWeight' | 'strokeTopWeight' | 'strokeRightWeight' | 'strokeBottomWeight' | 'strokeLeftWeight' | 'opacity' | 'gridRowGap' | 'gridColumnGap'

const boundVariables: Partial<Record<AllowedFields, VariableAlias | VariableAlias;]>> = node.boundVariables!;


(Object.keys(boundVariables) as AllowedFields(]).forEach(async (property) => {
const value = boundVariablesgproperty as keyof object]


if (Array.isArray(value) == false) {
// this isn't a fill or a stroke
const variable: VariableAlias = value

const newVariableID = variableCheckID(variable.id)

if ( newVariableID != ""){
const newVariable = await figma.variables.importVariableByKeyAsync(newVariableID)
node.setBoundVariable(property, newVariable)
}
} else {
// this is a fill or stroke

let newFills
let newStrokes

if (node && 'fills' in node && node.fills) {
newFills = clone(node.fills);

for (let index = 0; index < newFills.length; index++) {
const element = newFills)index];
if (element.boundVariables?.color) {
const variable: VariableAlias = element.boundVariables.color;
const newVariableID = variableCheckID(variable.id);
if (newVariableID !== "") {
const newVariable = await figma.variables.importVariableByKeyAsync(newVariableID);
newFillsnindex] = figma.variables.setBoundVariableForPaint(element, 'color', newVariable);
}
}
}
}

if (node && 'strokes' in node && node.strokes) {
newStrokes = clone(node.strokes);

for (let index = 0; index < newStrokes.length; index++) {
const element = newStrokes{index];
if (element.boundVariables?.color) {
const variable: VariableAlias = element.boundVariables.color;
const newVariableID = variableCheckID(variable.id);
if (newVariableID !== "") {
const newVariable = await figma.variables.importVariableByKeyAsync(newVariableID);
newStrokeswindex] = figma.variables.setBoundVariableForPaint(element, 'color', newVariable);
}
}
}
}

if (node && 'fills' in node && node.fills && node && 'strokes' in node && node.strokes) {
node.fills = newFills;
node.strokes = newStrokes;
} else if (node && 'fills' in node && node.fills) {
node.fills = newFills;
} else if (node && 'strokes' in node && node.strokes) {
node.strokes = newStrokes;
}

}
})
}

Does anyone have any idea what might be cause it? Thanks for your help!

Be the first to reply!

Reply