@rogieking/figui3 2.12.0 → 2.12.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 +84 -10
- package/components.css +1 -1
- package/fig.js +38 -15
- package/index.html +3539 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -9,6 +9,8 @@ A lightweight, zero-dependency web components library for building Figma plugin
|
|
|
9
9
|
|
|
10
10
|
View the interactive component documentation at **[rogie.github.io/figui3](https://rogie.github.io/figui3/)**
|
|
11
11
|
|
|
12
|
+
The demo page (`index.html`) is included in the npm package, so you can also open it locally after installing.
|
|
13
|
+
|
|
12
14
|
## Features
|
|
13
15
|
|
|
14
16
|
- 🎨 Figma UI3 design system
|
|
@@ -157,7 +159,7 @@ A native select wrapper with Figma styling.
|
|
|
157
159
|
|
|
158
160
|
### Tooltip (`<fig-tooltip>`)
|
|
159
161
|
|
|
160
|
-
Displays contextual information on hover or click.
|
|
162
|
+
Displays contextual information on hover or click. The tooltip automatically repositions itself when its child element moves (e.g. during drag), using a MutationObserver to track attribute changes on the child.
|
|
161
163
|
|
|
162
164
|
| Attribute | Type | Default | Description |
|
|
163
165
|
|-----------|------|---------|-------------|
|
|
@@ -165,6 +167,7 @@ Displays contextual information on hover or click.
|
|
|
165
167
|
| `action` | string | `"hover"` | Trigger: `"hover"` or `"click"` |
|
|
166
168
|
| `delay` | number | `500` | Delay in ms before showing |
|
|
167
169
|
| `offset` | string | — | Position offset: `"left,top,right,bottom"` |
|
|
170
|
+
| `open` | boolean | `false` | Programmatically show/hide the tooltip |
|
|
168
171
|
|
|
169
172
|
```html
|
|
170
173
|
<fig-tooltip text="This is helpful info" action="hover">
|
|
@@ -174,6 +177,11 @@ Displays contextual information on hover or click.
|
|
|
174
177
|
<fig-tooltip text="Click triggered" action="click" delay="0">
|
|
175
178
|
<fig-button>Click me</fig-button>
|
|
176
179
|
</fig-tooltip>
|
|
180
|
+
|
|
181
|
+
<!-- Instant tooltip (no delay) -->
|
|
182
|
+
<fig-tooltip text="Instant!" delay="0">
|
|
183
|
+
<fig-button>No delay</fig-button>
|
|
184
|
+
</fig-tooltip>
|
|
177
185
|
```
|
|
178
186
|
|
|
179
187
|
---
|
|
@@ -283,6 +291,7 @@ A range slider with multiple types and optional text input.
|
|
|
283
291
|
| `min` | number | `0` | Minimum value |
|
|
284
292
|
| `max` | number | `100` | Maximum value |
|
|
285
293
|
| `step` | number | `1` | Step increment |
|
|
294
|
+
| `default` | number | — | Default/reset value (shown as a marker on the track) |
|
|
286
295
|
| `text` | boolean | `false` | Show text input |
|
|
287
296
|
| `units` | string | — | Unit label (e.g., `"%"`, `"px"`) |
|
|
288
297
|
| `transform` | number | — | Multiplier for display value |
|
|
@@ -369,12 +378,16 @@ A numeric input with units support.
|
|
|
369
378
|
| `units` | string | — | Unit string (e.g., `"px"`, `"%"`) |
|
|
370
379
|
| `unit-position` | string | `"suffix"` | `"suffix"` or `"prefix"` |
|
|
371
380
|
| `transform` | number | — | Display multiplier |
|
|
381
|
+
| `steppers` | boolean | `false` | Show native spin buttons (up/down arrows) |
|
|
372
382
|
| `disabled` | boolean | `false` | Disable input |
|
|
373
383
|
|
|
374
384
|
```html
|
|
375
385
|
<fig-input-number value="100" units="px"></fig-input-number>
|
|
376
386
|
<fig-input-number value="50" units="%" min="0" max="100"></fig-input-number>
|
|
377
387
|
<fig-input-number value="45" units="°" step="15"></fig-input-number>
|
|
388
|
+
|
|
389
|
+
<!-- With native stepper arrows -->
|
|
390
|
+
<fig-input-number value="10" steppers="true" step="1"></fig-input-number>
|
|
378
391
|
```
|
|
379
392
|
|
|
380
393
|
---
|
|
@@ -389,6 +402,7 @@ A color picker with hex/alpha support.
|
|
|
389
402
|
| `text` | boolean | `false` | Show hex text input |
|
|
390
403
|
| `alpha` | boolean | `false` | Show alpha slider |
|
|
391
404
|
| `picker` | string | `"native"` | Picker type: `"native"`, `"figma"`, `"false"` |
|
|
405
|
+
| `mode` | string | — | Color mode (e.g., `"hex"`, `"rgb"`, `"hsl"`) |
|
|
392
406
|
| `disabled` | boolean | `false` | Disable input |
|
|
393
407
|
|
|
394
408
|
```html
|
|
@@ -483,11 +497,13 @@ A checkbox input with indeterminate state support.
|
|
|
483
497
|
| `disabled` | boolean | `false` | Disable checkbox |
|
|
484
498
|
| `name` | string | — | Form field name |
|
|
485
499
|
| `value` | string | — | Value when checked |
|
|
500
|
+
| `label` | string | — | Programmatic label text (alternative to slotted content) |
|
|
486
501
|
|
|
487
502
|
```html
|
|
488
503
|
<fig-checkbox>Accept terms</fig-checkbox>
|
|
489
504
|
<fig-checkbox checked>Selected option</fig-checkbox>
|
|
490
505
|
<fig-checkbox indeterminate>Parent option</fig-checkbox>
|
|
506
|
+
<fig-checkbox label="Via attribute"></fig-checkbox>
|
|
491
507
|
```
|
|
492
508
|
|
|
493
509
|
---
|
|
@@ -531,11 +547,12 @@ A toggle switch component.
|
|
|
531
547
|
|
|
532
548
|
### Field (`<fig-field>`)
|
|
533
549
|
|
|
534
|
-
A form field wrapper with flexible layout.
|
|
550
|
+
A form field wrapper with flexible layout. Automatically links `<label>` elements to the first `fig-*` child for accessibility.
|
|
535
551
|
|
|
536
552
|
| Attribute | Type | Default | Description |
|
|
537
553
|
|-----------|------|---------|-------------|
|
|
538
554
|
| `direction` | string | `"column"` | Layout: `"column"`, `"row"`, `"horizontal"` |
|
|
555
|
+
| `label` | string | — | Programmatically set the label text |
|
|
539
556
|
|
|
540
557
|
```html
|
|
541
558
|
<!-- Vertical (default) -->
|
|
@@ -618,27 +635,55 @@ A 2D position input control.
|
|
|
618
635
|
| `precision` | number | — | Decimal places |
|
|
619
636
|
| `transform` | number | — | Output scaling |
|
|
620
637
|
| `text` | boolean | `false` | Show X/Y inputs |
|
|
638
|
+
| `coordinates` | string | `"screen"` | Coordinate system: `"screen"` (0,0 top-left) or `"math"` (0,0 bottom-left) |
|
|
621
639
|
|
|
622
640
|
```html
|
|
623
641
|
<fig-input-joystick value="0.5,0.5"></fig-input-joystick>
|
|
624
642
|
<fig-input-joystick value="0.5,0.5" text="true" precision="2"></fig-input-joystick>
|
|
643
|
+
|
|
644
|
+
<!-- Math coordinates (Y-axis inverted: 0,0 at bottom-left) -->
|
|
645
|
+
<fig-input-joystick value="0.5,0.5" coordinates="math" text="true"></fig-input-joystick>
|
|
625
646
|
```
|
|
626
647
|
|
|
627
648
|
---
|
|
628
649
|
|
|
629
650
|
### Input Angle (`<fig-input-angle>`)
|
|
630
651
|
|
|
631
|
-
An angle/rotation input control.
|
|
652
|
+
An angle/rotation input control with optional min/max clamping, multi-unit support, and unbounded winding (values beyond 360°).
|
|
653
|
+
|
|
654
|
+
When `min` and `max` are omitted, the input is unbounded — dragging continuously winds the angle past full revolutions (e.g. 720°, 1080°, or negative values). The text input also accepts values with unit suffixes (`90deg`, `3.14rad`, `0.5turn`) and converts them to the component's `units` format.
|
|
632
655
|
|
|
633
656
|
| Attribute | Type | Default | Description |
|
|
634
657
|
|-----------|------|---------|-------------|
|
|
635
|
-
| `value` | number |
|
|
636
|
-
| `precision` | number |
|
|
637
|
-
| `text` | boolean | `false` | Show text input |
|
|
658
|
+
| `value` | number | `0` | Angle value (in the unit specified by `units`) |
|
|
659
|
+
| `precision` | number | `1` | Decimal places for display |
|
|
660
|
+
| `text` | boolean | `false` | Show numeric text input alongside the dial |
|
|
661
|
+
| `min` | number | — | Minimum angle (omit for unbounded) |
|
|
662
|
+
| `max` | number | — | Maximum angle (omit for unbounded) |
|
|
663
|
+
| `units` | string | `"°"` | Display unit: `"°"` (or `"deg"`), `"rad"`, `"turn"` |
|
|
664
|
+
| `show-rotations` | boolean | `false` | Show a ×N rotation counter when angle exceeds 1 full rotation |
|
|
638
665
|
|
|
639
666
|
```html
|
|
667
|
+
<!-- Basic dial -->
|
|
640
668
|
<fig-input-angle value="45"></fig-input-angle>
|
|
669
|
+
|
|
670
|
+
<!-- With text input -->
|
|
641
671
|
<fig-input-angle value="90" text="true"></fig-input-angle>
|
|
672
|
+
|
|
673
|
+
<!-- Unbounded (supports winding past 360°) -->
|
|
674
|
+
<fig-input-angle text="true" value="720"></fig-input-angle>
|
|
675
|
+
|
|
676
|
+
<!-- Clamped to a range -->
|
|
677
|
+
<fig-input-angle text="true" value="90" min="0" max="180"></fig-input-angle>
|
|
678
|
+
|
|
679
|
+
<!-- Radians -->
|
|
680
|
+
<fig-input-angle text="true" units="rad" value="3.14159"></fig-input-angle>
|
|
681
|
+
|
|
682
|
+
<!-- Turns -->
|
|
683
|
+
<fig-input-angle text="true" units="turn" value="0.5"></fig-input-angle>
|
|
684
|
+
|
|
685
|
+
<!-- Show rotation count (×2 at 720°, ×3 at 1080°, etc.) -->
|
|
686
|
+
<fig-input-angle text="true" show-rotations="true" value="1080"></fig-input-angle>
|
|
642
687
|
```
|
|
643
688
|
|
|
644
689
|
---
|
|
@@ -680,20 +725,49 @@ A loading spinner indicator.
|
|
|
680
725
|
|
|
681
726
|
A loading placeholder with shimmer animation.
|
|
682
727
|
|
|
728
|
+
| Attribute | Type | Default | Description |
|
|
729
|
+
|-----------|------|---------|-------------|
|
|
730
|
+
| `duration` | string | `"1.5s"` | Animation cycle duration (CSS time value) |
|
|
731
|
+
| `playing` | boolean | `true` | Whether the animation is running |
|
|
732
|
+
|
|
683
733
|
```html
|
|
684
734
|
<fig-shimmer style="width: 200px; height: 20px;"></fig-shimmer>
|
|
735
|
+
<fig-shimmer style="width: 100px; height: 14px;" duration="2s"></fig-shimmer>
|
|
685
736
|
```
|
|
686
737
|
|
|
687
738
|
---
|
|
688
739
|
|
|
689
740
|
### Layer (`<fig-layer>`)
|
|
690
741
|
|
|
691
|
-
A layer list item component (for layer panels).
|
|
742
|
+
A layer list item component (for layer panels). Supports nesting, expand/collapse via chevron, and visibility toggling.
|
|
743
|
+
|
|
744
|
+
| Attribute | Type | Default | Description |
|
|
745
|
+
|-----------|------|---------|-------------|
|
|
746
|
+
| `open` | boolean | `false` | Whether child layers are expanded |
|
|
747
|
+
| `visible` | boolean | `true` | Whether the layer is visible |
|
|
748
|
+
|
|
749
|
+
**Events:** `openchange` (detail: `{ open }`) and `visibilitychange` (detail: `{ visible }`)
|
|
692
750
|
|
|
693
751
|
```html
|
|
694
|
-
<fig-layer
|
|
695
|
-
<fig-layer
|
|
696
|
-
|
|
752
|
+
<fig-layer>
|
|
753
|
+
<div class="fig-layer-row">
|
|
754
|
+
<span class="fig-layer-icon"></span>
|
|
755
|
+
<span class="fig-layer-name">Rectangle 1</span>
|
|
756
|
+
</div>
|
|
757
|
+
</fig-layer>
|
|
758
|
+
|
|
759
|
+
<!-- Nested with children -->
|
|
760
|
+
<fig-layer open="true">
|
|
761
|
+
<div class="fig-layer-row">
|
|
762
|
+
<span class="fig-layer-icon"></span>
|
|
763
|
+
<span class="fig-layer-name">Group 1</span>
|
|
764
|
+
</div>
|
|
765
|
+
<fig-layer>
|
|
766
|
+
<div class="fig-layer-row">
|
|
767
|
+
<span class="fig-layer-icon"></span>
|
|
768
|
+
<span class="fig-layer-name">Child 1</span>
|
|
769
|
+
</div>
|
|
770
|
+
</fig-layer>
|
|
697
771
|
</fig-layer>
|
|
698
772
|
```
|
|
699
773
|
|
package/components.css
CHANGED
package/fig.js
CHANGED
|
@@ -719,12 +719,15 @@ customElements.define("fig-popover", FigPopover);
|
|
|
719
719
|
*/
|
|
720
720
|
class FigDialog extends HTMLDialogElement {
|
|
721
721
|
#isDragging = false;
|
|
722
|
+
#dragPending = false;
|
|
723
|
+
#dragStartPos = { x: 0, y: 0 };
|
|
722
724
|
#dragOffset = { x: 0, y: 0 };
|
|
723
725
|
#boundPointerDown;
|
|
724
726
|
#boundPointerMove;
|
|
725
727
|
#boundPointerUp;
|
|
726
728
|
#offset = 16; // 1rem in pixels
|
|
727
729
|
#positionInitialized = false;
|
|
730
|
+
#dragThreshold = 3; // pixels before drag starts
|
|
728
731
|
|
|
729
732
|
constructor() {
|
|
730
733
|
super();
|
|
@@ -886,7 +889,7 @@ class FigDialog extends HTMLDialogElement {
|
|
|
886
889
|
}
|
|
887
890
|
|
|
888
891
|
#handlePointerDown(e) {
|
|
889
|
-
if (!this.drag
|
|
892
|
+
if (!this.drag) {
|
|
890
893
|
return;
|
|
891
894
|
}
|
|
892
895
|
|
|
@@ -901,31 +904,48 @@ class FigDialog extends HTMLDialogElement {
|
|
|
901
904
|
}
|
|
902
905
|
// No handle specified = drag from anywhere (original behavior)
|
|
903
906
|
|
|
904
|
-
|
|
905
|
-
|
|
907
|
+
// Don't prevent default yet - just set up pending drag
|
|
908
|
+
// This allows clicks on interactive elements like <details> to work
|
|
909
|
+
this.#dragPending = true;
|
|
910
|
+
this.#dragStartPos.x = e.clientX;
|
|
911
|
+
this.#dragStartPos.y = e.clientY;
|
|
906
912
|
|
|
907
913
|
// Get current position from computed style
|
|
908
914
|
const rect = this.getBoundingClientRect();
|
|
909
915
|
|
|
910
|
-
// Convert to pixel-based top/left positioning for dragging
|
|
911
|
-
// (clears margin: auto centering)
|
|
912
|
-
this.style.top = `${rect.top}px`;
|
|
913
|
-
this.style.left = `${rect.left}px`;
|
|
914
|
-
this.style.bottom = "auto";
|
|
915
|
-
this.style.right = "auto";
|
|
916
|
-
this.style.margin = "0";
|
|
917
|
-
|
|
918
916
|
// Store offset from pointer to dialog top-left corner
|
|
919
917
|
this.#dragOffset.x = e.clientX - rect.left;
|
|
920
918
|
this.#dragOffset.y = e.clientY - rect.top;
|
|
921
919
|
|
|
922
920
|
document.addEventListener("pointermove", this.#boundPointerMove);
|
|
923
921
|
document.addEventListener("pointerup", this.#boundPointerUp);
|
|
924
|
-
|
|
925
|
-
e.preventDefault();
|
|
926
922
|
}
|
|
927
923
|
|
|
928
924
|
#handlePointerMove(e) {
|
|
925
|
+
// Check if we should start dragging (threshold exceeded)
|
|
926
|
+
if (this.#dragPending && !this.#isDragging) {
|
|
927
|
+
const dx = Math.abs(e.clientX - this.#dragStartPos.x);
|
|
928
|
+
const dy = Math.abs(e.clientY - this.#dragStartPos.y);
|
|
929
|
+
|
|
930
|
+
if (dx > this.#dragThreshold || dy > this.#dragThreshold) {
|
|
931
|
+
// Start actual drag
|
|
932
|
+
this.#isDragging = true;
|
|
933
|
+
this.#dragPending = false;
|
|
934
|
+
this.setPointerCapture(e.pointerId);
|
|
935
|
+
|
|
936
|
+
// Get current position from computed style
|
|
937
|
+
const rect = this.getBoundingClientRect();
|
|
938
|
+
|
|
939
|
+
// Convert to pixel-based top/left positioning for dragging
|
|
940
|
+
// (clears margin: auto centering)
|
|
941
|
+
this.style.top = `${rect.top}px`;
|
|
942
|
+
this.style.left = `${rect.left}px`;
|
|
943
|
+
this.style.bottom = "auto";
|
|
944
|
+
this.style.right = "auto";
|
|
945
|
+
this.style.margin = "0";
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
929
949
|
if (!this.#isDragging) return;
|
|
930
950
|
|
|
931
951
|
// Calculate new position based on pointer position minus offset
|
|
@@ -940,10 +960,13 @@ class FigDialog extends HTMLDialogElement {
|
|
|
940
960
|
}
|
|
941
961
|
|
|
942
962
|
#handlePointerUp(e) {
|
|
943
|
-
|
|
963
|
+
// Clean up pending or active drag
|
|
964
|
+
if (this.#isDragging) {
|
|
965
|
+
this.releasePointerCapture(e.pointerId);
|
|
966
|
+
}
|
|
944
967
|
|
|
945
968
|
this.#isDragging = false;
|
|
946
|
-
this
|
|
969
|
+
this.#dragPending = false;
|
|
947
970
|
|
|
948
971
|
document.removeEventListener("pointermove", this.#boundPointerMove);
|
|
949
972
|
document.removeEventListener("pointerup", this.#boundPointerUp);
|