@rogieking/figui3 6.16.0 → 6.18.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/fig-lab.css CHANGED
@@ -266,21 +266,17 @@ propskit-select {
266
266
  }
267
267
  }
268
268
 
269
- fig-dropdown {
269
+ fig-select {
270
270
  position: relative;
271
271
  flex: 0 0 auto;
272
272
  width: fit-content;
273
273
  min-width: 0;
274
274
  margin-left: auto;
275
275
  border-radius: var(--radius-medium);
276
+ background: transparent;
277
+ box-shadow: none;
276
278
 
277
- select {
278
- field-sizing: content;
279
- width: auto;
280
- min-width: 0;
281
- background: transparent;
282
- box-shadow: none;
283
- }
279
+ --fig-select-trigger-width: auto;
284
280
  }
285
281
  }
286
282
  }
@@ -644,6 +640,14 @@ propskit-slider {
644
640
 
645
641
  &[type="stepper"] {
646
642
  --slider-thumb-travel-offset: 0px;
643
+ datalist{
644
+ opacity: 0;
645
+ }
646
+ &:hover, &:focus-within {
647
+ datalist{
648
+ opacity: 1;
649
+ }
650
+ }
647
651
  }
648
652
 
649
653
  &[type="stepper"] .fig-slider-input-container input[type="range"] {
@@ -1238,3 +1242,271 @@ body.fig-reorder-dragging * {
1238
1242
  .fig-reorder-indicator[data-axis="horizontal"] {
1239
1243
  width: 2px;
1240
1244
  }
1245
+
1246
+ /* Select — host chrome; trigger/listbox live in shadow (options slotted) */
1247
+ fig-select {
1248
+ display: inline-flex;
1249
+ position: relative;
1250
+ align-items: center;
1251
+ min-width: 0;
1252
+ height: var(--spacer-4);
1253
+ border-radius: var(--radius-medium);
1254
+ background-color: var(--figma-color-bg);
1255
+ color: var(--figma-color-text);
1256
+ box-shadow: inset 0 0 0 1px var(--figma-color-border);
1257
+
1258
+ &[full]:not([full="false"]) {
1259
+ display: flex;
1260
+ width: 100%;
1261
+ }
1262
+
1263
+ &[disabled]:not([disabled="false"]) {
1264
+ pointer-events: none;
1265
+ color: var(--figma-color-text-tertiary);
1266
+
1267
+ &::after {
1268
+ background-color: var(--figma-color-icon-disabled);
1269
+ }
1270
+ }
1271
+
1272
+ &::after {
1273
+ content: "";
1274
+ position: absolute;
1275
+ right: 0.25rem;
1276
+ top: 50%;
1277
+ transform: translateY(-50%);
1278
+ width: 1rem;
1279
+ height: 1rem;
1280
+ mask-image: var(--icon-16-chevron);
1281
+ mask-size: contain;
1282
+ mask-repeat: no-repeat;
1283
+ mask-position: center;
1284
+ background-color: var(--figma-color-icon);
1285
+ pointer-events: none;
1286
+ z-index: 1;
1287
+ }
1288
+ }
1289
+
1290
+ /*
1291
+ * Internal listbox is a fig-popup inside fig-select's shadow, so document
1292
+ * dialog[is="fig-popup"] rules don't apply. Expose part=listbox and mirror
1293
+ * the menu-theme popup chrome (same tokens as components.css).
1294
+ */
1295
+ fig-select::part(listbox) {
1296
+ --z-index: 999999;
1297
+ --fig-popup-radius: var(--radius-large);
1298
+ --fig-popup-bg-color: var(--figma-color-bg-menu);
1299
+
1300
+ z-index: var(--z-index);
1301
+ position: fixed;
1302
+ inset: auto;
1303
+ margin: 0;
1304
+ border: 0;
1305
+ outline: 0;
1306
+ padding: 0;
1307
+ overflow: hidden;
1308
+ border-radius: var(--fig-popup-radius);
1309
+ background-color: var(--fig-popup-bg-color);
1310
+ color: var(--figma-color-text-menu);
1311
+ color-scheme: dark;
1312
+ box-shadow: var(--figma-elevation-100);
1313
+ /* width/min/max set in JS — ::part width rules override element.style. */
1314
+ max-height: min(20rem, calc(100vh - 1rem));
1315
+ height: max-content;
1316
+ }
1317
+
1318
+ /* Panel is the scroller; overflow uses top/bottom buttons (fig-chooser pattern). */
1319
+ fig-select-options {
1320
+ --fig-select-overflow-size: var(--spacer-4);
1321
+
1322
+ box-sizing: border-box;
1323
+ display: flex;
1324
+ flex-direction: column;
1325
+ gap: 0;
1326
+ width: 100%;
1327
+ max-width: 100%;
1328
+ max-height: min(20rem, calc(100vh - 1rem));
1329
+ /* No block padding — sticky overflow buttons must sit flush to the popup edges. */
1330
+ padding: 0;
1331
+ overflow: hidden auto;
1332
+ scrollbar-width: none;
1333
+
1334
+ &::-webkit-scrollbar {
1335
+ display: none;
1336
+ }
1337
+
1338
+ & > :not(.fig-overflow) {
1339
+ flex-shrink: 0;
1340
+ }
1341
+
1342
+ /* List breathing room (not on the scroller itself). */
1343
+ & > :not(.fig-overflow):first-child,
1344
+ & > .fig-overflow-start + :not(.fig-overflow) {
1345
+ margin-top: var(--spacer-2);
1346
+ }
1347
+
1348
+ & > :not(.fig-overflow):last-child,
1349
+ & > :not(.fig-overflow):has(+ .fig-overflow-end) {
1350
+ margin-bottom: var(--spacer-2);
1351
+ }
1352
+
1353
+ & > .fig-overflow {
1354
+ position: sticky;
1355
+ left: 0;
1356
+ flex: 0 0 var(--fig-select-overflow-size);
1357
+ width: 100%;
1358
+ height: var(--fig-select-overflow-size);
1359
+ margin: 0;
1360
+ z-index: 3;
1361
+ /* Menu chrome — not option hover (bg-menu-hover is brand blue). */
1362
+ color: var(--figma-color-text-menu);
1363
+ background: var(--figma-color-bg-menu) !important;
1364
+
1365
+ &::before {
1366
+ inset: 0;
1367
+ border-radius: 0;
1368
+ background: var(--figma-color-bg-menu) !important;
1369
+ }
1370
+
1371
+ &:hover::before {
1372
+ background: light-dark(
1373
+ rgba(0, 0, 0, 0.06),
1374
+ rgba(255, 255, 255, 0.08)
1375
+ )
1376
+ !important;
1377
+ }
1378
+
1379
+ &:hover {
1380
+ color: var(--figma-color-text-menu);
1381
+ }
1382
+ }
1383
+
1384
+ & > .fig-overflow-start {
1385
+ order: -1;
1386
+ top: 0;
1387
+ margin-block-end: calc(-1 * var(--fig-select-overflow-size));
1388
+
1389
+ &::before {
1390
+ border-radius: var(--radius-large) var(--radius-large) 0 0;
1391
+ }
1392
+
1393
+ .fig-overflow-chevron {
1394
+ rotate: 180deg;
1395
+ }
1396
+ }
1397
+
1398
+ & > .fig-overflow-end {
1399
+ order: 1;
1400
+ bottom: 0;
1401
+ margin-block-start: calc(-1 * var(--fig-select-overflow-size));
1402
+
1403
+ &::before {
1404
+ border-radius: 0 0 var(--radius-large) var(--radius-large);
1405
+ }
1406
+ }
1407
+
1408
+ & > fig-menu-separator {
1409
+ --fig-menu-separator-color: var(--figma-color-border-menu);
1410
+ --fig-menu-separator-label-color: var(--figma-color-text-menu-secondary);
1411
+ /* Align label with option text (padding + checkmark column). */
1412
+ --fig-menu-item-padding: calc(var(--spacer-1) * 2 + var(--spacer-1) + 1rem);
1413
+ &[label]:not([label=""]) {
1414
+ padding-left: var(--spacer-5);
1415
+ padding-right: var(--spacer-2);
1416
+ }
1417
+ }
1418
+ }
1419
+
1420
+ /*
1421
+ [label]:not([label=""]) {
1422
+ display: flex;
1423
+ flex-direction: column;
1424
+ gap: var(--spacer-2);
1425
+ height: auto;
1426
+ margin: var(--spacer-2) 0;
1427
+ margin-bottom: var(--spacer-1);
1428
+ padding: 0 var(--spacer-2) 0 var(--fig-menu-item-padding, var(--spacer-4));
1429
+ background: transparent;
1430
+
1431
+ &::before {
1432
+ content: "";
1433
+ display: block;
1434
+ height: 1px;
1435
+ margin-left: calc(-1 * var(--fig-menu-item-padding, var(--spacer-4)));
1436
+ margin-right: calc(-1 * var(--spacer-2));
1437
+ background: var(--fig-menu-separator-color);
1438
+ }
1439
+
1440
+ &::after {
1441
+ content: attr(label);
1442
+ display: block;
1443
+ color: var(--fig-menu-separator-label-color);
1444
+ line-height: var(--spacer-4);
1445
+ min-height: var(--spacer-4);
1446
+ }
1447
+ }*/
1448
+
1449
+ fig-select-option {
1450
+ /* Match fig-dropdown[experimental~="modern"] option + option::checkmark */
1451
+ display: flex;
1452
+ align-items: center;
1453
+ gap: var(--spacer-1);
1454
+ position: relative;
1455
+ height: var(--spacer-4);
1456
+ padding: 0 var(--spacer-2);
1457
+ border-radius: var(--radius-medium);
1458
+ color: var(--figma-color-text-menu);
1459
+ font-weight: var(--body-medium-fontWeight);
1460
+ cursor: default;
1461
+ user-select: none;
1462
+
1463
+ &::before {
1464
+ content: "";
1465
+ display: block;
1466
+ position: absolute;
1467
+ inset: 0 var(--spacer-2);
1468
+ border-radius: var(--radius-medium);
1469
+ z-index: -1;
1470
+ background-color: transparent;
1471
+ }
1472
+
1473
+ &::after {
1474
+ content: "";
1475
+ display: block;
1476
+ flex: 0 0 1rem;
1477
+ order: -1;
1478
+ width: 1rem;
1479
+ height: 1rem;
1480
+ margin-left: var(--spacer-1);
1481
+ background-color: currentColor;
1482
+ -webkit-mask-image: var(--icon-16-checkmark);
1483
+ mask-image: var(--icon-16-checkmark);
1484
+ -webkit-mask-repeat: no-repeat;
1485
+ mask-repeat: no-repeat;
1486
+ -webkit-mask-position: center;
1487
+ mask-position: center;
1488
+ -webkit-mask-size: contain;
1489
+ mask-size: contain;
1490
+ visibility: hidden;
1491
+ }
1492
+
1493
+ &:hover,
1494
+ &:focus-visible {
1495
+ outline: none;
1496
+
1497
+ &::before {
1498
+ background-color: var(--figma-color-bg-menu-hover);
1499
+ }
1500
+ }
1501
+
1502
+ &[selected]:not([selected="false"])::after,
1503
+ &[aria-selected="true"]::after {
1504
+ visibility: visible;
1505
+ }
1506
+
1507
+ &[disabled]:not([disabled="false"]),
1508
+ &[aria-disabled="true"] {
1509
+ opacity: 0.4;
1510
+ pointer-events: none;
1511
+ }
1512
+ }