@rogieking/figui3 2.13.0 → 2.13.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/components.css CHANGED
@@ -193,9 +193,10 @@
193
193
  :root {
194
194
  /* Typography & Sizing */
195
195
  --font-size: 16px;
196
- --font-family: "Inter", AppleSystemUIFont, BlinkMacSystemFont, avenir next,
197
- avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto,
198
- arial, sans-serif;
196
+ --font-family:
197
+ "Inter", AppleSystemUIFont, BlinkMacSystemFont, avenir next, avenir,
198
+ segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial,
199
+ sans-serif;
199
200
  --body-medium-fontSize: 0.6875rem;
200
201
  --body-large-fontSize: 0.8125rem;
201
202
  --body-letter-spacing: 0.055px;
@@ -206,6 +207,7 @@
206
207
  /* Spacing */
207
208
  --spacer-1: 0.25rem;
208
209
  --spacer-2: 0.5rem;
210
+ --spacer-2-5: 0.75rem;
209
211
  --spacer-3: 1rem;
210
212
  --spacer-4: 1.5rem;
211
213
  --spacer-5: 2rem;
@@ -304,15 +306,19 @@
304
306
  --icon-swap: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8.35355 6.35355C8.54882 6.15829 8.54882 5.84171 8.35355 5.64645C8.15829 5.45118 7.84171 5.45118 7.64645 5.64645L5.14645 8.14645C4.95118 8.34171 4.95118 8.65829 5.14645 8.85355L7.64645 11.3536C7.84171 11.5488 8.15829 11.5488 8.35355 11.3536C8.54882 11.1583 8.54882 10.8417 8.35355 10.6464L6.70711 9H18.5C18.7761 9 19 8.77614 19 8.5C19 8.22386 18.7761 8 18.5 8H6.70711L8.35355 6.35355ZM15.6464 13.3536C15.4512 13.1583 15.4512 12.8417 15.6464 12.6464C15.8417 12.4512 16.1583 12.4512 16.3536 12.6464L18.8536 15.1464C19.0488 15.3417 19.0488 15.6583 18.8536 15.8536L16.3536 18.3536C16.1583 18.5488 15.8417 18.5488 15.6464 18.3536C15.4512 18.1583 15.4512 17.8417 15.6464 17.6464L17.2929 16H5.5C5.22386 16 5 15.7761 5 15.5C5 15.2239 5.22386 15 5.5 15H17.2929L15.6464 13.3536Z' fill='currentColor'/%3E%3C/svg%3E");
305
307
 
306
308
  /* Elevations - light theme defaults */
307
- --elevation-500-modal-window: 0px 0px 0.5px rgba(0, 0, 0, 0.08),
308
- 0px 10px 24px rgba(0, 0, 0, 0.18), 0px 2px 5px rgba(0, 0, 0, 0.15);
309
- --figma-elevation-100: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.3),
310
- 0px 1px 3px 0px rgba(0, 0, 0, 0.15);
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
- --figma-elevation-400-menu-panel: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.12),
309
+ --elevation-500-modal-window:
310
+ 0px 0px 0.5px rgba(0, 0, 0, 0.08), 0px 10px 24px rgba(0, 0, 0, 0.18),
311
+ 0px 2px 5px rgba(0, 0, 0, 0.15);
312
+ --figma-elevation-100:
313
+ 0px 0px 0.5px 0px rgba(0, 0, 0, 0.3), 0px 1px 3px 0px rgba(0, 0, 0, 0.15);
314
+ --figma-elevation-200:
315
+ 0 0 0.5px 0 rgba(0, 0, 0, 0.18), 0 3px 8px 0 rgba(0, 0, 0, 0.1),
316
+ 0 1px 3px 0 rgba(0, 0, 0, 0.1);
317
+ --figma-elevation-400-menu-panel:
318
+ 0px 0px 0.5px 0px rgba(0, 0, 0, 0.12),
314
319
  0px 10px 16px 0px rgba(0, 0, 0, 0.12), 0px 2px 5px 0px rgba(0, 0, 0, 0.15);
315
- --figma-elevation-500-modal-window: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.08),
320
+ --figma-elevation-500-modal-window:
321
+ 0px 0px 0.5px 0px rgba(0, 0, 0, 0.08),
316
322
  0px 10px 24px 0px rgba(0, 0, 0, 0.18), 0px 2px 5px 0px rgba(0, 0, 0, 0.15);
317
323
  --handle-shadow: 0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--figma-elevation-100);
318
324
  }
@@ -321,44 +327,48 @@
321
327
  /* These cannot use light-dark() as they are complex values */
322
328
  @media (prefers-color-scheme: dark) {
323
329
  :root {
324
- --handle-shadow: 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
330
+ --handle-shadow:
331
+ 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
325
332
  0px 0px 0.5px 0px rgba(255, 255, 255, 0.1);
326
- --figma-elevation-100: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
333
+ --figma-elevation-100:
334
+ 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
327
335
  0px 0.75px 0px 0px rgba(255, 255, 255, 0.1) inset,
328
336
  0px 1px 3px 0px rgba(0, 0, 0, 0.4);
329
- --figma-elevation-200: 0px 3px 8px rgba(0, 0, 0, 0.35),
330
- 0px 1px 3px rgba(0, 0, 0, 0.5),
337
+ --figma-elevation-200:
338
+ 0px 3px 8px rgba(0, 0, 0, 0.35), 0px 1px 3px rgba(0, 0, 0, 0.5),
331
339
  inset 0px 0.5px 0px rgba(255, 255, 255, 0.08),
332
340
  inset 0px 0px 0.5px rgba(255, 255, 255, 0.3);
333
- --figma-elevation-400-menu-panel: 0px 0.5px 0px 0px
334
- rgba(255, 255, 255, 0.08) inset,
341
+ --figma-elevation-400-menu-panel:
342
+ 0px 0.5px 0px 0px rgba(255, 255, 255, 0.08) inset,
335
343
  0px 10px 16px 0px rgba(0, 0, 0, 0.35),
336
344
  inset 0px 0.75px 0px rgba(255, 255, 255, 0.075),
337
345
  0px 2px 5px 0px rgba(0, 0, 0, 0.35);
338
- --figma-elevation-500-modal-window: 0px 10px 24px rgba(0, 0, 0, 0.45),
339
- 0px 3px 5px rgba(0, 0, 0, 0.35),
346
+ --figma-elevation-500-modal-window:
347
+ 0px 10px 24px rgba(0, 0, 0, 0.45), 0px 3px 5px rgba(0, 0, 0, 0.35),
340
348
  inset 0px 0.75px 0px rgba(255, 255, 255, 0.1);
341
349
  }
342
350
  }
343
351
 
344
352
  /* Class-based dark theme override (for manual theme switching) */
345
353
  :root.figma-dark {
346
- --handle-shadow: 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
354
+ --handle-shadow:
355
+ 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
347
356
  0px 0px 0.5px 0px rgba(255, 255, 255, 0.1);
348
- --figma-elevation-100: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
357
+ --figma-elevation-100:
358
+ 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
349
359
  0px 0.75px 0px 0px rgba(255, 255, 255, 0.1) inset,
350
360
  0px 1px 3px 0px rgba(0, 0, 0, 0.4);
351
- --figma-elevation-200: 0px 3px 8px rgba(0, 0, 0, 0.35),
352
- 0px 1px 3px rgba(0, 0, 0, 0.5),
361
+ --figma-elevation-200:
362
+ 0px 3px 8px rgba(0, 0, 0, 0.35), 0px 1px 3px rgba(0, 0, 0, 0.5),
353
363
  inset 0px 0.5px 0px rgba(255, 255, 255, 0.08),
354
364
  inset 0px 0px 0.5px rgba(255, 255, 255, 0.3);
355
- --figma-elevation-400-menu-panel: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.08)
356
- inset,
365
+ --figma-elevation-400-menu-panel:
366
+ 0px 0.5px 0px 0px rgba(255, 255, 255, 0.08) inset,
357
367
  0px 10px 16px 0px rgba(0, 0, 0, 0.35),
358
368
  inset 0px 0.75px 0px rgba(255, 255, 255, 0.075),
359
369
  0px 2px 5px 0px rgba(0, 0, 0, 0.35);
360
- --figma-elevation-500-modal-window: 0px 10px 24px rgba(0, 0, 0, 0.45),
361
- 0px 3px 5px rgba(0, 0, 0, 0.35),
370
+ --figma-elevation-500-modal-window:
371
+ 0px 10px 24px rgba(0, 0, 0, 0.45), 0px 3px 5px rgba(0, 0, 0, 0.35),
362
372
  inset 0px 0.75px 0px rgba(255, 255, 255, 0.1);
363
373
  }
364
374
 
@@ -639,6 +649,11 @@ fig-dropdown,
639
649
  background-color: var(--figma-color-icon);
640
650
  pointer-events: none;
641
651
  }
652
+
653
+ /* Autoresize to content width */
654
+ &[autoresize] select {
655
+ field-sizing: content;
656
+ }
642
657
  }
643
658
 
644
659
  /* Button */
@@ -1119,7 +1134,8 @@ fig-chit {
1119
1134
  }
1120
1135
 
1121
1136
  &[selected]:not([selected="false"])::before {
1122
- box-shadow: inset 0 0 0 1px var(--figma-color-border-selected),
1137
+ box-shadow:
1138
+ inset 0 0 0 1px var(--figma-color-border-selected),
1123
1139
  inset 0 0 0 3px var(--figma-color-bg);
1124
1140
  }
1125
1141
 
@@ -1475,8 +1491,10 @@ input[type="radio"] {
1475
1491
  border-radius: 100%;
1476
1492
  background-color: var(--figma-color-icon-onbrand);
1477
1493
  transform: scale(0);
1478
- box-shadow: 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
1479
- 0px 1px 3px 0px rgba(0, 0, 0, 0.1), 0px 3px 8px 0px rgba(0, 0, 0, 0.1),
1494
+ box-shadow:
1495
+ 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
1496
+ 0px 1px 3px 0px rgba(0, 0, 0, 0.1),
1497
+ 0px 3px 8px 0px rgba(0, 0, 0, 0.1),
1480
1498
  0px 0px 0.5px 0px rgba(0, 0, 0, 0.18);
1481
1499
  }
1482
1500
  }
@@ -1573,12 +1591,12 @@ fig-slider {
1573
1591
  --slider-percent: calc(var(--slider-complete) * 100%);
1574
1592
  --start-percent: calc(var(--default, 0) * 100%);
1575
1593
  --slider-tick-size: calc(var(--slider-height) / 4);
1576
- --slider-handle-shadow: inset 0 0 0 calc(4px + 0.5rem * var(--unchanged))
1577
- var(--handle-color),
1594
+ --slider-handle-shadow:
1595
+ inset 0 0 0 calc(4px + 0.5rem * var(--unchanged)) var(--handle-color),
1578
1596
  0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--figma-elevation-100);
1579
- --slider-handle-shadow-focus: inset 0 0 0 4px var(--handle-color),
1580
- inset 0 0 0 5px rgba(0, 0, 0, 0.1), var(--handle-shadow),
1581
- 0 0 0 1px var(--figma-color-border-selected);
1597
+ --slider-handle-shadow-focus:
1598
+ inset 0 0 0 4px var(--handle-color), inset 0 0 0 5px rgba(0, 0, 0, 0.1),
1599
+ var(--handle-shadow), 0 0 0 1px var(--figma-color-border-selected);
1582
1600
  --slider-transition: all 0.1s ease-in-out;
1583
1601
  --handle-transition: var(--slider-transition);
1584
1602
 
@@ -1642,11 +1660,10 @@ fig-slider {
1642
1660
  );
1643
1661
  --width: calc(var(--slider-percent) - var(--start-percent));
1644
1662
  --abs-width: max(
1645
- var(--width) + var(--slider-height) / 2 + (1 - var(--slider-complete)) *
1646
- var(--slider-height),
1647
- -1 * var(--width) + var(--slider-height) / 2 + (
1648
- var(--slider-complete)
1649
- ) * var(--slider-height)
1663
+ var(--width) + var(--slider-height) / 2 +
1664
+ (1 - var(--slider-complete)) * var(--slider-height),
1665
+ -1 * var(--width) + var(--slider-height) / 2 +
1666
+ (var(--slider-complete)) * var(--slider-height)
1650
1667
  );
1651
1668
  width: var(--abs-width);
1652
1669
  --delta: calc(var(--slider-complete) - var(--default));
@@ -1736,7 +1753,8 @@ fig-slider {
1736
1753
  }
1737
1754
 
1738
1755
  &.opacity::-webkit-slider-runnable-track {
1739
- background: linear-gradient(to right, transparent, var(--color)),
1756
+ background:
1757
+ linear-gradient(to right, transparent, var(--color)),
1740
1758
  var(--checkerboard);
1741
1759
  }
1742
1760
  }
@@ -1810,7 +1828,8 @@ fig-slider {
1810
1828
  }
1811
1829
 
1812
1830
  &.opacity::-moz-range-track {
1813
- background: linear-gradient(to right, transparent, var(--color)),
1831
+ background:
1832
+ linear-gradient(to right, transparent, var(--color)),
1814
1833
  var(--checkerboard);
1815
1834
  }
1816
1835
  }
@@ -1859,8 +1878,8 @@ fig-slider {
1859
1878
  --slider-tick-size: calc(var(--slider-height) / 2);
1860
1879
  --handle-transition: none;
1861
1880
  --slider-transition: none;
1862
- --slider-handle-shadow: inset 0 0 0 calc(6px + 0.5rem * var(--unchanged))
1863
- var(--handle-color),
1881
+ --slider-handle-shadow:
1882
+ inset 0 0 0 calc(6px + 0.5rem * var(--unchanged)) var(--handle-color),
1864
1883
  0 0 0 0.75px rgba(0, 0, 0, 0.075), inset 0 0 0 5px rgba(0, 0, 0, 0.1),
1865
1884
  var(--figma-elevation-100);
1866
1885
 
@@ -1888,8 +1907,8 @@ fig-slider {
1888
1907
  --slider-tick-size: calc(var(--slider-height) / 2);
1889
1908
  --handle-transition: none;
1890
1909
  --slider-transition: none;
1891
- --slider-handle-shadow: inset 0 0 0 calc(6px + 0.5rem * var(--unchanged))
1892
- var(--handle-color),
1910
+ --slider-handle-shadow:
1911
+ inset 0 0 0 calc(6px + 0.5rem * var(--unchanged)) var(--handle-color),
1893
1912
  0 0 0 0.75px rgba(0, 0, 0, 0.075), inset 0 0 0 5px rgba(0, 0, 0, 0.1),
1894
1913
  var(--figma-elevation-100);
1895
1914
 
@@ -1994,8 +2013,10 @@ dialog,
1994
2013
  text-overflow: ellipsis;
1995
2014
 
1996
2015
  border-radius: var(--radius-medium, 0.3125rem);
1997
- box-shadow: 0px 0px 0.5px 0px rgba(0, 0, 0, 0.15),
1998
- 0px 5px 12px 0px rgba(0, 0, 0, 0.13), 0px 1px 3px 0px rgba(0, 0, 0, 0.1);
2016
+ box-shadow:
2017
+ 0px 0px 0.5px 0px rgba(0, 0, 0, 0.15),
2018
+ 0px 5px 12px 0px rgba(0, 0, 0, 0.13),
2019
+ 0px 1px 3px 0px rgba(0, 0, 0, 0.1);
1999
2020
 
2000
2021
  @supports (-webkit-line-clamp: 2) {
2001
2022
  white-space: initial;
@@ -2487,6 +2508,15 @@ fig-segmented-control {
2487
2508
  border-radius: calc(var(--radius-medium) - 1px);
2488
2509
  box-shadow: 0 0 0 1px var(--figma-color-border);
2489
2510
  }
2511
+
2512
+ svg {
2513
+ *[fill] {
2514
+ fill: currentColor;
2515
+ }
2516
+ *[stroke]:not([stroke="none"]) {
2517
+ stroke: currentColor;
2518
+ }
2519
+ }
2490
2520
  }
2491
2521
  }
2492
2522
 
@@ -2571,7 +2601,8 @@ fig-input-joystick {
2571
2601
  }
2572
2602
  }
2573
2603
  .fig-input-joystick-plane.dragging .fig-input-joystick-guides {
2574
- background: linear-gradient(
2604
+ background:
2605
+ linear-gradient(
2575
2606
  45deg,
2576
2607
  transparent calc(50% - 0.5px),
2577
2608
  var(--figma-color-border) calc(50% - 0.5px),
@@ -2883,13 +2914,17 @@ fig-fill-picker {
2883
2914
  height: 1rem;
2884
2915
  border-radius: 50%;
2885
2916
  background: var(--picker-color);
2886
- box-shadow: inset 0 0 0 0.125rem var(--handle-color),
2887
- 0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--figma-elevation-200);
2917
+ box-shadow:
2918
+ inset 0 0 0 0.125rem var(--handle-color),
2919
+ 0px 0 0 0.5px rgba(0, 0, 0, 0.1),
2920
+ var(--figma-elevation-200);
2888
2921
  transform: translate(-50%, -50%);
2889
2922
  z-index: 1;
2890
2923
  &:hover {
2891
- box-shadow: inset 0 0 0 0.25rem var(--handle-color),
2892
- 0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--figma-elevation-200);
2924
+ box-shadow:
2925
+ inset 0 0 0 0.25rem var(--handle-color),
2926
+ 0px 0 0 0.5px rgba(0, 0, 0, 0.1),
2927
+ var(--figma-elevation-200);
2893
2928
  transform: translate(-50%, -50%);
2894
2929
  }
2895
2930
  }
@@ -3045,16 +3080,21 @@ fig-fill-picker {
3045
3080
  .fig-fill-picker-checkerboard {
3046
3081
  position: absolute;
3047
3082
  inset: 0;
3048
- background-image: linear-gradient(
3049
- 45deg,
3083
+ background-image:
3084
+ linear-gradient(45deg, var(--figma-color-bg-tertiary) 25%, transparent 25%),
3085
+ linear-gradient(
3086
+ -45deg,
3050
3087
  var(--figma-color-bg-tertiary) 25%,
3051
3088
  transparent 25%
3052
3089
  ),
3053
- linear-gradient(-45deg, var(--figma-color-bg-tertiary) 25%, transparent 25%),
3054
3090
  linear-gradient(45deg, transparent 75%, var(--figma-color-bg-tertiary) 75%),
3055
3091
  linear-gradient(-45deg, transparent 75%, var(--figma-color-bg-tertiary) 75%);
3056
3092
  background-size: 16px 16px;
3057
- background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
3093
+ background-position:
3094
+ 0 0,
3095
+ 0 8px,
3096
+ 8px -8px,
3097
+ -8px 0px;
3058
3098
  }
3059
3099
 
3060
3100
  .fig-fill-picker-image-preview {
package/fig.js CHANGED
@@ -1368,14 +1368,14 @@ class FigSegmentedControl extends HTMLElement {
1368
1368
  }
1369
1369
 
1370
1370
  handleClick(event) {
1371
- const target = event.target;
1372
- if (target.nodeName.toLowerCase() === "fig-segment") {
1371
+ const segment = event.target.closest("fig-segment");
1372
+ if (segment) {
1373
1373
  const segments = this.querySelectorAll("fig-segment");
1374
- for (const segment of segments) {
1375
- if (segment === target) {
1376
- this.selectedSegment = segment;
1374
+ for (const seg of segments) {
1375
+ if (seg === segment) {
1376
+ this.selectedSegment = seg;
1377
1377
  } else {
1378
- segment.removeAttribute("selected");
1378
+ seg.removeAttribute("selected");
1379
1379
  }
1380
1380
  }
1381
1381
  }
@@ -2928,7 +2928,7 @@ class FigInputFill extends HTMLElement {
2928
2928
  }
2929
2929
 
2930
2930
  static get observedAttributes() {
2931
- return ["value", "disabled"];
2931
+ return ["value", "disabled", "mode"];
2932
2932
  }
2933
2933
 
2934
2934
  connectedCallback() {
@@ -3078,11 +3078,12 @@ class FigInputFill extends HTMLElement {
3078
3078
  break;
3079
3079
  }
3080
3080
 
3081
+ const modeAttr = this.getAttribute("mode");
3081
3082
  this.innerHTML = `
3082
3083
  <div class="input-combo">
3083
3084
  <fig-fill-picker value='${fillPickerValue}' ${
3084
3085
  disabled ? "disabled" : ""
3085
- }></fig-fill-picker>
3086
+ } ${modeAttr ? `mode="${modeAttr}"` : ""}></fig-fill-picker>
3086
3087
  ${controlsHtml}
3087
3088
  </div>`;
3088
3089
 
@@ -5554,31 +5555,43 @@ class FigFillPicker extends HTMLElement {
5554
5555
  this.#dialog.setAttribute("position", dialogPosition);
5555
5556
  }
5556
5557
 
5557
- // Check for locked mode
5558
+ // Check for allowed modes (supports comma-separated values like "solid,gradient")
5558
5559
  const mode = this.getAttribute("mode");
5559
- const validModes = ["solid", "gradient", "image", "video", "webcam"];
5560
- const lockedMode = validModes.includes(mode) ? mode : null;
5561
-
5562
- // If locked mode, force fillType
5563
- if (lockedMode) {
5564
- this.#fillType = lockedMode;
5565
- this.#activeTab = lockedMode;
5566
- }
5567
-
5568
- // Build header content - dropdown or label
5569
- const headerContent = lockedMode
5570
- ? `<span class="fig-fill-picker-type-label">${
5571
- lockedMode.charAt(0).toUpperCase() + lockedMode.slice(1)
5572
- }</span>`
5573
- : `<fig-dropdown class="fig-fill-picker-type" variant="neue" value="${
5574
- this.#fillType
5575
- }">
5576
- <option value="solid">Solid</option>
5577
- <option value="gradient">Gradient</option>
5578
- <option value="image">Image</option>
5579
- <option value="video">Video</option>
5580
- <option value="webcam">Webcam</option>
5560
+ const allModes = ["solid", "gradient", "image", "video", "webcam"];
5561
+ const modeLabels = {
5562
+ solid: "Solid",
5563
+ gradient: "Gradient",
5564
+ image: "Image",
5565
+ video: "Video",
5566
+ webcam: "Webcam",
5567
+ };
5568
+
5569
+ // Parse allowed modes
5570
+ let allowedModes = allModes;
5571
+ if (mode) {
5572
+ const requestedModes = mode.split(",").map((m) => m.trim().toLowerCase());
5573
+ allowedModes = requestedModes.filter((m) => allModes.includes(m));
5574
+ if (allowedModes.length === 0) allowedModes = allModes;
5575
+ }
5576
+
5577
+ // If current fillType not in allowed modes, switch to first allowed
5578
+ if (!allowedModes.includes(this.#fillType)) {
5579
+ this.#fillType = allowedModes[0];
5580
+ this.#activeTab = allowedModes[0];
5581
+ }
5582
+
5583
+ // Build header content - label if single mode, dropdown if multiple
5584
+ let headerContent;
5585
+ if (allowedModes.length === 1) {
5586
+ headerContent = `<span class="fig-fill-picker-type-label">${modeLabels[allowedModes[0]]}</span>`;
5587
+ } else {
5588
+ const options = allowedModes
5589
+ .map((m) => `<option value="${m}">${modeLabels[m]}</option>`)
5590
+ .join("\n ");
5591
+ headerContent = `<fig-dropdown class="fig-fill-picker-type" variant="neue" value="${this.#fillType}">
5592
+ ${options}
5581
5593
  </fig-dropdown>`;
5594
+ }
5582
5595
 
5583
5596
  this.#dialog.innerHTML = `
5584
5597
  <fig-header>
@@ -5627,13 +5640,19 @@ class FigFillPicker extends HTMLElement {
5627
5640
  }
5628
5641
 
5629
5642
  #switchTab(tabName) {
5630
- // Check for locked mode - prevent switching if locked
5643
+ // Check for allowed modes - prevent switching to disallowed mode
5631
5644
  const mode = this.getAttribute("mode");
5632
- const validModes = ["solid", "gradient", "image", "video", "webcam"];
5633
- const lockedMode = validModes.includes(mode) ? mode : null;
5645
+ const allModes = ["solid", "gradient", "image", "video", "webcam"];
5646
+
5647
+ let allowedModes = allModes;
5648
+ if (mode) {
5649
+ const requestedModes = mode.split(",").map((m) => m.trim().toLowerCase());
5650
+ allowedModes = requestedModes.filter((m) => allModes.includes(m));
5651
+ if (allowedModes.length === 0) allowedModes = allModes;
5652
+ }
5634
5653
 
5635
- if (lockedMode && tabName !== lockedMode) {
5636
- return; // Don't allow switching away from locked mode
5654
+ if (!allowedModes.includes(tabName)) {
5655
+ return; // Don't allow switching to disallowed mode
5637
5656
  }
5638
5657
 
5639
5658
  this.#activeTab = tabName;
@@ -6133,8 +6152,9 @@ class FigFillPicker extends HTMLElement {
6133
6152
  this.#gradient.centerY
6134
6153
  }%, ${stops})`;
6135
6154
  case "angular":
6136
- // Offset by 90° to align with fig-input-angle (0° = right) vs CSS conic (0° = top)
6137
- return `conic-gradient(from ${this.#gradient.angle + 90}deg, ${stops})`;
6155
+ // Internal gradient.angle is already in CSS coordinate system (0° = top)
6156
+ // because it's converted when reading from fig-input-angle
6157
+ return `conic-gradient(from ${this.#gradient.angle}deg, ${stops})`;
6138
6158
  default:
6139
6159
  return `linear-gradient(${this.#gradient.angle}deg, ${stops})`;
6140
6160
  }
package/index.html CHANGED
@@ -688,11 +688,16 @@
688
688
  </fig-field>
689
689
  <fig-field direction="horizontal">
690
690
  <label>Number</label>
691
- <fig-input-number value="50" min="0" max="100" units="px"></fig-input-number>
691
+ <fig-input-number value="50"
692
+ min="0"
693
+ max="100"
694
+ units="px"></fig-input-number>
692
695
  </fig-field>
693
696
  <fig-field direction="horizontal">
694
697
  <label>Slider</label>
695
- <fig-slider value="50" min="0" max="100"></fig-slider>
698
+ <fig-slider value="50"
699
+ min="0"
700
+ max="100"></fig-slider>
696
701
  </fig-field>
697
702
  <fig-field direction="horizontal">
698
703
  <label>Checkbox</label>
@@ -749,11 +754,14 @@
749
754
  <p>This dialog is positioned at a specific corner.</p>
750
755
  <fig-field direction="horizontal">
751
756
  <label>Number</label>
752
- <fig-input-number value="100" units="%"></fig-input-number>
757
+ <fig-input-number value="100"
758
+ units="%"></fig-input-number>
753
759
  </fig-field>
754
760
  <fig-field direction="horizontal">
755
761
  <label>Slider</label>
756
- <fig-slider value="50" min="0" max="100"></fig-slider>
762
+ <fig-slider value="50"
763
+ min="0"
764
+ max="100"></fig-slider>
757
765
  </fig-field>
758
766
  </fig-content>
759
767
  <footer>
@@ -800,11 +808,16 @@
800
808
  </ul>
801
809
  <fig-field direction="horizontal">
802
810
  <label>Number</label>
803
- <fig-input-number value="45" units="°" min="0" max="360"></fig-input-number>
811
+ <fig-input-number value="45"
812
+ units="°"
813
+ min="0"
814
+ max="360"></fig-input-number>
804
815
  </fig-field>
805
816
  <fig-field direction="horizontal">
806
817
  <label>Slider</label>
807
- <fig-slider value="50" min="0" max="100"></fig-slider>
818
+ <fig-slider value="50"
819
+ min="0"
820
+ max="100"></fig-slider>
808
821
  </fig-field>
809
822
  <details>
810
823
  <summary>More options</summary>
@@ -848,6 +861,20 @@
848
861
  <option>Option Three</option>
849
862
  </fig-dropdown>
850
863
 
864
+ <h3>Autoresize to Content</h3>
865
+ <p style="font-size: 12px; color: var(--figma-color-text-secondary); margin-bottom: 8px;">
866
+ Uses <code>field-sizing: content</code> to resize based on selected option.
867
+ </p>
868
+ <fig-dropdown autoresize
869
+ variant="neue">
870
+ <option>XS</option>
871
+ <option>Small</option>
872
+ <option>Medium</option>
873
+ <option>Large</option>
874
+ <option>Extra Large with Long Text</option>
875
+ <option>XXL Super Extended Option</option>
876
+ </fig-dropdown>
877
+
851
878
  <h3>Dropdown Neue Variant (with many options)</h3>
852
879
  <fig-dropdown variant="neue"
853
880
  type="dropdown"
@@ -1251,6 +1278,19 @@
1251
1278
  <h4>Image Only</h4>
1252
1279
  <fig-fill-picker mode="image"></fig-fill-picker>
1253
1280
 
1281
+ <h3>Limited Mode Selection</h3>
1282
+ <p class="description">Use comma-separated values in the <code>mode</code> attribute to limit available modes
1283
+ while still allowing switching between them.</p>
1284
+
1285
+ <h4>Solid and Gradient Only</h4>
1286
+ <fig-fill-picker mode="solid,gradient"></fig-fill-picker>
1287
+
1288
+ <h4>Solid, Gradient, and Image</h4>
1289
+ <fig-fill-picker mode="solid,gradient,image"></fig-fill-picker>
1290
+
1291
+ <h4>With fig-input-fill (mode passed through)</h4>
1292
+ <fig-input-fill mode="solid,gradient" value='{"type":"solid","color":"#667eea"}'></fig-input-fill>
1293
+
1254
1294
  <h3>Event Listening</h3>
1255
1295
  <fig-fill-picker id="fill-picker-events"
1256
1296
  value='{"type":"solid","color":"#FCBAD3"}'></fig-fill-picker>
@@ -2525,6 +2565,20 @@
2525
2565
  <fig-segment>Right</fig-segment>
2526
2566
  </fig-segmented-control>
2527
2567
 
2568
+ <h3>With Icons</h3>
2569
+ <fig-segmented-control>
2570
+ <fig-segment selected>
2571
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2572
+ <path d="M8.5 5.59686C8.80936 5.41829 9.19064 5.41829 9.5 5.59686L15 8.77264C15.6185 9.12984 15.9998 9.78984 16 10.5041V16.8557C15.9999 17.2128 15.8093 17.5433 15.5 17.7219C15.1907 17.9003 14.8093 17.9003 14.5 17.7219L14.2988 17.6057L14.1025 17.4924L13.9111 17.381L13.7236 17.2736L13.541 17.1672L13.3613 17.0637L13.1846 16.9621L13.0117 16.8625L12.8418 16.7639L12.6738 16.6672L12.5078 16.5715L12.3438 16.4767L12.1816 16.383L12.0205 16.2902L11.8613 16.1974L11.7012 16.1057L11.543 16.0139L11.0654 15.7385L10.9053 15.6457L10.7432 15.5519L10.5801 15.4582L10.416 15.3635L10.249 15.2668L10.0801 15.1691L9.9082 15.0705L9.73438 14.9699L9.55664 14.8674L9.375 14.7619L9.18945 14.6555L9.00098 14.5461C8.38287 14.1892 8.00002 13.5289 8 12.8137V6.46307C8 6.10581 8.1906 5.7755 8.5 5.59686ZM9 12.8137C9.00001 13.1709 9.1916 13.5012 9.50098 13.6799C11.542 14.8584 12.8291 15.6022 15 16.8557V10.5051C15 10.1925 14.8541 9.89983 14.6104 9.7121L14.5 9.63885L9 6.46307V12.8137Z" fill="black" fill-opacity="0.9"/>
2573
+ </svg>
2574
+ </fig-segment>
2575
+ <fig-segment>
2576
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2577
+ <path d="M14.4998 5.5968C14.8091 5.41823 15.1904 5.41823 15.4998 5.5968C15.8092 5.77543 15.9998 6.10575 15.9998 6.46301V12.8136C15.9997 13.5281 15.6185 14.1888 14.9998 14.546L9.49976 17.7218C9.19046 17.9003 8.80905 17.9003 8.49976 17.7218C8.19043 17.5432 7.99986 17.2127 7.99976 16.8556V10.504C7.99995 9.78978 8.38122 9.12978 8.99976 8.77258L14.4998 5.5968ZM9.49976 9.63879L9.3894 9.71204C9.14564 9.89977 8.99977 10.1924 8.99976 10.505V16.8556L14.4998 13.6798C14.7704 13.5235 14.9502 13.2513 14.991 12.9464L14.9998 12.8136V6.46301L9.49976 9.63879Z" fill="black" fill-opacity="0.9"/>
2578
+ </svg>
2579
+ </fig-segment>
2580
+ </fig-segmented-control>
2581
+
2528
2582
  <h3>Many Options</h3>
2529
2583
  <fig-segmented-control>
2530
2584
  <fig-segment>XS</fig-segment>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "2.13.0",
3
+ "version": "2.13.2",
4
4
  "description": "A lightweight web components library for building Figma plugin and widget UIs with native look and feel",
5
5
  "author": "Rogie King",
6
6
  "license": "MIT",