@rogieking/figui3
v4.5.1
Published
A lightweight web components library for building Figma plugin and widget UIs with native look and feel
Maintainers
Readme
FigUI3
A lightweight, zero-dependency web components library for building Figma plugin and widget UIs with native look and feel.
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/figui3Import:
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
valuedirectly in JSX during re-renders — use refs to prevent infinite loops fromattributeChangedCallback.SSR (Next.js/Remix/Astro): Import
fig.jsonly 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 onlyBuild 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 sourcePlayground
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
