@rogieking/figui3 4.8.2 → 4.9.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 +42 -29
- package/dist/components.css +1 -1
- package/dist/fig.css +1 -1
- package/dist/fig.js +30 -30
- package/fig.js +158 -150
- package/package.json +1 -1
package/fig.js
CHANGED
|
@@ -1027,37 +1027,34 @@ customElements.define("fig-truncate", FigTruncate);
|
|
|
1027
1027
|
* @attr {string} closedby - Controls how the dialog can be dismissed: "any" (default, Escape + light dismiss), "closerequest" (Escape only), "none" (programmatic only)
|
|
1028
1028
|
*/
|
|
1029
1029
|
class FigDialog extends HTMLDialogElement {
|
|
1030
|
-
#isDragging = false;
|
|
1031
|
-
#dragPending = false;
|
|
1032
|
-
#dragStartPos = { x: 0, y: 0 };
|
|
1033
|
-
#dragOffset = { x: 0, y: 0 };
|
|
1034
|
-
#boundPointerDown;
|
|
1035
|
-
#boundPointerMove;
|
|
1036
|
-
#boundPointerUp;
|
|
1037
|
-
#boundClose;
|
|
1038
|
-
#boundIframeMessage;
|
|
1039
|
-
#boundContentMutation;
|
|
1040
|
-
#boundContentResize;
|
|
1041
|
-
#resizeObserver = null;
|
|
1042
|
-
#mutationObserver = null;
|
|
1043
|
-
#autoResizeRafId = 0;
|
|
1044
|
-
#offset = 16; // 1rem in pixels
|
|
1045
|
-
#positionInitialized = false;
|
|
1046
|
-
#dragThreshold = 3; // pixels before drag starts
|
|
1047
|
-
|
|
1048
|
-
static get observedAttributes() {
|
|
1049
|
-
return ["autoresize"];
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
1030
|
constructor() {
|
|
1053
1031
|
super();
|
|
1054
|
-
this
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1032
|
+
this._figInit();
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
// Lazy initializer used by both the native constructor path and the
|
|
1036
|
+
// Safari `is="..."` polyfill (which prototype-swaps existing nodes
|
|
1037
|
+
// without invoking the constructor, so class fields are never set).
|
|
1038
|
+
_figInit() {
|
|
1039
|
+
if (this._figInitialized) return;
|
|
1040
|
+
this._figInitialized = true;
|
|
1041
|
+
this._isDragging = false;
|
|
1042
|
+
this._dragPending = false;
|
|
1043
|
+
this._dragStartPos = { x: 0, y: 0 };
|
|
1044
|
+
this._dragOffset = { x: 0, y: 0 };
|
|
1045
|
+
this._resizeObserver = null;
|
|
1046
|
+
this._mutationObserver = null;
|
|
1047
|
+
this._autoResizeRafId = 0;
|
|
1048
|
+
this._offset = 16;
|
|
1049
|
+
this._positionInitialized = false;
|
|
1050
|
+
this._dragThreshold = 3;
|
|
1051
|
+
this._boundPointerDown = this._handlePointerDown.bind(this);
|
|
1052
|
+
this._boundPointerMove = this._handlePointerMove.bind(this);
|
|
1053
|
+
this._boundPointerUp = this._handlePointerUp.bind(this);
|
|
1054
|
+
this._boundClose = this.close.bind(this);
|
|
1055
|
+
this._boundIframeMessage = this._handleIframeMessage.bind(this);
|
|
1056
|
+
this._boundContentMutation = this._scheduleAutoResize.bind(this);
|
|
1057
|
+
this._boundContentResize = this._scheduleAutoResize.bind(this);
|
|
1061
1058
|
}
|
|
1062
1059
|
|
|
1063
1060
|
get autoresize() {
|
|
@@ -1068,6 +1065,7 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1068
1065
|
}
|
|
1069
1066
|
|
|
1070
1067
|
connectedCallback() {
|
|
1068
|
+
this._figInit();
|
|
1071
1069
|
this.modal =
|
|
1072
1070
|
this.hasAttribute("modal") && this.getAttribute("modal") !== "false";
|
|
1073
1071
|
|
|
@@ -1075,34 +1073,29 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1075
1073
|
this.drag =
|
|
1076
1074
|
this.hasAttribute("drag") && this.getAttribute("drag") !== "false";
|
|
1077
1075
|
|
|
1078
|
-
this
|
|
1076
|
+
this._ensureHeader();
|
|
1079
1077
|
|
|
1080
1078
|
requestAnimationFrame(() => {
|
|
1081
|
-
this
|
|
1082
|
-
this
|
|
1083
|
-
this
|
|
1084
|
-
this
|
|
1079
|
+
this._addCloseListeners();
|
|
1080
|
+
this._setupDragListeners();
|
|
1081
|
+
this._applyPosition();
|
|
1082
|
+
this._syncAutoResize();
|
|
1085
1083
|
});
|
|
1086
1084
|
|
|
1087
|
-
window.addEventListener("message", this
|
|
1085
|
+
window.addEventListener("message", this._boundIframeMessage);
|
|
1088
1086
|
}
|
|
1089
1087
|
|
|
1090
1088
|
disconnectedCallback() {
|
|
1091
|
-
this
|
|
1089
|
+
this._figInit();
|
|
1090
|
+
this._removeDragListeners();
|
|
1092
1091
|
this.querySelectorAll("fig-button[close-dialog]").forEach((button) => {
|
|
1093
|
-
button.removeEventListener("click", this
|
|
1092
|
+
button.removeEventListener("click", this._boundClose);
|
|
1094
1093
|
});
|
|
1095
|
-
window.removeEventListener("message", this
|
|
1096
|
-
this
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
attributeChangedCallback(name) {
|
|
1100
|
-
if (name === "autoresize" && this.isConnected) {
|
|
1101
|
-
this.#syncAutoResize();
|
|
1102
|
-
}
|
|
1094
|
+
window.removeEventListener("message", this._boundIframeMessage);
|
|
1095
|
+
this._teardownAutoResize();
|
|
1103
1096
|
}
|
|
1104
1097
|
|
|
1105
|
-
|
|
1098
|
+
_handleIframeMessage(event) {
|
|
1106
1099
|
if (!this.autoresize) return;
|
|
1107
1100
|
const data = event?.data;
|
|
1108
1101
|
if (!data || data.type !== "figui:iframe-resize") return;
|
|
@@ -1112,41 +1105,41 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1112
1105
|
(el) => el.contentWindow === source,
|
|
1113
1106
|
);
|
|
1114
1107
|
if (!iframe) return;
|
|
1115
|
-
this
|
|
1108
|
+
this._resizeForIframe(iframe, data);
|
|
1116
1109
|
}
|
|
1117
1110
|
|
|
1118
|
-
|
|
1111
|
+
_syncAutoResize() {
|
|
1119
1112
|
if (this.autoresize) {
|
|
1120
|
-
this
|
|
1121
|
-
this
|
|
1113
|
+
this._setupAutoResize();
|
|
1114
|
+
this._scheduleAutoResize();
|
|
1122
1115
|
} else {
|
|
1123
|
-
this
|
|
1116
|
+
this._teardownAutoResize();
|
|
1124
1117
|
}
|
|
1125
1118
|
}
|
|
1126
1119
|
|
|
1127
|
-
|
|
1128
|
-
if (!this
|
|
1129
|
-
this
|
|
1120
|
+
_setupAutoResize() {
|
|
1121
|
+
if (!this._resizeObserver) {
|
|
1122
|
+
this._resizeObserver = new ResizeObserver(this._boundContentResize);
|
|
1130
1123
|
for (const child of this.children) {
|
|
1131
1124
|
try {
|
|
1132
|
-
this
|
|
1125
|
+
this._resizeObserver.observe(child);
|
|
1133
1126
|
} catch {}
|
|
1134
1127
|
}
|
|
1135
1128
|
}
|
|
1136
|
-
if (!this
|
|
1137
|
-
this
|
|
1129
|
+
if (!this._mutationObserver) {
|
|
1130
|
+
this._mutationObserver = new MutationObserver((mutations) => {
|
|
1138
1131
|
for (const m of mutations) {
|
|
1139
1132
|
m.addedNodes?.forEach((node) => {
|
|
1140
1133
|
if (node instanceof Element && node.parentElement === this) {
|
|
1141
1134
|
try {
|
|
1142
|
-
this
|
|
1135
|
+
this._resizeObserver?.observe(node);
|
|
1143
1136
|
} catch {}
|
|
1144
1137
|
}
|
|
1145
1138
|
});
|
|
1146
1139
|
}
|
|
1147
|
-
this
|
|
1140
|
+
this._scheduleAutoResize();
|
|
1148
1141
|
});
|
|
1149
|
-
this
|
|
1142
|
+
this._mutationObserver.observe(this, {
|
|
1150
1143
|
childList: true,
|
|
1151
1144
|
subtree: true,
|
|
1152
1145
|
attributes: true,
|
|
@@ -1155,39 +1148,39 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1155
1148
|
}
|
|
1156
1149
|
}
|
|
1157
1150
|
|
|
1158
|
-
|
|
1159
|
-
if (this
|
|
1160
|
-
this
|
|
1161
|
-
this
|
|
1151
|
+
_teardownAutoResize() {
|
|
1152
|
+
if (this._resizeObserver) {
|
|
1153
|
+
this._resizeObserver.disconnect();
|
|
1154
|
+
this._resizeObserver = null;
|
|
1162
1155
|
}
|
|
1163
|
-
if (this
|
|
1164
|
-
this
|
|
1165
|
-
this
|
|
1156
|
+
if (this._mutationObserver) {
|
|
1157
|
+
this._mutationObserver.disconnect();
|
|
1158
|
+
this._mutationObserver = null;
|
|
1166
1159
|
}
|
|
1167
|
-
if (this
|
|
1168
|
-
cancelAnimationFrame(this
|
|
1169
|
-
this
|
|
1160
|
+
if (this._autoResizeRafId) {
|
|
1161
|
+
cancelAnimationFrame(this._autoResizeRafId);
|
|
1162
|
+
this._autoResizeRafId = 0;
|
|
1170
1163
|
}
|
|
1171
1164
|
}
|
|
1172
1165
|
|
|
1173
|
-
|
|
1166
|
+
_scheduleAutoResize() {
|
|
1174
1167
|
if (!this.autoresize) return;
|
|
1175
|
-
if (this
|
|
1176
|
-
this
|
|
1177
|
-
this
|
|
1178
|
-
this
|
|
1168
|
+
if (this._autoResizeRafId) return;
|
|
1169
|
+
this._autoResizeRafId = requestAnimationFrame(() => {
|
|
1170
|
+
this._autoResizeRafId = 0;
|
|
1171
|
+
this._applyAutoResize();
|
|
1179
1172
|
});
|
|
1180
1173
|
}
|
|
1181
1174
|
|
|
1182
|
-
|
|
1175
|
+
_applyAutoResize() {
|
|
1183
1176
|
if (!this.autoresize) return;
|
|
1184
1177
|
// When an iframe child is present, defer to the iframe's postMessage
|
|
1185
1178
|
// broadcast (the only reliable source of its content height).
|
|
1186
1179
|
if (this.querySelector(":scope > iframe")) return;
|
|
1187
|
-
this
|
|
1180
|
+
this._resizeToContent(null);
|
|
1188
1181
|
}
|
|
1189
1182
|
|
|
1190
|
-
|
|
1183
|
+
_computeChrome(skipChild) {
|
|
1191
1184
|
const cs = window.getComputedStyle(this);
|
|
1192
1185
|
const verticalBoxExtras =
|
|
1193
1186
|
parseFloat(cs.paddingTop || "0") +
|
|
@@ -1215,20 +1208,20 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1215
1208
|
return verticalBoxExtras + siblingsHeight;
|
|
1216
1209
|
}
|
|
1217
1210
|
|
|
1218
|
-
|
|
1211
|
+
_resizeForIframe(iframe, data) {
|
|
1219
1212
|
if (typeof data.height !== "number" || !(data.height > 0)) return;
|
|
1220
|
-
const chrome = this
|
|
1213
|
+
const chrome = this._computeChrome(iframe);
|
|
1221
1214
|
this.style.height = `${Math.ceil(data.height + chrome)}px`;
|
|
1222
1215
|
}
|
|
1223
1216
|
|
|
1224
|
-
|
|
1217
|
+
_resizeToContent() {
|
|
1225
1218
|
// Let CSS handle the sizing via `height: max-content` (applied by the
|
|
1226
1219
|
// [autoresize] rule). Just clear any previously applied inline height
|
|
1227
1220
|
// (e.g. from drag/resize) so the CSS rule wins.
|
|
1228
1221
|
if (this.style.height) this.style.height = "";
|
|
1229
1222
|
}
|
|
1230
1223
|
|
|
1231
|
-
|
|
1224
|
+
_ensureHeader() {
|
|
1232
1225
|
if (this.querySelector("fig-header[dialog-header]")) return;
|
|
1233
1226
|
const header = document.createElement("fig-header");
|
|
1234
1227
|
header.setAttribute("dialog-header", "");
|
|
@@ -1251,14 +1244,14 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1251
1244
|
this.prepend(header);
|
|
1252
1245
|
}
|
|
1253
1246
|
|
|
1254
|
-
|
|
1247
|
+
_addCloseListeners() {
|
|
1255
1248
|
this.querySelectorAll("fig-button[close-dialog]").forEach((button) => {
|
|
1256
|
-
button.removeEventListener("click", this
|
|
1257
|
-
button.addEventListener("click", this
|
|
1249
|
+
button.removeEventListener("click", this._boundClose);
|
|
1250
|
+
button.addEventListener("click", this._boundClose);
|
|
1258
1251
|
});
|
|
1259
1252
|
}
|
|
1260
1253
|
|
|
1261
|
-
|
|
1254
|
+
_applyPosition() {
|
|
1262
1255
|
const position = this.getAttribute("position") || "";
|
|
1263
1256
|
|
|
1264
1257
|
// Apply common styles
|
|
@@ -1282,9 +1275,9 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1282
1275
|
|
|
1283
1276
|
// Vertical positioning
|
|
1284
1277
|
if (hasTop) {
|
|
1285
|
-
this.style.top = `${this
|
|
1278
|
+
this.style.top = `${this._offset}px`;
|
|
1286
1279
|
} else if (hasBottom) {
|
|
1287
|
-
this.style.bottom = `${this
|
|
1280
|
+
this.style.bottom = `${this._offset}px`;
|
|
1288
1281
|
} else if (hasVCenter) {
|
|
1289
1282
|
this.style.top = "0";
|
|
1290
1283
|
this.style.bottom = "0";
|
|
@@ -1292,9 +1285,9 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1292
1285
|
|
|
1293
1286
|
// Horizontal positioning
|
|
1294
1287
|
if (hasLeft) {
|
|
1295
|
-
this.style.left = `${this
|
|
1288
|
+
this.style.left = `${this._offset}px`;
|
|
1296
1289
|
} else if (hasRight) {
|
|
1297
|
-
this.style.right = `${this
|
|
1290
|
+
this.style.right = `${this._offset}px`;
|
|
1298
1291
|
} else if (hasHCenter) {
|
|
1299
1292
|
this.style.left = "0";
|
|
1300
1293
|
this.style.right = "0";
|
|
@@ -1311,12 +1304,12 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1311
1304
|
this.style.marginRight = "auto";
|
|
1312
1305
|
}
|
|
1313
1306
|
|
|
1314
|
-
this
|
|
1307
|
+
this._positionInitialized = true;
|
|
1315
1308
|
}
|
|
1316
1309
|
|
|
1317
|
-
|
|
1310
|
+
_setupDragListeners() {
|
|
1318
1311
|
if (this.drag) {
|
|
1319
|
-
this.addEventListener("pointerdown", this
|
|
1312
|
+
this.addEventListener("pointerdown", this._boundPointerDown);
|
|
1320
1313
|
const handleSelector = this.getAttribute("handle");
|
|
1321
1314
|
const handleEl = handleSelector
|
|
1322
1315
|
? this.querySelector(handleSelector)
|
|
@@ -1327,13 +1320,13 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1327
1320
|
}
|
|
1328
1321
|
}
|
|
1329
1322
|
|
|
1330
|
-
|
|
1331
|
-
this.removeEventListener("pointerdown", this
|
|
1332
|
-
document.removeEventListener("pointermove", this
|
|
1333
|
-
document.removeEventListener("pointerup", this
|
|
1323
|
+
_removeDragListeners() {
|
|
1324
|
+
this.removeEventListener("pointerdown", this._boundPointerDown);
|
|
1325
|
+
document.removeEventListener("pointermove", this._boundPointerMove);
|
|
1326
|
+
document.removeEventListener("pointerup", this._boundPointerUp);
|
|
1334
1327
|
}
|
|
1335
1328
|
|
|
1336
|
-
|
|
1329
|
+
_isInteractiveElement(element) {
|
|
1337
1330
|
// Standard HTML interactive elements
|
|
1338
1331
|
const interactiveSelectors = [
|
|
1339
1332
|
"input",
|
|
@@ -1385,13 +1378,13 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1385
1378
|
return false;
|
|
1386
1379
|
}
|
|
1387
1380
|
|
|
1388
|
-
|
|
1381
|
+
_handlePointerDown(e) {
|
|
1389
1382
|
if (!this.drag) {
|
|
1390
1383
|
return;
|
|
1391
1384
|
}
|
|
1392
1385
|
|
|
1393
1386
|
// Don't interfere with interactive elements (inputs, sliders, buttons, etc.)
|
|
1394
|
-
if (this
|
|
1387
|
+
if (this._isInteractiveElement(e.target)) {
|
|
1395
1388
|
return;
|
|
1396
1389
|
}
|
|
1397
1390
|
|
|
@@ -1408,30 +1401,30 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1408
1401
|
|
|
1409
1402
|
// Don't prevent default yet - just set up pending drag
|
|
1410
1403
|
// This allows clicks on non-interactive elements like <details> to work
|
|
1411
|
-
this
|
|
1412
|
-
this
|
|
1413
|
-
this
|
|
1404
|
+
this._dragPending = true;
|
|
1405
|
+
this._dragStartPos.x = e.clientX;
|
|
1406
|
+
this._dragStartPos.y = e.clientY;
|
|
1414
1407
|
|
|
1415
1408
|
// Get current position from computed style
|
|
1416
1409
|
const rect = this.getBoundingClientRect();
|
|
1417
1410
|
|
|
1418
1411
|
// Store offset from pointer to dialog top-left corner
|
|
1419
|
-
this
|
|
1420
|
-
this
|
|
1412
|
+
this._dragOffset.x = e.clientX - rect.left;
|
|
1413
|
+
this._dragOffset.y = e.clientY - rect.top;
|
|
1421
1414
|
|
|
1422
|
-
document.addEventListener("pointermove", this
|
|
1423
|
-
document.addEventListener("pointerup", this
|
|
1415
|
+
document.addEventListener("pointermove", this._boundPointerMove);
|
|
1416
|
+
document.addEventListener("pointerup", this._boundPointerUp);
|
|
1424
1417
|
}
|
|
1425
1418
|
|
|
1426
|
-
|
|
1419
|
+
_handlePointerMove(e) {
|
|
1427
1420
|
// Check if we should start dragging (threshold exceeded)
|
|
1428
|
-
if (this
|
|
1429
|
-
const dx = Math.abs(e.clientX - this
|
|
1430
|
-
const dy = Math.abs(e.clientY - this
|
|
1421
|
+
if (this._dragPending && !this._isDragging) {
|
|
1422
|
+
const dx = Math.abs(e.clientX - this._dragStartPos.x);
|
|
1423
|
+
const dy = Math.abs(e.clientY - this._dragStartPos.y);
|
|
1431
1424
|
|
|
1432
|
-
if (dx > this
|
|
1433
|
-
this
|
|
1434
|
-
this
|
|
1425
|
+
if (dx > this._dragThreshold || dy > this._dragThreshold) {
|
|
1426
|
+
this._isDragging = true;
|
|
1427
|
+
this._dragPending = false;
|
|
1435
1428
|
this.setPointerCapture(e.pointerId);
|
|
1436
1429
|
this.style.cursor = "grabbing";
|
|
1437
1430
|
|
|
@@ -1444,40 +1437,54 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1444
1437
|
}
|
|
1445
1438
|
}
|
|
1446
1439
|
|
|
1447
|
-
if (!this
|
|
1440
|
+
if (!this._isDragging) return;
|
|
1448
1441
|
|
|
1449
|
-
this.style.left = `${e.clientX - this
|
|
1450
|
-
this.style.top = `${e.clientY - this
|
|
1442
|
+
this.style.left = `${e.clientX - this._dragOffset.x}px`;
|
|
1443
|
+
this.style.top = `${e.clientY - this._dragOffset.y}px`;
|
|
1451
1444
|
e.preventDefault();
|
|
1452
1445
|
}
|
|
1453
1446
|
|
|
1454
|
-
|
|
1455
|
-
if (this
|
|
1447
|
+
_handlePointerUp(e) {
|
|
1448
|
+
if (this._isDragging) {
|
|
1456
1449
|
this.releasePointerCapture(e.pointerId);
|
|
1457
1450
|
this.style.cursor = "";
|
|
1458
1451
|
}
|
|
1459
1452
|
|
|
1460
|
-
this
|
|
1461
|
-
this
|
|
1453
|
+
this._isDragging = false;
|
|
1454
|
+
this._dragPending = false;
|
|
1462
1455
|
|
|
1463
|
-
document.removeEventListener("pointermove", this
|
|
1464
|
-
document.removeEventListener("pointerup", this
|
|
1456
|
+
document.removeEventListener("pointermove", this._boundPointerMove);
|
|
1457
|
+
document.removeEventListener("pointerup", this._boundPointerUp);
|
|
1465
1458
|
|
|
1466
1459
|
e.preventDefault();
|
|
1467
1460
|
}
|
|
1468
1461
|
|
|
1469
1462
|
static get observedAttributes() {
|
|
1470
|
-
return [
|
|
1463
|
+
return [
|
|
1464
|
+
"modal",
|
|
1465
|
+
"drag",
|
|
1466
|
+
"position",
|
|
1467
|
+
"handle",
|
|
1468
|
+
"title",
|
|
1469
|
+
"resizable",
|
|
1470
|
+
"closedby",
|
|
1471
|
+
"autoresize",
|
|
1472
|
+
];
|
|
1471
1473
|
}
|
|
1472
1474
|
|
|
1473
1475
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
1476
|
+
this._figInit();
|
|
1477
|
+
if (name === "autoresize" && this.isConnected) {
|
|
1478
|
+
this._syncAutoResize();
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1474
1481
|
if (name === "drag") {
|
|
1475
1482
|
this.drag = newValue !== null && newValue !== "false";
|
|
1476
1483
|
|
|
1477
1484
|
if (this.drag) {
|
|
1478
|
-
this
|
|
1485
|
+
this._setupDragListeners();
|
|
1479
1486
|
} else {
|
|
1480
|
-
this
|
|
1487
|
+
this._removeDragListeners();
|
|
1481
1488
|
const header = this.querySelector("fig-header, header");
|
|
1482
1489
|
if (header) {
|
|
1483
1490
|
header.style.cursor = "";
|
|
@@ -1485,8 +1492,8 @@ class FigDialog extends HTMLDialogElement {
|
|
|
1485
1492
|
}
|
|
1486
1493
|
}
|
|
1487
1494
|
|
|
1488
|
-
if (name === "position" && this
|
|
1489
|
-
this
|
|
1495
|
+
if (name === "position" && this._positionInitialized) {
|
|
1496
|
+
this._applyPosition();
|
|
1490
1497
|
}
|
|
1491
1498
|
|
|
1492
1499
|
if (name === "modal") {
|
|
@@ -6607,10 +6614,10 @@ class FigInputPalette extends HTMLElement {
|
|
|
6607
6614
|
);
|
|
6608
6615
|
});
|
|
6609
6616
|
inlineWrap.appendChild(wrap);
|
|
6610
|
-
|
|
6611
|
-
if (this.#showAdd) this.#createAddButton(disabled, inlineWrap);
|
|
6612
6617
|
this.appendChild(inlineWrap);
|
|
6613
6618
|
|
|
6619
|
+
if (this.#showAdd) this.#createAddButton(disabled, this);
|
|
6620
|
+
|
|
6614
6621
|
const expandedWrap = document.createElement("div");
|
|
6615
6622
|
expandedWrap.className = "palette-colors-expanded";
|
|
6616
6623
|
this.#colors.forEach((entry, i) => {
|
|
@@ -6637,7 +6644,7 @@ class FigInputPalette extends HTMLElement {
|
|
|
6637
6644
|
ic.setAttribute("alpha", "true");
|
|
6638
6645
|
} else {
|
|
6639
6646
|
ic.setAttribute("text", "true");
|
|
6640
|
-
ic.setAttribute("alpha", "
|
|
6647
|
+
ic.setAttribute("alpha", "false");
|
|
6641
6648
|
ic.setAttribute("full", "");
|
|
6642
6649
|
}
|
|
6643
6650
|
if (disabled) ic.setAttribute("disabled", "");
|
|
@@ -6708,7 +6715,7 @@ class FigInputPalette extends HTMLElement {
|
|
|
6708
6715
|
#createAddButton(disabled, parent = this) {
|
|
6709
6716
|
const atMax = this.#colors.length >= this.#max;
|
|
6710
6717
|
const addBtn = document.createElement("fig-button");
|
|
6711
|
-
addBtn.setAttribute("variant", "
|
|
6718
|
+
addBtn.setAttribute("variant", "ghost");
|
|
6712
6719
|
addBtn.setAttribute("icon", "true");
|
|
6713
6720
|
addBtn.setAttribute("aria-label", "Add color");
|
|
6714
6721
|
addBtn.className = "palette-add-btn";
|
|
@@ -7034,7 +7041,7 @@ class FigInputGradient extends HTMLElement {
|
|
|
7034
7041
|
const gradientValue = JSON.stringify(this.value);
|
|
7035
7042
|
this.innerHTML = `
|
|
7036
7043
|
<fig-fill-picker mode="gradient"${expAttr} value='${gradientValue}'${disabled ? " disabled" : ""}>
|
|
7037
|
-
<fig-chit
|
|
7044
|
+
<fig-chit background="${this.#buildGradientCSS()}"${disabled ? " disabled" : ""}></fig-chit>
|
|
7038
7045
|
</fig-fill-picker>`;
|
|
7039
7046
|
this.#chit = this.querySelector("fig-chit");
|
|
7040
7047
|
this.#track = null;
|
|
@@ -7043,7 +7050,7 @@ class FigInputGradient extends HTMLElement {
|
|
|
7043
7050
|
}
|
|
7044
7051
|
|
|
7045
7052
|
this.innerHTML = `
|
|
7046
|
-
<fig-chit
|
|
7053
|
+
<fig-chit background="${this.#buildGradientCSS()}"${disabled ? " disabled" : ""}></fig-chit>
|
|
7047
7054
|
${mode === "true" ? `<div class="fig-input-gradient-track">${this.#buildStopHandles()}</div>` : ""}`;
|
|
7048
7055
|
this.#chit = this.querySelector("fig-chit");
|
|
7049
7056
|
this.#track = this.querySelector(".fig-input-gradient-track");
|
|
@@ -7817,13 +7824,17 @@ customElements.define("fig-switch", FigSwitch);
|
|
|
7817
7824
|
* @attr {boolean} open - Whether the toast is visible
|
|
7818
7825
|
*/
|
|
7819
7826
|
class FigToast extends HTMLDialogElement {
|
|
7820
|
-
_defaultOffset = 16; // 1rem in pixels
|
|
7821
|
-
_autoCloseTimer = null;
|
|
7822
|
-
#boundHandleClose;
|
|
7823
|
-
|
|
7824
7827
|
constructor() {
|
|
7825
7828
|
super();
|
|
7826
|
-
this
|
|
7829
|
+
this._figInit();
|
|
7830
|
+
}
|
|
7831
|
+
|
|
7832
|
+
_figInit() {
|
|
7833
|
+
if (this._figInitialized) return;
|
|
7834
|
+
this._figInitialized = true;
|
|
7835
|
+
this._defaultOffset = 16;
|
|
7836
|
+
this._autoCloseTimer = null;
|
|
7837
|
+
this._boundHandleClose = this.handleClose.bind(this);
|
|
7827
7838
|
}
|
|
7828
7839
|
|
|
7829
7840
|
getOffset() {
|
|
@@ -7831,12 +7842,7 @@ class FigToast extends HTMLDialogElement {
|
|
|
7831
7842
|
}
|
|
7832
7843
|
|
|
7833
7844
|
connectedCallback() {
|
|
7834
|
-
|
|
7835
|
-
this._defaultOffset = 16;
|
|
7836
|
-
}
|
|
7837
|
-
if (typeof this._autoCloseTimer === "undefined") {
|
|
7838
|
-
this._autoCloseTimer = null;
|
|
7839
|
-
}
|
|
7845
|
+
this._figInit();
|
|
7840
7846
|
|
|
7841
7847
|
// Set default theme if not specified
|
|
7842
7848
|
if (!this.hasAttribute("theme")) {
|
|
@@ -7868,13 +7874,14 @@ class FigToast extends HTMLDialogElement {
|
|
|
7868
7874
|
}
|
|
7869
7875
|
|
|
7870
7876
|
disconnectedCallback() {
|
|
7877
|
+
this._figInit();
|
|
7871
7878
|
this.clearAutoClose();
|
|
7872
7879
|
}
|
|
7873
7880
|
|
|
7874
7881
|
addCloseListeners() {
|
|
7875
7882
|
this.querySelectorAll("[close-toast]").forEach((button) => {
|
|
7876
|
-
button.removeEventListener("click", this
|
|
7877
|
-
button.addEventListener("click", this
|
|
7883
|
+
button.removeEventListener("click", this._boundHandleClose);
|
|
7884
|
+
button.addEventListener("click", this._boundHandleClose);
|
|
7878
7885
|
});
|
|
7879
7886
|
}
|
|
7880
7887
|
|
|
@@ -7911,7 +7918,7 @@ class FigToast extends HTMLDialogElement {
|
|
|
7911
7918
|
}
|
|
7912
7919
|
}
|
|
7913
7920
|
|
|
7914
|
-
|
|
7921
|
+
_resolveAutoTheme() {
|
|
7915
7922
|
if (this.getAttribute("theme") !== "auto") return;
|
|
7916
7923
|
const cs = getComputedStyle(document.documentElement).colorScheme || "";
|
|
7917
7924
|
const isDark = cs.includes("dark");
|
|
@@ -7922,7 +7929,7 @@ class FigToast extends HTMLDialogElement {
|
|
|
7922
7929
|
* Show the toast notification (non-modal)
|
|
7923
7930
|
*/
|
|
7924
7931
|
showToast() {
|
|
7925
|
-
this
|
|
7932
|
+
this._resolveAutoTheme();
|
|
7926
7933
|
this.show(); // Non-modal show
|
|
7927
7934
|
this.applyPosition();
|
|
7928
7935
|
this.startAutoClose();
|
|
@@ -7943,6 +7950,7 @@ class FigToast extends HTMLDialogElement {
|
|
|
7943
7950
|
}
|
|
7944
7951
|
|
|
7945
7952
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
7953
|
+
this._figInit();
|
|
7946
7954
|
if (name === "offset") {
|
|
7947
7955
|
this.applyPosition();
|
|
7948
7956
|
}
|
|
@@ -7957,7 +7965,7 @@ class FigToast extends HTMLDialogElement {
|
|
|
7957
7965
|
|
|
7958
7966
|
if (name === "theme") {
|
|
7959
7967
|
if (newValue === "auto") {
|
|
7960
|
-
this
|
|
7968
|
+
this._resolveAutoTheme();
|
|
7961
7969
|
} else {
|
|
7962
7970
|
this.style.removeProperty("color-scheme");
|
|
7963
7971
|
}
|
package/package.json
CHANGED