Hello everyone,
I am developing a Figma plugin where I have created a ComponentSet with two variants. Each variant has a state and a heading property. I want to dynamically assign the heading property to a text node within each variant.
Here is the simplified code for creating the ComponentSet:
figma.showUI(__html__, {
height: 200,
width: 400,
});
figma.ui.onmessage = async (msg) => {
if (msg.type === 'create-input-field') {
await figma.loadFontAsync({ family: 'Inter', style: 'Regular' });
// Create variants for the component
const defaultComponent = createComponentWithFrame('State=Default');
const filledComponent = createComponentWithFrame('State=Filled');
// Create a component set and add the components as variants
const componentSet = figma.combineAsVariants([defaultComponent, filledComponent], figma.currentPage);
componentSet.name = 'My Component Set';
componentSet.resizeWithoutConstraints(1200, componentSet.height);
componentSet.layoutMode = 'HORIZONTAL';
componentSet.counterAxisSizingMode = 'AUTO';
componentSet.primaryAxisSizingMode = 'AUTO';
componentSet.paddingTop = 20;
componentSet.paddingBottom = 20;
componentSet.paddingLeft = 20;
componentSet.paddingRight = 20;
componentSet.itemSpacing = 18;
componentSet.fills = [];
componentSet.cornerRadius = 5;
componentSet.strokes = [{ type: 'SOLID', color: { r: 0.592, g: 0.278, b: 1.0 } }]; // #9747ff
componentSet.strokeWeight = 1;
componentSet.dashPattern = [10, 5];
componentSet.strokeAlign = 'INSIDE';
componentSet.strokeJoin = 'MITER';
componentSet.strokeMiterLimit = 16;
componentSet.clipsContent = true;
// Position the component set on the canvas
componentSet.x = figma.viewport.center.x - componentSet.width / 2;
componentSet.y = figma.viewport.center.y - componentSet.height / 2;
}
};
const createComponentWithFrame = (variant: string): ComponentNode => {
let color: Paint[] = [{ type: 'SOLID', color: { r: 0.592, g: 0.278, b: 1.0 } }];
switch (variant) {
case 'State=Filled':
color = [{ type: 'SOLID', color: { r: 0.9, g: 0.9, b: 0.9 } }];
break;
default:
color = [{ type: 'SOLID', color: { r: 0.592, g: 0.278, b: 1.0 } }];
break;
}
const component = figma.createComponent();
component.name = variant;
component.layoutMode = 'VERTICAL';
component.fills = color;
component.resizeWithoutConstraints(252, component.height);
component.addComponentProperty('Heading', 'TEXT', '');
setupAutoLayoutAndText(component);
return component;
};
const setupAutoLayoutAndText = (node: BaseFrameMixin): void => {
node.layoutMode = 'VERTICAL';
node.primaryAxisSizingMode = 'AUTO';
node.counterAxisSizingMode = 'AUTO';
node.paddingTop = 0;
node.paddingBottom = 0;
node.paddingLeft = 0;
node.paddingRight = 0;
node.itemSpacing = 4;
const label = figma.createText();
label.characters = 'Label';
label.fontName = { family: 'Inter', style: 'Regular' };
label.lineHeight = {
value: 23,
unit: 'PIXELS',
};
label.letterSpacing = { value: 0, unit: 'PERCENT' };
label.textAlignHorizontal = 'LEFT';
label.textAlignVertical = 'BOTTOM';
label.fontSize = 14;
label.name = 'Label';
const labelContainer = figma.createFrame();
const childContainer = figma.createFrame();
labelContainer.counterAxisAlignItems = 'CENTER';
labelContainer.counterAxisSizingMode = 'AUTO';
labelContainer.primaryAxisAlignItems = 'MIN';
labelContainer.primaryAxisSizingMode = 'FIXED';
labelContainer.fills = [];
labelContainer.strokes = [];
labelContainer.paddingTop = 0;
labelContainer.paddingBottom = 0;
labelContainer.paddingLeft = 0;
labelContainer.paddingRight = 0;
labelContainer.itemSpacing = 4;
labelContainer.clipsContent = false;
labelContainer.layoutAlign = 'STRETCH';
labelContainer.layoutGrow = 0;
labelContainer.layoutMode = 'HORIZONTAL';
labelContainer.layoutGrids = [];
labelContainer.layoutPositioning = 'AUTO';
labelContainer.appendChild(label);
node.appendChild(labelContainer);
node.appendChild(childContainer);
};
I am looking to understand how I can link the heading property to the text node so that changes to the property reflect in the text content.
Any guidance or examples on how to achieve this would be greatly appreciated.
Thank you!


