@rogieking/figui3 8.5.0 → 8.6.1
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 +3 -1
- package/components.css +11 -2
- package/dist/components.css +1 -1
- package/dist/fig-editor.css +1 -1
- package/dist/fig.css +1 -1
- package/dist/fig.js +2 -2
- package/fig-editor.css +30 -4
- package/fig.js +125 -2
- package/package.json +1 -1
package/fig-editor.css
CHANGED
|
@@ -53,22 +53,32 @@ fig-interpolation-swatch {
|
|
|
53
53
|
|
|
54
54
|
/* Toast */
|
|
55
55
|
dialog[is="fig-toast"] {
|
|
56
|
-
|
|
56
|
+
--fig-toast-bg-color: var(--figma-color-bg);
|
|
57
57
|
--z-index: 999999;
|
|
58
|
+
contain: none;
|
|
58
59
|
z-index: var(--z-index);
|
|
59
60
|
box-shadow: var(--figma-elevation-100);
|
|
60
61
|
border-radius: var(--radius-large);
|
|
61
62
|
padding: var(--spacer-2) var(--spacer-3);
|
|
62
63
|
align-items: center;
|
|
63
|
-
gap: var(--spacer-2);
|
|
64
|
+
gap: var(--spacer-2-5);
|
|
64
65
|
height: 2.5rem;
|
|
66
|
+
flex-wrap: nowrap;
|
|
65
67
|
justify-content: center;
|
|
66
68
|
min-width: 0;
|
|
67
69
|
color: var(--figma-color-text);
|
|
68
|
-
background-color: var(--
|
|
70
|
+
background-color: var(--fig-toast-bg-color);
|
|
71
|
+
|
|
72
|
+
&[icon]{
|
|
73
|
+
&>fig-icon:first-child {
|
|
74
|
+
margin-inline: calc(var(--spacer-2) * -1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
69
77
|
|
|
78
|
+
/* Generic dialog[open] styling stacks content in a column; toasts stay inline. */
|
|
70
79
|
&[open]:not([open="false"]) {
|
|
71
80
|
display: flex;
|
|
81
|
+
flex-direction: row;
|
|
72
82
|
}
|
|
73
83
|
|
|
74
84
|
& p {
|
|
@@ -82,8 +92,24 @@ dialog[is="fig-toast"] {
|
|
|
82
92
|
margin: 0;
|
|
83
93
|
}
|
|
84
94
|
|
|
95
|
+
& > fig-separator[data-fig-toast-dismiss-separator] {
|
|
96
|
+
flex: 0 0 auto;
|
|
97
|
+
align-self: stretch;
|
|
98
|
+
margin: 0;
|
|
99
|
+
--fig-separator-color: var(--figma-color-bordertranslucent);
|
|
100
|
+
}
|
|
85
101
|
& fig-button:last-child {
|
|
86
|
-
margin-
|
|
102
|
+
margin-inline: calc(var(--spacer-2) * -1);
|
|
103
|
+
margin-left: calc(var(--spacer-1) * -1);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
& > fig-icon[data-fig-toast-icon] {
|
|
107
|
+
flex: 0 0 auto;
|
|
108
|
+
--size: var(--spacer-4);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
& > fig-button[data-fig-toast-dismiss] {
|
|
112
|
+
flex: 0 0 auto;
|
|
87
113
|
}
|
|
88
114
|
|
|
89
115
|
&[theme="dark"] {
|
package/fig.js
CHANGED
|
@@ -2295,6 +2295,17 @@ class FigDialog extends HTMLDialogElement {
|
|
|
2295
2295
|
figDefineCustomizedBuiltIn("fig-dialog", FigDialog, { extends: "dialog" });
|
|
2296
2296
|
|
|
2297
2297
|
/* Toast */
|
|
2298
|
+
/* Toast */
|
|
2299
|
+
/**
|
|
2300
|
+
* A temporary toast notification based on <dialog>.
|
|
2301
|
+
* @attr {number|string} duration - Auto-dismiss ms (default 5000; 0 = no dismiss).
|
|
2302
|
+
* @attr {number|string} offset - Distance from bottom in px (default 16).
|
|
2303
|
+
* @attr {string} theme - Visual theme: "dark", "light", "danger", "brand", "success", or "auto".
|
|
2304
|
+
* @attr {string} live - Set to "assertive" for urgent announcements.
|
|
2305
|
+
* @attr {string} icon - Optional fig-icon name prepended when set; omit for no icon.
|
|
2306
|
+
* @attr {boolean|string} dismiss - When true, appends a ghost close button that hides the toast.
|
|
2307
|
+
* @attr {boolean|string} open - Open when present and not "false".
|
|
2308
|
+
*/
|
|
2298
2309
|
class FigToast extends HTMLDialogElement {
|
|
2299
2310
|
constructor() {
|
|
2300
2311
|
super();
|
|
@@ -2310,6 +2321,9 @@ class FigToast extends HTMLDialogElement {
|
|
|
2310
2321
|
this._syncingOpen = false;
|
|
2311
2322
|
this._managedRole = null;
|
|
2312
2323
|
this._managedLive = null;
|
|
2324
|
+
this._managedIcon = null;
|
|
2325
|
+
this._managedDismiss = null;
|
|
2326
|
+
this._managedDismissSeparator = null;
|
|
2313
2327
|
this._boundHandleClose = this.handleClose.bind(this);
|
|
2314
2328
|
}
|
|
2315
2329
|
|
|
@@ -2317,6 +2331,8 @@ class FigToast extends HTMLDialogElement {
|
|
|
2317
2331
|
this._figInit();
|
|
2318
2332
|
if (!this.hasAttribute("theme")) this.setAttribute("theme", "dark");
|
|
2319
2333
|
this.syncLiveRegion();
|
|
2334
|
+
this.syncIcon();
|
|
2335
|
+
this.syncDismiss();
|
|
2320
2336
|
this.addCloseListeners();
|
|
2321
2337
|
this.applyPosition();
|
|
2322
2338
|
if (this.hasAttribute("open") && this.getAttribute("open") !== "false") {
|
|
@@ -2384,6 +2400,101 @@ class FigToast extends HTMLDialogElement {
|
|
|
2384
2400
|
}
|
|
2385
2401
|
}
|
|
2386
2402
|
|
|
2403
|
+
syncIcon() {
|
|
2404
|
+
const name = this.getAttribute("icon");
|
|
2405
|
+
let icon = this._managedIcon;
|
|
2406
|
+
if (!icon || icon.parentNode !== this) {
|
|
2407
|
+
icon = this.querySelector(":scope > fig-icon[data-fig-toast-icon]");
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2410
|
+
if (!name) {
|
|
2411
|
+
if (icon) icon.remove();
|
|
2412
|
+
this._managedIcon = null;
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
if (!icon) {
|
|
2417
|
+
icon = document.createElement("fig-icon");
|
|
2418
|
+
icon.setAttribute("data-fig-toast-icon", "");
|
|
2419
|
+
icon.setAttribute("aria-hidden", "true");
|
|
2420
|
+
this.prepend(icon);
|
|
2421
|
+
} else if (this.firstElementChild !== icon) {
|
|
2422
|
+
this.prepend(icon);
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
if (icon.getAttribute("size") !== "medium") {
|
|
2426
|
+
icon.setAttribute("size", "medium");
|
|
2427
|
+
}
|
|
2428
|
+
if (icon.getAttribute("name") !== name) {
|
|
2429
|
+
icon.setAttribute("name", name);
|
|
2430
|
+
}
|
|
2431
|
+
this._managedIcon = icon;
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
syncDismiss() {
|
|
2435
|
+
const enabled = figBooleanAttribute(this, "dismiss");
|
|
2436
|
+
let button = this._managedDismiss;
|
|
2437
|
+
if (!button || button.parentNode !== this) {
|
|
2438
|
+
button = this.querySelector(":scope > fig-button[data-fig-toast-dismiss]");
|
|
2439
|
+
}
|
|
2440
|
+
let separator = this._managedDismissSeparator;
|
|
2441
|
+
if (!separator || separator.parentNode !== this) {
|
|
2442
|
+
separator = this.querySelector(
|
|
2443
|
+
":scope > fig-separator[data-fig-toast-dismiss-separator]",
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
if (!enabled) {
|
|
2448
|
+
if (button) {
|
|
2449
|
+
button.removeEventListener("click", this._boundHandleClose);
|
|
2450
|
+
button.remove();
|
|
2451
|
+
}
|
|
2452
|
+
if (separator) separator.remove();
|
|
2453
|
+
this._managedDismiss = null;
|
|
2454
|
+
this._managedDismissSeparator = null;
|
|
2455
|
+
return;
|
|
2456
|
+
}
|
|
2457
|
+
|
|
2458
|
+
if (!separator) {
|
|
2459
|
+
separator = document.createElement("fig-separator");
|
|
2460
|
+
separator.setAttribute("data-fig-toast-dismiss-separator", "");
|
|
2461
|
+
separator.setAttribute("direction", "vertical");
|
|
2462
|
+
separator.setAttribute("aria-orientation", "vertical");
|
|
2463
|
+
separator.setAttribute("aria-hidden", "true");
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
if (!button) {
|
|
2467
|
+
button = document.createElement("fig-button");
|
|
2468
|
+
button.setAttribute("data-fig-toast-dismiss", "");
|
|
2469
|
+
button.setAttribute("variant", "ghost");
|
|
2470
|
+
button.setAttribute("icon", "");
|
|
2471
|
+
button.setAttribute("close-toast", "");
|
|
2472
|
+
button.setAttribute("aria-label", "Close notification");
|
|
2473
|
+
const icon = document.createElement("fig-icon");
|
|
2474
|
+
icon.setAttribute("name", "close");
|
|
2475
|
+
icon.setAttribute("aria-hidden", "true");
|
|
2476
|
+
button.append(icon);
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
if (separator.parentNode !== this || button.parentNode !== this) {
|
|
2480
|
+
this.append(separator, button);
|
|
2481
|
+
} else if (
|
|
2482
|
+
this.lastElementChild !== button ||
|
|
2483
|
+
button.previousElementSibling !== separator
|
|
2484
|
+
) {
|
|
2485
|
+
this.append(separator, button);
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
if (separator.getAttribute("direction") !== "vertical") {
|
|
2489
|
+
separator.setAttribute("direction", "vertical");
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
button.removeEventListener("click", this._boundHandleClose);
|
|
2493
|
+
button.addEventListener("click", this._boundHandleClose);
|
|
2494
|
+
this._managedDismiss = button;
|
|
2495
|
+
this._managedDismissSeparator = separator;
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2387
2498
|
startAutoClose() {
|
|
2388
2499
|
this.clearAutoClose();
|
|
2389
2500
|
const duration = parseInt(this.getAttribute("duration") ?? "5000");
|
|
@@ -2409,6 +2520,8 @@ class FigToast extends HTMLDialogElement {
|
|
|
2409
2520
|
showToast() {
|
|
2410
2521
|
const wasVisible = this._toastVisible;
|
|
2411
2522
|
this.syncLiveRegion();
|
|
2523
|
+
this.syncIcon();
|
|
2524
|
+
this.syncDismiss();
|
|
2412
2525
|
this._resolveAutoTheme();
|
|
2413
2526
|
this._syncingOpen = true;
|
|
2414
2527
|
try {
|
|
@@ -2441,7 +2554,7 @@ class FigToast extends HTMLDialogElement {
|
|
|
2441
2554
|
}
|
|
2442
2555
|
|
|
2443
2556
|
static get observedAttributes() {
|
|
2444
|
-
return ["duration", "offset", "open", "theme", "live"];
|
|
2557
|
+
return ["duration", "offset", "open", "theme", "live", "icon", "dismiss"];
|
|
2445
2558
|
}
|
|
2446
2559
|
|
|
2447
2560
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
@@ -2460,6 +2573,8 @@ class FigToast extends HTMLDialogElement {
|
|
|
2460
2573
|
else this.style.removeProperty("color-scheme");
|
|
2461
2574
|
}
|
|
2462
2575
|
if (name === "theme" || name === "live") this.syncLiveRegion();
|
|
2576
|
+
if (name === "icon") this.syncIcon();
|
|
2577
|
+
if (name === "dismiss") this.syncDismiss();
|
|
2463
2578
|
}
|
|
2464
2579
|
}
|
|
2465
2580
|
figDefineCustomizedBuiltIn("fig-toast", FigToast, { extends: "dialog" });
|
|
@@ -16419,6 +16534,7 @@ const FIG_ICON_TOKENS = {
|
|
|
16419
16534
|
visible: { medium: "--icon-24-visible", small: "--icon-16-visible" },
|
|
16420
16535
|
hidden: { medium: "--icon-24-hidden", small: "--icon-16-hidden" },
|
|
16421
16536
|
globe: { medium: "--icon-24-globe", small: "--icon-16-globe" },
|
|
16537
|
+
warning: { medium: "--icon-24-warning", small: "--icon-16-warning" },
|
|
16422
16538
|
};
|
|
16423
16539
|
|
|
16424
16540
|
function figIconCssVar(name, size = "medium") {
|
|
@@ -18572,11 +18688,12 @@ figDefineElement("fig-menu-item", FigMenuItem);
|
|
|
18572
18688
|
/**
|
|
18573
18689
|
* Visual divider between content groups.
|
|
18574
18690
|
* @attr {string} label - Optional group label shown in secondary text under the line.
|
|
18691
|
+
* @attr {string} direction - Orientation: "vertical" for a tall rule; default is horizontal.
|
|
18575
18692
|
* @attr {boolean} borderless - Hides the separator line when present or "true".
|
|
18576
18693
|
*/
|
|
18577
18694
|
class FigSeparator extends HTMLElement {
|
|
18578
18695
|
static get observedAttributes() {
|
|
18579
|
-
return ["label"];
|
|
18696
|
+
return ["label", "direction"];
|
|
18580
18697
|
}
|
|
18581
18698
|
|
|
18582
18699
|
get label() {
|
|
@@ -18601,6 +18718,12 @@ class FigSeparator extends HTMLElement {
|
|
|
18601
18718
|
if (!this.hasAttribute("role")) {
|
|
18602
18719
|
this.setAttribute("role", "separator");
|
|
18603
18720
|
}
|
|
18721
|
+
const direction = this.getAttribute("direction");
|
|
18722
|
+
if (direction === "vertical") {
|
|
18723
|
+
this.setAttribute("aria-orientation", "vertical");
|
|
18724
|
+
} else if (!this.hasAttribute("aria-orientation")) {
|
|
18725
|
+
this.setAttribute("aria-orientation", "horizontal");
|
|
18726
|
+
}
|
|
18604
18727
|
const label = this.label.trim();
|
|
18605
18728
|
if (label) this.setAttribute("aria-label", label);
|
|
18606
18729
|
else this.removeAttribute("aria-label");
|
package/package.json
CHANGED