Mapping functions, which help you map your Figma components to your code components, are essential for leveraging your existing code components to generate code when using the Builder Figma plugin.
Mapped components should always be in a .mapper file. For more details on how to generate mapped components through the Builder CLI, visit Map components.
Component mapping functions provide the figma object. This object has access to your Figma component's properties and content.
Optionally create a generic mapper that is applied to all Figma elements.
The mapping function is the mapper() method within the object passed to the figmaMapping() function.
This function has access to an object, figma, which contains details about the Figma component, identified by the "component-id".
An HTML template is used for the component's value, with the component function inserted as an interpolated value. For more details on this, visit Component mapping basics.
The Figma component's properties, such as ButtonText and Variant, are used as prop values within the SimpleButton component.
The mapping function is the mapper() method within the object passed to the figmaMapping() function.
This function has access to an object, figma, which contains details about the Figma component, identified by the "component-id".
The Figma component's properties, such as ButtonText and Variant, are used as prop values within the SimpleButton component.
The component function, SimpleButton, is passed to the $cmp property. For more details on this, visit Component mapping basics.
The diagram below shows how the Figma properties, on the left, correspond to the mapper() method, on the right:
This next screenshot shows how Figma layers, on the left, correspond to code, on the right.
This way, the Builder Figma Plugin converts your Figma designs directly into React code, simplifying the process of transforming your design ideas into real, functional code components.
Properties on your Figma component can be accessed with the same name on the figma object. For example, if your Figma component has an OnSale boolean property, access the value of this property with the mapper() method with figma.OnSale.
In the example below, multiple Figma properties, including Version, ProductName, Price, and OnSale, are passed to the ProductCard component.
Although Builder's Figma plugin uses AI semantic matching to automatically identify which components in your codebase correspond to your components in Figma, every design is unique and might require additional attention during the mapping process.
The video below shows opening the plugin in Figma and editing the mapping function for an example design.
Purpose: Retrieves the text content from the current Figma design node. If the node is a text node, it returns its characters. It aggregates the text from all child text nodes for group, frame, component, or instance nodes and returns it as a single string.
Example: Below is an example of using $textContent to extract text from a Figma node whose children are startIcon, text and endIcon.
Purpose: Traverses all child nodes of the current Figma design and applies a given function to each node.
Callback Parameters:
node: The current child node being visited.
Usage:
node.$textContent: Retrieves the text content of the child node.
node.name: Retrieves the layer name of the child node in Figma.
node.inputs: Retrieves the properties (inputs) set on the child node.
node.componentName: Retrieves the name of the Builder component that the child node maps to.
Example: The example below iterates over nodes and converts nodes named Header into <h1> HTML tags with their content, and directly returns the text content of nodes named Content.
If your components or prop types aren't showing up in the plugin, or the AI isn't mapping your props at all, be sure that you are exporting your components and specify types for the props. For more detail, read Mapping components from libraries.
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
// Use the text from the 2nd child ($children is zero indexed)
const text = figma.$children[1].$textContent;
return <Button>{text}</Button>;
},
});
Another option is to retrieve children by their layer name:
import { figmaMapping, html } from "@builder.io/dev-tools/figma";
import { VButton } from "@acme/design-system";
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
// Use the text from the 2nd child ($children is zero indexed)
const text = figma.$children[1].$textContent;
return html`
<${VButton}>${text}<//>
`;
},
});
Another option is to retrieve children by their layer name:
import { figmaMapping, html } from "@builder.io/dev-tools/figma";
import { VButton } from "@acme/design-system";
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
const text = figma.$findOneByName("Label").$textContent;
return html`
<${VButton}>${text}<//>
`;
},
});
import { figmaMapping } from "@builder.io/dev-tools/figma";
import Button from '../components/Button';
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
// Use the text from the 2nd child ($children is zero indexed)
const text = figma.$children[1].$textContent;
return <Button>{text}</Button>;
},
});
Another option is to retrieve children by their layer name:
import { figmaMapping } from "@builder.io/dev-tools/figma";
import Button from '../components/Button';
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
const text = figma.$findOneByName("Label").$textContent;
return <Button>{text}</Button>;
},
});
Use $cmp to connect the mapped HTML element to the actual Angular component class for preview and code generation.
For more details on the $cmp property in Angular mappings, see Map components.
// src/mappings/MyButton.mapper.ts
import { MyButton } from "@/components/ui/button";
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
// Use the text from the 2nd child ($children is zero indexed)
const text = figma.$children[1].$textContent;
return html`<button-component $cmp="{MyButton}">${text}</button-component>`;
},
});
Another option is to retrieve children by their layer name:
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
// Make an array to hold the CSS class names
const classes = ["button"];
// If figma.variant is 'primary', add the 'button-primary' class
if (figma.variant === "primary") {
classes.push("button-primary");
}
// Return a button with className applied
return <button className={classes.join(" ")}>{figma.Text}</button>;
},
});
import { figmaMapping, html } from "@builder.io/dev-tools/figma";
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
// Make an array to hold the CSS class names
const classes = ["button"];
// If figma.variant is 'primary', add the 'button-primary' class
if (figma.variant === "primary") {
classes.push("button-primary");
}
// Return a button with class binding
return html`<button :class=${classes.join(" ")}>${figma.Text}</button>`;
},
});
import { figmaMapping } from "@builder.io/dev-tools/figma";
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
// Create style objects based on Figma properties
let buttonStyle = [styles.button];
let textStyle = [styles.buttonText];
// If figma.variant is 'primary', add the primary styles
if (figma.variant === "primary") {
buttonStyle.push(styles.buttonPrimary);
textStyle.push(styles.buttonPrimaryText);
}
// Return a TouchableOpacity with style applied
return (
<TouchableOpacity style={buttonStyle}>
<Text style={textStyle}>{figma.Text}</Text>
</TouchableOpacity>
);
},
});
// Styles would be defined separately
const styles = StyleSheet.create({
button: {
borderRadius: 4,
paddingVertical: 8,
paddingHorizontal: 16,
alignItems: 'center',
},
buttonText: {
fontSize: 16,
fontWeight: '500',
},
buttonPrimary: {
backgroundColor: '#1976d2',
},
buttonPrimaryText: {
color: '#ffffff',
},
});
figmaMapping({
componentKey: "button-component-key",
mapper(figma) {
// Make an array to hold the CSS class names
const classes = ["button"];
// If figma.variant is 'primary', add the 'button-primary' class
if (figma.variant === "primary") {
classes.push("button-primary");
}
// Return a button with className applied
return html`<button class="${classes.join(" ")}">${figma.Text}</button>`;
},
});
Component mapping supports a subset of JSX syntax. The design generation process handles unsupported syntax by either removing the unsupported elements or throwing validation errors.
Function expressions are one feature of JSX syntax that component mapping does not support. Don't assign function expressions to props in the JSX returned by the mapper() function. The code generation process implements the function logic automatically or requires manual implementation after generating the code.
Omit these props that commonly use function expressions:
Event handlers: onClick, onPress, onSubmit
Form handlers: onChange, onInput
Interaction handlers: onHover, onFocus
The following examples compare incorrect and correct approaches to function expressions in props:
The generic mapping function automates mapping complex Figma designs, including grid-like structures. It is versatile enough to map any non-component Figma node to any corresponding code component or element.
Automating the mapping of grid-like structures is particularly useful for developers working with complex layouts that otherwise would require extensive effort to map.
Builder's generic mapping function runs on each non-component layer within your Figma design. These layers can be converted into any element or code component based on their properties.
This gives a high degree of flexibility to handle designs that include a mix of Figma components and non-component structural layers that should be treated more specifically than generic wrappers.
This function integrates with Builder's existing findOne() logic and enhances its capability to handle diverse and complex designs.
In the mappings/ folder, create a genericMapper.mapper.tsx. Below is an example where different Figma nodes are mapped based on their names.
// mappings/genericMapper.mapper.tsx
import { figmaMapping, type BaseFigmaProps } from "@builder.io/dev-tools/figma";
import { Grid } from "@/components/Grid";
figmaMapping({
genericMapper(figma: BaseFigmaProps) {
if (figma.$name === "Grid row") {
return <Grid>{figma.$children}</Grid>;
} else if (figma.$name === "Section") {
return <section>{figma.$children}</section>;
}
// For other nodes, do not apply the generic
// mapper and keep the default rendering behavior
return undefined;
},
});
// mappings/genericMapper.mapper.tsx
import { figmaMapping, type BaseFigmaProps } from "@builder.io/dev-tools/figma";
import { VGrid } from "@/components/Grid";
figmaMapping({
genericMapper(figma: BaseFigmaProps) {
if (figma.$name === "Grid row") {
return html`<${VGrid}>${figma.$children}<//>`;
} else if (figma.$name === "Section") {
return html`<section>${figma.$children}</section>`;
}
return undefined;
},
});
// mappings/genericMapper.mapper.tsx
import { figmaMapping, type BaseFigmaProps } from "@builder.io/dev-tools/figma";
import { Grid } from "@/components/Grid";
figmaMapping({
genericMapper(figma: BaseFigmaProps) {
if (figma.$name === "Grid row") {
return <Grid>{figma.$children}</Grid>;
} else if (figma.$name === "Section") {
return <section>{figma.$children}</section>;
}
// For other nodes, do not apply the generic
// mapper and keep the default rendering behavior
return undefined;
},
});
// mappings/genericMapper.mapper.tsx
import { figmaMapping, type BaseFigmaProps } from "@builder.io/dev-tools/figma";
import { Grid } from "@/components/Grid";
figmaMapping({
genericMapper(figma: BaseFigmaProps) {
if (figma.$name === "Grid row") {
return html`<grid-component $cmp=${Grid}>${figma.$children}</grid-component>`;
} else if (figma.$name === "Section") {
return html`<section>${figma.$children}</section>`;
}
return undefined;
},
});
In this example:
A Figma node named Grid row is automatically wrapped in a <Grid> component.
A node named Section is mapped to a <section> HTML element.
Nodes that do not match specific criteria retain their default rendering behavior for flexibility and control over the design-to-code process.
If you publish a generic mapper function, it displays in the Builder Figma Plugin. However, the plugin does not show a generic mapper function if you don't publish one.
To display a generic mapper function in the Builder Figma Plugin, click on the Generic Mapper section to expand the mapping function as in the screenshot below:
For more details on the basics of mapping components, visit Map components. If you encounter issues exporting Figma components to code, visit Debug view.
Certain parts of this workflow use AI. For more information, visit How Builder Uses AI.