@rogieking/figui3 6.15.0 → 6.17.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
@@ -83,6 +83,124 @@ propskit-switch {
83
83
  }
84
84
  }
85
85
 
86
+ propskit-color {
87
+ --propskit-color-height: 2rem;
88
+ --propskit-color-vertical-padding: var(--spacer-1);
89
+ --propskit-color-horizontal-padding: var(--spacer-3);
90
+ --figma-focus-outline-offset: 1px;
91
+
92
+ display: block;
93
+ width: 100%;
94
+ height: var(--propskit-color-height);
95
+ padding: var(--propskit-color-vertical-padding)
96
+ var(--propskit-color-horizontal-padding);
97
+
98
+ &[size="large"] {
99
+ --propskit-color-vertical-padding: 0px;
100
+ }
101
+
102
+ &[disabled]:not([disabled="false"]) {
103
+ pointer-events: none;
104
+
105
+ label {
106
+ color: var(--figma-color-text-disabled);
107
+ }
108
+ }
109
+
110
+ fig-field:not([direction="vertical"]) {
111
+ position: relative;
112
+ display: flex;
113
+ align-items: center;
114
+ gap: var(--spacer-2);
115
+ height: 100%;
116
+ padding-left: var(--spacer-2);
117
+ border-radius: var(--radius-medium);
118
+ background-color: var(--figma-color-bg-secondary);
119
+
120
+ &::after {
121
+ content: "";
122
+ position: absolute;
123
+ inset: 0;
124
+ border-radius: inherit;
125
+ pointer-events: none;
126
+ }
127
+
128
+ &:hover::after {
129
+ box-shadow: inset 0 0 0 1px var(--figma-color-bordertranslucent);
130
+ }
131
+
132
+ & > label {
133
+ position: relative;
134
+ z-index: 1;
135
+ display: flex;
136
+ align-items: center;
137
+ flex: 0 0 auto;
138
+ width: auto;
139
+ max-width: 50%;
140
+ min-width: 0;
141
+ margin: 0;
142
+ padding: 0;
143
+ overflow: hidden;
144
+ color: var(--figma-color-text-secondary);
145
+ text-overflow: ellipsis;
146
+ white-space: nowrap;
147
+ pointer-events: none;
148
+
149
+ fig-icon:first-child {
150
+ margin-left: calc(var(--spacer-1) * -1);
151
+ }
152
+ }
153
+
154
+ fig-input-color {
155
+ --figma-focus-outline-offset: 1px;
156
+
157
+ position: relative;
158
+ align-self: center;
159
+ flex: 0 1 auto !important;
160
+ width: fit-content !important;
161
+ max-width: none;
162
+ min-width: 0;
163
+ margin-left: auto;
164
+ height: calc(
165
+ var(--propskit-color-height) - var(--propskit-color-vertical-padding) * 2
166
+ );
167
+ border-radius: var(--radius-medium);
168
+ background-color: transparent;
169
+ box-shadow: none;
170
+
171
+ > .input-combo {
172
+ flex: 0 0 auto;
173
+ width: auto;
174
+ }
175
+
176
+ fig-input-text {
177
+ flex: 0 0 3.25rem;
178
+ width: 3.25rem;
179
+
180
+ input {
181
+ field-sizing: fixed;
182
+ box-sizing: border-box;
183
+ width: 100%;
184
+ min-width: 0;
185
+ }
186
+ }
187
+
188
+ fig-input-number {
189
+ flex: 0 0 3rem;
190
+ width: 3rem;
191
+ min-width: 3rem;
192
+
193
+ input {
194
+ field-sizing: fixed;
195
+ box-sizing: border-box;
196
+ width: 100%;
197
+ min-width: 0;
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+
86
204
  propskit-select {
87
205
  --propskit-select-height: 2rem;
88
206
  --propskit-select-vertical-padding: var(--spacer-1);
@@ -148,21 +266,21 @@ propskit-select {
148
266
  }
149
267
  }
150
268
 
151
- fig-dropdown {
269
+ fig-select {
152
270
  position: relative;
153
271
  flex: 0 0 auto;
154
272
  width: fit-content;
155
273
  min-width: 0;
156
274
  margin-left: auto;
157
275
  border-radius: var(--radius-medium);
276
+ background: transparent;
277
+ box-shadow: none;
158
278
 
159
- select {
160
- field-sizing: content;
161
- width: auto;
162
- min-width: 0;
163
- background: transparent;
164
- box-shadow: none;
279
+ &::after {
280
+ right: 0;
165
281
  }
282
+
283
+ --fig-select-trigger-width: auto;
166
284
  }
167
285
  }
168
286
  }
@@ -1120,3 +1238,269 @@ body.fig-reorder-dragging * {
1120
1238
  .fig-reorder-indicator[data-axis="horizontal"] {
1121
1239
  width: 2px;
1122
1240
  }
1241
+
1242
+ /* Select — host chrome; trigger/listbox live in shadow (options slotted) */
1243
+ fig-select {
1244
+ display: inline-flex;
1245
+ position: relative;
1246
+ align-items: center;
1247
+ min-width: 0;
1248
+ height: var(--spacer-4);
1249
+ border-radius: var(--radius-medium);
1250
+ background-color: var(--figma-color-bg);
1251
+ color: var(--figma-color-text);
1252
+ box-shadow: inset 0 0 0 1px var(--figma-color-border);
1253
+
1254
+ &[full]:not([full="false"]) {
1255
+ display: flex;
1256
+ width: 100%;
1257
+ }
1258
+
1259
+ &[disabled]:not([disabled="false"]) {
1260
+ pointer-events: none;
1261
+ &::after {
1262
+ background-color: var(--figma-color-icon-disabled);
1263
+ }
1264
+ }
1265
+
1266
+ &::after {
1267
+ content: "";
1268
+ position: absolute;
1269
+ right: 0.25rem;
1270
+ top: 50%;
1271
+ transform: translateY(-50%);
1272
+ width: 1rem;
1273
+ height: 1rem;
1274
+ mask-image: var(--icon-16-chevron);
1275
+ mask-size: contain;
1276
+ mask-repeat: no-repeat;
1277
+ mask-position: center;
1278
+ background-color: var(--figma-color-icon);
1279
+ pointer-events: none;
1280
+ z-index: 1;
1281
+ }
1282
+ }
1283
+
1284
+ /*
1285
+ * Internal listbox is a fig-popup inside fig-select's shadow, so document
1286
+ * dialog[is="fig-popup"] rules don't apply. Expose part=listbox and mirror
1287
+ * the menu-theme popup chrome (same tokens as components.css).
1288
+ */
1289
+ fig-select::part(listbox) {
1290
+ --z-index: 999999;
1291
+ --fig-popup-radius: var(--radius-large);
1292
+ --fig-popup-bg-color: var(--figma-color-bg-menu);
1293
+
1294
+ z-index: var(--z-index);
1295
+ position: fixed;
1296
+ inset: auto;
1297
+ margin: 0;
1298
+ border: 0;
1299
+ outline: 0;
1300
+ padding: 0;
1301
+ overflow: hidden;
1302
+ border-radius: var(--fig-popup-radius);
1303
+ background-color: var(--fig-popup-bg-color);
1304
+ color: var(--figma-color-text-menu);
1305
+ color-scheme: dark;
1306
+ box-shadow: var(--figma-elevation-100);
1307
+ /* width/min/max set in JS — ::part width rules override element.style. */
1308
+ max-height: min(20rem, calc(100vh - 1rem));
1309
+ height: max-content;
1310
+ }
1311
+
1312
+ /* Panel is the scroller; overflow uses top/bottom buttons (fig-chooser pattern). */
1313
+ fig-select-options {
1314
+ --fig-select-overflow-size: var(--spacer-4);
1315
+
1316
+ box-sizing: border-box;
1317
+ display: flex;
1318
+ flex-direction: column;
1319
+ gap: 0;
1320
+ width: 100%;
1321
+ max-width: 100%;
1322
+ max-height: min(20rem, calc(100vh - 1rem));
1323
+ /* No block padding — sticky overflow buttons must sit flush to the popup edges. */
1324
+ padding: 0;
1325
+ overflow: hidden auto;
1326
+ scrollbar-width: none;
1327
+
1328
+ &::-webkit-scrollbar {
1329
+ display: none;
1330
+ }
1331
+
1332
+ & > :not(.fig-overflow) {
1333
+ flex-shrink: 0;
1334
+ }
1335
+
1336
+ /* List breathing room (not on the scroller itself). */
1337
+ & > :not(.fig-overflow):first-child,
1338
+ & > .fig-overflow-start + :not(.fig-overflow) {
1339
+ margin-top: var(--spacer-2);
1340
+ }
1341
+
1342
+ & > :not(.fig-overflow):last-child,
1343
+ & > :not(.fig-overflow):has(+ .fig-overflow-end) {
1344
+ margin-bottom: var(--spacer-2);
1345
+ }
1346
+
1347
+ & > .fig-overflow {
1348
+ position: sticky;
1349
+ left: 0;
1350
+ flex: 0 0 var(--fig-select-overflow-size);
1351
+ width: 100%;
1352
+ height: var(--fig-select-overflow-size);
1353
+ margin: 0;
1354
+ z-index: 3;
1355
+ /* Menu chrome — not option hover (bg-menu-hover is brand blue). */
1356
+ color: var(--figma-color-text-menu);
1357
+ background: var(--figma-color-bg-menu) !important;
1358
+
1359
+ &::before {
1360
+ inset: 0;
1361
+ border-radius: 0;
1362
+ background: var(--figma-color-bg-menu) !important;
1363
+ }
1364
+
1365
+ &:hover::before {
1366
+ background: light-dark(
1367
+ rgba(0, 0, 0, 0.06),
1368
+ rgba(255, 255, 255, 0.08)
1369
+ )
1370
+ !important;
1371
+ }
1372
+
1373
+ &:hover {
1374
+ color: var(--figma-color-text-menu);
1375
+ }
1376
+ }
1377
+
1378
+ & > .fig-overflow-start {
1379
+ order: -1;
1380
+ top: 0;
1381
+ margin-block-end: calc(-1 * var(--fig-select-overflow-size));
1382
+
1383
+ &::before {
1384
+ border-radius: var(--radius-large) var(--radius-large) 0 0;
1385
+ }
1386
+
1387
+ .fig-overflow-chevron {
1388
+ rotate: 180deg;
1389
+ }
1390
+ }
1391
+
1392
+ & > .fig-overflow-end {
1393
+ order: 1;
1394
+ bottom: 0;
1395
+ margin-block-start: calc(-1 * var(--fig-select-overflow-size));
1396
+
1397
+ &::before {
1398
+ border-radius: 0 0 var(--radius-large) var(--radius-large);
1399
+ }
1400
+ }
1401
+
1402
+ & > fig-menu-separator {
1403
+ --fig-menu-separator-color: var(--figma-color-border-menu);
1404
+ --fig-menu-separator-label-color: var(--figma-color-text-menu-secondary);
1405
+ /* Align label with option text (padding + checkmark column). */
1406
+ --fig-menu-item-padding: calc(var(--spacer-1) * 2 + var(--spacer-1) + 1rem);
1407
+ &[label]:not([label=""]) {
1408
+ padding-left: var(--spacer-5);
1409
+ padding-right: var(--spacer-2);
1410
+ }
1411
+ }
1412
+ }
1413
+
1414
+ /*
1415
+ [label]:not([label=""]) {
1416
+ display: flex;
1417
+ flex-direction: column;
1418
+ gap: var(--spacer-2);
1419
+ height: auto;
1420
+ margin: var(--spacer-2) 0;
1421
+ margin-bottom: var(--spacer-1);
1422
+ padding: 0 var(--spacer-2) 0 var(--fig-menu-item-padding, var(--spacer-4));
1423
+ background: transparent;
1424
+
1425
+ &::before {
1426
+ content: "";
1427
+ display: block;
1428
+ height: 1px;
1429
+ margin-left: calc(-1 * var(--fig-menu-item-padding, var(--spacer-4)));
1430
+ margin-right: calc(-1 * var(--spacer-2));
1431
+ background: var(--fig-menu-separator-color);
1432
+ }
1433
+
1434
+ &::after {
1435
+ content: attr(label);
1436
+ display: block;
1437
+ color: var(--fig-menu-separator-label-color);
1438
+ line-height: var(--spacer-4);
1439
+ min-height: var(--spacer-4);
1440
+ }
1441
+ }*/
1442
+
1443
+ fig-select-option {
1444
+ /* Match fig-dropdown[experimental~="modern"] option + option::checkmark */
1445
+ display: flex;
1446
+ align-items: center;
1447
+ gap: var(--spacer-1);
1448
+ position: relative;
1449
+ height: var(--spacer-4);
1450
+ padding: 0 var(--spacer-2);
1451
+ border-radius: var(--radius-medium);
1452
+ color: var(--figma-color-text-menu);
1453
+ font-weight: var(--body-medium-fontWeight);
1454
+ cursor: default;
1455
+ user-select: none;
1456
+
1457
+ &::before {
1458
+ content: "";
1459
+ display: block;
1460
+ position: absolute;
1461
+ inset: 0 var(--spacer-2);
1462
+ border-radius: var(--radius-medium);
1463
+ z-index: -1;
1464
+ background-color: transparent;
1465
+ }
1466
+
1467
+ &::after {
1468
+ content: "";
1469
+ display: block;
1470
+ flex: 0 0 1rem;
1471
+ order: -1;
1472
+ width: 1rem;
1473
+ height: 1rem;
1474
+ margin-left: var(--spacer-1);
1475
+ background-color: currentColor;
1476
+ -webkit-mask-image: var(--icon-16-checkmark);
1477
+ mask-image: var(--icon-16-checkmark);
1478
+ -webkit-mask-repeat: no-repeat;
1479
+ mask-repeat: no-repeat;
1480
+ -webkit-mask-position: center;
1481
+ mask-position: center;
1482
+ -webkit-mask-size: contain;
1483
+ mask-size: contain;
1484
+ visibility: hidden;
1485
+ }
1486
+
1487
+ &:hover,
1488
+ &:focus-visible {
1489
+ outline: none;
1490
+
1491
+ &::before {
1492
+ background-color: var(--figma-color-bg-menu-hover);
1493
+ }
1494
+ }
1495
+
1496
+ &[selected]:not([selected="false"])::after,
1497
+ &[aria-selected="true"]::after {
1498
+ visibility: visible;
1499
+ }
1500
+
1501
+ &[disabled]:not([disabled="false"]),
1502
+ &[aria-disabled="true"] {
1503
+ opacity: 0.4;
1504
+ pointer-events: none;
1505
+ }
1506
+ }