@rogieking/figui3 2.11.1 → 2.12.1

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
@@ -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 | | Angle in degrees |
636
- | `precision` | number | | Decimal places |
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 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>
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
@@ -308,20 +308,20 @@
308
308
  0px 10px 24px rgba(0, 0, 0, 0.18), 0px 2px 5px rgba(0, 0, 0, 0.15);
309
309
  --figma-elevation-100: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.3),
310
310
  0px 1px 3px 0px rgba(0, 0, 0, 0.15);
311
- --figma-elevation-200: 0px 1px 3px 0px rgba(0, 0, 0, 0.102),
312
- 0px 3px 8px 0px rgba(0, 0, 0, 0.102), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.18);
311
+ --figma-elevation-200: 0 0 0.5px 0 rgba(0, 0, 0, 0.18),
312
+ 0 3px 8px 0 rgba(0, 0, 0, 0.1), 0 1px 3px 0 rgba(0, 0, 0, 0.1);
313
313
  --figma-elevation-400-menu-panel: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.12),
314
314
  0px 10px 16px 0px rgba(0, 0, 0, 0.12), 0px 2px 5px 0px rgba(0, 0, 0, 0.15);
315
315
  --figma-elevation-500-modal-window: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.08),
316
316
  0px 10px 24px 0px rgba(0, 0, 0, 0.18), 0px 2px 5px 0px rgba(0, 0, 0, 0.15);
317
- --handle-shadow: 0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--figma-elevation-200);
317
+ --handle-shadow: 0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--figma-elevation-100);
318
318
  }
319
319
 
320
320
  /* Dark theme overrides for non-color values (shadows, elevations) */
321
321
  /* These cannot use light-dark() as they are complex values */
322
322
  @media (prefers-color-scheme: dark) {
323
323
  :root {
324
- --handle-shadow: 0px 0 0 0.75px 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
324
+ --handle-shadow: 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
325
325
  0px 0px 0.5px 0px rgba(255, 255, 255, 0.1);
326
326
  --figma-elevation-100: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
327
327
  0px 0.75px 0px 0px rgba(255, 255, 255, 0.1) inset,
@@ -343,7 +343,7 @@
343
343
 
344
344
  /* Class-based dark theme override (for manual theme switching) */
345
345
  :root.figma-dark {
346
- --handle-shadow: 0px 0 0 0.75px 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
346
+ --handle-shadow: 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
347
347
  0px 0px 0.5px 0px rgba(255, 255, 255, 0.1);
348
348
  --figma-elevation-100: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
349
349
  0px 0.75px 0px 0px rgba(255, 255, 255, 0.1) inset,
@@ -1575,7 +1575,7 @@ fig-slider {
1575
1575
  --slider-tick-size: calc(var(--slider-height) / 4);
1576
1576
  --slider-handle-shadow: inset 0 0 0 calc(4px + 0.5rem * var(--unchanged))
1577
1577
  var(--handle-color),
1578
- 0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--figma-elevation-200);
1578
+ 0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--figma-elevation-100);
1579
1579
  --slider-handle-shadow-focus: inset 0 0 0 4px var(--handle-color),
1580
1580
  inset 0 0 0 5px rgba(0, 0, 0, 0.1), var(--handle-shadow),
1581
1581
  0 0 0 1px var(--figma-color-border-selected);
@@ -1862,7 +1862,7 @@ fig-slider {
1862
1862
  --slider-handle-shadow: inset 0 0 0 calc(6px + 0.5rem * var(--unchanged))
1863
1863
  var(--handle-color),
1864
1864
  0 0 0 0.75px rgba(0, 0, 0, 0.075), inset 0 0 0 5px rgba(0, 0, 0, 0.1),
1865
- var(--figma-elevation-200);
1865
+ var(--figma-elevation-100);
1866
1866
 
1867
1867
  .fig-slider-input-container {
1868
1868
  height: var(--slider-height);
@@ -1891,7 +1891,7 @@ fig-slider {
1891
1891
  --slider-handle-shadow: inset 0 0 0 calc(6px + 0.5rem * var(--unchanged))
1892
1892
  var(--handle-color),
1893
1893
  0 0 0 0.75px rgba(0, 0, 0, 0.075), inset 0 0 0 5px rgba(0, 0, 0, 0.1),
1894
- var(--figma-elevation-200);
1894
+ var(--figma-elevation-100);
1895
1895
 
1896
1896
  background-color: var(--figma-color-bg-secondary);
1897
1897
  border-radius: var(--radius-medium);
@@ -2643,7 +2643,7 @@ fig-input-angle {
2643
2643
  grid-area: 1/1;
2644
2644
  width: calc(0.5rem + 2px);
2645
2645
  height: calc(0.5rem + 2px);
2646
- &:before {
2646
+ &::before {
2647
2647
  content: "";
2648
2648
  display: block;
2649
2649
  width: 0.5rem;