figma-plugin-utilities Svelte Themes

Figma Plugin Utilities

Shared Svelte components and utilities for Figma plugins

figma-plugin-utils

Shared Svelte components and utilities for Figma plugins.

Installation

# Local file reference
npm install file:../_packages/figma-plugin-utils

Usage

Import Everything

import {
  // Components
  PluginLayout,
  Header,
  Footer,
  StatusBar,
  EmptyState,
  ListItem,
  LoadingState,
  FieldGroup,
  // Utilities
  sendToPlugin,
  createMessageHandler,
  rgbToHex,
  hexToRgb,
  validateUrl,
  validateJsonString,
  sanitizeName,
} from "figma-plugin-utils";

Import Specific Modules

// Components only
import { PluginLayout, Header, Footer } from "figma-plugin-utils/components";

// Utilities only
import { sendToPlugin, createMessageHandler } from "figma-plugin-utils/lib";

Components

Component Description
PluginLayout Main content wrapper with scrollable area
Header Header bar with left, center, right slots and optional title
Footer Footer with right, split, and full layout variants
StatusBar Toast notifications with auto-dismiss (info/success/error/warning)
EmptyState Empty/error states with optional icon and action buttons
ListItem Selectable list items with metadata slot and action menu
LoadingState Centered loading indicator with custom message
FieldGroup Label + input wrapper for form fields
<Header title="My Plugin">
  <svelte:fragment slot="left">
    <IconButton iconName={IconBack} on:click={goBack} />
  </svelte:fragment>
  <svelte:fragment slot="right">
    <IconButton iconName={IconSettings} />
  </svelte:fragment>
</Header>

<!-- Without border -->
<Header title="Settings" noBorder />
<!-- Right-aligned (default) -->
<Footer>
  <Button variant="primary">Save</Button>
</Footer>

<!-- Split layout -->
<Footer variant="split">
  <svelte:fragment slot="left">
    <Button variant="secondary">Cancel</Button>
  </svelte:fragment>
  <svelte:fragment slot="right">
    <Button variant="primary">Save</Button>
  </svelte:fragment>
</Footer>

<!-- Full-width buttons -->
<Footer variant="full">
  <Button variant="primary">Generate</Button>
</Footer>

StatusBar

<StatusBar 
  message={status.message} 
  type={status.type} 
  on:close={() => status = { message: '', type: 'info' }} 
/>

Types: info, success, error, warning. Auto-dismisses after 4s for info and success.

EmptyState

<EmptyState
  message="No items yet"
  icon="search"
  actions={[
    { label: "Add Item", handler: handleAdd },
    { label: "Import", handler: handleImport }
  ]}
/>

ListItem

<ListItem
  id="item-1"
  title="My Item"
  active={selectedId === 'item-1'}
  menuItems={[
    { label: 'Edit', value: 'edit' },
    { label: 'Delete', value: 'delete' }
  ]}
  on:click={handleSelect}
  on:menuSelect={handleMenuAction}
>
  <span>Additional metadata</span>
</ListItem>

Utilities

Messages (lib/messages.js)

// Send message to plugin code
sendToPlugin("my-action", { data: "value" });

// Handle messages from plugin
window.onmessage = createMessageHandler({
  success: (msg) => console.log("Success:", msg),
  error: (msg) => console.error("Error:", msg),
});

Colors (lib/colors.js)

// Convert between formats (Figma uses 0-1 range)
const rgb = hexToRgb("#FF0000"); // { r: 1, g: 0, b: 0 }
const hex = rgbToHex({ r: 1, g: 0, b: 0 }); // "#FF0000"

// Calculate contrast
const ratio = getContrastRatio(color1, color2);
const passes = meetsContrastLevel(ratio, "AA"); // true/false

Validation (lib/validation.js)

const urlResult = validateUrl("https://example.com");
// { valid: true } or { valid: false, error: "..." }

const jsonResult = validateJsonString('{"key": "value"}');
// { valid: true, parsed: {...} } or { valid: false, error: "..." }

const clean = sanitizeName("My Plugin!!!"); // "My Plugin"

Error Handling (lib/errorHandling.js)

// Safe async operations
const result = await safeAsync(
  () => fetch(url),
  "Loading data"
);
if (result.ok) {
  console.log(result.value);
} else {
  console.error(result.error.userMessage);
}

// Parse JSON safely
const parsed = parseJsonSafe(jsonString);
// { ok: true, value: {...} } or { ok: false, error: "..." }

Figma Helpers (lib/figma-helpers.ts)

For use in code.ts:

import { sendToUI, showError, focusNodes, loadFont } from "figma-plugin-utils/lib/figma-helpers";

// Send message to UI
sendToUI("success", { message: "Done!" });

// Show notification
showError("Something went wrong");

// Focus viewport on nodes
focusNodes(figma.currentPage.selection);

// Load font before using
await loadFont("Inter", "Regular");

// Client storage
await saveToStorage("settings", { theme: "dark" });
const settings = await loadFromStorage("settings", { theme: "light" });

Top categories

Loading Svelte Themes