@rogieking/figui3 4.8.2 → 4.8.3

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.
Files changed (3) hide show
  1. package/dist/fig.js +30 -30
  2. package/fig.js +152 -144
  3. 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.#boundPointerDown = this.#handlePointerDown.bind(this);
1055
- this.#boundPointerMove = this.#handlePointerMove.bind(this);
1056
- this.#boundPointerUp = this.#handlePointerUp.bind(this);
1057
- this.#boundClose = this.close.bind(this);
1058
- this.#boundIframeMessage = this.#handleIframeMessage.bind(this);
1059
- this.#boundContentMutation = this.#scheduleAutoResize.bind(this);
1060
- this.#boundContentResize = this.#scheduleAutoResize.bind(this);
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.#ensureHeader();
1076
+ this._ensureHeader();
1079
1077
 
1080
1078
  requestAnimationFrame(() => {
1081
- this.#addCloseListeners();
1082
- this.#setupDragListeners();
1083
- this.#applyPosition();
1084
- this.#syncAutoResize();
1079
+ this._addCloseListeners();
1080
+ this._setupDragListeners();
1081
+ this._applyPosition();
1082
+ this._syncAutoResize();
1085
1083
  });
1086
1084
 
1087
- window.addEventListener("message", this.#boundIframeMessage);
1085
+ window.addEventListener("message", this._boundIframeMessage);
1088
1086
  }
1089
1087
 
1090
1088
  disconnectedCallback() {
1091
- this.#removeDragListeners();
1089
+ this._figInit();
1090
+ this._removeDragListeners();
1092
1091
  this.querySelectorAll("fig-button[close-dialog]").forEach((button) => {
1093
- button.removeEventListener("click", this.#boundClose);
1092
+ button.removeEventListener("click", this._boundClose);
1094
1093
  });
1095
- window.removeEventListener("message", this.#boundIframeMessage);
1096
- this.#teardownAutoResize();
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
- #handleIframeMessage(event) {
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.#resizeForIframe(iframe, data);
1108
+ this._resizeForIframe(iframe, data);
1116
1109
  }
1117
1110
 
1118
- #syncAutoResize() {
1111
+ _syncAutoResize() {
1119
1112
  if (this.autoresize) {
1120
- this.#setupAutoResize();
1121
- this.#scheduleAutoResize();
1113
+ this._setupAutoResize();
1114
+ this._scheduleAutoResize();
1122
1115
  } else {
1123
- this.#teardownAutoResize();
1116
+ this._teardownAutoResize();
1124
1117
  }
1125
1118
  }
1126
1119
 
1127
- #setupAutoResize() {
1128
- if (!this.#resizeObserver) {
1129
- this.#resizeObserver = new ResizeObserver(this.#boundContentResize);
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.#resizeObserver.observe(child);
1125
+ this._resizeObserver.observe(child);
1133
1126
  } catch {}
1134
1127
  }
1135
1128
  }
1136
- if (!this.#mutationObserver) {
1137
- this.#mutationObserver = new MutationObserver((mutations) => {
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.#resizeObserver?.observe(node);
1135
+ this._resizeObserver?.observe(node);
1143
1136
  } catch {}
1144
1137
  }
1145
1138
  });
1146
1139
  }
1147
- this.#scheduleAutoResize();
1140
+ this._scheduleAutoResize();
1148
1141
  });
1149
- this.#mutationObserver.observe(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
- #teardownAutoResize() {
1159
- if (this.#resizeObserver) {
1160
- this.#resizeObserver.disconnect();
1161
- this.#resizeObserver = null;
1151
+ _teardownAutoResize() {
1152
+ if (this._resizeObserver) {
1153
+ this._resizeObserver.disconnect();
1154
+ this._resizeObserver = null;
1162
1155
  }
1163
- if (this.#mutationObserver) {
1164
- this.#mutationObserver.disconnect();
1165
- this.#mutationObserver = null;
1156
+ if (this._mutationObserver) {
1157
+ this._mutationObserver.disconnect();
1158
+ this._mutationObserver = null;
1166
1159
  }
1167
- if (this.#autoResizeRafId) {
1168
- cancelAnimationFrame(this.#autoResizeRafId);
1169
- this.#autoResizeRafId = 0;
1160
+ if (this._autoResizeRafId) {
1161
+ cancelAnimationFrame(this._autoResizeRafId);
1162
+ this._autoResizeRafId = 0;
1170
1163
  }
1171
1164
  }
1172
1165
 
1173
- #scheduleAutoResize() {
1166
+ _scheduleAutoResize() {
1174
1167
  if (!this.autoresize) return;
1175
- if (this.#autoResizeRafId) return;
1176
- this.#autoResizeRafId = requestAnimationFrame(() => {
1177
- this.#autoResizeRafId = 0;
1178
- this.#applyAutoResize();
1168
+ if (this._autoResizeRafId) return;
1169
+ this._autoResizeRafId = requestAnimationFrame(() => {
1170
+ this._autoResizeRafId = 0;
1171
+ this._applyAutoResize();
1179
1172
  });
1180
1173
  }
1181
1174
 
1182
- #applyAutoResize() {
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.#resizeToContent(null);
1180
+ this._resizeToContent(null);
1188
1181
  }
1189
1182
 
1190
- #computeChrome(skipChild) {
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
- #resizeForIframe(iframe, data) {
1211
+ _resizeForIframe(iframe, data) {
1219
1212
  if (typeof data.height !== "number" || !(data.height > 0)) return;
1220
- const chrome = this.#computeChrome(iframe);
1213
+ const chrome = this._computeChrome(iframe);
1221
1214
  this.style.height = `${Math.ceil(data.height + chrome)}px`;
1222
1215
  }
1223
1216
 
1224
- #resizeToContent() {
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
- #ensureHeader() {
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
- #addCloseListeners() {
1247
+ _addCloseListeners() {
1255
1248
  this.querySelectorAll("fig-button[close-dialog]").forEach((button) => {
1256
- button.removeEventListener("click", this.#boundClose);
1257
- button.addEventListener("click", this.#boundClose);
1249
+ button.removeEventListener("click", this._boundClose);
1250
+ button.addEventListener("click", this._boundClose);
1258
1251
  });
1259
1252
  }
1260
1253
 
1261
- #applyPosition() {
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.#offset}px`;
1278
+ this.style.top = `${this._offset}px`;
1286
1279
  } else if (hasBottom) {
1287
- this.style.bottom = `${this.#offset}px`;
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.#offset}px`;
1288
+ this.style.left = `${this._offset}px`;
1296
1289
  } else if (hasRight) {
1297
- this.style.right = `${this.#offset}px`;
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.#positionInitialized = true;
1307
+ this._positionInitialized = true;
1315
1308
  }
1316
1309
 
1317
- #setupDragListeners() {
1310
+ _setupDragListeners() {
1318
1311
  if (this.drag) {
1319
- this.addEventListener("pointerdown", this.#boundPointerDown);
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
- #removeDragListeners() {
1331
- this.removeEventListener("pointerdown", this.#boundPointerDown);
1332
- document.removeEventListener("pointermove", this.#boundPointerMove);
1333
- document.removeEventListener("pointerup", this.#boundPointerUp);
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
- #isInteractiveElement(element) {
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
- #handlePointerDown(e) {
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.#isInteractiveElement(e.target)) {
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.#dragPending = true;
1412
- this.#dragStartPos.x = e.clientX;
1413
- this.#dragStartPos.y = e.clientY;
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.#dragOffset.x = e.clientX - rect.left;
1420
- this.#dragOffset.y = e.clientY - rect.top;
1412
+ this._dragOffset.x = e.clientX - rect.left;
1413
+ this._dragOffset.y = e.clientY - rect.top;
1421
1414
 
1422
- document.addEventListener("pointermove", this.#boundPointerMove);
1423
- document.addEventListener("pointerup", this.#boundPointerUp);
1415
+ document.addEventListener("pointermove", this._boundPointerMove);
1416
+ document.addEventListener("pointerup", this._boundPointerUp);
1424
1417
  }
1425
1418
 
1426
- #handlePointerMove(e) {
1419
+ _handlePointerMove(e) {
1427
1420
  // Check if we should start dragging (threshold exceeded)
1428
- if (this.#dragPending && !this.#isDragging) {
1429
- const dx = Math.abs(e.clientX - this.#dragStartPos.x);
1430
- const dy = Math.abs(e.clientY - this.#dragStartPos.y);
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.#dragThreshold || dy > this.#dragThreshold) {
1433
- this.#isDragging = true;
1434
- this.#dragPending = false;
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.#isDragging) return;
1440
+ if (!this._isDragging) return;
1448
1441
 
1449
- this.style.left = `${e.clientX - this.#dragOffset.x}px`;
1450
- this.style.top = `${e.clientY - this.#dragOffset.y}px`;
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
- #handlePointerUp(e) {
1455
- if (this.#isDragging) {
1447
+ _handlePointerUp(e) {
1448
+ if (this._isDragging) {
1456
1449
  this.releasePointerCapture(e.pointerId);
1457
1450
  this.style.cursor = "";
1458
1451
  }
1459
1452
 
1460
- this.#isDragging = false;
1461
- this.#dragPending = false;
1453
+ this._isDragging = false;
1454
+ this._dragPending = false;
1462
1455
 
1463
- document.removeEventListener("pointermove", this.#boundPointerMove);
1464
- document.removeEventListener("pointerup", this.#boundPointerUp);
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 ["modal", "drag", "position", "handle", "title", "resizable", "closedby"];
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.#setupDragListeners();
1485
+ this._setupDragListeners();
1479
1486
  } else {
1480
- this.#removeDragListeners();
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.#positionInitialized) {
1489
- this.#applyPosition();
1495
+ if (name === "position" && this._positionInitialized) {
1496
+ this._applyPosition();
1490
1497
  }
1491
1498
 
1492
1499
  if (name === "modal") {
@@ -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.#boundHandleClose = this.handleClose.bind(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
- if (typeof this._defaultOffset !== "number") {
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.#boundHandleClose);
7877
- button.addEventListener("click", this.#boundHandleClose);
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
- #resolveAutoTheme() {
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.#resolveAutoTheme();
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.#resolveAutoTheme();
7968
+ this._resolveAutoTheme();
7961
7969
  } else {
7962
7970
  this.style.removeProperty("color-scheme");
7963
7971
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "4.8.2",
3
+ "version": "4.8.3",
4
4
  "description": "A lightweight web components library for building Figma plugin and widget UIs with native look and feel",
5
5
  "author": "Rogie King",
6
6
  "license": "MIT",