interface CreateRectangleParams {
x?: number;
y?: number;
width?: number;
height?: number;
name?: string;
parentId?: string;
}
interface CreateFrameParams {
x?: number;
y?: number;
width?: number;
height?: number;
name?: string;
parentId?: string;
fillColor?: { r: number; g: number; b: number; a?: number };
strokeColor?: { r: number; g: number; b: number; a?: number };
strokeWeight?: number;
layoutMode?: "NONE" | "HORIZONTAL" | "VERTICAL";
layoutWrap?: "NO_WRAP" | "WRAP";
paddingTop?: number;
paddingRight?: number;
paddingBottom?: number;
paddingLeft?: number;
primaryAxisAlignItems?: "MIN" | "CENTER" | "MAX" | "SPACE_BETWEEN";
counterAxisAlignItems?: "MIN" | "CENTER" | "MAX" | "BASELINE";
layoutSizingHorizontal?: "FIXED" | "HUG" | "FILL";
layoutSizingVertical?: "FIXED" | "HUG" | "FILL";
itemSpacing?: number;
}
/**
* Create a rectangle
*/
export async function createRectangle(params: CreateRectangleParams): Promise<{
id: string;
name: string;
x: number;
y: number;
width: number;
height: number;
parentId?: string;
}> {
const {
x = 0,
y = 0,
width = 100,
height = 100,
name = "Rectangle",
parentId,
} = params;
const rect = figma.createRectangle();
rect.x = x;
rect.y = y;
rect.resize(width, height);
rect.name = name;
// If parentId is provided, append to that node, otherwise append to current page
if (parentId) {
const parentNode = await figma.getNodeByIdAsync(parentId);
if (!parentNode) {
throw new Error(`Parent node not found with ID: ${parentId}`);
}
if (!("appendChild" in parentNode)) {
throw new Error(`Parent node does not support children: ${parentId}`);
}
(parentNode as ChildrenMixin).appendChild(rect);
} else {
figma.currentPage.appendChild(rect);
}
return {
id: rect.id,
name: rect.name,
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height,
parentId: rect.parent?.id,
};
}
/**
* Create a frame
*/
export async function createFrame(params: CreateFrameParams): Promise<{
id: string;
name: string;
x: number;
y: number;
width: number;
height: number;
parentId?: string;
}> {
const {
x = 0,
y = 0,
width = 100,
height = 100,
name = "Frame",
parentId,
fillColor,
strokeColor,
strokeWeight,
layoutMode = "NONE",
layoutWrap = "NO_WRAP",
paddingTop = 10,
paddingRight = 10,
paddingBottom = 10,
paddingLeft = 10,
primaryAxisAlignItems = "MIN",
counterAxisAlignItems = "MIN",
layoutSizingHorizontal = "FIXED",
layoutSizingVertical = "FIXED",
itemSpacing = 0,
} = params;
const frame = figma.createFrame();
frame.x = x;
frame.y = y;
frame.resize(width, height);
frame.name = name;
// Set layout mode if provided
if (layoutMode !== "NONE") {
frame.layoutMode = layoutMode;
frame.layoutWrap = layoutWrap;
// Set padding values only when layoutMode is not NONE
frame.paddingTop = paddingTop;
frame.paddingRight = paddingRight;
frame.paddingBottom = paddingBottom;
frame.paddingLeft = paddingLeft;
// Set axis alignment only when layoutMode is not NONE
frame.primaryAxisAlignItems = primaryAxisAlignItems;
frame.counterAxisAlignItems = counterAxisAlignItems;
// Set layout sizing only when layoutMode is not NONE
frame.layoutSizingHorizontal = layoutSizingHorizontal;
frame.layoutSizingVertical = layoutSizingVertical;
// Set item spacing only when layoutMode is not NONE
frame.itemSpacing = itemSpacing;
}
// Set fill color if provided
if (fillColor) {
frame.fills = [
{
type: "SOLID",
color: { r: fillColor.r, g: fillColor.g, b: fillColor.b },
opacity: fillColor.a ?? 1,
},
];
}
// Set stroke if provided
if (strokeColor) {
frame.strokes = [
{
type: "SOLID",
color: { r: strokeColor.r, g: strokeColor.g, b: strokeColor.b },
opacity: strokeColor.a ?? 1,
},
];
frame.strokeWeight = strokeWeight ?? 1;
}
// If parentId is provided, append to that node, otherwise append to current page
if (parentId) {
const parentNode = await figma.getNodeByIdAsync(parentId);
if (!parentNode) {
throw new Error(`Parent node not found with ID: ${parentId}`);
}
if (!("appendChild" in parentNode)) {
throw new Error(`Parent node does not support children: ${parentId}`);
}
(parentNode as ChildrenMixin).appendChild(frame);
} else {
figma.currentPage.appendChild(frame);
}
return {
id: frame.id,
name: frame.name,
x: frame.x,
y: frame.y,
width: frame.width,
height: frame.height,
parentId: frame.parent?.id,
};
}