@rogieking/figui3 2.10.0 → 2.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,165 +1,151 @@
1
1
  # FigUI3
2
2
 
3
- A lightweight, customizable web component library that uses Figmas UI3 style for modern web applications, but specifically for Figma plugins.
3
+ A lightweight, zero-dependency web components library for building Figma plugin and widget UIs with native look and feel.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@rogieking/figui3.svg)](https://www.npmjs.com/package/@rogieking/figui3)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Live Demo
9
+
10
+ View the interactive component documentation at **[rogie.github.io/figui3](https://rogie.github.io/figui3/)**
4
11
 
5
12
  ## Features
6
13
 
7
- - 🎨 Figma-inspired design system
14
+ - 🎨 Figma UI3 design system
8
15
  - 📦 Zero dependencies
9
- - 🚀 Lightweight and performant
16
+ - 🚀 Lightweight (~50kb unminified)
10
17
  - 🎯 Built with Web Components
11
- - 🔧 Highly customizable
12
- - 🌐 Framework agnostic
13
-
14
- ## Components
15
-
16
- The library includes the following components:
17
-
18
- - `<fig-button>` - Versatile button component with multiple variants
19
- - `<fig-checkbox>` - Checkbox input with indeterminate state support
20
- - `<fig-dialog>` - Modal dialog component
21
- - `<fig-dropdown>` - Customizable dropdown select
22
- - `<fig-field>` - Form field wrapper with flexible layout options
23
- - `<fig-header>` - Section header component
24
- - `<fig-input-color>` - Color picker with hex/rgba support
25
- - `<fig-input-text>` - Text/Number input with optional prefix/suffix slots
26
- - `<fig-slider>` - Input slider with optional text input and units
27
- - `<fig-switch>` - Toggle switch component
28
- - `<fig-tooltip>` - Hover and click-triggered tooltips
29
- - `<fig-spinner>` - Loading spinner component
30
- - `<fig-combo-input>` - Combobox input
31
- - `<fig-chit>` - Color/Gradient/Pattern/Image/Icon/Text chit component
32
- - `<fig-tabs>` - Tabbed navigation component
33
- - `<fig-segmented-control>` - Segmented control component
34
- - `<fig-image>` - Image display or input component
18
+ - 🌗 Automatic light/dark theme support
19
+ - Accessible with ARIA attributes and keyboard navigation
20
+ - 🔧 Framework agnostic (works with React, Vue, Svelte, or vanilla JS)
35
21
 
36
22
  ## Installation
37
23
 
24
+ ### npm / yarn / bun / pnpm
25
+
38
26
  ```bash
39
27
  npm install @rogieking/figui3
28
+ # or
29
+ yarn add @rogieking/figui3
30
+ # or
31
+ bun add @rogieking/figui3
32
+ # or
33
+ pnpm add @rogieking/figui3
40
34
  ```
41
35
 
42
- ```jsx
36
+ Then import in your JavaScript/TypeScript:
37
+
38
+ ```js
43
39
  import "@rogieking/figui3/fig.css";
44
40
  import "@rogieking/figui3/fig.js";
45
41
  ```
46
42
 
47
- Or include directly in your HTML:
43
+ ### CDN
48
44
 
49
45
  ```html
50
- <link
51
- rel="stylesheet"
52
- href="https://unpkg.com/@rogieking/figui3@latest/fig.css"
53
- />
46
+ <link rel="stylesheet" href="https://unpkg.com/@rogieking/figui3@latest/fig.css" />
54
47
  <script src="https://unpkg.com/@rogieking/figui3@latest/fig.js"></script>
55
48
  ```
56
49
 
57
- or
50
+ Or via esm.sh:
58
51
 
59
52
  ```html
60
53
  <link rel="stylesheet" href="https://esm.sh/@rogieking/figui3@latest/fig.css" />
61
54
  <script src="https://esm.sh/@rogieking/figui3@latest/fig.js"></script>
62
55
  ```
63
56
 
64
- ## Usage
65
-
66
- ```html
67
- <!-- Basic button -->
68
- <fig-button>Click me</fig-button>
57
+ ### Development
69
58
 
70
- <!-- Slider with text input -->
71
- <fig-field direction="horizontal">
72
- <label>Opacity</label>
73
- <fig-slider type="opacity" value="0.75" color="#ff0000" units="%" text="true">
74
- </fig-slider>
75
- </fig-field>
59
+ ```bash
60
+ git clone https://github.com/rogie/figui3.git
61
+ cd figui3
62
+ bun install
63
+ bun dev # Opens documentation at http://localhost:3000
76
64
  ```
77
65
 
78
- ## Documentation
79
-
80
- For detailed documentation and examples, visit our [documentation site](https://github.com/rogie/figui3#readme).
66
+ ## Quick Start
81
67
 
82
- ## Browser Support
83
-
84
- Fig.js supports all modern browsers that implement the Web Components standard:
85
-
86
- - Chrome/Edge (Chromium) 67+
87
- - Firefox 63+
88
- - Safari 10.1+
89
-
90
- ## Contributing
91
-
92
- Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) before submitting a pull request.
93
-
94
- ## License
68
+ ```html
69
+ <!DOCTYPE html>
70
+ <html lang="en">
71
+ <head>
72
+ <link rel="stylesheet" href="https://unpkg.com/@rogieking/figui3@latest/fig.css" />
73
+ <script src="https://unpkg.com/@rogieking/figui3@latest/fig.js"></script>
74
+ </head>
75
+ <body>
76
+ <fig-field>
77
+ <label>Color</label>
78
+ <fig-input-color value="#FF5733" text="true" alpha="true"></fig-input-color>
79
+ </fig-field>
80
+
81
+ <fig-button variant="primary">Save</fig-button>
82
+ </body>
83
+ </html>
84
+ ```
95
85
 
96
- [MIT License](LICENSE)
86
+ ---
97
87
 
98
- ## Component Examples
88
+ ## Components
99
89
 
100
90
  ### Button (`<fig-button>`)
101
91
 
102
- ```html
103
- <!-- Basic button -->
104
- <fig-button>Click me</fig-button>
105
-
106
- <!-- Primary variant -->
107
- <fig-button variant="primary">Primary Button</fig-button>
92
+ A versatile button component with multiple variants and types.
108
93
 
109
- <!-- Secondary variant -->
110
- <fig-button variant="secondary">Secondary Button</fig-button>
94
+ | Attribute | Type | Default | Description |
95
+ |-----------|------|---------|-------------|
96
+ | `variant` | string | `"primary"` | Visual style: `"primary"`, `"secondary"`, `"ghost"`, `"link"` |
97
+ | `type` | string | `"button"` | Button type: `"button"`, `"toggle"`, `"submit"`, `"select"`, `"upload"` |
98
+ | `size` | string | — | Size variant: `"large"`, `"compact"` |
99
+ | `selected` | boolean | `false` | Whether button is in selected state (for toggle type) |
100
+ | `disabled` | boolean | `false` | Whether button is disabled |
101
+ | `icon` | boolean | `false` | Icon-only button styling |
102
+ | `href` | string | — | URL for link-style buttons |
103
+ | `target` | string | — | Target window for links (e.g., `"_blank"`) |
111
104
 
112
- <!-- Ghost variant -->
113
- <fig-button variant="ghost">Ghost Button</fig-button>
105
+ ```html
106
+ <!-- Variants -->
107
+ <fig-button>Primary</fig-button>
108
+ <fig-button variant="secondary">Secondary</fig-button>
109
+ <fig-button variant="ghost">Ghost</fig-button>
110
+ <fig-button variant="link">Link</fig-button>
111
+
112
+ <!-- Types -->
113
+ <fig-button type="toggle" selected="true">Toggle</fig-button>
114
+ <fig-button type="submit">Submit</fig-button>
114
115
 
115
- <!-- Ghost variant with icon -->
116
- <fig-button variant="ghost" icon="true">
117
- <svg><!-- your icon svg --></svg>
116
+ <!-- Icon button -->
117
+ <fig-button variant="ghost" icon>
118
+ <svg><!-- icon --></svg>
118
119
  </fig-button>
119
120
 
120
- <!-- Link variant -->
121
- <fig-button variant="link">Link Button</fig-button>
122
-
123
- <!-- Disabled state -->
124
- <fig-button disabled>Disabled</fig-button>
125
-
126
- <!-- Toggle button -->
127
- <fig-button type="toggle">Toggle Me</fig-button>
128
-
129
- <!-- Submit button -->
130
- <fig-button type="submit">Submit</fig-button>
131
-
132
- <!-- Select list button -->
121
+ <!-- Select button with dropdown -->
133
122
  <fig-button type="select">
134
- Select Me
123
+ Select Option
135
124
  <fig-dropdown>
136
125
  <option value="1">Option 1</option>
137
126
  <option value="2">Option 2</option>
138
- <option value="3">Option 3</option>
139
127
  </fig-dropdown>
140
128
  </fig-button>
141
129
 
142
- <!-- Default button -->
143
- <fig-button type="button">Default</fig-button>
144
-
145
130
  <!-- Upload button -->
146
131
  <fig-button type="upload">
147
- Upload
132
+ Upload File
148
133
  <input type="file" />
149
134
  </fig-button>
150
135
  ```
151
136
 
137
+ ---
138
+
152
139
  ### Dropdown (`<fig-dropdown>`)
153
140
 
154
- ```html
155
- <!-- Basic dropdown -->
156
- <fig-dropdown>
157
- <option value="1">Option 1</option>
158
- <option value="2">Option 2</option>
159
- <option value="3">Option 3</option>
160
- </fig-dropdown>
141
+ A native select wrapper with Figma styling.
161
142
 
162
- <!-- With default selection -->
143
+ | Attribute | Type | Default | Description |
144
+ |-----------|------|---------|-------------|
145
+ | `value` | string | — | Currently selected value |
146
+ | `type` | string | `"select"` | Type: `"select"` or `"dropdown"` |
147
+
148
+ ```html
163
149
  <fig-dropdown value="2">
164
150
  <option value="1">Option 1</option>
165
151
  <option value="2">Option 2</option>
@@ -167,82 +153,158 @@ Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTIN
167
153
  </fig-dropdown>
168
154
  ```
169
155
 
156
+ ---
157
+
170
158
  ### Tooltip (`<fig-tooltip>`)
171
159
 
160
+ Displays contextual information on hover or click.
161
+
162
+ | Attribute | Type | Default | Description |
163
+ |-----------|------|---------|-------------|
164
+ | `text` | string | — | Tooltip text content |
165
+ | `action` | string | `"hover"` | Trigger: `"hover"` or `"click"` |
166
+ | `delay` | number | `500` | Delay in ms before showing |
167
+ | `offset` | string | — | Position offset: `"left,top,right,bottom"` |
168
+
172
169
  ```html
173
- <!-- Hover tooltip -->
174
- <fig-tooltip text="This is a tooltip" action="hover">
175
- Hover over me
170
+ <fig-tooltip text="This is helpful info" action="hover">
171
+ <fig-button>Hover me</fig-button>
176
172
  </fig-tooltip>
177
173
 
178
- <!-- Click tooltip -->
179
- <fig-tooltip text="Click tooltip" action="click"> Click me </fig-tooltip>
174
+ <fig-tooltip text="Click triggered" action="click" delay="0">
175
+ <fig-button>Click me</fig-button>
176
+ </fig-tooltip>
180
177
  ```
181
178
 
179
+ ---
180
+
182
181
  ### Popover (`<fig-popover>`)
183
182
 
183
+ A popover container for rich content.
184
+
185
+ | Attribute | Type | Default | Description |
186
+ |-----------|------|---------|-------------|
187
+ | `action` | string | `"click"` | Trigger: `"click"` or `"hover"` |
188
+ | `size` | string | — | Size of the popover |
189
+
184
190
  ```html
185
- <!-- Basic popover -->
186
- <fig-popover>
187
- <button slot="trigger">Open Popover</button>
191
+ <fig-popover action="click">
192
+ <fig-button slot="trigger">Open Popover</fig-button>
188
193
  <div slot="content">
189
194
  <h3>Popover Title</h3>
190
- <p>This is the popover content.</p>
195
+ <p>Rich content goes here.</p>
191
196
  </div>
192
197
  </fig-popover>
193
198
  ```
194
199
 
200
+ ---
201
+
195
202
  ### Dialog (`<fig-dialog>`)
196
203
 
204
+ A modal dialog component with drag support.
205
+
206
+ | Attribute | Type | Default | Description |
207
+ |-----------|------|---------|-------------|
208
+ | `open` | boolean | `false` | Whether dialog is visible |
209
+ | `modal` | boolean | `false` | Whether dialog is modal |
210
+ | `drag` | boolean | `false` | Whether dialog is draggable |
211
+ | `handle` | string | — | CSS selector for drag handle |
212
+ | `position` | string | — | Position: `"center center"`, `"top left"`, etc. |
213
+
197
214
  ```html
198
- <!-- Basic dialog -->
199
- <fig-dialog>
215
+ <fig-dialog id="myDialog" modal drag handle="fig-header">
200
216
  <fig-header>Dialog Title</fig-header>
201
217
  <div slot="content">
202
218
  <p>Dialog content goes here.</p>
203
219
  </div>
204
220
  <div slot="footer">
205
- <fig-button>Cancel</fig-button>
206
- <fig-button variant="primary">Confirm</fig-button>
221
+ <fig-button variant="secondary">Cancel</fig-button>
222
+ <fig-button>Confirm</fig-button>
207
223
  </div>
208
224
  </fig-dialog>
225
+
226
+ <script>
227
+ document.getElementById('myDialog').showModal();
228
+ </script>
209
229
  ```
210
230
 
211
- ### Tabs (`<fig-tabs>`)
231
+ ---
232
+
233
+ ### Tabs (`<fig-tabs>` / `<fig-tab>`)
234
+
235
+ Tabbed navigation component.
236
+
237
+ | Attribute | Type | Default | Description |
238
+ |-----------|------|---------|-------------|
239
+ | `value` | string | — | Currently selected tab value |
240
+ | `name` | string | — | Tabs group identifier |
241
+ | `disabled` | boolean | `false` | Disable all tabs |
212
242
 
213
243
  ```html
214
- <fig-tabs>
215
- <fig-tab label="Tab 1">Content 1</fig-tab>
216
- <fig-tab label="Tab 2">Content 2</fig-tab>
217
- <fig-tab label="Tab 3">Content 3</fig-tab>
244
+ <fig-tabs value="tab1">
245
+ <fig-tab value="tab1" label="General">
246
+ <p>General settings content</p>
247
+ </fig-tab>
248
+ <fig-tab value="tab2" label="Advanced">
249
+ <p>Advanced settings content</p>
250
+ </fig-tab>
218
251
  </fig-tabs>
219
252
  ```
220
253
 
221
- ### Segmented Control (`<fig-segmented-control>`)
254
+ ---
255
+
256
+ ### Segmented Control (`<fig-segmented-control>` / `<fig-segment>`)
257
+
258
+ A segmented button group for exclusive selection.
259
+
260
+ | Attribute | Type | Default | Description |
261
+ |-----------|------|---------|-------------|
262
+ | `name` | string | — | Control group identifier |
263
+ | `value` | string | — | Selected segment value |
222
264
 
223
265
  ```html
224
266
  <fig-segmented-control>
225
- <button value="1">Option 1</button>
226
- <button value="2">Option 2</button>
227
- <button value="3">Option 3</button>
267
+ <fig-segment value="left" selected="true">Left</fig-segment>
268
+ <fig-segment value="center">Center</fig-segment>
269
+ <fig-segment value="right">Right</fig-segment>
228
270
  </fig-segmented-control>
229
271
  ```
230
272
 
273
+ ---
274
+
231
275
  ### Slider (`<fig-slider>`)
232
276
 
277
+ A range slider with multiple types and optional text input.
278
+
279
+ | Attribute | Type | Default | Description |
280
+ |-----------|------|---------|-------------|
281
+ | `type` | string | `"range"` | Type: `"range"`, `"hue"`, `"opacity"`, `"delta"`, `"stepper"` |
282
+ | `value` | number | — | Current value |
283
+ | `min` | number | `0` | Minimum value |
284
+ | `max` | number | `100` | Maximum value |
285
+ | `step` | number | `1` | Step increment |
286
+ | `text` | boolean | `false` | Show text input |
287
+ | `units` | string | — | Unit label (e.g., `"%"`, `"px"`) |
288
+ | `transform` | number | — | Multiplier for display value |
289
+ | `color` | string | — | Track color (for opacity type) |
290
+ | `disabled` | boolean | `false` | Disable slider |
291
+
233
292
  ```html
234
- <!-- Basic range slider -->
293
+ <!-- Basic slider -->
235
294
  <fig-slider min="0" max="100" value="50"></fig-slider>
236
295
 
237
- <!-- Slider with text input and units -->
238
- <fig-slider min="0" max="100" value="75" text="true" units="%"> </fig-slider>
296
+ <!-- With text input and units -->
297
+ <fig-slider min="0" max="100" value="75" text="true" units="%"></fig-slider>
239
298
 
240
299
  <!-- Hue slider -->
241
- <fig-slider type="hue" value="55"></fig-slider>
300
+ <fig-slider type="hue" value="180"></fig-slider>
242
301
 
243
- <!-- Stepper slider with discrete snapping values-->
244
- <fig-slider type="stepper" value="25" default="50" step="25">
245
- <datalist id="markers">
302
+ <!-- Opacity slider with color -->
303
+ <fig-slider type="opacity" value="75" color="#FF5733" text="true" units="%"></fig-slider>
304
+
305
+ <!-- Stepper with snap points -->
306
+ <fig-slider type="stepper" value="50" step="25">
307
+ <datalist>
246
308
  <option value="0"></option>
247
309
  <option value="25"></option>
248
310
  <option value="50"></option>
@@ -251,145 +313,576 @@ Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTIN
251
313
  </datalist>
252
314
  </fig-slider>
253
315
 
254
- <!-- Delta slider -->
255
- <fig-slider type="delta" value=".25" default="0" step="0.25" min="-5" max="5">
256
- <datalist id="markers">
316
+ <!-- Delta slider -->
317
+ <fig-slider type="delta" value="0" min="-5" max="5" step="0.25">
318
+ <datalist>
257
319
  <option value="0"></option>
258
320
  </datalist>
259
321
  </fig-slider>
260
-
261
- <!-- Opacity slider with color -->
262
- <fig-slider type="opacity" value="0.75" color="#ff0000" units="%" text="true">
263
- </fig-slider>
264
-
265
- <!-- Number slider with number transform and percentage units -->
266
- <fig-slider
267
- min="0"
268
- max="1"
269
- transform="100"
270
- units="%"
271
- step="0.01"
272
- text="true"
273
- value="0.5"
274
- >
275
- </fig-slider>
276
322
  ```
277
323
 
324
+ ---
325
+
278
326
  ### Text Input (`<fig-input-text>`)
279
327
 
328
+ A styled text input with optional slots.
329
+
330
+ | Attribute | Type | Default | Description |
331
+ |-----------|------|---------|-------------|
332
+ | `value` | string | — | Input value |
333
+ | `placeholder` | string | — | Placeholder text |
334
+ | `type` | string | `"text"` | Input type: `"text"` or `"number"` |
335
+ | `disabled` | boolean | `false` | Disable input |
336
+ | `multiline` | boolean | `false` | Use textarea |
337
+ | `min` | number | — | Min value (number type) |
338
+ | `max` | number | — | Max value (number type) |
339
+ | `step` | number | — | Step (number type) |
340
+ | `transform` | number | — | Display multiplier |
341
+
280
342
  ```html
281
343
  <!-- Basic text input -->
282
- <fig-input-text value="Hello World"></fig-input-text>
283
-
284
- <!-- With placeholder -->
285
- <fig-input-text placeholder="Enter text..."></fig-input-text>
344
+ <fig-input-text value="Hello" placeholder="Enter text..."></fig-input-text>
286
345
 
287
- <!-- With prepend and append slots -->
346
+ <!-- With prepend/append slots -->
288
347
  <fig-input-text>
289
348
  <span slot="prepend">$</span>
290
349
  <span slot="append">.00</span>
291
350
  </fig-input-text>
351
+
352
+ <!-- Multiline -->
353
+ <fig-input-text multiline placeholder="Enter description..."></fig-input-text>
354
+ ```
355
+
356
+ ---
357
+
358
+ ### Number Input (`<fig-input-number>`)
359
+
360
+ A numeric input with units support.
361
+
362
+ | Attribute | Type | Default | Description |
363
+ |-----------|------|---------|-------------|
364
+ | `value` | string | — | Numeric value |
365
+ | `placeholder` | string | — | Placeholder text |
366
+ | `min` | number | — | Minimum value |
367
+ | `max` | number | — | Maximum value |
368
+ | `step` | number | — | Step increment |
369
+ | `units` | string | — | Unit string (e.g., `"px"`, `"%"`) |
370
+ | `unit-position` | string | `"suffix"` | `"suffix"` or `"prefix"` |
371
+ | `transform` | number | — | Display multiplier |
372
+ | `disabled` | boolean | `false` | Disable input |
373
+
374
+ ```html
375
+ <fig-input-number value="100" units="px"></fig-input-number>
376
+ <fig-input-number value="50" units="%" min="0" max="100"></fig-input-number>
377
+ <fig-input-number value="45" units="°" step="15"></fig-input-number>
378
+ ```
379
+
380
+ ---
381
+
382
+ ### Color Input (`<fig-input-color>`)
383
+
384
+ A color picker with hex/alpha support.
385
+
386
+ | Attribute | Type | Default | Description |
387
+ |-----------|------|---------|-------------|
388
+ | `value` | string | — | Hex color value (e.g., `"#FF5733"` or `"#FF573380"`) |
389
+ | `text` | boolean | `false` | Show hex text input |
390
+ | `alpha` | boolean | `false` | Show alpha slider |
391
+ | `picker` | string | `"native"` | Picker type: `"native"`, `"figma"`, `"false"` |
392
+ | `disabled` | boolean | `false` | Disable input |
393
+
394
+ ```html
395
+ <!-- Basic color picker -->
396
+ <fig-input-color value="#FF5733"></fig-input-color>
397
+
398
+ <!-- With text and alpha -->
399
+ <fig-input-color value="#FF5733" text="true" alpha="true"></fig-input-color>
400
+
401
+ <!-- With Figma-style picker dialog -->
402
+ <fig-input-color value="#FF5733" text="true" alpha="true" picker="figma"></fig-input-color>
403
+ ```
404
+
405
+ ---
406
+
407
+ ### Fill Input (`<fig-input-fill>`)
408
+
409
+ A comprehensive fill input supporting colors, gradients, images, and video.
410
+
411
+ | Attribute | Type | Default | Description |
412
+ |-----------|------|---------|-------------|
413
+ | `value` | string | — | JSON fill data |
414
+ | `disabled` | boolean | `false` | Disable input |
415
+
416
+ ```html
417
+ <!-- Solid color -->
418
+ <fig-input-fill value='{"type":"solid","color":"#FF5733","opacity":100}'></fig-input-fill>
419
+
420
+ <!-- Gradient -->
421
+ <fig-input-fill value='{"type":"gradient","gradient":{"type":"linear","angle":90,"stops":[{"position":0,"color":"#FF0000"},{"position":100,"color":"#0000FF"}]}}'></fig-input-fill>
422
+
423
+ <!-- Image -->
424
+ <fig-input-fill value='{"type":"image","image":{"url":"path/to/image.jpg","scaleMode":"fill"}}'></fig-input-fill>
425
+ ```
426
+
427
+ ---
428
+
429
+ ### Fill Picker (`<fig-fill-picker>`)
430
+
431
+ A comprehensive fill picker dialog supporting solid colors, gradients, images, video, and webcam.
432
+
433
+ | Attribute | Type | Default | Description |
434
+ |-----------|------|---------|-------------|
435
+ | `value` | string | — | JSON fill value |
436
+ | `disabled` | boolean | `false` | Disable picker |
437
+ | `alpha` | boolean | `true` | Show alpha controls |
438
+ | `mode` | string | — | Lock to mode: `"solid"`, `"gradient"`, `"image"`, `"video"`, `"webcam"` |
439
+
440
+ ```html
441
+ <!-- Wraps a trigger element -->
442
+ <fig-fill-picker value='{"type":"solid","color":"#FF5733"}'>
443
+ <fig-chit></fig-chit>
444
+ </fig-fill-picker>
445
+
446
+ <!-- Lock to solid color mode -->
447
+ <fig-fill-picker mode="solid" alpha="true">
448
+ <fig-button>Pick Color</fig-button>
449
+ </fig-fill-picker>
450
+ ```
451
+
452
+ ---
453
+
454
+ ### Chit (`<fig-chit>`)
455
+
456
+ A color/gradient/image swatch element.
457
+
458
+ | Attribute | Type | Default | Description |
459
+ |-----------|------|---------|-------------|
460
+ | `background` | string | — | CSS background value |
461
+ | `size` | string | `"small"` | Size: `"small"` or `"large"` |
462
+ | `selected` | boolean | `false` | Show selection ring |
463
+ | `disabled` | boolean | `false` | Disable interaction |
464
+ | `alpha` | number | — | Opacity (0-1) |
465
+
466
+ ```html
467
+ <fig-chit background="#FF5733"></fig-chit>
468
+ <fig-chit background="linear-gradient(90deg, #FF0000, #0000FF)"></fig-chit>
469
+ <fig-chit background="url(image.jpg)" size="large"></fig-chit>
470
+ <fig-chit background="#FF5733" alpha="0.5"></fig-chit>
471
+ ```
472
+
473
+ ---
474
+
475
+ ### Checkbox (`<fig-checkbox>`)
476
+
477
+ A checkbox input with indeterminate state support.
478
+
479
+ | Attribute | Type | Default | Description |
480
+ |-----------|------|---------|-------------|
481
+ | `checked` | boolean | `false` | Whether checked |
482
+ | `indeterminate` | boolean | `false` | Indeterminate state |
483
+ | `disabled` | boolean | `false` | Disable checkbox |
484
+ | `name` | string | — | Form field name |
485
+ | `value` | string | — | Value when checked |
486
+
487
+ ```html
488
+ <fig-checkbox>Accept terms</fig-checkbox>
489
+ <fig-checkbox checked>Selected option</fig-checkbox>
490
+ <fig-checkbox indeterminate>Parent option</fig-checkbox>
491
+ ```
492
+
493
+ ---
494
+
495
+ ### Radio (`<fig-radio>`)
496
+
497
+ A radio button input.
498
+
499
+ | Attribute | Type | Default | Description |
500
+ |-----------|------|---------|-------------|
501
+ | `checked` | boolean | `false` | Whether selected |
502
+ | `disabled` | boolean | `false` | Disable radio |
503
+ | `name` | string | — | Radio group name |
504
+ | `value` | string | — | Value when selected |
505
+
506
+ ```html
507
+ <fig-radio name="size" value="small">Small</fig-radio>
508
+ <fig-radio name="size" value="medium" checked>Medium</fig-radio>
509
+ <fig-radio name="size" value="large">Large</fig-radio>
510
+ ```
511
+
512
+ ---
513
+
514
+ ### Switch (`<fig-switch>`)
515
+
516
+ A toggle switch component.
517
+
518
+ | Attribute | Type | Default | Description |
519
+ |-----------|------|---------|-------------|
520
+ | `checked` | boolean | `false` | Whether on |
521
+ | `disabled` | boolean | `false` | Disable switch |
522
+ | `name` | string | — | Form field name |
523
+ | `value` | string | — | Value when on |
524
+
525
+ ```html
526
+ <fig-switch>Enable notifications</fig-switch>
527
+ <fig-switch checked>Active feature</fig-switch>
292
528
  ```
293
529
 
530
+ ---
531
+
294
532
  ### Field (`<fig-field>`)
295
533
 
534
+ A form field wrapper with flexible layout.
535
+
536
+ | Attribute | Type | Default | Description |
537
+ |-----------|------|---------|-------------|
538
+ | `direction` | string | `"column"` | Layout: `"column"`, `"row"`, `"horizontal"` |
539
+
296
540
  ```html
297
- <!-- Vertical layout -->
541
+ <!-- Vertical (default) -->
298
542
  <fig-field>
299
543
  <label>Username</label>
300
544
  <fig-input-text></fig-input-text>
301
- <span class="help">Enter your username</span>
302
545
  </fig-field>
303
546
 
304
- <!-- Horizontal layout -->
547
+ <!-- Horizontal -->
305
548
  <fig-field direction="horizontal">
306
549
  <label>Volume</label>
307
550
  <fig-slider min="0" max="100" value="50"></fig-slider>
308
551
  </fig-field>
309
552
  ```
310
553
 
311
- ### Color Input (`<fig-input-color>`)
554
+ ---
555
+
556
+ ### Combo Input (`<fig-combo-input>`)
557
+
558
+ A text input with dropdown suggestions.
559
+
560
+ | Attribute | Type | Default | Description |
561
+ |-----------|------|---------|-------------|
562
+ | `options` | string | — | Comma-separated options |
563
+ | `placeholder` | string | — | Placeholder text |
564
+ | `value` | string | — | Current value |
565
+ | `disabled` | boolean | `false` | Disable input |
312
566
 
313
567
  ```html
314
- <!-- Basic color picker -->
315
- <fig-input-color value="#ff0000"></fig-input-color>
568
+ <fig-combo-input
569
+ options="House, Apartment, Condo, Other"
570
+ placeholder="Type of residence">
571
+ </fig-combo-input>
572
+ ```
573
+
574
+ ---
575
+
576
+ ### Avatar (`<fig-avatar>`)
577
+
578
+ Displays a user's profile image or initials.
316
579
 
317
- <!-- With text input and alpha channel -->
318
- <fig-input-color value="#ff0000" text="true" alpha="true"> </fig-input-color>
580
+ | Attribute | Type | Default | Description |
581
+ |-----------|------|---------|-------------|
582
+ | `src` | string | — | Image URL |
583
+ | `name` | string | — | Name for initials fallback |
584
+ | `size` | string | — | Size: `"large"` |
585
+
586
+ ```html
587
+ <fig-avatar src="https://example.com/photo.jpg" name="John Doe"></fig-avatar>
588
+ <fig-avatar name="Jane Smith" size="large"></fig-avatar>
319
589
  ```
320
590
 
321
- ### Checkbox (`<fig-checkbox>`)
591
+ ---
592
+
593
+ ### Image (`<fig-image>`)
594
+
595
+ An image display or upload component.
596
+
597
+ | Attribute | Type | Default | Description |
598
+ |-----------|------|---------|-------------|
599
+ | `src` | string | — | Image URL |
600
+ | `upload` | boolean | `false` | Show upload button |
601
+ | `label` | string | — | Upload button label |
602
+ | `size` | string | — | Preview size |
322
603
 
323
604
  ```html
324
- <!-- Basic checkbox -->
325
- <fig-checkbox>Accept terms</fig-checkbox>
605
+ <fig-image src="photo.jpg"></fig-image>
606
+ <fig-image upload label="Upload Image"></fig-image>
607
+ ```
326
608
 
327
- <!-- Checked state -->
328
- <fig-checkbox checked>Selected option</fig-checkbox>
609
+ ---
329
610
 
330
- <!-- Indeterminate state -->
331
- <fig-checkbox indeterminate>Parent option</fig-checkbox>
611
+ ### Input Joystick (`<fig-input-joystick>`)
612
+
613
+ A 2D position input control.
614
+
615
+ | Attribute | Type | Default | Description |
616
+ |-----------|------|---------|-------------|
617
+ | `value` | string | — | Position: `"x,y"` (0-1 range) |
618
+ | `precision` | number | — | Decimal places |
619
+ | `transform` | number | — | Output scaling |
620
+ | `text` | boolean | `false` | Show X/Y inputs |
621
+
622
+ ```html
623
+ <fig-input-joystick value="0.5,0.5"></fig-input-joystick>
624
+ <fig-input-joystick value="0.5,0.5" text="true" precision="2"></fig-input-joystick>
332
625
  ```
333
626
 
334
- ### Switch (`<fig-switch>`)
627
+ ---
628
+
629
+ ### Input Angle (`<fig-input-angle>`)
630
+
631
+ An angle/rotation input control.
632
+
633
+ | Attribute | Type | Default | Description |
634
+ |-----------|------|---------|-------------|
635
+ | `value` | number | — | Angle in degrees |
636
+ | `precision` | number | — | Decimal places |
637
+ | `text` | boolean | `false` | Show text input |
335
638
 
336
639
  ```html
337
- <!-- Basic switch -->
338
- <fig-switch></fig-switch>
640
+ <fig-input-angle value="45"></fig-input-angle>
641
+ <fig-input-angle value="90" text="true"></fig-input-angle>
642
+ ```
339
643
 
340
- <!-- With label -->
341
- <fig-switch>Enable notifications</fig-switch>
644
+ ---
645
+
646
+ ### Toast (`<fig-toast>`)
647
+
648
+ A toast notification component.
649
+
650
+ | Attribute | Type | Default | Description |
651
+ |-----------|------|---------|-------------|
652
+ | `duration` | number | `5000` | Auto-dismiss ms (0 = no dismiss) |
653
+ | `offset` | number | `16` | Distance from bottom |
654
+ | `theme` | string | `"dark"` | Theme: `"dark"`, `"light"`, `"danger"`, `"brand"` |
655
+ | `open` | boolean | `false` | Whether visible |
342
656
 
343
- <!-- Checked state -->
344
- <fig-switch checked>Active</fig-switch>
657
+ ```html
658
+ <fig-toast id="myToast" theme="brand" duration="3000">
659
+ Settings saved successfully!
660
+ </fig-toast>
661
+
662
+ <script>
663
+ document.getElementById('myToast').show();
664
+ </script>
345
665
  ```
346
666
 
667
+ ---
668
+
347
669
  ### Spinner (`<fig-spinner>`)
348
670
 
671
+ A loading spinner indicator.
672
+
349
673
  ```html
350
- <!-- Basic spinner -->
351
674
  <fig-spinner></fig-spinner>
352
675
  ```
353
676
 
354
- ### Combo Input (`<fig-combo-input>`)
677
+ ---
355
678
 
356
- ```html
357
- <!-- Basic combo input -->
358
- <fig-combo-input
359
- options="House, Apartment, Condo, Other"
360
- placeholder="Type of residence"
361
- ></fig-combo-input>
362
- ```
679
+ ### Shimmer (`<fig-shimmer>`)
363
680
 
364
- ### Chit (`<fig-chit>`)
681
+ A loading placeholder with shimmer animation.
365
682
 
366
683
  ```html
367
- <!-- Basic chit -->
368
- <fig-chit type="color" value="#ff0000"></fig-chit>
684
+ <fig-shimmer style="width: 200px; height: 20px;"></fig-shimmer>
369
685
  ```
370
686
 
371
- ### Image (`<fig-image>`)
687
+ ---
688
+
689
+ ### Layer (`<fig-layer>`)
690
+
691
+ A layer list item component (for layer panels).
372
692
 
373
693
  ```html
374
- <!-- Basic image -->
375
- <fig-image src="https://via.placeholder.com/150"></fig-image>
694
+ <fig-layer name="Rectangle 1" type="rectangle" selected></fig-layer>
695
+ <fig-layer name="Group 1" type="group" expanded>
696
+ <fig-layer name="Child 1" type="frame"></fig-layer>
697
+ </fig-layer>
376
698
  ```
377
699
 
700
+ ---
701
+
378
702
  ### Header (`<fig-header>`)
379
703
 
704
+ A section header component.
705
+
380
706
  ```html
381
- <!-- Basic header -->
382
- <fig-header>
383
- <h3>Header</h3>
384
- </fig-header>
707
+ <fig-header>Section Title</fig-header>
708
+ ```
709
+
710
+ ---
711
+
712
+ ## Events
713
+
714
+ All form components emit standard `input` and `change` events:
715
+
716
+ - **`input`** - Fires continuously during interaction (dragging, typing)
717
+ - **`change`** - Fires when interaction completes (mouse up, blur)
718
+
719
+ Events include a `detail` object with component-specific data:
720
+
721
+ ```js
722
+ // Color input events
723
+ colorInput.addEventListener('input', (e) => {
724
+ console.log(e.detail);
725
+ // { color: "#FF5733", alpha: 0.8, hsv: { h: 14, s: 80, v: 100, a: 0.8 } }
726
+ });
727
+
728
+ // Fill picker events
729
+ fillPicker.addEventListener('change', (e) => {
730
+ console.log(e.detail);
731
+ // { type: "gradient", gradient: { type: "linear", angle: 90, stops: [...] }, css: "linear-gradient(...)" }
732
+ });
733
+
734
+ // Slider events
735
+ slider.addEventListener('input', (e) => {
736
+ console.log(e.target.value); // "75"
737
+ });
738
+ ```
739
+
740
+ ---
741
+
742
+ ## Framework Integration
743
+
744
+ ### React
745
+
746
+ Web components work in React, but require some considerations:
747
+
748
+ ```jsx
749
+ import { useRef, useEffect } from 'react';
750
+ import '@rogieking/figui3/fig.css';
751
+ import '@rogieking/figui3/fig.js';
752
+
753
+ function ColorPicker({ value, onChange }) {
754
+ const ref = useRef(null);
755
+
756
+ useEffect(() => {
757
+ const el = ref.current;
758
+ if (!el) return;
759
+
760
+ const handleChange = (e) => onChange(e.detail);
761
+ el.addEventListener('change', handleChange);
762
+ return () => el.removeEventListener('change', handleChange);
763
+ }, [onChange]);
764
+
765
+ // Set initial value via ref to avoid infinite loops
766
+ useEffect(() => {
767
+ if (ref.current) {
768
+ ref.current.setAttribute('value', value);
769
+ }
770
+ }, [value]);
771
+
772
+ return (
773
+ <fig-input-color
774
+ ref={ref}
775
+ text="true"
776
+ alpha="true"
777
+ picker="figma"
778
+ />
779
+ );
780
+ }
385
781
  ```
386
782
 
387
- ### fig-segmented-control (`<fig-segmented-control>`)
783
+ > **Note:** Avoid setting the `value` prop directly on web components in JSX during re-renders, as `attributeChangedCallback` may trigger events that cause infinite loops. Use refs to control updates.
784
+
785
+ ### Vue
786
+
787
+ ```vue
788
+ <template>
789
+ <fig-input-color
790
+ :value="color"
791
+ text="true"
792
+ alpha="true"
793
+ @input="onInput"
794
+ @change="onChange"
795
+ />
796
+ </template>
797
+
798
+ <script setup>
799
+ import { ref } from 'vue';
800
+ import '@rogieking/figui3/fig.css';
801
+ import '@rogieking/figui3/fig.js';
802
+
803
+ const color = ref('#FF5733');
804
+
805
+ const onInput = (e) => {
806
+ color.value = e.detail.color;
807
+ };
808
+
809
+ const onChange = (e) => {
810
+ console.log('Final color:', e.detail);
811
+ };
812
+ </script>
813
+ ```
814
+
815
+ ### Svelte
816
+
817
+ ```svelte
818
+ <script>
819
+ import '@rogieking/figui3/fig.css';
820
+ import '@rogieking/figui3/fig.js';
821
+
822
+ let color = '#FF5733';
823
+
824
+ function handleInput(e) {
825
+ color = e.detail.color;
826
+ }
827
+ </script>
828
+
829
+ <fig-input-color
830
+ value={color}
831
+ text="true"
832
+ alpha="true"
833
+ on:input={handleInput}
834
+ on:change={(e) => console.log('Saved:', e.detail)}
835
+ />
836
+ ```
837
+
838
+ ---
839
+
840
+ ## Theming
841
+
842
+ FigUI3 automatically adapts to light and dark themes using CSS custom properties. The library uses Figma's color variable naming convention:
843
+
844
+ ```css
845
+ /* Colors automatically switch based on color-scheme */
846
+ --figma-color-bg
847
+ --figma-color-bg-secondary
848
+ --figma-color-bg-hover
849
+ --figma-color-text
850
+ --figma-color-text-secondary
851
+ --figma-color-border
852
+ --figma-color-icon
853
+ /* ... and more */
854
+ ```
855
+
856
+ ### Using in Figma Plugins
857
+
858
+ In Figma plugins, these variables are provided automatically. For standalone usage, the library includes fallback values that respond to `prefers-color-scheme`.
859
+
860
+ ### Manual Theme Control
388
861
 
389
862
  ```html
390
- <!-- Basic segmented control -->
391
- <fig-segmented-control>
392
- <fig-segment value="1" selected="true">Option 1</fig-segment>
393
- <fig-segment value="2">Option 2</fig-segment>
394
- </fig-segmented-control>
863
+ <body style="color-scheme: dark;">
864
+ <!-- Forces dark theme -->
865
+ </body>
395
866
  ```
867
+
868
+ ---
869
+
870
+ ## Browser Support
871
+
872
+ FigUI3 supports all modern browsers with Web Components support:
873
+
874
+ - Chrome/Edge 67+
875
+ - Firefox 63+
876
+ - Safari 10.1+
877
+
878
+ ---
879
+
880
+ ## Contributing
881
+
882
+ Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) before submitting a pull request.
883
+
884
+ ---
885
+
886
+ ## License
887
+
888
+ [MIT License](LICENSE) © Rogie King