@rogieking/figui3 2.27.0 → 2.29.0

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
@@ -184,29 +184,6 @@ Displays contextual information on hover or click. The tooltip automatically rep
184
184
  </fig-tooltip>
185
185
  ```
186
186
 
187
- ---
188
-
189
- ### Popover (`<fig-popover>`)
190
-
191
- A popover container for rich content.
192
-
193
- | Attribute | Type | Default | Description |
194
- |-----------|------|---------|-------------|
195
- | `action` | string | `"click"` | Trigger: `"click"` or `"hover"` |
196
- | `size` | string | — | Size of the popover |
197
-
198
- ```html
199
- <fig-popover action="click">
200
- <fig-button slot="trigger">Open Popover</fig-button>
201
- <div slot="content">
202
- <h3>Popover Title</h3>
203
- <p>Rich content goes here.</p>
204
- </div>
205
- </fig-popover>
206
- ```
207
-
208
- ---
209
-
210
187
  ### Dialog (`<fig-dialog>`)
211
188
 
212
189
  A modal dialog component with drag support.
package/components.css CHANGED
@@ -214,8 +214,14 @@
214
214
  --spacer-6: 2.5rem;
215
215
 
216
216
  /* Radii */
217
+ --radius-none: 0;
218
+ --radius-small: 0.125rem;
217
219
  --radius-medium: 0.3125rem;
218
220
  --radius-large: 0.8125rem;
221
+ --figma-radius-none: var(--radius-none);
222
+ --figma-radius-small: var(--radius-small);
223
+ --figma-radius-medium: var(--radius-medium);
224
+ --figma-radius-large: var(--radius-large);
219
225
 
220
226
  /* Transitions */
221
227
  --input-transition: all 0.08s ease-out;
@@ -294,7 +300,7 @@
294
300
 
295
301
  /* Icons - colorless shapes for use with mask-image */
296
302
  --icon-chevron: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.87868 7.12132L8 9.24264L10.1213 7.12132' stroke='black' stroke-linecap='round'/%3E%3C/svg%3E%0A");
297
- --icon-checkmark: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11.7773 4.08403C12.0071 4.2372 12.0692 4.54764 11.916 4.7774L7.91603 10.7774C7.83293 10.902 7.69834 10.9829 7.54927 10.9976C7.4002 11.0124 7.25237 10.9595 7.14645 10.8536L4.14645 7.85361C3.95118 7.65834 3.95118 7.34176 4.14645 7.1465C4.34171 6.95124 4.65829 6.95124 4.85355 7.1465L7.42229 9.71523L11.084 4.2227C11.2372 3.99294 11.5476 3.93085 11.7773 4.08403Z' fill='white'/%3E%3C/svg%3E%0A");
303
+ --icon-checkmark: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.084 4.22266C11.2372 3.99292 11.5476 3.93084 11.7773 4.08398C12.0071 4.23716 12.0692 4.54758 11.916 4.77734L7.91602 10.7773C7.83292 10.902 7.6979 10.9833 7.54883 10.998C7.39993 11.0126 7.25229 10.9593 7.14648 10.8535L4.14648 7.85352C3.95126 7.65825 3.95123 7.34173 4.14648 7.14648C4.34174 6.95124 4.65825 6.95126 4.85352 7.14648L7.42188 9.71484L11.084 4.22266Z' fill='white'/%3E%3C/svg%3E%0A");
298
304
  --icon-steppers: 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 d='M11.7245 6.08191C11.9186 5.95386 12.1826 5.97562 12.3534 6.14637L14.3534 8.14637L14.4179 8.22449C14.546 8.41852 14.5242 8.68253 14.3534 8.8534C14.1826 9.02426 13.9186 9.04601 13.7245 8.91785L13.6464 8.8534L11.9999 7.20691L10.3534 8.8534C10.1582 9.04866 9.84166 9.04866 9.6464 8.8534C9.45123 8.65813 9.45117 8.3416 9.6464 8.14637L11.6464 6.14637L11.7245 6.08191Z' fill='black'/%3E%3Cpath d='M13.7248 15.0822C13.9189 14.9541 14.1829 14.9758 14.3537 15.1467C14.5246 15.3176 14.5463 15.5815 14.4182 15.7756L14.3537 15.8537L12.3537 17.8537C12.1829 18.0246 11.9189 18.0463 11.7248 17.9182L11.6467 17.8537L9.64669 15.8537L9.58224 15.7756C9.45407 15.5815 9.47583 15.3176 9.64669 15.1467C9.81756 14.9758 10.0815 14.9541 10.2756 15.0822L10.3537 15.1467L12.0002 16.7932L13.6467 15.1467L13.7248 15.0822Z' fill='black' /%3E%3C/svg%3E%0A");
299
305
  --icon-eyedropper: 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='M15.1592 5.65801C16.0376 4.78045 17.4621 4.78055 18.3408 5.65899L18.4951 5.82989C19.1671 6.65442 19.168 7.84476 18.4951 8.66973L18.3408 8.84063L16.6455 10.533C17.1104 11.083 17.1181 11.889 16.6641 12.4461L16.5605 12.5604C16.0111 13.1097 15.1425 13.1428 14.5537 12.6629L14.5342 12.6453L10.0908 17.0916C9.6188 17.5633 8.98876 17.7764 8.375 17.742L7.56055 18.5574C6.97441 19.1432 6.02451 19.1422 5.43945 18.5584V18.5574C4.8538 17.9718 4.85405 17.0221 5.43945 16.4363L6.25586 15.618C6.22412 15.0058 6.44026 14.3794 6.90918 13.91L11.3516 9.46367C10.856 8.87434 10.885 7.99381 11.4395 7.43926L11.5537 7.33574C12.1094 6.88283 12.9136 6.88854 13.4639 7.35137L15.1592 5.65801ZM7.61621 14.617C7.33755 14.8961 7.21782 15.2747 7.25781 15.6385C7.27925 15.8351 7.24419 16.0445 7.10449 16.1844L6.14648 17.1434C5.9516 17.3387 5.95135 17.6553 6.14648 17.8504C6.34167 18.0449 6.65842 18.0451 6.85352 17.8504L7.80859 16.8943C7.94931 16.7536 8.16065 16.7184 8.3584 16.741C8.72329 16.7828 9.10374 16.6643 9.38379 16.3846L13.8223 11.9432L12.0547 10.1756L7.61621 14.617ZM17.6338 6.36602C17.1458 5.87828 16.3544 5.8783 15.8662 6.36602L14.084 8.14629L14.0186 8.20586C13.6767 8.48476 13.1722 8.46484 12.8535 8.14629C12.6583 7.95131 12.3417 7.95119 12.1465 8.14629C11.9514 8.34148 11.9515 8.65808 12.1465 8.85332L15.1465 11.8533C15.3175 12.024 15.5814 12.0451 15.7754 11.9168L15.8535 11.8533C16.0486 11.6582 16.0484 11.3416 15.8535 11.1463V11.1453C15.8524 11.1443 15.8507 11.1434 15.8496 11.1424C15.5128 10.8013 15.514 10.2513 15.8535 9.91192L17.6338 8.1336C18.1216 7.6457 18.1213 6.85425 17.6338 6.36602Z' fill='black' fill-opacity='0.9'/%3E%3C/svg%3E");
300
306
  --icon-add: 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='M12 6C12.2761 6 12.5 6.22386 12.5 6.5V11.5H17.5C17.7761 11.5 18 11.7239 18 12C18 12.2761 17.7761 12.5 17.5 12.5H12.5V17.5C12.5 17.7761 12.2761 18 12 18C11.7239 18 11.5 17.7761 11.5 17.5V12.5H6.5C6.22386 12.5 6 12.2761 6 12C6 11.7239 6.22386 11.5 6.5 11.5H11.5V6.5C11.5 6.22386 11.7239 6 12 6Z' fill='currentColor'/%3E%3C/svg%3E");
@@ -474,15 +480,25 @@ input[type="text"][list] {
474
480
  }
475
481
 
476
482
  option::checkmark {
477
- content: var(--icon-checkmark);
483
+ content: "";
478
484
  display: block;
479
485
  width: 1rem;
480
486
  height: 1rem;
487
+ margin-right: calc(var(--spacer-1) * -1);
488
+ background-color: currentColor;
489
+ -webkit-mask-image: var(--icon-checkmark);
490
+ mask-image: var(--icon-checkmark);
491
+ -webkit-mask-repeat: no-repeat;
492
+ mask-repeat: no-repeat;
493
+ -webkit-mask-position: center;
494
+ mask-position: center;
495
+ -webkit-mask-size: contain;
496
+ mask-size: contain;
481
497
  }
482
498
 
483
499
  option {
484
500
  display: flex;
485
- gap: var(--spacer-2);
501
+ gap: var(--spacer-1);
486
502
  padding: 0 var(--spacer-4) 0 calc(var(--spacer-1) * 2 + var(--spacer-1));
487
503
  font-weight: var(--body-medium-fontWeight);
488
504
  color: var(--figma-color-text-menu);
@@ -493,13 +509,18 @@ input[type="text"][list] {
493
509
  &[hidden] {
494
510
  display: none;
495
511
  }
496
- &:not(:checked):before {
512
+ &:before {
497
513
  content: "";
498
514
  display: block;
499
515
  position: absolute;
500
516
  inset: 0 var(--spacer-2);
501
517
  border-radius: var(--radius-medium);
502
518
  z-index: -1;
519
+ }
520
+ &:checked:before {
521
+ background-color: transparent;
522
+ }
523
+ &:not(:checked):before {
503
524
  background-color: transparent;
504
525
  }
505
526
  &:not(:disabled) {
@@ -558,12 +579,46 @@ input[type="text"][list] {
558
579
  display: none;
559
580
  }
560
581
  }
582
+
583
+ /* Customizable select button content (closed state) */
584
+ &:has(> button) {
585
+ padding-left: 0;
586
+ }
587
+ & > button {
588
+ display: flex;
589
+ align-items: center;
590
+ gap: var(--spacer-1);
591
+ width: 100%;
592
+ border: 0;
593
+ background: transparent;
594
+ padding: 0;
595
+ margin: 0;
596
+ color: inherit;
597
+ font: inherit;
598
+ height: 100%;
599
+ white-space: nowrap;
600
+ text-overflow: ellipsis;
601
+ overflow: hidden;
602
+
603
+ & > selectedcontent {
604
+ display: flex;
605
+ align-items: center;
606
+ gap: 0;
607
+ min-width: 0;
608
+ &:not(:has(> svg)) {
609
+ padding-left: var(--spacer-2);
610
+ }
611
+
612
+ & svg {
613
+ flex-shrink: 0;
614
+ }
615
+ }
616
+ }
561
617
  }
562
618
  ::picker-icon {
563
619
  display: none;
564
620
  }
565
621
 
566
- /* https://codepen.io/editor/argyleink/pen/019c1f28-bbc2-7bac-ad4a-a7e41d3730f1 */
567
622
  ::picker(select) {
568
623
  appearance: base-select;
569
624
  color-scheme: dark;
@@ -1269,18 +1324,41 @@ fig-easing-curve {
1269
1324
  display: flex;
1270
1325
  flex-direction: column;
1271
1326
  gap: var(--spacer-2);
1272
- --stroke-width: 1.25;
1327
+ --stroke-width: 1;
1328
+ --easing-bezier-handle-radius: 4.25;
1329
+ --easing-spring-handle-radius: 4.25;
1330
+ --easing-handle-fill: var(--figma-color-border-strong);
1331
+ --easing-handle-fill-active: var(--figma-color-bg-brand);
1332
+ --easing-handle-stroke: var(--figma-color-bg-secondary);
1333
+ --easing-handle-stroke-width: var(--stroke-width);
1334
+ --easing-duration-bar-width: 4.25;
1335
+ --easing-duration-bar-height: 16;
1336
+ --easing-duration-bar-radius: 3;
1337
+ --aspect-ratio: 1 / 1;
1338
+ --easing-duration-bar-fill: var(--figma-color-border-strong);
1339
+ --easing-duration-bar-stroke: var(--figma-color-bg-secondary);
1340
+ --easing-duration-bar-stroke-width: var(--stroke-width);
1273
1341
 
1274
1342
  width: 100%;
1275
1343
  .fig-easing-curve-svg {
1276
1344
  width: 100%;
1277
- aspect-ratio: 1 / 1;
1345
+ aspect-ratio: var(--aspect-ratio);
1278
1346
  overflow: visible;
1279
1347
  }
1280
1348
  .fig-easing-curve-svg-container {
1281
1349
  border-radius: var(--radius-medium);
1282
1350
  background: var(--figma-color-bg-secondary);
1283
- padding: var(--spacer-2);
1351
+ padding: var(--spacer-3);
1352
+ overflow: hidden;
1353
+ &:is(:hover, :active, :focus, :focus-visible, :focus-within) {
1354
+ overflow: visible;
1355
+ }
1356
+ }
1357
+ &.spring-mode {
1358
+ .fig-easing-curve-svg-container,
1359
+ .fig-easing-curve-svg {
1360
+ cursor: ew-resize;
1361
+ }
1284
1362
  }
1285
1363
  .fig-easing-curve-diagonal,
1286
1364
  .fig-easing-curve-bounds,
@@ -1318,22 +1396,32 @@ fig-easing-curve {
1318
1396
  stroke-linecap: round;
1319
1397
  }
1320
1398
  .fig-easing-curve-handle {
1321
- fill: var(--figma-color-border-strong);
1322
- cursor: grab;
1399
+ fill: var(--easing-handle-fill);
1400
+ cursor: default;
1323
1401
  pointer-events: all;
1324
- stroke: var(--figma-color-bg-secondary);
1325
- stroke-width: var(--stroke-width);
1402
+ stroke: var(--easing-handle-stroke);
1403
+ stroke-width: var(--easing-handle-stroke-width);
1404
+ &:hover {
1405
+ fill: var(--easing-handle-fill-active);
1406
+ }
1326
1407
  &:active {
1327
1408
  cursor: grabbing;
1328
- fill: var(--figma-color-bg-brand);
1409
+ fill: var(--easing-handle-fill-active);
1329
1410
  }
1330
1411
  }
1331
1412
  .fig-easing-curve-duration-bar {
1332
- fill: var(--figma-color-border-strong);
1333
- stroke: var(--figma-color-bg-secondary);
1334
- stroke-width: var(--stroke-width);
1335
- cursor: ew-resize;
1413
+ fill: var(--easing-duration-bar-fill);
1414
+ stroke: var(--easing-duration-bar-stroke);
1415
+ stroke-width: var(--easing-duration-bar-stroke-width);
1416
+ cursor: default;
1336
1417
  pointer-events: all;
1418
+ &:hover {
1419
+ fill: var(--easing-handle-fill-active);
1420
+ }
1421
+ &:active {
1422
+ cursor: grabbing;
1423
+ fill: var(--easing-handle-fill-active);
1424
+ }
1337
1425
  }
1338
1426
  .fig-easing-curve-dropdown {
1339
1427
  option svg {
@@ -1342,6 +1430,148 @@ fig-easing-curve {
1342
1430
  }
1343
1431
  }
1344
1432
 
1433
+ /* 3D Rotate */
1434
+ fig-3d-rotate {
1435
+ display: flex;
1436
+ flex-wrap: wrap;
1437
+ gap: var(--spacer-2);
1438
+ width: 100%;
1439
+ --aspect-ratio: 1 / 1;
1440
+ --gradient-start-color: rgba(0, 0, 0, 0.05);
1441
+ --gradient-end-color: transparent;
1442
+ --figma-3d-rotate-handle-size: 6px;
1443
+
1444
+ fig-field[direction="horizontal"] & {
1445
+ flex: 1;
1446
+ min-width: 0;
1447
+ }
1448
+
1449
+ > fig-input-number {
1450
+ flex: 1 0 4rem;
1451
+ }
1452
+
1453
+ .fig-3d-rotate-container {
1454
+ flex: 1 1 100%;
1455
+ border-radius: var(--radius-medium);
1456
+ background: var(--figma-color-bg-secondary);
1457
+ padding: 0 2.5rem;
1458
+ width: 100%;
1459
+ aspect-ratio: var(--aspect-ratio);
1460
+ display: flex;
1461
+ align-items: center;
1462
+ justify-content: center;
1463
+ cursor: grab;
1464
+ user-select: none;
1465
+ overflow: hidden;
1466
+
1467
+ &.dragging,
1468
+ &:active {
1469
+ cursor: grabbing;
1470
+ }
1471
+ &:focus {
1472
+ outline: 0;
1473
+ }
1474
+ }
1475
+
1476
+ .fig-3d-rotate-scene {
1477
+ width: 100%;
1478
+ aspect-ratio: 1 / 1;
1479
+ max-height: max(3.5rem, 50%);
1480
+ max-width: max(3.5rem, 50%);
1481
+ perspective: 20rem;
1482
+ }
1483
+
1484
+ .fig-3d-rotate-cube {
1485
+ width: 100%;
1486
+ height: 100%;
1487
+ position: relative;
1488
+ aspect-ratio: 1 / 1;
1489
+ transform-style: preserve-3d;
1490
+ }
1491
+
1492
+ .fig-3d-rotate-face {
1493
+ position: absolute;
1494
+ inset: 0;
1495
+ backface-visibility: visible;
1496
+ background: linear-gradient(
1497
+ to bottom,
1498
+ var(--gradient-start-color),
1499
+ var(--gradient-end-color)
1500
+ );
1501
+
1502
+ &.front {
1503
+ background: var(--figma-color-bg);
1504
+ border-radius: var(--radius-medium);
1505
+ transform-style: preserve-3d;
1506
+ box-shadow: var(--figma-elevation-100);
1507
+ inset: -1px;
1508
+
1509
+ &::after {
1510
+ content: "";
1511
+ position: absolute;
1512
+ width: var(--figma-3d-rotate-handle-size);
1513
+ height: var(--figma-3d-rotate-handle-size);
1514
+ border-radius: 50%;
1515
+ background: var(--figma-color-border-strong);
1516
+ top: 50%;
1517
+ left: 50%;
1518
+ transform: translate(-50%, -50%);
1519
+ backface-visibility: hidden;
1520
+ }
1521
+ }
1522
+ &.back {
1523
+ transform-origin: 100% 50%;
1524
+ transform: translateX(-100%) rotateY(-0.25turn) translateX(-100%)
1525
+ rotateY(-0.25turn);
1526
+ background: linear-gradient(
1527
+ to bottom,
1528
+ var(--gradient-start-color),
1529
+ var(--gradient-start-color)
1530
+ );
1531
+ border-radius: var(--radius-medium);
1532
+ }
1533
+ &.right {
1534
+ transform-origin: 0% 50%;
1535
+ transform: translateX(100%) rotateY(0.25turn);
1536
+ background: linear-gradient(
1537
+ to right,
1538
+ var(--gradient-start-color),
1539
+ var(--gradient-end-color)
1540
+ );
1541
+ }
1542
+ &.left {
1543
+ transform-origin: 100% 50%;
1544
+ transform: translateX(-100%) rotateY(-0.25turn);
1545
+ background: linear-gradient(
1546
+ to left,
1547
+ var(--gradient-start-color),
1548
+ var(--gradient-end-color)
1549
+ );
1550
+ }
1551
+ &.top {
1552
+ translate: 0 -100%;
1553
+ transform-origin: 50% 100%;
1554
+ transform: rotateX(0.25turn);
1555
+ background: linear-gradient(
1556
+ to top,
1557
+ var(--gradient-start-color),
1558
+ var(--gradient-end-color)
1559
+ );
1560
+ }
1561
+ &.bottom {
1562
+ top: 100%;
1563
+ bottom: auto;
1564
+ transform-origin: 50% 0%;
1565
+ transform: rotateX(-0.25turn);
1566
+ background: linear-gradient(
1567
+ to bottom,
1568
+ var(--gradient-start-color),
1569
+ var(--gradient-end-color)
1570
+ );
1571
+ }
1572
+ }
1573
+ }
1574
+
1345
1575
  /* Combo input */
1346
1576
  .input-combo {
1347
1577
  display: inline-flex;
@@ -1461,7 +1691,6 @@ input[type="checkbox"].switch:checked:focus {
1461
1691
  /* Checkbox */
1462
1692
  input[type="checkbox"]:not(.switch) {
1463
1693
  --size: 1rem;
1464
- --checkmark: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.50012 7.5L7.50012 10.5L11.5001 4.5' stroke='white' opacity='1' stroke-linecap='round' stroke-linejoin='round' stroke-width='1' /%3E%3C/svg%3E%0A");
1465
1694
  appearance: none;
1466
1695
  border-radius: var(--radius-medium);
1467
1696
  width: var(--size);
@@ -1476,7 +1705,7 @@ input[type="checkbox"]:not(.switch) {
1476
1705
  width: var(--size);
1477
1706
  height: var(--size);
1478
1707
  background-color: transparent;
1479
- mask-image: var(--checkmark);
1708
+ mask-image: var(--icon-checkmark);
1480
1709
  }
1481
1710
  &:hover:not(:checked):not(:disabled) {
1482
1711
  &::after {
@@ -1488,7 +1717,6 @@ input[type="checkbox"]:not(.switch) {
1488
1717
  &:checked {
1489
1718
  background-color: var(--figma-color-bg-brand);
1490
1719
  box-shadow: inset 0 0 0 1px var(--figma-color-border-selected-strong);
1491
- background-image: var(--light-checkmark);
1492
1720
  &::after {
1493
1721
  background-color: var(--figma-color-icon-onbrand);
1494
1722
  }
@@ -2260,8 +2488,7 @@ dialog[is="fig-toast"] {
2260
2488
  }
2261
2489
 
2262
2490
  /* Tooltip */
2263
- fig-tooltip,
2264
- fig-popover {
2491
+ fig-tooltip {
2265
2492
  display: contents;
2266
2493
  }
2267
2494
  .fig-tooltip {
@@ -2312,8 +2539,7 @@ fig-popover {
2312
2539
  }
2313
2540
  }
2314
2541
 
2315
- .fig-tooltip,
2316
- .fig-popover {
2542
+ .fig-tooltip {
2317
2543
  overflow: visible;
2318
2544
  box-shadow: inset 0 0.5px 0 0 rgba(255, 255, 255, 0.1);
2319
2545
  filter: drop-shadow(0px 1px 1.5px rgba(0, 0, 0, 0.1))
@@ -2360,7 +2586,6 @@ fig-icon.close {
2360
2586
 
2361
2587
  /* Web Components */
2362
2588
  fig-button,
2363
- fig-popover,
2364
2589
  fig-content,
2365
2590
  fig-slider,
2366
2591
  fig-switch,