### Install Figma Widget and Plugin Typings
Source: https://www.figma.com/widget-docs/setup-guide
Installs the necessary TypeScript typings for Figma widgets and plugins using npm. These packages provide type definitions to enhance development with TypeScript.
```bash
npm install --save-dev @figma/widget-typings @figma/plugin-typings
```
--------------------------------
### Install Widget Dependencies
Source: https://www.figma.com/widget-docs/setup-guide
Installs the necessary dependencies for widget development, including TypeScript and typings for both the widget and plugin APIs. This command is run within the widget's project directory.
```bash
npm install
```
--------------------------------
### Initialize Figma Widget Project
Source: https://www.figma.com/widget-docs/setup-guide
This command initializes a new Figma widget project using npm. It sets up the basic structure and dependencies required for widget development.
```bash
npm init @figma/widget
```
--------------------------------
### Figma Widget Undo/Redo Example
Source: https://www.figma.com/widget-docs/undo-redo
Demonstrates how undo/redo works with synced state and map variables in a Figma widget. It shows the initial setup and how user interactions modify the synced state, affecting the widget's re-rendering.
```JavaScript
const { widget } = figma;
const { AutoLayout, useSyncedState, useSyncedMap } = widget;
function UndoWidget() {
const [count, setCount] = useSyncedState("count", 0);
const [countMap] = useSyncedMap("countMap");
return (
{
countMap.set("userA", 1);
countMap.set("userB", 2);
}}
>
{String(count)}
);
}
figma.widget.register(UndoWidget);
```
--------------------------------
### Watch and Compile TypeScript
Source: https://www.figma.com/widget-docs/setup-guide
This command compiles TypeScript code (`.tsx` files) to JavaScript (`.js`) and watches for changes, automatically recompiling when files are modified. It's essential for seeing your widget code changes reflected.
```bash
npm: watch
```
--------------------------------
### Figma Widget Property Menu Example
Source: https://www.figma.com/widget-docs/api/properties/widget-usepropertymenu
This JavaScript code demonstrates how to use the `usePropertyMenu` hook to create a property menu for a Figma widget. It includes examples of action, separator, color selector, dropdown, and link menu items, along with handling user selections via the `onChange` callback.
```javascript
const{ widget }= figma
const{ useSyncedState, usePropertyMenu,AutoLayout,Text}= widget
functionPropertyMenuWidget(){
const[color, setColor]=useSyncedState("theme","#e06666")
const[fruit, setFruit]=useSyncedState("fruit","mango")
const fruitOptions =[{option:"mango", label:"Mango"},{option:"apple", label:"Apple"}]
usePropertyMenu(
[
{
itemType:'action',
tooltip:'Action',
propertyName:'action',
},
{
itemType:'separator',
},
{
itemType:'color-selector',
propertyName:'colors',
tooltip:'Color selector',
selectedOption: color,
options:[{option:"#e06666", tooltip:"Red"},{option:"#ffe599", tooltip:"Yellow"}],
},
{
itemType:'dropdown',
propertyName:'fruits',
tooltip:'Fruit selector',
selectedOption: fruit,
options: fruitOptions,
},
{
itemType:'link',
propertyName:'fruitLink',
tooltip:'Learn about fruit!',
icon:null,
href:'https://en.wikipedia.org/wiki/Fruit',
},
],
({propertyName, propertyValue})=>{
if(propertyName ==="colors"){
setColor(propertyValue)
}elseif(propertyName ==="fruits"){
setFruit(propertyValue)
}elseif(propertyName ==="action"){
console.log(propertyName)
}
},
)
return(
{fruitOptions.find(f => f.option === fruit).label}
)
}
widget.register(PropertyMenuWidget)
```
--------------------------------
### Widget Counter Example
Source: https://www.figma.com/widget-docs/samples
A basic counter widget demonstrating the use of ``, ``, `useSyncedState`, `usePropertyMenu`, and `onClick` for interactive elements.
```TypeScript
function CounterWidget() {
const [count, setCount] = useSyncedState('count', 0);
return (
{`Count: ${count}`}
);
}
figma.widget.register(CounterWidget, {
usePropertyMenu: [
{
item: 'Reset',
onClick: () => setCount(0)
}
]
});
```
--------------------------------
### Widget Notepad Input Example
Source: https://www.figma.com/widget-docs/samples
Showcases the `Input` component for capturing user input directly on the Figma canvas, enabling interactive data entry within widgets.
```TypeScript
function NotepadWidget() {
const [text, setText] = useSyncedState('notepadText', '');
return (
{text}
);
}
```
--------------------------------
### Configure TypeScript for Figma Widgets
Source: https://www.figma.com/widget-docs/setup-guide
This tsconfig.json file is configured for building Figma widgets with React, specifying JSX factory and fragment factory for Figma's widget API. It targets ES6 and enables strict type checking.
```typescript
{
"compilerOptions":{
"jsx":"react",
"jsxFactory":"figma.widget.h",
"jsxFragmentFactory":"figma.widget.Fragment",
"target":"es6",
"strict":true,
"typeRoots":[
"./node_modules/@types",
"./node_modules/@figma"
]
}
}
```
--------------------------------
### Install Figma Widget and Plugin Typings
Source: https://www.figma.com/widget-docs/api/typings
This command installs the necessary TypeScript typings for Figma widgets and plugins as development dependencies using npm. These typings are crucial for type safety and autocompletion during widget development.
```bash
npm install --save-dev @figma/widget-typings @figma/plugin-typings
```
--------------------------------
### create-widget-app React Iframe Example
Source: https://www.figma.com/widget-docs/samples
A template widget that utilizes an iframe rendered with React, serving as a structural example for developing non-trivial widgets and their associated iframes.
```TypeScript
import React from 'react';
import ReactDOM from 'react-dom';
function AppContent() {
return
Hello from React iframe!
;
}
ReactDOM.render(, document.getElementById('react-root'));
figma.ui.onMessage = msg => {
console.log(msg);
};
figma.showUI(__html__, { width: 300, height: 200 });
```
--------------------------------
### Widget Simple Annotate Inline Editing Example
Source: https://www.figma.com/widget-docs/samples
A straightforward widget for creating inline-editable annotations, published to the Figma community for easy integration.
```TypeScript
function AnnotateWidget() {
const [annotation, setAnnotation] = useSyncedState('annotationText', '');
return (
{annotation}
);
}
```
--------------------------------
### Figma Widget Gradient Paint Example
Source: https://www.figma.com/widget-docs/get-help
Demonstrates how to apply a linear gradient fill to a rectangle within a Figma widget. This example showcases the structure for defining gradient type, handle positions, and color stops.
```TypeScript
```
--------------------------------
### Widget Toast UI Message Example
Source: https://www.figma.com/widget-docs/samples
Demonstrates how to use a UI to send messages to a widget, enabling communication and notifications from external interfaces to the widget.
```TypeScript
figma.ui.onMessage = msg => {
if (msg.type === 'showToast') {
figma.notify(msg.message);
}
};
function App() {
return (
);
}
```
--------------------------------
### Widget User Badge Image Example
Source: https://www.figma.com/widget-docs/samples
Demonstrates the use of the `` component and `figma.currentUser.photoUrl` to display user profile images within a widget.
```TypeScript
function UserBadgeWidget() {
const userPhotoUrl = figma.currentUser.photoUrl;
return (
{figma.currentUser.name}
);
}
```
--------------------------------
### Widget Stickable and Stickable Host Example
Source: https://www.figma.com/widget-docs/samples
Illustrates the concepts of 'stickable' elements and their 'stickable host' within the Figma widget framework, enabling elements to adhere to specific positions or behaviors.
```TypeScript
function StickableHostWidget() {
return (
);
}
```
--------------------------------
### Widget Table SyncedMap Example
Source: https://www.figma.com/widget-docs/samples
A simple table widget utilizing `useSyncedMap` to facilitate concurrent updates, demonstrating the `key` prop for efficient data management in collaborative environments.
```TypeScript
interface RowData { id: string; value: number; }
function TableWidget() {
const [data, setData] = useSyncedMap('tableData', []);
return (
{data.map(row => (
{row.id}{row.value.toString()}
))}
);
}
```
--------------------------------
### Basic useEffect Usage Example
Source: https://www.figma.com/widget-docs/api/properties/widget-useeffect
A simple example demonstrating the basic usage of `useEffect` in a Figma widget. The effect callback is executed when the widget renders or its state changes.
```javascript
const{ widget }= figma
const{Text, useEffect }= widget
functionUseEffectExample(){
useEffect(()=>{
console.log("useEffect callback called")
})
returnuseEffect example
}
widget.register(UseEffectExample)
```
--------------------------------
### Hot Reloading Example
Source: https://www.figma.com/widget-docs/prototyping-widget-ui
Illustrates the concept of hot reloading in Figma widgets, where code changes are reflected in real-time without losing the widget's current state. This example shows changing a color property.
```javascript
// Original code snippet (conceptual)
// const widget = new Widget();
// widget.ui.setProperties({ fill: '#FFFFFF' });
// After code change in editor:
// const widget = new Widget();
// widget.ui.setProperties({ fill: '#F1F6FF' });
// The widget renders in the file with the updated fill, while the counter stays at 3.
```
--------------------------------
### Configure Manifest with Allowed Domain
Source: https://www.figma.com/widget-docs/making-network-requests
This example demonstrates how to specify a single domain, `httpbin.org`, in the `allowedDomains` list within the `manifest.json` file for network access.
```json
{
"name":"MyWidget",
"id":"737805260747778093",
"api":"1.0.0",
"widgetApi":"1.0.0",
"editorType":["figma","figjam"],
"containsWidget":true,
"main":"code.js",
"ui":"ui.html",
"networkAccess":{
"allowedDomains":["httpbin.org"],
"reasoning":"",
"devAllowedDomains":[]
}
}
```
--------------------------------
### Configure Manifest with Reasoning for Access
Source: https://www.figma.com/widget-docs/making-network-requests
This example illustrates how to provide a `reasoning` string in `manifest.json` to explain the network access granted by `allowedDomains`, which is visible on the widget's Community page.
```json
{
"name":"MyWidget",
"id":"737805260747778093",
"api":"1.0.0",
"widgetApi":"1.0.0",
"editorType":["figma","figjam"],
"containsWidget":true,
"main":"code.js",
"ui":"ui.html",
"networkAccess":{
"allowedDomains":["httpbin.org/get"],
"reasoning":"MyPlugin queries httpbin.org/get for example responses.",
"devAllowedDomains":[]
}
}
```
--------------------------------
### Register a Figma Widget
Source: https://www.figma.com/widget-docs/api/properties/widget-register
Example of how to register a simple Figma widget that displays 'Hello Widget'. This demonstrates the basic structure of a widget function and its registration using `widget.register`.
```javascript
const { widget } = figma
const { Text } = widget
function MyFirstWidget() {
return Hello Widget
}
widget.register(MyFirstWidget)
```
--------------------------------
### Widget Document Change Event Listener Example
Source: https://www.figma.com/widget-docs/samples
Demonstrates how to effectively listen for and respond to document change events within a widget's execution context, allowing widgets to react to file modifications.
```TypeScript
figma.on('documentchange', (event) => {
console.log('Document changed:', event);
});
function DocumentChangeListenerWidget() {
return Listening for document changes...;
}
```
--------------------------------
### Widget Multiplayer Counter SyncedMap Example
Source: https://www.figma.com/widget-docs/samples
A multiplayer-safe counter widget employing `useSyncedMap` and `figma.activeUsers[0].sessionId` to ensure synchronized state across multiple users.
```TypeScript
function MultiplayerCounterWidget() {
const [count, setCount] = useSyncedMap('multiplayerCount', 0);
const sessionId = figma.activeUsers[0]?.sessionId;
return (
{`Count: ${count}`}{`Your Session: ${sessionId}`}
);
}
```
--------------------------------
### Widget API: Stickable Interactions (FigJam Only)
Source: https://www.figma.com/widget-docs/figma-figjam-widgets
Demonstrates the use of `useStickable` and `useStickableHost` hooks, which are exclusive to FigJam files. These hooks allow widgets to attach to other nodes or host other attachable widgets. Accessing these in Figma design files will result in errors.
```javascript
import { useStickable, useStickableHost } from '@figma/widget-api';
// Example usage for a stickable widget
function StickableWidget() {
useStickable();
// ... widget implementation
}
// Example usage for a stickable host widget
function StickableHostWidget() {
useStickableHost();
// ... widget implementation
}
```
--------------------------------
### Figma Widget Samples - Multiplayer Counter Widget
Source: https://www.figma.com/widget-docs/samples
An example of a counter widget that supports real-time updates across multiple users in a FigJam session. It likely uses shared state management provided by the FigJam API.
```JavaScript
/**
* @type {import('figma-widget').WidgetRenderer}
*/
const MultiplayerCounter = ({ count, increment, decrement }) => {
return (
Shared Count: {count}
);
};
export default MultiplayerCounter;
```
--------------------------------
### Figma Widget Manifest with Network Access
Source: https://www.figma.com/widget-docs/updates/2023/05/10
Example of a Figma widget manifest JSON file including the `networkAccess` key with a list of allowed domains. This configuration restricts the widget to only access the specified domains.
```json
{
"name":"MyWidget",
"id":"737805260747778093",
"api":"1.0.0",
"widgetApi":"1.0.0",
"editorType":["figma","figjam"],
"containsWidget":true,
"main":"code.js",
"ui":"ui.html",
"networkAccess":{
"allowedDomains":["https://my-app.cdn.com","wss://socket.io","*.example.com","example.com/api/","exact-path.com/content"]
}
}
```
--------------------------------
### Figma Widget Samples - Create Widget App Script
Source: https://www.figma.com/widget-docs/samples
A script used to initialize and set up new FigJam widget projects. It likely automates the creation of necessary files and configurations.
```Shell
#!/bin/bash
# Script to create a new FigJam widget project
if [ -z "$1" ]; then
echo "Usage: $0 "
exit 1
fi
WIDGET_NAME=$1
# Create project directory
mkdir "${WIDGET_NAME}"
cd "${WIDGET_NAME}"
# Initialize npm project
npm init -y
# Install necessary dependencies
npm install figma-widget
# Create basic widget file structure
mkdir src
echo "// Basic widget structure\nexport default () => {\n return \n};" > src/index.js
echo "// Widget manifest file\n{\"name\": \"${WIDGET_NAME}\", \"apiVersion\": \"1.0.0\"}" > widget.json
echo "Project '${WIDGET_NAME}' created successfully!"
```
--------------------------------
### Figma Widget Samples - Run All Scripts
Source: https://www.figma.com/widget-docs/samples
A utility script to execute all sample widgets or related build processes. This is useful for testing or demonstrating multiple widgets at once.
```JavaScript
const { exec } = require('child_process');
const widgets = [
'WidgetCounter',
'WidgetDocumentChange',
'WidgetMultiplayerCounter',
'WidgetNotepad',
'WidgetSimpleAnnotate',
'WidgetStickables',
'WidgetTable',
'WidgetToast',
'WidgetUserBadge'
];
widgets.forEach(widget => {
console.log(`Running ${widget}...`);
// Assuming each widget has a build or start script
// This is a placeholder, actual command might differ
exec(`npm run build --prefix ./${widget}`, (error, stdout, stderr) => {
if (error) {
console.error(`Error running ${widget}: ${error.message}`);
return;
}
if (stderr) {
console.error(`Stderr for ${widget}: ${stderr}`);
return;
}
console.log(`Stdout for ${widget}: ${stdout}`);
});
});
console.log('All widget processes initiated.');
```
--------------------------------
### Use Figma Widget ID in onClick Handler
Source: https://www.figma.com/widget-docs/api/properties/widget-usewidgetid
This example demonstrates how to use the `useWidgetId` hook to get the current widget's ID and then use it within an `onClick` event handler to clone the widget and position the copy next to the original.
```javascript
const{ widget }= figma
const{Text, useWidgetId }= widget
functionUseWidgetIdExample(){
const widgetId =useWidgetId()
return(
{
const widgetNode = figma.getNodeById(widgetId)asWidgetNode;
const clonedWidget = widgetNode.clone();
// Position the cloned widget beside this widget
widgetNode.parent!.appendChild(clonedWidget);
clonedWidget.x = widgetNode.x + widgetNode.width +50;
clonedWidget.y = widgetNode.y;
}}
>
Make a copy
)
}
widget.register(UseWidgetIdExample)
```
--------------------------------
### Configure Manifest for Network Access (Initial)
Source: https://www.figma.com/widget-docs/making-network-requests
This JSON snippet shows the initial structure of the `manifest.json` file with the `networkAccess` key, including empty arrays for `allowedDomains` and `devAllowedDomains`, and an empty string for `reasoning`.
```json
{
"name":"MyWidget",
"id":"737805260747778093",
"api":"1.0.0",
"widgetApi":"1.0.0",
"editorType":["figma","figjam"],
"containsWidget":true,
"main":"code.js",
"ui":"ui.html",
"networkAccess":{
"allowedDomains":[],
"reasoning":"",
"devAllowedDomains":[]
}
}
```
--------------------------------
### Example: Applying Layer Blur Effect
Source: https://www.figma.com/widget-docs/api/type-Effect
Demonstrates how to use the BlurEffect interface to apply a 'layer-blur' to a Figma widget Frame. This example shows setting the blur radius and type within the 'effect' property.
```javascript
const{
widget
}= figma
const{
Frame
}= widget
functionBlurExample(){
return(
)
}
widget.register(BlurExample)
```
--------------------------------
### Figma Widget Text Input Example
Source: https://www.figma.com/widget-docs/text-editing
This example demonstrates how to use the `Input` component in a Figma widget to allow users to type text. It utilizes `useSyncedState` to manage the input's value and updates the state when the text editing ends via the `onTextEditEnd` callback. The component is configured with placeholder text, styling, and input behavior.
```javascript
const{ widget }= figma
const{ useSyncedState,AutoLayout,Input}= widget
functionInputWidget(){
const[text, setText]=useSyncedState("text","")
return(
{
setText(e.characters);
}}
fontSize={64}
fill="#7f1d1d"
width={500}
inputFrameProps={{
fill:"#fee2e2",
stroke:"#b91c1c",
cornerRadius:16,
padding:20,
}}
inputBehavior="wrap"
/>
)
}
widget.register(InputWidget)
```
--------------------------------
### Example Widget Manifest JSON
Source: https://www.figma.com/widget-docs/widget-manifest
This JSON object represents a typical `manifest.json` file for a Figma widget. It includes essential properties like name, ID, API versions, editor compatibility, main script path, UI file path, and document access settings.
```json
{
"name":"MyWidget",
"id":"737805260747778093",
"api":"1.0.0",
"widgetApi":"1.0.0",
"editorType":["figma","figjam"],
"containsWidget":true,
"main":"code.js",
"ui":"ui.html",
"documentAccess":"dynamic-page",
"networkAccess":{
"allowedDomains":["none"]
}
}
```
--------------------------------
### Create Donut Ellipse
Source: https://www.figma.com/widget-docs/api/type-ArcData
Illustrates the creation of a donut shape using the Ellipse component by setting the starting and ending angles, and an inner radius.
```javascript
// Make a donut \n
```
--------------------------------
### Define ArcData Type
Source: https://www.figma.com/widget-docs/api/type-ArcData
Defines the structure for ArcData, specifying the starting angle, ending angle, and inner radius for arc properties in Figma widgets.
```typescript
type ArcData={\n readonly startingAngle:number\n readonly endingAngle:number\n readonly innerRadius:number\n}
```
--------------------------------
### Figma Widget Input Component Link Behavior
Source: https://www.figma.com/widget-docs/api/component-Input
Example of using the 'href' prop to make the Input component's text behave as a clickable link.
```typescript
import { widget } from '@figma/widget';
widget.register({
name: 'LinkInputWidget',
render: () => (
),
});
```
--------------------------------
### Create Diamond Gradient
Source: https://www.figma.com/widget-docs/api/type-GradientPaint
Example of creating a Rectangle with a diamond gradient fill using the Figma Widget API. It specifies the gradient type, handle positions, and color stops.
```jsx
```
--------------------------------
### Manage Stickable Host (FigJam) - Figma Widget API
Source: https://www.figma.com/widget-docs/api/figma-widget
The `useStickableHost` hook, exclusive to FigJam, lets widgets run a callback when a stickable is added or removed. By default, all widgets act as stickable hosts.
```typescript
figma.widget.useStickableHost(onAttachmentsChanged?: (e: WidgetAttachedStickablesChangedEvent) => void | Promise): void;
```
--------------------------------
### Create Angular Gradient
Source: https://www.figma.com/widget-docs/api/type-GradientPaint
Example of creating a Rectangle with an angular gradient fill using the Figma Widget API. It specifies the gradient type, handle positions, and color stops.
```jsx
```
--------------------------------
### Configure Manifest with Development Domain Access
Source: https://www.figma.com/widget-docs/making-network-requests
This JSON configuration shows how to add a local development server domain, `http://localhost:3000`, to the `devAllowedDomains` list in `manifest.json` for testing purposes.
```json
{
"name":"MyPlugin",
"id":"737805260747778092",
"api":"1.0.0",
"main":"code.js",
"ui":"ui.html",
"networkAccess":{
"allowedDomains":["httpbin.org/get"],
"reasoning":"MyPlugin queries httpbin.org/get for example responses.",
"devAllowedDomains":["http://localhost:3000"]
}
}
```
--------------------------------
### Create Radial Gradient
Source: https://www.figma.com/widget-docs/api/type-GradientPaint
Example of creating a Rectangle with a radial gradient fill using the Figma Widget API. It specifies the gradient type, handle positions, and color stops.
```jsx
```
--------------------------------
### Figma Widget Input Component Usage
Source: https://www.figma.com/widget-docs/api/component-Input
Demonstrates the basic usage of the Input component in a Figma widget, including handling text edits and setting initial values.
```typescript
import { widget, TextEditEvent } from '@figma/widget';
widget.register({
name: 'MyInputWidget',
render: () => {
const [text, setText] = widget.useSyncedState('text', '');
const handleTextEditEnd = (event: TextEditEvent) => {
setText(event.characters);
};
return (
);
},
});
```
--------------------------------
### Create New Widget with esbuild Bundling (Figma)
Source: https://www.figma.com/widget-docs/updates/2022/10/10
This snippet outlines the steps to create a new widget in Figma that utilizes esbuild for bundling. This feature simplifies extending widgets beyond a single source file. It requires logging into the Figma desktop app and navigating through the widget development menu.
```text
1. Log in to your account and open the Figma desktop app
2. You can open any existing Figma / FigJam document or create a new one.
3. Go to Menu > Widgets > Development > New widget...
```
--------------------------------
### Create Linear Gradient
Source: https://www.figma.com/widget-docs/api/type-GradientPaint
Example of creating a Rectangle with a linear gradient fill using the Figma Widget API. It specifies the gradient type, handle positions, and color stops.
```jsx
```
--------------------------------
### Widget API: Enable Localhost in Manifest Network Access
Source: https://www.figma.com/widget-docs/updates/2023/09/21
Updates the Widget API manifest configuration to include support for `localhost` in the `networkAccess.allowedDomains` field. This allows widgets to access resources hosted on the local development environment.
```JSON
{
"networkAccess": {
"allowedDomains": [
"localhost",
"*.figma.com"
]
}
}
```
--------------------------------
### JSX Syntax for Figma Widgets
Source: https://www.figma.com/widget-docs/prerequisites
Demonstrates the basic structure of a Figma widget using JSX, showing how to create an AutoLayout containing a Text element. This code is compiled into JavaScript for execution in the Widget Sandbox.
```JSX
const{ widget }= figma
const{AutoLayout,Text}= widget
functionJSXSample(){
return(
Hello Widget
)
}
widget.register(JSXSample)
```
```JavaScript
figma.widget.h(Text,null,"Hello Widget")
```
--------------------------------
### Figma Widget Samples - Notepad Widget
Source: https://www.figma.com/widget-docs/samples
A simple notepad widget allowing users to jot down notes within FigJam. It likely uses a text input field and stores the content.
```JavaScript
/**
* @type {import('figma-widget').WidgetRenderer}
*/
const Notepad = ({ note, setNote }) => {
return (
My Notes