@rogieking/figui3 4.1.4 → 4.3.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/components.css +211 -207
- package/fig.js +380 -2
- package/package.json +1 -1
package/components.css
CHANGED
|
@@ -1036,7 +1036,6 @@ fig-tab,
|
|
|
1036
1036
|
}
|
|
1037
1037
|
}
|
|
1038
1038
|
|
|
1039
|
-
&:has(:checked),
|
|
1040
1039
|
&[selected]:not([selected="false"]) {
|
|
1041
1040
|
background-color: var(--figma-color-bg-secondary);
|
|
1042
1041
|
font-weight: var(--body-medium-strong-fontWeight);
|
|
@@ -1046,22 +1045,13 @@ fig-tab,
|
|
|
1046
1045
|
&:hover {
|
|
1047
1046
|
background-color: var(--figma-color-bg-secondary);
|
|
1048
1047
|
}
|
|
1049
|
-
|
|
1050
|
-
& [type="radio"] {
|
|
1051
|
-
position: absolute;
|
|
1052
|
-
inset: 0;
|
|
1053
|
-
border-radius: 0;
|
|
1054
|
-
opacity: 0;
|
|
1055
|
-
z-index: 1;
|
|
1056
|
-
width: 100%;
|
|
1057
|
-
height: 100%;
|
|
1058
|
-
}
|
|
1059
1048
|
}
|
|
1060
1049
|
|
|
1061
1050
|
fig-tabs,
|
|
1062
1051
|
.tabs {
|
|
1063
1052
|
display: flex;
|
|
1064
|
-
gap: var(--spacer-
|
|
1053
|
+
gap: var(--spacer-1);
|
|
1054
|
+
padding: var(--spacer-1) var(--spacer-2);
|
|
1065
1055
|
}
|
|
1066
1056
|
|
|
1067
1057
|
fig-tab-content,
|
|
@@ -1990,52 +1980,52 @@ input[type="checkbox"].switch {
|
|
|
1990
1980
|
transition: var(--input-transition);
|
|
1991
1981
|
box-shadow: var(--handle-shadow);
|
|
1992
1982
|
}
|
|
1993
|
-
}
|
|
1994
|
-
|
|
1995
|
-
input[type="checkbox"].switch[indeterminate="true"]:after {
|
|
1996
|
-
width: 0.625rem;
|
|
1997
|
-
height: 0.125rem;
|
|
1998
|
-
transform: none;
|
|
1999
|
-
}
|
|
2000
1983
|
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
1984
|
+
&[indeterminate="true"]:after {
|
|
1985
|
+
width: 0.625rem;
|
|
1986
|
+
height: 0.125rem;
|
|
1987
|
+
transform: none;
|
|
1988
|
+
}
|
|
2005
1989
|
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
(var(--height) - var(--knob-height)) * -0.5
|
|
2011
|
-
)
|
|
2012
|
-
);
|
|
2013
|
-
}
|
|
1990
|
+
&[indeterminate="true"],
|
|
1991
|
+
&:checked {
|
|
1992
|
+
background-color: var(--figma-color-bg-brand);
|
|
1993
|
+
}
|
|
2014
1994
|
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
1995
|
+
&:checked:after {
|
|
1996
|
+
transform: translate(
|
|
1997
|
+
calc(
|
|
1998
|
+
(var(--width) - var(--knob-width)) * 0.5 +
|
|
1999
|
+
(var(--height) - var(--knob-height)) * -0.5
|
|
2000
|
+
)
|
|
2001
|
+
);
|
|
2021
2002
|
}
|
|
2022
2003
|
|
|
2023
|
-
&:
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
box-shadow: none;
|
|
2004
|
+
&:disabled {
|
|
2005
|
+
background-color: transparent;
|
|
2006
|
+
cursor: not-allowed;
|
|
2027
2007
|
&:after {
|
|
2028
|
-
background-color: var(--figma-color-
|
|
2008
|
+
background-color: var(--figma-color-icon-disabled);
|
|
2009
|
+
box-shadow: none;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
&:checked,
|
|
2013
|
+
&[indeterminate="true"] {
|
|
2014
|
+
background-color: var(--figma-color-bg-disabled);
|
|
2015
|
+
box-shadow: none;
|
|
2016
|
+
&:after {
|
|
2017
|
+
background-color: var(--figma-color-bg);
|
|
2018
|
+
}
|
|
2029
2019
|
}
|
|
2030
2020
|
}
|
|
2031
|
-
}
|
|
2032
2021
|
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
}
|
|
2022
|
+
&:focus {
|
|
2023
|
+
outline: 0;
|
|
2024
|
+
}
|
|
2036
2025
|
|
|
2037
|
-
|
|
2038
|
-
|
|
2026
|
+
&:checked:focus {
|
|
2027
|
+
outline: 0;
|
|
2028
|
+
}
|
|
2039
2029
|
}
|
|
2040
2030
|
|
|
2041
2031
|
/* Checkbox */
|
|
@@ -2143,6 +2133,22 @@ input[type="radio"] {
|
|
|
2143
2133
|
}
|
|
2144
2134
|
}
|
|
2145
2135
|
|
|
2136
|
+
&:disabled {
|
|
2137
|
+
background-color: transparent;
|
|
2138
|
+
cursor: not-allowed;
|
|
2139
|
+
&:after {
|
|
2140
|
+
background-color: var(--figma-color-icon-disabled);
|
|
2141
|
+
box-shadow: none;
|
|
2142
|
+
}
|
|
2143
|
+
&:checked {
|
|
2144
|
+
background-color: var(--figma-color-bg-disabled);
|
|
2145
|
+
box-shadow: none;
|
|
2146
|
+
&:after {
|
|
2147
|
+
background-color: var(--figma-color-icon-disabled);
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2146
2152
|
&::after {
|
|
2147
2153
|
content: "";
|
|
2148
2154
|
width: 0.375rem;
|
|
@@ -2242,7 +2248,6 @@ details {
|
|
|
2242
2248
|
}
|
|
2243
2249
|
|
|
2244
2250
|
/* Sliders */
|
|
2245
|
-
.fig-slider,
|
|
2246
2251
|
fig-slider {
|
|
2247
2252
|
--slider-field-height: 1.5rem;
|
|
2248
2253
|
--slider-height: 1rem;
|
|
@@ -2274,17 +2279,28 @@ fig-slider {
|
|
|
2274
2279
|
--slider-transition: none;
|
|
2275
2280
|
--handle-transition: var(--slider-transition);
|
|
2276
2281
|
|
|
2277
|
-
display:
|
|
2282
|
+
display: flex;
|
|
2278
2283
|
align-items: center;
|
|
2279
2284
|
position: relative;
|
|
2285
|
+
min-width: 0;
|
|
2280
2286
|
height: var(--slider-field-height);
|
|
2281
2287
|
transition: var(--slider-transition);
|
|
2282
2288
|
|
|
2289
|
+
& .slider {
|
|
2290
|
+
flex: 1 1 0;
|
|
2291
|
+
min-width: 0;
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2294
|
+
& fig-input-number {
|
|
2295
|
+
flex: 0 0 3rem;
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2283
2298
|
.fig-slider-input-container {
|
|
2284
2299
|
height: var(--slider-height);
|
|
2285
2300
|
position: relative;
|
|
2286
2301
|
display: block;
|
|
2287
|
-
|
|
2302
|
+
flex: 1 1 0;
|
|
2303
|
+
min-width: 0;
|
|
2288
2304
|
transition: var(--slider-transition);
|
|
2289
2305
|
background: var(--figma-color-bg-secondary);
|
|
2290
2306
|
border-radius: var(--slider-border-radius);
|
|
@@ -2356,31 +2372,36 @@ fig-slider {
|
|
|
2356
2372
|
}
|
|
2357
2373
|
}
|
|
2358
2374
|
|
|
2359
|
-
/* Chromium */
|
|
2360
2375
|
input[type="range"] {
|
|
2361
2376
|
height: var(--slider-height);
|
|
2362
2377
|
appearance: none;
|
|
2363
2378
|
-webkit-appearance: none;
|
|
2379
|
+
-moz-appearance: none;
|
|
2364
2380
|
border-radius: var(--slider-border-radius);
|
|
2365
2381
|
display: block;
|
|
2366
2382
|
width: 100%;
|
|
2383
|
+
min-width: 0;
|
|
2367
2384
|
background-color: transparent;
|
|
2368
2385
|
transition: var(--slider-transition);
|
|
2369
2386
|
position: relative;
|
|
2370
2387
|
|
|
2371
|
-
&:active::-webkit-slider-thumb {
|
|
2372
|
-
cursor: grabbing;
|
|
2373
|
-
cursor: -webkit-grabbing;
|
|
2374
|
-
}
|
|
2375
|
-
|
|
2376
2388
|
&:focus {
|
|
2377
2389
|
outline: none;
|
|
2378
2390
|
}
|
|
2379
2391
|
|
|
2392
|
+
&:disabled {
|
|
2393
|
+
cursor: not-allowed;
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
/* Chromium thumb */
|
|
2397
|
+
&:active::-webkit-slider-thumb {
|
|
2398
|
+
cursor: grabbing;
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2380
2401
|
&::-webkit-slider-thumb {
|
|
2381
2402
|
appearance: none;
|
|
2382
|
-
background: transparent;
|
|
2383
2403
|
-webkit-appearance: none;
|
|
2404
|
+
background: transparent;
|
|
2384
2405
|
color-scheme: inherit;
|
|
2385
2406
|
transition: var(--handle-transition);
|
|
2386
2407
|
border-radius: var(--slider-thumb-radius);
|
|
@@ -2391,7 +2412,6 @@ fig-slider {
|
|
|
2391
2412
|
);
|
|
2392
2413
|
outline: var(--slider-thumb-outline);
|
|
2393
2414
|
outline-offset: var(--slider-thumb-outline-offset);
|
|
2394
|
-
|
|
2395
2415
|
aspect-ratio: 1;
|
|
2396
2416
|
border: none;
|
|
2397
2417
|
position: relative;
|
|
@@ -2401,22 +2421,8 @@ fig-slider {
|
|
|
2401
2421
|
opacity: var(--slider-thumb-opacity);
|
|
2402
2422
|
}
|
|
2403
2423
|
|
|
2404
|
-
&:disabled {
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
&::-webkit-slider-runnable-track {
|
|
2408
|
-
color-scheme: inherit;
|
|
2409
|
-
background: linear-gradient(
|
|
2410
|
-
to right,
|
|
2411
|
-
var(--figma-color-bg-secondary) 0%,
|
|
2412
|
-
var(--figma-color-bg-secondary) var(--slider-percent),
|
|
2413
|
-
var(--figma-color-bg) var(--slider-percent)
|
|
2414
|
-
);
|
|
2415
|
-
}
|
|
2416
|
-
|
|
2417
|
-
&::-webkit-slider-thumb {
|
|
2418
|
-
box-shadow: inset 0 0 0 1rem var(--figma-color-bg-disabled);
|
|
2419
|
-
}
|
|
2424
|
+
&:disabled::-webkit-slider-thumb {
|
|
2425
|
+
box-shadow: inset 0 0 0 1rem var(--figma-color-bg-disabled);
|
|
2420
2426
|
}
|
|
2421
2427
|
|
|
2422
2428
|
&::-webkit-slider-runnable-track {
|
|
@@ -2427,6 +2433,15 @@ fig-slider {
|
|
|
2427
2433
|
border-radius: var(--slider-border-radius);
|
|
2428
2434
|
}
|
|
2429
2435
|
|
|
2436
|
+
&:disabled::-webkit-slider-runnable-track {
|
|
2437
|
+
background: linear-gradient(
|
|
2438
|
+
to right,
|
|
2439
|
+
var(--figma-color-bg-secondary) 0%,
|
|
2440
|
+
var(--figma-color-bg-secondary) var(--slider-percent),
|
|
2441
|
+
var(--figma-color-bg) var(--slider-percent)
|
|
2442
|
+
);
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2430
2445
|
&.hue::-webkit-slider-runnable-track {
|
|
2431
2446
|
background: var(--bg-hue);
|
|
2432
2447
|
}
|
|
@@ -2436,34 +2451,18 @@ fig-slider {
|
|
|
2436
2451
|
linear-gradient(to right, transparent, var(--color)),
|
|
2437
2452
|
var(--checkerboard);
|
|
2438
2453
|
}
|
|
2439
|
-
}
|
|
2440
|
-
|
|
2441
|
-
/* Firefox */
|
|
2442
|
-
input[type="range"] {
|
|
2443
|
-
height: var(--slider-height);
|
|
2444
|
-
appearance: none;
|
|
2445
|
-
-moz-appearance: none;
|
|
2446
|
-
border-radius: var(--slider-border-radius);
|
|
2447
|
-
display: block;
|
|
2448
|
-
width: 100%;
|
|
2449
|
-
background-color: transparent;
|
|
2450
|
-
transition: var(--slider-transition);
|
|
2451
|
-
position: relative;
|
|
2452
|
-
|
|
2453
|
-
&:focus {
|
|
2454
|
-
outline: none;
|
|
2455
|
-
}
|
|
2456
2454
|
|
|
2455
|
+
/* Firefox thumb */
|
|
2457
2456
|
&:active::-moz-range-thumb {
|
|
2458
2457
|
cursor: grabbing;
|
|
2459
|
-
cursor: -webkit-grabbing;
|
|
2460
2458
|
}
|
|
2461
2459
|
|
|
2462
2460
|
&::-moz-range-thumb {
|
|
2463
|
-
color-scheme: inherit;
|
|
2464
2461
|
appearance: none;
|
|
2465
2462
|
-moz-appearance: none;
|
|
2466
2463
|
background: transparent;
|
|
2464
|
+
color-scheme: inherit;
|
|
2465
|
+
transition: var(--handle-transition);
|
|
2467
2466
|
border-radius: var(--slider-thumb-radius);
|
|
2468
2467
|
height: var(--slider-thumb-height);
|
|
2469
2468
|
width: var(--slider-thumb-width);
|
|
@@ -2475,26 +2474,11 @@ fig-slider {
|
|
|
2475
2474
|
z-index: 1;
|
|
2476
2475
|
cursor: default;
|
|
2477
2476
|
box-shadow: var(--slider-handle-shadow);
|
|
2478
|
-
transition: var(--handle-transition);
|
|
2479
2477
|
opacity: var(--slider-thumb-opacity);
|
|
2480
2478
|
}
|
|
2481
2479
|
|
|
2482
|
-
&:disabled {
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
&::-moz-range-track {
|
|
2486
|
-
color-scheme: inherit;
|
|
2487
|
-
background: linear-gradient(
|
|
2488
|
-
to right,
|
|
2489
|
-
var(--figma-color-bg-secondary) 0%,
|
|
2490
|
-
var(--figma-color-bg-secondary) var(--slider-percent),
|
|
2491
|
-
var(--figma-color-bg) var(--slider-percent)
|
|
2492
|
-
);
|
|
2493
|
-
}
|
|
2494
|
-
|
|
2495
|
-
&::-moz-range-thumb {
|
|
2496
|
-
box-shadow: inset 0 0 0 1rem var(--figma-color-bg-disabled);
|
|
2497
|
-
}
|
|
2480
|
+
&:disabled::-moz-range-thumb {
|
|
2481
|
+
box-shadow: inset 0 0 0 1rem var(--figma-color-bg-disabled);
|
|
2498
2482
|
}
|
|
2499
2483
|
|
|
2500
2484
|
&::-moz-range-track {
|
|
@@ -2504,6 +2488,15 @@ fig-slider {
|
|
|
2504
2488
|
transition: var(--slider-transition);
|
|
2505
2489
|
}
|
|
2506
2490
|
|
|
2491
|
+
&:disabled::-moz-range-track {
|
|
2492
|
+
background: linear-gradient(
|
|
2493
|
+
to right,
|
|
2494
|
+
var(--figma-color-bg-secondary) 0%,
|
|
2495
|
+
var(--figma-color-bg-secondary) var(--slider-percent),
|
|
2496
|
+
var(--figma-color-bg) var(--slider-percent)
|
|
2497
|
+
);
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2507
2500
|
&.hue::-moz-range-track {
|
|
2508
2501
|
background: var(--bg-hue);
|
|
2509
2502
|
}
|
|
@@ -2584,7 +2577,7 @@ fig-slider {
|
|
|
2584
2577
|
}
|
|
2585
2578
|
fig-input-text,
|
|
2586
2579
|
fig-input-number {
|
|
2587
|
-
flex-basis:
|
|
2580
|
+
flex-basis: 3rem;
|
|
2588
2581
|
border-top-left-radius: 0;
|
|
2589
2582
|
border-bottom-left-radius: 0;
|
|
2590
2583
|
border-left: 1px solid var(--figma-color-bg);
|
|
@@ -2617,7 +2610,8 @@ dialog,
|
|
|
2617
2610
|
|
|
2618
2611
|
box-shadow: var(--figma-elevation-500-modal-window);
|
|
2619
2612
|
|
|
2620
|
-
footer
|
|
2613
|
+
footer,
|
|
2614
|
+
fig-footer {
|
|
2621
2615
|
display: flex;
|
|
2622
2616
|
justify-content: flex-end;
|
|
2623
2617
|
padding: var(--spacer-2);
|
|
@@ -2693,6 +2687,19 @@ dialog,
|
|
|
2693
2687
|
dialog[is="fig-dialog"] {
|
|
2694
2688
|
--z-index: 999999;
|
|
2695
2689
|
z-index: var(--z-index);
|
|
2690
|
+
|
|
2691
|
+
&[resizable]:not([resizable="false"]) {
|
|
2692
|
+
resize: both;
|
|
2693
|
+
overflow: auto;
|
|
2694
|
+
min-width: 12rem;
|
|
2695
|
+
min-height: 6rem;
|
|
2696
|
+
}
|
|
2697
|
+
& > fig-header[dialog-header]:not([borderless]):not([borderless="false"]) {
|
|
2698
|
+
margin-bottom: var(--spacer-2-5);
|
|
2699
|
+
}
|
|
2700
|
+
& > fig-footer:not([borderless]):not([borderless="false"]) {
|
|
2701
|
+
margin-top: var(--spacer-2-5);
|
|
2702
|
+
}
|
|
2696
2703
|
}
|
|
2697
2704
|
|
|
2698
2705
|
dialog[is="fig-popup"] {
|
|
@@ -2948,7 +2955,6 @@ fig-input-fill,
|
|
|
2948
2955
|
fig-checkbox,
|
|
2949
2956
|
fig-radio,
|
|
2950
2957
|
fig-tab,
|
|
2951
|
-
fig-tabs,
|
|
2952
2958
|
fig-segmented-control,
|
|
2953
2959
|
fig-input-palette {
|
|
2954
2960
|
display: inline-flex;
|
|
@@ -3013,7 +3019,7 @@ fig-header {
|
|
|
3013
3019
|
|
|
3014
3020
|
fig-group {
|
|
3015
3021
|
display: block;
|
|
3016
|
-
|
|
3022
|
+
margin-bottom: var(--spacer-2-5);
|
|
3017
3023
|
|
|
3018
3024
|
/* Sibling groups */
|
|
3019
3025
|
& + fig-group {
|
|
@@ -3021,9 +3027,6 @@ fig-group {
|
|
|
3021
3027
|
&:not([name]) {
|
|
3022
3028
|
padding-top: var(--spacer-2-5);
|
|
3023
3029
|
}
|
|
3024
|
-
&:last-of-type {
|
|
3025
|
-
padding-bottom: 0;
|
|
3026
|
-
}
|
|
3027
3030
|
}
|
|
3028
3031
|
|
|
3029
3032
|
& > fig-header {
|
|
@@ -3048,7 +3051,7 @@ fig-group {
|
|
|
3048
3051
|
|
|
3049
3052
|
&[collapsible]:not([open]):not([open="true"]),
|
|
3050
3053
|
&[collapsible][open="false"] {
|
|
3051
|
-
|
|
3054
|
+
margin-bottom: 0;
|
|
3052
3055
|
fig-header {
|
|
3053
3056
|
color: var(--figma-color-text-secondary);
|
|
3054
3057
|
&:hover {
|
|
@@ -3412,7 +3415,7 @@ fig-input-palette {
|
|
|
3412
3415
|
}
|
|
3413
3416
|
&[open]:not([open="false"]):not([edit="false"]) {
|
|
3414
3417
|
.palette-colors-expanded {
|
|
3415
|
-
display:
|
|
3418
|
+
display: grid;
|
|
3416
3419
|
}
|
|
3417
3420
|
}
|
|
3418
3421
|
&[add="false"] {
|
|
@@ -3423,7 +3426,7 @@ fig-input-palette {
|
|
|
3423
3426
|
}
|
|
3424
3427
|
.palette-colors-expanded {
|
|
3425
3428
|
display: none;
|
|
3426
|
-
|
|
3429
|
+
grid-template-columns: [input] 1fr [button] 1.5rem;
|
|
3427
3430
|
overflow: visible;
|
|
3428
3431
|
border-radius: 0;
|
|
3429
3432
|
gap: var(--spacer-2);
|
|
@@ -3431,6 +3434,16 @@ fig-input-palette {
|
|
|
3431
3434
|
|
|
3432
3435
|
> fig-input-color {
|
|
3433
3436
|
min-width: 0;
|
|
3437
|
+
grid-column: input / -1;
|
|
3438
|
+
|
|
3439
|
+
&:has(+ fig-button) {
|
|
3440
|
+
grid-column: input;
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3443
|
+
|
|
3444
|
+
> fig-button,
|
|
3445
|
+
> button {
|
|
3446
|
+
grid-column: button;
|
|
3434
3447
|
}
|
|
3435
3448
|
|
|
3436
3449
|
fig-chit {
|
|
@@ -3442,39 +3455,27 @@ fig-input-palette {
|
|
|
3442
3455
|
}
|
|
3443
3456
|
}
|
|
3444
3457
|
|
|
3445
|
-
fig-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
fig-field,
|
|
3463
|
-
.fig-field {
|
|
3464
|
-
--field-label-width: 4rem;
|
|
3465
|
-
display: flex;
|
|
3466
|
-
padding: var(--spacer-1) var(--spacer-3);
|
|
3458
|
+
fig-field {
|
|
3459
|
+
--fig-field-gap: var(--spacer-2);
|
|
3460
|
+
--fig-field-left-padding: var(--spacer-3);
|
|
3461
|
+
--fig-field-right-padding: var(--spacer-3);
|
|
3462
|
+
--fig-field-top-padding: var(--spacer-1);
|
|
3463
|
+
--fig-field-bottom-padding: var(--spacer-1);
|
|
3464
|
+
--fig-field-label-ratio: 1fr;
|
|
3465
|
+
--fig-field-input-ratio: 2fr;
|
|
3466
|
+
display: grid;
|
|
3467
|
+
grid-template-columns: var(--fig-field-left-padding) 1fr var(
|
|
3468
|
+
--fig-field-right-padding
|
|
3469
|
+
);
|
|
3470
|
+
grid-template-rows: auto auto;
|
|
3471
|
+
grid-template-areas:
|
|
3472
|
+
"chevron label pad"
|
|
3473
|
+
". input pad";
|
|
3467
3474
|
margin: 0;
|
|
3468
|
-
|
|
3475
|
+
padding: var(--fig-field-top-padding) 0 var(--fig-field-bottom-padding) 0;
|
|
3469
3476
|
gap: 0;
|
|
3470
3477
|
align-items: start;
|
|
3471
3478
|
|
|
3472
|
-
&[direction="horizontal"] {
|
|
3473
|
-
flex-direction: row;
|
|
3474
|
-
align-items: center;
|
|
3475
|
-
gap: var(--spacer-2);
|
|
3476
|
-
}
|
|
3477
|
-
|
|
3478
3479
|
& > [full] {
|
|
3479
3480
|
flex: 1 1 auto;
|
|
3480
3481
|
}
|
|
@@ -3485,15 +3486,17 @@ fig-field,
|
|
|
3485
3486
|
}
|
|
3486
3487
|
|
|
3487
3488
|
& > label {
|
|
3488
|
-
|
|
3489
|
+
grid-area: label;
|
|
3490
|
+
display: block;
|
|
3489
3491
|
padding: var(--spacer-1) 0;
|
|
3490
|
-
|
|
3491
|
-
display: flex;
|
|
3492
|
-
align-items: center;
|
|
3493
|
-
width: 100%;
|
|
3492
|
+
line-height: 1rem;
|
|
3494
3493
|
user-select: none;
|
|
3495
3494
|
}
|
|
3496
3495
|
|
|
3496
|
+
& > *:not(.fig-field-chevron):not(label) {
|
|
3497
|
+
grid-area: input;
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3497
3500
|
& > .fig-field-chevron {
|
|
3498
3501
|
--icon: var(--icon-chevron);
|
|
3499
3502
|
--size: 1rem;
|
|
@@ -3502,64 +3505,37 @@ fig-field,
|
|
|
3502
3505
|
transition: transform var(--transition-duration)
|
|
3503
3506
|
var(--transition-timing-function);
|
|
3504
3507
|
flex-shrink: 0;
|
|
3505
|
-
|
|
3506
|
-
margin-
|
|
3507
|
-
margin-right: calc(var(--spacer-2) * -1);
|
|
3508
|
+
grid-area: chevron;
|
|
3509
|
+
margin-top: var(--spacer-1);
|
|
3508
3510
|
}
|
|
3509
3511
|
|
|
3510
3512
|
&:has(> [open]:not([open="false"])) > .fig-field-chevron {
|
|
3511
3513
|
transform: rotate(0deg);
|
|
3512
3514
|
}
|
|
3513
3515
|
|
|
3514
|
-
&[direction="horizontal"] > label {
|
|
3515
|
-
display: block;
|
|
3516
|
-
width: auto;
|
|
3517
|
-
min-width: var(--field-label-width);
|
|
3518
|
-
max-width: var(--field-label-width);
|
|
3519
|
-
overflow: hidden;
|
|
3520
|
-
text-overflow: ellipsis;
|
|
3521
|
-
white-space: nowrap;
|
|
3522
|
-
padding: 0;
|
|
3523
|
-
line-height: 1.5rem;
|
|
3524
|
-
}
|
|
3525
|
-
|
|
3526
3516
|
&[direction="horizontal"] {
|
|
3527
|
-
|
|
3517
|
+
display: grid;
|
|
3518
|
+
grid-template-columns:
|
|
3519
|
+
var(--fig-field-left-padding) minmax(0, var(--fig-field-label-ratio))
|
|
3520
|
+
minmax(0, var(--fig-field-input-ratio)) var(--fig-field-right-padding);
|
|
3521
|
+
grid-template-areas: "chevron label input pad";
|
|
3522
|
+
gap: 0;
|
|
3528
3523
|
align-items: start;
|
|
3529
|
-
flex-direction: row;
|
|
3530
|
-
&[columns="thirds"] {
|
|
3531
|
-
display: grid;
|
|
3532
|
-
grid-template-columns: repeat(3, 1fr);
|
|
3533
|
-
gap: var(--spacer-2);
|
|
3534
|
-
|
|
3535
|
-
& > label {
|
|
3536
|
-
grid-column: 1;
|
|
3537
|
-
}
|
|
3538
|
-
|
|
3539
|
-
& > label ~ * {
|
|
3540
|
-
grid-column: 2 / span 2;
|
|
3541
|
-
}
|
|
3542
3524
|
|
|
3543
|
-
&:not(:has(> label)) > * {
|
|
3544
|
-
grid-column: 1 / -1;
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
3525
|
&[columns="half"] {
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
grid-column: 1 / -1;
|
|
3562
|
-
}
|
|
3526
|
+
--fig-field-label-ratio: 2fr;
|
|
3527
|
+
}
|
|
3528
|
+
& > label {
|
|
3529
|
+
overflow: hidden;
|
|
3530
|
+
text-overflow: ellipsis;
|
|
3531
|
+
white-space: nowrap;
|
|
3532
|
+
padding-right: var(--fig-field-gap);
|
|
3533
|
+
min-width: 0;
|
|
3534
|
+
}
|
|
3535
|
+
/* If the field has no label, set the input ratio to 1fr */
|
|
3536
|
+
&:not(:has(> label)) {
|
|
3537
|
+
--fig-field-input-ratio: 1fr;
|
|
3538
|
+
--fig-field-label-ratio: 0fr;
|
|
3563
3539
|
}
|
|
3564
3540
|
}
|
|
3565
3541
|
}
|
|
@@ -3617,14 +3593,18 @@ fig-segmented-control {
|
|
|
3617
3593
|
|
|
3618
3594
|
& fig-segment {
|
|
3619
3595
|
flex: 1 1 0;
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3596
|
+
min-width: 0;
|
|
3597
|
+
display: block;
|
|
3598
|
+
text-align: center;
|
|
3599
|
+
line-height: calc(1.5rem - 2px);
|
|
3623
3600
|
position: relative;
|
|
3624
3601
|
z-index: 1;
|
|
3625
3602
|
appearance: none;
|
|
3626
3603
|
color: var(--figma-color-text-secondary);
|
|
3627
3604
|
padding: 0 var(--spacer-2);
|
|
3605
|
+
overflow: hidden;
|
|
3606
|
+
text-overflow: ellipsis;
|
|
3607
|
+
white-space: nowrap;
|
|
3628
3608
|
transition: none;
|
|
3629
3609
|
|
|
3630
3610
|
&[selected]:not([selected="false"]),
|
|
@@ -3708,6 +3688,21 @@ fig-segmented-control {
|
|
|
3708
3688
|
}
|
|
3709
3689
|
}
|
|
3710
3690
|
|
|
3691
|
+
/* Options */
|
|
3692
|
+
fig-options {
|
|
3693
|
+
display: flex;
|
|
3694
|
+
width: 100%;
|
|
3695
|
+
|
|
3696
|
+
& > fig-segmented-control {
|
|
3697
|
+
flex: 1;
|
|
3698
|
+
min-width: 0;
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3701
|
+
& > fig-dropdown {
|
|
3702
|
+
flex: 1;
|
|
3703
|
+
}
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3711
3706
|
fig-joystick {
|
|
3712
3707
|
--size: 100%;
|
|
3713
3708
|
--aspect-ratio: 1 / 1;
|
|
@@ -4547,13 +4542,16 @@ fig-chooser {
|
|
|
4547
4542
|
|
|
4548
4543
|
display: flex;
|
|
4549
4544
|
flex-direction: column;
|
|
4550
|
-
gap:
|
|
4545
|
+
gap: 0;
|
|
4551
4546
|
overflow: visible auto;
|
|
4552
4547
|
scrollbar-width: none;
|
|
4553
4548
|
scroll-snap-type: y mandatory;
|
|
4554
4549
|
|
|
4555
4550
|
> * {
|
|
4556
4551
|
scroll-snap-align: start;
|
|
4552
|
+
&:not(.fig-chooser-nav-start):not(.fig-chooser-nav-end) {
|
|
4553
|
+
margin-block-end: var(--fig-chooser-gap);
|
|
4554
|
+
}
|
|
4557
4555
|
}
|
|
4558
4556
|
|
|
4559
4557
|
&[padding="false"] {
|
|
@@ -4585,6 +4583,12 @@ fig-chooser {
|
|
|
4585
4583
|
fig-image[full] {
|
|
4586
4584
|
min-width: 3rem;
|
|
4587
4585
|
}
|
|
4586
|
+
> * {
|
|
4587
|
+
&:not(.fig-chooser-nav-start):not(.fig-chooser-nav-end) {
|
|
4588
|
+
margin-inline-end: var(--fig-chooser-gap);
|
|
4589
|
+
margin-block-end: 0;
|
|
4590
|
+
}
|
|
4591
|
+
}
|
|
4588
4592
|
}
|
|
4589
4593
|
|
|
4590
4594
|
&[layout="grid"] {
|
package/fig.js
CHANGED
|
@@ -517,6 +517,8 @@ class FigTooltip extends HTMLElement {
|
|
|
517
517
|
#boundHandleTouchMove;
|
|
518
518
|
#boundHandleTouchEnd;
|
|
519
519
|
#boundHandleTouchCancel;
|
|
520
|
+
#boundHandleDialogClose;
|
|
521
|
+
#parentDialog = null;
|
|
520
522
|
#touchTimeout;
|
|
521
523
|
#isTouching = false;
|
|
522
524
|
#observer = null;
|
|
@@ -535,10 +537,15 @@ class FigTooltip extends HTMLElement {
|
|
|
535
537
|
this.#boundHandleTouchMove = this.#handleTouchMove.bind(this);
|
|
536
538
|
this.#boundHandleTouchEnd = this.#handleTouchEnd.bind(this);
|
|
537
539
|
this.#boundHandleTouchCancel = this.#handleTouchCancel.bind(this);
|
|
540
|
+
this.#boundHandleDialogClose = () => this.hidePopup();
|
|
538
541
|
}
|
|
539
542
|
connectedCallback() {
|
|
540
543
|
this.setup();
|
|
541
544
|
this.setupEventListeners();
|
|
545
|
+
this.#parentDialog = this.closest("dialog");
|
|
546
|
+
if (this.#parentDialog) {
|
|
547
|
+
this.#parentDialog.addEventListener("close", this.#boundHandleDialogClose);
|
|
548
|
+
}
|
|
542
549
|
}
|
|
543
550
|
|
|
544
551
|
disconnectedCallback() {
|
|
@@ -549,6 +556,10 @@ class FigTooltip extends HTMLElement {
|
|
|
549
556
|
true,
|
|
550
557
|
);
|
|
551
558
|
this.#stopObserving();
|
|
559
|
+
if (this.#parentDialog) {
|
|
560
|
+
this.#parentDialog.removeEventListener("close", this.#boundHandleDialogClose);
|
|
561
|
+
this.#parentDialog = null;
|
|
562
|
+
}
|
|
552
563
|
|
|
553
564
|
if (this.action === "click") {
|
|
554
565
|
document.body.removeEventListener(
|
|
@@ -1110,6 +1121,9 @@ customElements.define("fig-truncate", FigTruncate);
|
|
|
1110
1121
|
* @attr {boolean} drag - Whether the dialog is draggable
|
|
1111
1122
|
* @attr {string} handle - CSS selector for the drag handle element (e.g., "fig-header"). If not specified, the entire dialog is draggable when drag is enabled.
|
|
1112
1123
|
* @attr {string} position - Position of the dialog (e.g., "bottom right", "top left", "center center")
|
|
1124
|
+
* @attr {string} title - Title text for the auto-generated header. If no fig-header[dialog-header] exists, one is prepended with this title and a close button.
|
|
1125
|
+
* @attr {boolean} resizable - Whether the dialog can be manually resized by the user (default: false)
|
|
1126
|
+
* @attr {string} closedby - Controls how the dialog can be dismissed: "any" (default, Escape + light dismiss), "closerequest" (Escape only), "none" (programmatic only)
|
|
1113
1127
|
*/
|
|
1114
1128
|
class FigDialog extends HTMLDialogElement {
|
|
1115
1129
|
#isDragging = false;
|
|
@@ -1140,6 +1154,8 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1140
1154
|
this.drag =
|
|
1141
1155
|
this.hasAttribute("drag") && this.getAttribute("drag") !== "false";
|
|
1142
1156
|
|
|
1157
|
+
this.#ensureHeader();
|
|
1158
|
+
|
|
1143
1159
|
requestAnimationFrame(() => {
|
|
1144
1160
|
this.#addCloseListeners();
|
|
1145
1161
|
this.#setupDragListeners();
|
|
@@ -1154,6 +1170,29 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1154
1170
|
});
|
|
1155
1171
|
}
|
|
1156
1172
|
|
|
1173
|
+
#ensureHeader() {
|
|
1174
|
+
if (this.querySelector("fig-header[dialog-header]")) return;
|
|
1175
|
+
const header = document.createElement("fig-header");
|
|
1176
|
+
header.setAttribute("dialog-header", "");
|
|
1177
|
+
header.setAttribute("data-auto", "");
|
|
1178
|
+
const h3 = document.createElement("h3");
|
|
1179
|
+
h3.textContent = this.getAttribute("title") || "Dialog";
|
|
1180
|
+
const tooltip = document.createElement("fig-tooltip");
|
|
1181
|
+
tooltip.setAttribute("text", "Close");
|
|
1182
|
+
const btn = document.createElement("fig-button");
|
|
1183
|
+
btn.setAttribute("variant", "ghost");
|
|
1184
|
+
btn.setAttribute("icon", "");
|
|
1185
|
+
btn.setAttribute("close-dialog", "");
|
|
1186
|
+
const icon = document.createElement("span");
|
|
1187
|
+
icon.className = "fig-mask-icon";
|
|
1188
|
+
icon.style.setProperty("--icon", "var(--icon-close)");
|
|
1189
|
+
btn.appendChild(icon);
|
|
1190
|
+
tooltip.appendChild(btn);
|
|
1191
|
+
header.appendChild(h3);
|
|
1192
|
+
header.appendChild(tooltip);
|
|
1193
|
+
this.prepend(header);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1157
1196
|
#addCloseListeners() {
|
|
1158
1197
|
this.querySelectorAll("fig-button[close-dialog]").forEach((button) => {
|
|
1159
1198
|
button.removeEventListener("click", this.#boundClose);
|
|
@@ -1370,7 +1409,7 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1370
1409
|
}
|
|
1371
1410
|
|
|
1372
1411
|
static get observedAttributes() {
|
|
1373
|
-
return ["modal", "drag", "position", "handle"];
|
|
1412
|
+
return ["modal", "drag", "position", "handle", "title", "resizable", "closedby"];
|
|
1374
1413
|
}
|
|
1375
1414
|
|
|
1376
1415
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
@@ -1391,6 +1430,27 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1391
1430
|
if (name === "position" && this.#positionInitialized) {
|
|
1392
1431
|
this.#applyPosition();
|
|
1393
1432
|
}
|
|
1433
|
+
|
|
1434
|
+
if (name === "modal") {
|
|
1435
|
+
const wasModal = this.modal;
|
|
1436
|
+
this.modal = newValue !== null && newValue !== "false";
|
|
1437
|
+
if (this.open && wasModal !== this.modal) {
|
|
1438
|
+
this.close();
|
|
1439
|
+
if (this.modal) this.showModal();
|
|
1440
|
+
else this.show();
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
if (name === "closedby") {
|
|
1445
|
+
this.closedby = newValue || "any";
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
if (name === "title") {
|
|
1449
|
+
const autoHeader = this.querySelector("fig-header[data-auto] h3");
|
|
1450
|
+
if (autoHeader) {
|
|
1451
|
+
autoHeader.textContent = newValue || "Dialog";
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1394
1454
|
}
|
|
1395
1455
|
}
|
|
1396
1456
|
figDefineCustomizedBuiltIn("fig-dialog", FigDialog, { extends: "dialog" });
|
|
@@ -3071,6 +3131,277 @@ class FigSegmentedControl extends HTMLElement {
|
|
|
3071
3131
|
}
|
|
3072
3132
|
customElements.define("fig-segmented-control", FigSegmentedControl);
|
|
3073
3133
|
|
|
3134
|
+
/* Options */
|
|
3135
|
+
/**
|
|
3136
|
+
* A responsive option picker that renders as a segmented control by default,
|
|
3137
|
+
* automatically swapping to a dropdown when any label overflows.
|
|
3138
|
+
* @attr {string} options - Comma-separated list of option labels
|
|
3139
|
+
* @attr {string} value - Currently selected value
|
|
3140
|
+
* @attr {boolean} disabled - Disables the control
|
|
3141
|
+
* @attr {boolean} full - Full-width segmented control
|
|
3142
|
+
* @attr {string} sizing - Segment sizing mode: "equal" (default) or "auto"
|
|
3143
|
+
*/
|
|
3144
|
+
class FigOptions extends HTMLElement {
|
|
3145
|
+
static get observedAttributes() {
|
|
3146
|
+
return ["options", "value", "disabled", "full", "sizing"];
|
|
3147
|
+
}
|
|
3148
|
+
|
|
3149
|
+
#currentMode = "segments"; // "segments" | "dropdown"
|
|
3150
|
+
#naturalWidth = 0;
|
|
3151
|
+
#resizeObserver = null;
|
|
3152
|
+
#parsedOptions = [];
|
|
3153
|
+
#childControl = null;
|
|
3154
|
+
#suppressEvents = false;
|
|
3155
|
+
|
|
3156
|
+
connectedCallback() {
|
|
3157
|
+
this.#parseOptions();
|
|
3158
|
+
this.#renderSegments();
|
|
3159
|
+
this.#startResizeObserver();
|
|
3160
|
+
requestAnimationFrame(() => {
|
|
3161
|
+
requestAnimationFrame(() => this.#checkOverflow());
|
|
3162
|
+
});
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
disconnectedCallback() {
|
|
3166
|
+
this.#resizeObserver?.disconnect();
|
|
3167
|
+
this.#resizeObserver = null;
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
get value() {
|
|
3171
|
+
return this.getAttribute("value") || "";
|
|
3172
|
+
}
|
|
3173
|
+
|
|
3174
|
+
set value(val) {
|
|
3175
|
+
if (val === null || val === undefined) {
|
|
3176
|
+
this.removeAttribute("value");
|
|
3177
|
+
} else {
|
|
3178
|
+
this.setAttribute("value", String(val));
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
|
|
3182
|
+
get options() {
|
|
3183
|
+
return this.#parsedOptions.slice();
|
|
3184
|
+
}
|
|
3185
|
+
|
|
3186
|
+
set options(val) {
|
|
3187
|
+
if (Array.isArray(val)) {
|
|
3188
|
+
const hasComma = val.some((v) => String(v).includes(","));
|
|
3189
|
+
const str = hasComma ? JSON.stringify(val) : val.join(",");
|
|
3190
|
+
this.setAttribute("options", str);
|
|
3191
|
+
} else {
|
|
3192
|
+
this.setAttribute("options", String(val || ""));
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3196
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
3197
|
+
if (oldValue === newValue) return;
|
|
3198
|
+
|
|
3199
|
+
if (name === "options") {
|
|
3200
|
+
this.#parseOptions();
|
|
3201
|
+
this.#rebuildCurrentControl();
|
|
3202
|
+
return;
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
if (name === "value") {
|
|
3206
|
+
this.#syncValueToChild();
|
|
3207
|
+
return;
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3210
|
+
if (name === "disabled") {
|
|
3211
|
+
this.#syncAttrToChild("disabled");
|
|
3212
|
+
return;
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3215
|
+
if (name === "full") {
|
|
3216
|
+
this.#syncAttrToChild("full");
|
|
3217
|
+
return;
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
if (name === "sizing") {
|
|
3221
|
+
this.#syncAttrToChild("sizing");
|
|
3222
|
+
this.#rebuildCurrentControl();
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
|
|
3226
|
+
#parseOptions() {
|
|
3227
|
+
const raw = this.getAttribute("options") || "";
|
|
3228
|
+
if (raw.startsWith("[")) {
|
|
3229
|
+
try { this.#parsedOptions = JSON.parse(raw); return; } catch {}
|
|
3230
|
+
}
|
|
3231
|
+
const delimiter = raw.includes("\n") ? "\n" : ",";
|
|
3232
|
+
this.#parsedOptions = raw.split(delimiter).map((s) => s.trim()).filter(Boolean);
|
|
3233
|
+
}
|
|
3234
|
+
|
|
3235
|
+
#renderSegments() {
|
|
3236
|
+
this.innerHTML = "";
|
|
3237
|
+
if (this.#parsedOptions.length === 0) return;
|
|
3238
|
+
|
|
3239
|
+
const sc = document.createElement("fig-segmented-control");
|
|
3240
|
+
sc.setAttribute("sizing", this.getAttribute("sizing") || "equal");
|
|
3241
|
+
|
|
3242
|
+
if (this.hasAttribute("disabled")) sc.setAttribute("disabled", "");
|
|
3243
|
+
if (this.hasAttribute("full")) sc.setAttribute("full", "");
|
|
3244
|
+
|
|
3245
|
+
const currentValue = this.getAttribute("value");
|
|
3246
|
+
let hasSelection = false;
|
|
3247
|
+
|
|
3248
|
+
for (const opt of this.#parsedOptions) {
|
|
3249
|
+
const seg = document.createElement("fig-segment");
|
|
3250
|
+
seg.setAttribute("value", opt);
|
|
3251
|
+
seg.textContent = opt;
|
|
3252
|
+
if (currentValue === opt) {
|
|
3253
|
+
seg.setAttribute("selected", "true");
|
|
3254
|
+
hasSelection = true;
|
|
3255
|
+
}
|
|
3256
|
+
sc.appendChild(seg);
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
if (currentValue) sc.setAttribute("value", currentValue);
|
|
3260
|
+
|
|
3261
|
+
sc.addEventListener("input", (e) => {
|
|
3262
|
+
if (this.#suppressEvents) return;
|
|
3263
|
+
this.#suppressEvents = true;
|
|
3264
|
+
this.setAttribute("value", e.detail);
|
|
3265
|
+
this.#suppressEvents = false;
|
|
3266
|
+
this.dispatchEvent(
|
|
3267
|
+
new CustomEvent("input", { detail: e.detail, bubbles: true }),
|
|
3268
|
+
);
|
|
3269
|
+
});
|
|
3270
|
+
sc.addEventListener("change", (e) => {
|
|
3271
|
+
if (this.#suppressEvents) return;
|
|
3272
|
+
this.dispatchEvent(
|
|
3273
|
+
new CustomEvent("change", { detail: e.detail, bubbles: true }),
|
|
3274
|
+
);
|
|
3275
|
+
});
|
|
3276
|
+
|
|
3277
|
+
this.appendChild(sc);
|
|
3278
|
+
this.#childControl = sc;
|
|
3279
|
+
this.#currentMode = "segments";
|
|
3280
|
+
}
|
|
3281
|
+
|
|
3282
|
+
#renderDropdown() {
|
|
3283
|
+
this.innerHTML = "";
|
|
3284
|
+
if (this.#parsedOptions.length === 0) return;
|
|
3285
|
+
|
|
3286
|
+
const dd = document.createElement("fig-dropdown");
|
|
3287
|
+
if (this.hasAttribute("disabled")) dd.setAttribute("disabled", "");
|
|
3288
|
+
|
|
3289
|
+
const currentValue = this.getAttribute("value");
|
|
3290
|
+
|
|
3291
|
+
for (const opt of this.#parsedOptions) {
|
|
3292
|
+
const option = document.createElement("option");
|
|
3293
|
+
option.value = opt;
|
|
3294
|
+
option.textContent = opt;
|
|
3295
|
+
if (currentValue === opt) option.selected = true;
|
|
3296
|
+
dd.appendChild(option);
|
|
3297
|
+
}
|
|
3298
|
+
|
|
3299
|
+
if (currentValue) dd.setAttribute("value", currentValue);
|
|
3300
|
+
|
|
3301
|
+
dd.addEventListener("input", (e) => {
|
|
3302
|
+
if (this.#suppressEvents) return;
|
|
3303
|
+
this.#suppressEvents = true;
|
|
3304
|
+
this.setAttribute("value", e.detail);
|
|
3305
|
+
this.#suppressEvents = false;
|
|
3306
|
+
this.dispatchEvent(
|
|
3307
|
+
new CustomEvent("input", { detail: e.detail, bubbles: true }),
|
|
3308
|
+
);
|
|
3309
|
+
});
|
|
3310
|
+
dd.addEventListener("change", (e) => {
|
|
3311
|
+
if (this.#suppressEvents) return;
|
|
3312
|
+
this.dispatchEvent(
|
|
3313
|
+
new CustomEvent("change", { detail: e.detail, bubbles: true }),
|
|
3314
|
+
);
|
|
3315
|
+
});
|
|
3316
|
+
|
|
3317
|
+
this.appendChild(dd);
|
|
3318
|
+
this.#childControl = dd;
|
|
3319
|
+
this.#currentMode = "dropdown";
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
#rebuildCurrentControl() {
|
|
3323
|
+
if (this.#currentMode === "segments") {
|
|
3324
|
+
this.#renderSegments();
|
|
3325
|
+
requestAnimationFrame(() => {
|
|
3326
|
+
requestAnimationFrame(() => this.#checkOverflow());
|
|
3327
|
+
});
|
|
3328
|
+
} else {
|
|
3329
|
+
this.#renderDropdown();
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
#syncValueToChild() {
|
|
3334
|
+
if (!this.#childControl || this.#suppressEvents) return;
|
|
3335
|
+
const val = this.getAttribute("value") || "";
|
|
3336
|
+
this.#childControl.value = val;
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3339
|
+
#syncAttrToChild(attr) {
|
|
3340
|
+
if (!this.#childControl) return;
|
|
3341
|
+
if (this.hasAttribute(attr)) {
|
|
3342
|
+
this.#childControl.setAttribute(attr, this.getAttribute(attr) || "");
|
|
3343
|
+
} else {
|
|
3344
|
+
this.#childControl.removeAttribute(attr);
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
|
|
3348
|
+
#startResizeObserver() {
|
|
3349
|
+
this.#resizeObserver?.disconnect();
|
|
3350
|
+
this.#resizeObserver = new ResizeObserver(() => {
|
|
3351
|
+
this.#checkOverflow();
|
|
3352
|
+
});
|
|
3353
|
+
this.#resizeObserver.observe(this);
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3356
|
+
#isSegmentTruncated(seg) {
|
|
3357
|
+
const range = document.createRange();
|
|
3358
|
+
range.selectNodeContents(seg);
|
|
3359
|
+
const textWidth = range.getBoundingClientRect().width;
|
|
3360
|
+
const segRect = seg.getBoundingClientRect();
|
|
3361
|
+
const segWidth = segRect.width;
|
|
3362
|
+
const cs = getComputedStyle(seg);
|
|
3363
|
+
const padL = parseFloat(cs.paddingLeft) || 0;
|
|
3364
|
+
const padR = parseFloat(cs.paddingRight) || 0;
|
|
3365
|
+
const contentWidth = segWidth - padL - padR;
|
|
3366
|
+
return textWidth > contentWidth + 0.5;
|
|
3367
|
+
}
|
|
3368
|
+
|
|
3369
|
+
#anySegmentTruncated() {
|
|
3370
|
+
const segments = this.querySelectorAll("fig-segment");
|
|
3371
|
+
for (const seg of segments) {
|
|
3372
|
+
if (this.#isSegmentTruncated(seg)) return true;
|
|
3373
|
+
}
|
|
3374
|
+
return false;
|
|
3375
|
+
}
|
|
3376
|
+
|
|
3377
|
+
#checkOverflow() {
|
|
3378
|
+
if (this.#parsedOptions.length <= 1) return;
|
|
3379
|
+
|
|
3380
|
+
if (this.#currentMode === "segments") {
|
|
3381
|
+
const sc = this.#childControl;
|
|
3382
|
+
const containerOverflow = sc && sc.scrollWidth > sc.clientWidth + 1;
|
|
3383
|
+
if (containerOverflow || this.#anySegmentTruncated()) {
|
|
3384
|
+
this.#naturalWidth = this.clientWidth;
|
|
3385
|
+
this.#renderDropdown();
|
|
3386
|
+
}
|
|
3387
|
+
} else {
|
|
3388
|
+
if (this.#naturalWidth > 0 && this.clientWidth >= this.#naturalWidth) {
|
|
3389
|
+
this.#renderSegments();
|
|
3390
|
+
requestAnimationFrame(() => {
|
|
3391
|
+
requestAnimationFrame(() => {
|
|
3392
|
+
const sc = this.#childControl;
|
|
3393
|
+
const containerOverflow = sc && sc.scrollWidth > sc.clientWidth + 1;
|
|
3394
|
+
if (containerOverflow || this.#anySegmentTruncated()) {
|
|
3395
|
+
this.#renderDropdown();
|
|
3396
|
+
}
|
|
3397
|
+
});
|
|
3398
|
+
});
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
customElements.define("fig-options", FigOptions);
|
|
3404
|
+
|
|
3074
3405
|
/* Slider */
|
|
3075
3406
|
/**
|
|
3076
3407
|
* A custom slider input element.
|
|
@@ -6105,6 +6436,7 @@ class FigInputPalette extends HTMLElement {
|
|
|
6105
6436
|
expandedWrap.className = "palette-colors-expanded";
|
|
6106
6437
|
this.#colors.forEach((entry, i) => {
|
|
6107
6438
|
expandedWrap.appendChild(this.#createPicker(entry, i, disabled));
|
|
6439
|
+
expandedWrap.appendChild(this.#createRemoveButton(i, disabled));
|
|
6108
6440
|
});
|
|
6109
6441
|
this.appendChild(expandedWrap);
|
|
6110
6442
|
}
|
|
@@ -6169,6 +6501,31 @@ class FigInputPalette extends HTMLElement {
|
|
|
6169
6501
|
return ic;
|
|
6170
6502
|
}
|
|
6171
6503
|
|
|
6504
|
+
#createRemoveButton(index, disabled) {
|
|
6505
|
+
const btn = document.createElement("fig-button");
|
|
6506
|
+
btn.setAttribute("variant", "ghost");
|
|
6507
|
+
btn.setAttribute("icon", "true");
|
|
6508
|
+
btn.setAttribute("aria-label", "Remove color");
|
|
6509
|
+
btn.className = "palette-remove-btn";
|
|
6510
|
+
if (disabled || this.#colors.length <= this.#min) btn.setAttribute("disabled", "");
|
|
6511
|
+
btn.innerHTML = `<span class="fig-mask-icon" style="--icon: var(--icon-minus)"></span>`;
|
|
6512
|
+
btn.addEventListener("click", () => {
|
|
6513
|
+
if (this.hasAttribute("disabled") && this.getAttribute("disabled") !== "false") return;
|
|
6514
|
+
this.#removeColor(index);
|
|
6515
|
+
});
|
|
6516
|
+
return btn;
|
|
6517
|
+
}
|
|
6518
|
+
|
|
6519
|
+
#removeColor(index) {
|
|
6520
|
+
if (index < 0 || index >= this.#colors.length) return;
|
|
6521
|
+
if (this.#colors.length <= this.#min) return;
|
|
6522
|
+
this.#colors.splice(index, 1);
|
|
6523
|
+
this.#inlinePickers = [];
|
|
6524
|
+
this.#expandedPickers = [];
|
|
6525
|
+
this.#render();
|
|
6526
|
+
this.#emitChange();
|
|
6527
|
+
}
|
|
6528
|
+
|
|
6172
6529
|
#createAddButton(disabled, parent = this) {
|
|
6173
6530
|
const atMax = this.#colors.length >= this.#max;
|
|
6174
6531
|
const addBtn = document.createElement("fig-button");
|
|
@@ -6208,7 +6565,10 @@ class FigInputPalette extends HTMLElement {
|
|
|
6208
6565
|
|
|
6209
6566
|
const expandedIc = this.#createPicker(entry, index, disabled);
|
|
6210
6567
|
const expandedWrap = this.querySelector(".palette-colors-expanded");
|
|
6211
|
-
if (expandedWrap)
|
|
6568
|
+
if (expandedWrap) {
|
|
6569
|
+
expandedWrap.appendChild(expandedIc);
|
|
6570
|
+
expandedWrap.appendChild(this.#createRemoveButton(index, disabled));
|
|
6571
|
+
}
|
|
6212
6572
|
|
|
6213
6573
|
if (this.#colors.length >= this.#max) {
|
|
6214
6574
|
const addBtn = this.querySelector(".palette-add-btn");
|
|
@@ -10652,6 +11012,24 @@ class FigGroup extends HTMLElement {
|
|
|
10652
11012
|
}
|
|
10653
11013
|
customElements.define("fig-group", FigGroup);
|
|
10654
11014
|
|
|
11015
|
+
/**
|
|
11016
|
+
* A presentational header element used inside fig-dialog, fig-group, and other containers.
|
|
11017
|
+
* Styling is handled entirely in CSS; this registration makes it a known custom element.
|
|
11018
|
+
*
|
|
11019
|
+
* @attr {boolean} borderless - Removes the bottom border
|
|
11020
|
+
* @attr {boolean} dialog-header - Marks this as a dialog header (auto-generated by fig-dialog)
|
|
11021
|
+
*/
|
|
11022
|
+
class FigHeader extends HTMLElement {}
|
|
11023
|
+
customElements.define("fig-header", FigHeader);
|
|
11024
|
+
|
|
11025
|
+
/**
|
|
11026
|
+
* fig-footer
|
|
11027
|
+
* @element fig-footer
|
|
11028
|
+
* @attr {boolean} borderless - Removes the top border
|
|
11029
|
+
*/
|
|
11030
|
+
class FigFooter extends HTMLElement {}
|
|
11031
|
+
customElements.define("fig-footer", FigFooter);
|
|
11032
|
+
|
|
10655
11033
|
// FigFillPicker
|
|
10656
11034
|
/**
|
|
10657
11035
|
* A comprehensive fill picker component supporting solid colors, gradients, images, video, and webcam.
|
package/package.json
CHANGED