### 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