npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rogieking/figui3

v4.5.1

Published

A lightweight web components library for building Figma plugin and widget UIs with native look and feel

Readme

FigUI3

A lightweight, zero-dependency web components library for building Figma plugin and widget UIs with native look and feel.

npm version License: MIT

Live Playground & Demos

Features

  • Figma UI3 design system
  • Zero dependencies
  • ~228 KB JS + ~102 KB CSS minified
  • Built with Web Components
  • Automatic light/dark theme support
  • Accessible with ARIA attributes and keyboard navigation
  • Framework agnostic (React, Vue, Svelte, or vanilla JS)

Quick Start

Install:

npm install @rogieking/figui3

Import:

import "@rogieking/figui3/fig.css";
import "@rogieking/figui3/fig.js";

Or use a CDN:

<link rel="stylesheet" href="https://unpkg.com/@rogieking/figui3@latest/dist/fig.css" />
<script type="module" src="https://unpkg.com/@rogieking/figui3@latest/dist/fig.js"></script>

Minimal example:

<fig-field direction="horizontal">
  <label>Color</label>
  <fig-input-color value="#FF5733" text="true" alpha="true"></fig-input-color>
</fig-field>
<fig-button variant="primary">Save</fig-button>

Components

| Component | Tag | Description | |---|---|---| | Button | <fig-button> | Buttons with variants, toggle, select, upload | | Dropdown | <fig-dropdown> | Native select wrapper with Figma styling | | Combo Input | <fig-combo-input> | Text input with dropdown suggestions | | Checkbox | <fig-checkbox> | Checkbox with indeterminate state | | Radio | <fig-radio> | Radio button | | Switch | <fig-switch> | Toggle switch | | Slider | <fig-slider> | Range, hue, opacity, delta, stepper | | Field Slider | <fig-field-slider> | Labeled field + slider combo | | Text Input | <fig-input-text> | Styled text/textarea input | | Number Input | <fig-input-number> | Numeric input with units | | Input Angle | <fig-input-angle> | Angle/rotation dial and text input | | Chit | <fig-chit> | Color/gradient/image swatch | | Color Tip | <fig-color-tip> | Compact color tip with picker | | Color Input | <fig-input-color> | Color picker with hex/alpha | | Input Palette | <fig-input-palette> | Editable multi-color palette | | Gradient Input | <fig-input-gradient> | Gradient editor with stops | | Fill Input | <fig-input-fill> | Solid, gradient, image, video fill | | Fill Picker | <fig-fill-picker> | Full fill picker dialog | | Tabs | <fig-tabs> / <fig-tab> | Tabbed navigation | | Segmented Control | <fig-segmented-control> / <fig-segment> | Segmented button group | | Chooser | <fig-chooser> / <fig-choice> | Selection list with drag scroll | | Field | <fig-field> | Form field wrapper with layout | | Joystick | <fig-joystick> | 2D position input | | Origin Grid | <fig-origin-grid> | Transform-origin grid | | Easing Curve | <fig-easing-curve> | Bezier/spring curve editor | | 3D Rotate | <fig-3d-rotate> | 3D cube rotation control | | Handle | <fig-handle> | Draggable handle on a surface | | Canvas Control | <fig-canvas-control> | Point with optional radius, angle, or second point | | Dialog | <fig-dialog> | Modal/non-modal dialog | | Popup | <fig-popup> | Anchored floating surface | | Toast | <fig-toast> | Toast notification | | Tooltip | <fig-tooltip> | Hover/click tooltip | | Header | <fig-header> | Section header | | Layer | <fig-layer> | Collapsible layer list item | | Image | <fig-image> | Image display/upload | | Avatar | <fig-avatar> | Profile image or initials | | Spinner | <fig-spinner> | Loading spinner | | Shimmer | <fig-shimmer> | Shimmer loading placeholder | | Skeleton | <fig-skeleton> | Skeleton loading placeholder |


Form Controls

Button

<fig-button>demo

| Attribute | Type | Default | Description | |---|---|---|---| | variant | string | "primary" | "primary", "secondary", "ghost", "link" | | type | string | "button" | "button", "toggle", "submit", "select", "upload" | | size | string | — | "large", "compact" | | selected | boolean | false | Selected state (toggle type) | | disabled | boolean | false | Disabled state | | icon | boolean | false | Icon-only styling | | href | string | — | URL for link buttons | | target | string | — | Link target (e.g. "_blank") |

<fig-button>Primary</fig-button>
<fig-button variant="secondary">Secondary</fig-button>
<fig-button type="toggle" selected="true">Toggle</fig-button>
<fig-button variant="ghost" icon>
  <svg><!-- icon --></svg>
</fig-button>

Dropdown

<fig-dropdown>demo

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Selected value | | type | string | "select" | "select" or "dropdown" | | experimental | string | — | Feature flags (e.g. "modern" for appearance: base-select) |

<fig-dropdown value="2">
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
</fig-dropdown>

Combo Input

<fig-combo-input>demo

| Attribute | Type | Default | Description | |---|---|---|---| | options | string | — | Comma-separated suggestion list | | placeholder | string | — | Placeholder text | | value | string | — | Current value | | disabled | boolean | false | Disabled state |

<fig-combo-input options="House, Apartment, Condo" placeholder="Residence type"></fig-combo-input>

Checkbox

<fig-checkbox>demo

| Attribute | Type | Default | Description | |---|---|---|---| | checked | boolean | false | Whether checked | | indeterminate | boolean | false | Indeterminate state | | disabled | boolean | false | Disabled state | | name | string | — | Form field name | | value | string | — | Value when checked | | label | string | — | Label text (alternative to slotted content) |

<fig-checkbox>Accept terms</fig-checkbox>
<fig-checkbox checked>Selected</fig-checkbox>
<fig-checkbox indeterminate>Parent option</fig-checkbox>

Radio

<fig-radio>demo

| Attribute | Type | Default | Description | |---|---|---|---| | checked | boolean | false | Whether selected | | disabled | boolean | false | Disabled state | | name | string | — | Radio group name | | value | string | — | Value when selected |

<fig-radio name="size" value="small">Small</fig-radio>
<fig-radio name="size" value="medium" checked>Medium</fig-radio>
<fig-radio name="size" value="large">Large</fig-radio>

Switch

<fig-switch>demo

| Attribute | Type | Default | Description | |---|---|---|---| | checked | boolean | false | Whether on | | disabled | boolean | false | Disabled state | | name | string | — | Form field name | | value | string | — | Value when on |

<fig-switch>Enable notifications</fig-switch>
<fig-switch checked>Active feature</fig-switch>

Inputs

Slider

<fig-slider>demo

| Attribute | Type | Default | Description | |---|---|---|---| | type | string | "range" | "range", "hue", "opacity", "delta", "stepper" | | value | number | — | Current value | | min | number | 0 | Minimum | | max | number | 100 | Maximum | | step | number | 1 | Step increment | | default | number | — | Default/reset value (shown as marker) | | text | boolean | false | Show text input | | placeholder | string | "##" | Text input placeholder | | units | string | — | Unit label (e.g. "%", "px") | | transform | number | — | Display value multiplier | | color | string | — | Track color (opacity type) | | variant | string | — | Visual variant (e.g. "neue") | | precision | number | — | Decimal places for output | | disabled | boolean | false | Disabled state |

Events: input (continuous), change (on release).

<fig-slider min="0" max="100" value="50" text="true" units="%"></fig-slider>
<fig-slider type="hue" value="180"></fig-slider>
<fig-slider type="opacity" value="75" color="#FF5733" text="true" units="%"></fig-slider>

Field Slider

<fig-field-slider>

Wraps a <fig-field> and <fig-slider> into a single labeled control. All slider attributes (except label, direction) are forwarded to the inner slider.

| Attribute | Type | Default | Description | |---|---|---|---| | label | string | — | Field label text | | direction | string | "column" | Layout direction | | slider attrs | — | — | All <fig-slider> attributes are forwarded |

Events: input, change — forwarded from the inner slider.

<fig-field-slider label="Opacity" min="0" max="100" value="75" text="true" units="%"></fig-field-slider>

Text Input

<fig-input-text>demo

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Input value | | placeholder | string | — | Placeholder text | | type | string | "text" | "text" or "number" | | disabled | boolean | false | Disabled state | | multiline | boolean | false | Use textarea | | min | number | — | Min (number type) | | max | number | — | Max (number type) | | step | number | — | Step (number type) | | transform | number | — | Display multiplier |

<fig-input-text value="Hello" placeholder="Enter text..."></fig-input-text>
<fig-input-text multiline placeholder="Enter description..."></fig-input-text>

Number Input

<fig-input-number>demo

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Numeric value | | placeholder | string | — | Placeholder text | | min | number | — | Minimum | | max | number | — | Maximum | | step | number | — | Step increment | | units | string | — | Unit string (e.g. "px", "%") | | units-disallow | string | "px" | Comma-separated unit disallow list (e.g. "px,rem") | | unit-position | string | "suffix" | "suffix" or "prefix" | | transform | number | — | Display multiplier | | steppers | boolean | false | Show spin buttons | | disabled | boolean | false | Disabled state |

<fig-input-number value="100" units="px"></fig-input-number>
<fig-input-number value="50" units="%" min="0" max="100"></fig-input-number>

Input Angle

<fig-input-angle>demo

Angle/rotation input with circular dial, optional text input, multi-unit support, and unbounded winding past 360deg. Accepts unit suffixes in text input (90deg, 3.14rad, 0.5turn).

| Attribute | Type | Default | Description | |---|---|---|---| | value | number | 0 | Angle value | | precision | number | 1 | Decimal places | | text | boolean | false | Show text input | | dial | boolean | true | Show circular dial | | min | number | — | Minimum (omit for unbounded) | | max | number | — | Maximum (omit for unbounded) | | units | string | "°" | "°" / "deg", "rad", "turn" | | rotations | boolean | false | Show rotation counter |

Events: input (continuous), change (on release).

<fig-input-angle value="90" text="true"></fig-input-angle>
<fig-input-angle text="true" units="rad" value="3.14159"></fig-input-angle>
<fig-input-angle text="true" rotations value="1080"></fig-input-angle>

Color & Fill

Chit

<fig-chit>demo

A color/gradient/image swatch element with checkerboard background for alpha.

| Attribute | Type | Default | Description | |---|---|---|---| | background | string | — | CSS background value | | size | string | "small" | "small" or "large" | | selected | boolean | false | Selection ring | | disabled | boolean | false | Disabled state | | alpha | number | — | Opacity (0-1) |

<fig-chit background="#FF5733"></fig-chit>
<fig-chit background="linear-gradient(90deg, #FF0000, #0000FF)" size="large"></fig-chit>

Color Tip

<fig-color-tip>demo

A compact solid-color swatch that wraps <fig-fill-picker>. Used inside gradient handles and other controls.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Color string (hex/rgb/hsl/named) | | selected | boolean | false | Selected state | | disabled | boolean | false | Disabled state | | alpha | boolean | false | Show alpha controls | | control | string | — | "add" or "remove" for icon-only mode |

Events:

| Event | Detail | |---|---| | input | { color, opacity? } — while editing | | change | { color, opacity? } — on commit | | add | — (when control="add" is clicked) | | remove | — (when control="remove" is clicked) |

<fig-color-tip value="#FF5733"></fig-color-tip>
<fig-color-tip value="#00AAFF" alpha="true"></fig-color-tip>

Color Input

<fig-input-color>demo

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Hex color (e.g. "#FF5733" or "#FF573380") | | text | boolean | false | Show hex text input | | alpha | boolean | false | Show alpha slider | | picker | string | "native" | "native", "figma", "false" | | mode | string | — | Color mode ("hex", "rgb", "hsl") | | experimental | string | — | Feature flags | | disabled | boolean | false | Disabled state |

Events:

| Event | Detail | |---|---| | input | { color, alpha, hsv: { h, s, v, a } } | | change | { color, alpha, hsv: { h, s, v, a } } |

<fig-input-color value="#FF5733" text="true" alpha="true"></fig-input-color>
<fig-input-color value="#FF5733" text="true" alpha="true" picker="figma"></fig-input-color>

Input Palette

<fig-input-palette>

An editable palette of solid colors, each rendered as a <fig-input-color> swatch with add/remove support.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | JSON array of hex strings or {color, alpha} objects | | disabled | boolean | false | Disabled state | | min | number | 2 | Minimum number of colors | | max | number | 8 | Maximum (add button hidden at max) | | expanded | boolean | false | Show text + alpha inputs per color | | add | boolean | true | Show add-color button (add="false" hides it) |

Events:

| Event | Detail | |---|---| | input | Full color array (during editing) | | change | Full color array (on commit or add) |

<fig-input-palette value='["#FF0000","#00FF00","#0000FF"]'></fig-input-palette>
<fig-input-palette value='[{"color":"#FF0000","alpha":0.5},{"color":"#00FF00","alpha":1}]' open></fig-input-palette>

Gradient Input

<fig-input-gradient>

A gradient editor with draggable stops. Opens <fig-fill-picker> locked to gradient mode.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | JSON gradient fill data | | disabled | boolean | false | Disabled state | | experimental | string | — | Picker feature flags | | picker-* | string | — | Passthrough picker attributes | | picker-anchor | string | "self" | Anchor selector or "self" |

Supported interpolation spaces: srgb, srgb-linear, display-p3, oklab, oklch (with hueInterpolation: shorter, longer, increasing, decreasing).

Events:

| Event | Detail | |---|---| | input | { type, gradient, css } | | change | { type, gradient, css } |

<fig-input-gradient
  value='{"type":"gradient","gradient":{"type":"linear","angle":90,"interpolationSpace":"oklab","stops":[{"position":0,"color":"#FF0000","opacity":100},{"position":100,"color":"#0000FF","opacity":100}]}}'
></fig-input-gradient>

Fill Input

<fig-input-fill>demo

A comprehensive fill input supporting solid, gradient, image, and video fills.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | JSON fill data | | disabled | boolean | false | Disabled state | | mode | string | — | Lock to a fill mode | | experimental | string | — | Feature flags | | alpha | boolean | true | Show alpha controls |

Events:

| Event | Detail | |---|---| | input | { type, color?, gradient?, image?, video?, css } | | change | { type, color?, gradient?, image?, video?, css } |

<fig-input-fill value='{"type":"solid","color":"#FF5733","opacity":100}'></fig-input-fill>

Fill Picker

<fig-fill-picker>demo

Full fill picker dialog supporting solid, gradient, image, video, and webcam. Wraps a trigger element (e.g. <fig-chit>).

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | JSON fill value | | disabled | boolean | false | Disabled state | | alpha | boolean | true | Show alpha controls | | mode | string | — | Lock to mode: "solid", "gradient", "image", "video", "webcam" | | experimental | string | — | Feature flags |

Events:

| Event | Detail | |---|---| | input | { type, gradient?, color?, css } | | change | { type, gradient?, color?, css } |

<fig-fill-picker value='{"type":"solid","color":"#FF5733"}'>
  <fig-chit></fig-chit>
</fig-fill-picker>

Selection

Tabs

<fig-tabs> / <fig-tab>demo

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Selected tab value | | name | string | — | Tabs group identifier | | disabled | boolean | false | Disable all tabs |

Events: input, change with selected tab value.

<fig-tabs value="tab1">
  <fig-tab value="tab1">General</fig-tab>
  <fig-tab value="tab2">Advanced</fig-tab>
</fig-tabs>

Segmented Control

<fig-segmented-control> / <fig-segment>demo

| Attribute | Type | Default | Description | |---|---|---|---| | name | string | — | Group identifier | | value | string | — | Selected segment value | | animated | boolean | false | Animate indicator transitions | | sizing | string | "equal" | "equal" or "auto" width mode |

Events: input, change — detail contains the selected value.

<fig-segmented-control>
  <fig-segment value="left" selected="true">Left</fig-segment>
  <fig-segment value="center">Center</fig-segment>
  <fig-segment value="right">Right</fig-segment>
</fig-segmented-control>

Chooser

<fig-chooser> / <fig-choice>

A selection list controller. <fig-choice> elements are selectable options within a <fig-chooser>.

fig-chooser attributes:

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Selected choice value | | choice-element | string | "fig-choice" | CSS selector for child choices | | layout | string | "vertical" | "vertical", "horizontal", "grid" | | disabled | boolean | false | Disabled state | | drag | boolean | false | Enable drag-to-scroll | | overflow | string | — | Overflow behavior | | loop | boolean | false | Loop keyboard navigation | | padding | boolean | true | Internal padding (padding="false" removes it) |

fig-choice attributes:

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Choice identifier | | selected | boolean | false | Selected state | | disabled | boolean | false | Disabled state |

Events (on fig-chooser): input, change — detail is the selected value string.

<fig-chooser value="opt1">
  <fig-choice value="opt1">Option 1</fig-choice>
  <fig-choice value="opt2">Option 2</fig-choice>
  <fig-choice value="opt3">Option 3</fig-choice>
</fig-chooser>

Spatial Controls

Joystick

<fig-joystick>

A 2D position input control with optional X/Y fields.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | "50% 50%" | Position as percentages | | precision | number | — | Decimal places | | transform | number | — | Output scaling | | fields | boolean | false | Show X/Y inputs | | coordinates | string | "screen" | "screen" (0,0 top-left) or "math" (0,0 bottom-left) | | aspect-ratio | string | "1 / 1" | Plane ratio |

Events:

| Event | Detail | |---|---| | input | { x, y, value } — while dragging | | change | { x, y, value } — on release |

<fig-joystick value="50% 50%" fields="true" precision="2"></fig-joystick>

Origin Grid

<fig-origin-grid>

A transform-origin grid control with a draggable handle and optional X/Y percentage fields.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | "50% 50%" | CSS transform-origin pair | | precision | number | 0 | Decimal places | | aspect-ratio | string | — | Grid aspect ratio | | drag | boolean | true | Enable handle dragging | | fields | boolean | false | Show X/Y fields |

Events:

| Event | Detail | |---|---| | input | { value, x, y } — while dragging | | change | { value, x, y } — on release |

<fig-origin-grid value="50% 50%" drag="true" fields="true"></fig-origin-grid>

Easing Curve

<fig-easing-curve>

An interactive bezier or spring easing curve editor with draggable control points and an optional preset dropdown.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Bezier: "0.42, 0, 0.58, 1" or Spring: "spring(200, 15, 1)" | | precision | number | 2 | Decimal places | | aspect-ratio | string | — | Editor aspect ratio | | dropdown | boolean | false | Show preset dropdown |

Static: FigEasingCurve.PRESETS — built-in preset array. FigEasingCurve.curveIcon(value) — SVG icon helper.

Events:

| Event | Detail | |---|---| | input | { mode, value, cssValue, preset } — while dragging | | change | { mode, value, cssValue, preset } — on release |

<fig-easing-curve value="0.42, 0, 0.58, 1" dropdown="true"></fig-easing-curve>
<fig-easing-curve value="spring(200, 15, 1)"></fig-easing-curve>

3D Rotate

<fig-3d-rotate>

An interactive 3D cube for setting rotation values. Supports drag interaction and optional X/Y/Z number fields.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | CSS transform, e.g. "rotateX(20deg) rotateY(-35deg) rotateZ(0deg)" | | precision | number | 1 | Decimal places | | aspect-ratio | string | — | Cube container ratio | | fields | boolean | false | Show X/Y/Z number inputs | | perspective | string | — | CSS perspective value | | perspective-origin | string | — | CSS perspective-origin | | transform-origin | string | — | CSS transform-origin | | selected | string | — | Highlighted face | | drag | boolean | true | Enable drag rotation |

Events:

| Event | Detail | |---|---| | input | { value, rotateX, rotateY, rotateZ } — while dragging | | change | { value, rotateX, rotateY, rotateZ } — on release |

<fig-3d-rotate value="rotateX(20deg) rotateY(-35deg) rotateZ(0deg)" fields="true"></fig-3d-rotate>

Handle

<fig-handle>

A draggable handle element. Positioned on a drag-surface container with axis constraints and snapping. Used internally by gradient editors and spatial controls, but also available standalone.

| Attribute | Type | Default | Description | |---|---|---|---| | value | string | — | Position as "X% Y%" | | color | string | — | Handle color | | selected | boolean | false | Selected state | | disabled | boolean | false | Disabled state | | drag | boolean | false | Enable dragging | | drag-surface | string | — | CSS selector for drag container (defaults to parent) | | drag-axes | string | "xy" | Constrain axes: "x", "y", "xy" | | drag-snapping | string | — | Snapping behavior | | type | string | — | "color" for color handle with fig-color-tip | | control | string | — | "add" or "remove" delegated to color tip | | hit-area | string | — | Expanded interaction zone (unitless px). "8", "8 12" (v h), or "8 circle" | | hit-area-mode | string | "handle" | "handle" proxies to handle drag/select; "delegate" emits hitareadown event |

Events:

| Event | Detail | |---|---| | input | { x, y, px, py, shiftKey } — while dragging | | change | { x, y, px, py } — on release | | add | — (when control="add") | | remove | — (when control="remove") | | hitareadown | { originalEvent } — when hit-area-mode="delegate" and the hit area is clicked |

<div style="position: relative; width: 200px; height: 200px; background: #eee;">
  <fig-handle drag="true" value="50% 50%"></fig-handle>
</div>

Canvas Control

<fig-canvas-control>demo

A composite point control with optional radius circle, angle handle, or second point. Place inside a positioned container; the component uses display: contents and does not create its own box.

| Attribute | Type | Default | Description | |---|---|---|---| | type | string | "point" | "point", "color", "point-radius", "point-radius-angle", "point-point" | | value | JSON string | — | { "x": 50, "y": 50 } — see type-specific shapes below | | name | string | — | Tooltip label(s). Comma-separated for two handles: "Start, End" | | color | string | — | Passthrough color for type="color" handle | | tooltips | string | "true" | Show value tooltips on interaction | | disabled | boolean | false | Disable all interaction | | drag-surface | string | "parent" | Forwarded to inner fig-handles | | snapping | string | "false" | "false", "true", "modifier" — applies to all handles |

Value shapes by type:

| Type | Value shape | |---|---| | point, color | { x, y } | | point-radius | { x, y, radius } — radius: number (px) or "25%" | | point-radius-angle | { x, y, radius, angle } — angle in degrees | | point-point | { x, y, x2, y2 } — angle and length inferred |

Events:

| Event | Detail | |---|---| | input | Value object (shape depends on type) — while dragging | | change | Value object (shape depends on type) — on release |

For point-point, both handles support direct drag (with a dynamic directional resize cursor) and rotation via their hit area (dragging from the hit area rotates around the opposite handle at fixed distance, with a rotate cursor).

<div style="position: relative; width: 200px; height: 200px; background: #eee;">
  <fig-canvas-control
    type="point-point"
    name="Start, End"
    value='{"x":25,"y":25,"x2":75,"y2":75}'
    snapping="modifier"
  ></fig-canvas-control>
</div>

Layout & Feedback

Field

<fig-field>demo

A form field wrapper with flexible layout. Automatically links <label> to the first fig-* child for accessibility.

| Attribute | Type | Default | Description | |---|---|---|---| | direction | string | "column" | "column", "row", "horizontal" | | columns | string | — | Split preset: "thirds" or "half" | | label | string | — | Programmatic label text |

<fig-field direction="horizontal" columns="thirds">
  <label>Opacity</label>
  <fig-slider value="50" text="true" units="%"></fig-slider>
</fig-field>

Dialog

<fig-dialog>demo

A modal/non-modal dialog. Uses is="fig-dialog" on a native <dialog> element.

| Attribute | Type | Default | Description | |---|---|---|---| | open | boolean | false | Visible state | | modal | boolean | false | Modal mode | | drag | boolean | false | Draggable | | handle | string | — | CSS selector for drag handle | | position | string | — | "center center", "top left", etc. |

<dialog is="fig-dialog" id="myDialog" modal drag handle="fig-header" position="center center">
  <fig-header>Dialog Title</fig-header>
  <fig-content><p>Content here.</p></fig-content>
</dialog>

Popup

<fig-popup>demo

An anchored floating surface built on <dialog> with collision-aware positioning.

| Attribute | Type | Default | Description | |---|---|---|---| | anchor | string | — | CSS selector for anchor element | | position | string | "top center" | Placement | | offset | string | "0 0" | X/Y offset | | viewport-margin | string | "8" | Viewport safety margin | | variant | string | — | "popover" for beak styling | | theme | string | — | "light", "dark", "menu" | | closedby | string | "any" | "any", "closerequest", "none" | | open | boolean | false | Open state | | drag | boolean | false | Draggable | | handle | string | — | CSS selector for drag handle | | autoresize | boolean | false | Auto-resize to content |

<dialog is="fig-popup" anchor="#my-button" position="center right" variant="popover">
  <fig-header><h3>Popup</h3></fig-header>
</dialog>

Toast

<fig-toast>demo

A toast notification. Uses is="fig-toast" on a native <dialog>.

| Attribute | Type | Default | Description | |---|---|---|---| | duration | number | 5000 | Auto-dismiss ms (0 = no dismiss) | | offset | number | 16 | Distance from bottom | | theme | string | "dark" | "dark", "light", "danger", "brand", "auto" |

<dialog is="fig-toast" id="myToast" theme="brand" duration="3000">
  Settings saved!
</dialog>
<fig-button onclick="document.getElementById('myToast').showToast()">Show</fig-button>

Tooltip

<fig-tooltip>demo

Contextual tooltip on hover or click. Auto-repositions when the child element moves.

| Attribute | Type | Default | Description | |---|---|---|---| | text | string | — | Tooltip text | | action | string | "hover" | "hover", "click", "manual" | | delay | number | 500 | Show delay in ms | | offset | string | — | "left,top,right,bottom" | | show | boolean | false | Persistent show state | | open | boolean | false | Programmatic show/hide |

<fig-tooltip text="Helpful info">
  <fig-button>Hover me</fig-button>
</fig-tooltip>

Header

<fig-header>demo

A section header component.

<fig-header>Section Title</fig-header>

Layer

<fig-layer>demo

A collapsible layer list item with expand/collapse and visibility toggling. Supports nesting.

| Attribute | Type | Default | Description | |---|---|---|---| | open | boolean | false | Whether children are expanded | | visible | boolean | true | Whether the layer is visible |

Events: openchange (detail: { open }), visibilitychange (detail: { visible }).

<fig-layer open="true">
  <div class="fig-layer-row">
    <span class="fig-layer-icon"></span>
    <span class="fig-layer-name">Group 1</span>
  </div>
  <fig-layer>
    <div class="fig-layer-row">
      <span class="fig-layer-icon"></span>
      <span class="fig-layer-name">Child 1</span>
    </div>
  </fig-layer>
</fig-layer>

Image

<fig-image>demo

An image display component with optional upload, aspect ratio, and object-fit control.

| Attribute | Type | Default | Description | |---|---|---|---| | src | string | — | Image URL | | upload | boolean | false | Show upload overlay (fig-input-file) | | label | string | "Upload" | Upload button label | | aspect-ratio | string | — | CSS aspect-ratio, or "auto" for lazy dimension detection | | fit | string | — | CSS object-fit ("cover", "contain", etc.) | | checkerboard | boolean | false | Show checkerboard behind transparent images |

<fig-image src="photo.jpg" aspect-ratio="16 / 9" fit="cover"></fig-image>
<fig-image upload label="Upload Image"></fig-image>

Avatar

<fig-avatar>demo

Profile image or initials fallback.

| Attribute | Type | Default | Description | |---|---|---|---| | src | string | — | Image URL | | name | string | — | Name for initials fallback | | size | string | — | "large" |

<fig-avatar src="https://example.com/photo.jpg" name="John Doe"></fig-avatar>
<fig-avatar name="Jane Smith" size="large"></fig-avatar>

Spinner

<fig-spinner>demo

A loading spinner.

<fig-spinner></fig-spinner>

Shimmer

<fig-shimmer>demo

A shimmer loading placeholder.

| Attribute | Type | Default | Description | |---|---|---|---| | duration | string | "1.5s" | Animation cycle duration | | playing | boolean | true | Whether animating |

<fig-shimmer style="width: 200px; height: 20px;"></fig-shimmer>

Skeleton

<fig-skeleton>

Extends <fig-shimmer> with no additional attributes. Use for structured loading placeholders.

<fig-skeleton style="width: 100%; height: 1rem; border-radius: 4px;"></fig-skeleton>

Theming

FigUI3 adapts to light and dark themes via CSS custom properties using Figma's naming convention:

--figma-color-bg
--figma-color-bg-secondary
--figma-color-bg-hover
--figma-color-text
--figma-color-text-secondary
--figma-color-border
--figma-color-icon
/* ... and more */

In Figma plugins, these variables are provided automatically. For standalone usage, the library includes fallback values that respond to prefers-color-scheme.

Force a theme manually:

<body style="color-scheme: dark;">
  <!-- Forces dark theme -->
</body>

Framework Integration

React

import { useRef, useEffect } from 'react';
import '@rogieking/figui3/fig.css';
import '@rogieking/figui3/fig.js';

function ColorPicker({ value, onChange }) {
  const ref = useRef(null);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const handleChange = (e) => onChange(e.detail);
    el.addEventListener('change', handleChange);
    return () => el.removeEventListener('change', handleChange);
  }, [onChange]);

  useEffect(() => {
    if (ref.current) ref.current.setAttribute('value', value);
  }, [value]);

  return <fig-input-color ref={ref} text="true" alpha="true" picker="figma" />;
}

Note: Avoid setting value directly in JSX during re-renders — use refs to prevent infinite loops from attributeChangedCallback.

SSR (Next.js/Remix/Astro): Import fig.js only on the client to keep server rendering safe.

Vue

<template>
  <fig-input-color :value="color" text="true" alpha="true" @input="onInput" @change="onChange" />
</template>

<script setup>
import { ref } from 'vue';
import '@rogieking/figui3/fig.css';
import '@rogieking/figui3/fig.js';

const color = ref('#FF5733');
const onInput = (e) => { color.value = e.detail.color; };
const onChange = (e) => { console.log('Final:', e.detail); };
</script>

Svelte

<script>
  import '@rogieking/figui3/fig.css';
  import '@rogieking/figui3/fig.js';
  let color = '#FF5733';
</script>

<fig-input-color value={color} text="true" alpha="true"
  on:input={(e) => color = e.detail.color}
  on:change={(e) => console.log('Saved:', e.detail)} />

Development

git clone https://github.com/rogie/figui3.git
cd figui3
bun install
bun dev                # Component docs at http://localhost:3000
npm run dev:playground # Playground at http://localhost:5173 (/figui3, /propkit, /sandbox)
npm run build          # Build minified dist/ (JS + CSS)
npm run build:css      # Build minified CSS only

Build Output

npm run build produces minified files in dist/:

| Source | Minified | Tool | |---|---|---| | fig.js (416 KB) | dist/fig.js (228 KB) | Bun --minify | | fig.css (133 KB) | dist/fig.css (102 KB) | lightningcss --minify --nesting --bundle | | base.css (1.9 KB) | dist/base.css (1.5 KB) | lightningcss | | components.css (131 KB) | dist/components.css (100 KB) | lightningcss |

Default imports resolve to minified dist/ files. Unminified source is available via @rogieking/figui3/src/*:

import "@rogieking/figui3/fig.css";      // minified (default)
import "@rogieking/figui3/src/fig.css";  // unminified source

Playground

The playground is the fastest way to explore and validate component markup:

  • /figui3 — component examples with attribute controls
  • /propkit — property panel patterns
  • /sandbox — styled React sample app

Browser Support

  • Chrome/Edge 67+
  • Firefox 63+
  • Safari 10.1+

License

MIT License © Rogie King