react-os-shell 0.1.5 → 0.1.7

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 (30) hide show
  1. package/dist/{Calculator-MBZQ67JD.js → Calculator-PTET7HM2.js} +4 -4
  2. package/dist/{Calculator-MBZQ67JD.js.map → Calculator-PTET7HM2.js.map} +1 -1
  3. package/dist/{Calendar-T3ICM2WO.js → Calendar-H6WA57K2.js} +3 -3
  4. package/dist/{Calendar-T3ICM2WO.js.map → Calendar-H6WA57K2.js.map} +1 -1
  5. package/dist/{CurrencyConverter-MBMRX5RJ.js → CurrencyConverter-ZLZIO4TW.js} +4 -4
  6. package/dist/{CurrencyConverter-MBMRX5RJ.js.map → CurrencyConverter-ZLZIO4TW.js.map} +1 -1
  7. package/dist/{Email-TDD2OOEQ.js → Email-E3ZZUUON.js} +3 -3
  8. package/dist/{Email-TDD2OOEQ.js.map → Email-E3ZZUUON.js.map} +1 -1
  9. package/dist/{Minesweeper-JOEK7UEM.js → Minesweeper-OBQCXZKI.js} +3 -3
  10. package/dist/{Minesweeper-JOEK7UEM.js.map → Minesweeper-OBQCXZKI.js.map} +1 -1
  11. package/dist/{Notepad-B7X2A6LE.js → Notepad-6L6BWIBG.js} +3 -3
  12. package/dist/{Notepad-B7X2A6LE.js.map → Notepad-6L6BWIBG.js.map} +1 -1
  13. package/dist/{PomodoroTimer-6GSD3YKY.js → PomodoroTimer-SDRN2GZD.js} +4 -4
  14. package/dist/{PomodoroTimer-6GSD3YKY.js.map → PomodoroTimer-SDRN2GZD.js.map} +1 -1
  15. package/dist/{Spreadsheet-SHJLUKS5.js → Spreadsheet-N6CTEPJM.js} +3 -3
  16. package/dist/{Spreadsheet-SHJLUKS5.js.map → Spreadsheet-N6CTEPJM.js.map} +1 -1
  17. package/dist/{Weather-MBZS6ZJ5.js → Weather-QZJWPPUP.js} +4 -4
  18. package/dist/{Weather-MBZS6ZJ5.js.map → Weather-QZJWPPUP.js.map} +1 -1
  19. package/dist/apps/index.d.ts +1 -1
  20. package/dist/apps/index.js +10 -10
  21. package/dist/apps/index.js.map +1 -1
  22. package/dist/{chunk-2MNCN6VM.js → chunk-4POBPSEW.js} +3 -3
  23. package/dist/{chunk-2MNCN6VM.js.map → chunk-4POBPSEW.js.map} +1 -1
  24. package/dist/{chunk-OVUT6VRS.js → chunk-ZR2DVGZI.js} +143 -45
  25. package/dist/chunk-ZR2DVGZI.js.map +1 -0
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +2 -2
  28. package/dist/{types-CFIZ1_xt.d.ts → types-BKoa7nhP.d.ts} +4 -0
  29. package/package.json +1 -1
  30. package/dist/chunk-OVUT6VRS.js.map +0 -1
@@ -911,6 +911,7 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
911
911
  ref: panelRef,
912
912
  "data-modal-panel": true,
913
913
  "data-modal-id": modalId,
914
+ "data-window-key": windowKey || void 0,
914
915
  ...allowPinOnTop ? { "data-utility": "" } : {},
915
916
  className: `fixed rounded-lg flex flex-col overflow-hidden group ${widget ? isActive ? "shadow-2xl" : "shadow-lg" : `border ${isActive ? "shadow-2xl border-gray-200" : "shadow-lg border-gray-300"}`}`,
916
917
  onMouseDown: (e) => {
@@ -1269,6 +1270,9 @@ function RestoredRegistryModal({ item, onClose, onMinimize }) {
1269
1270
  }
1270
1271
  );
1271
1272
  }
1273
+ function findPanelByWindowKey(key) {
1274
+ return document.querySelector(`[data-modal-panel][data-window-key="${key}"]`);
1275
+ }
1272
1276
  function findPanelByLabel(label) {
1273
1277
  const panels = document.querySelectorAll("[data-modal-panel]");
1274
1278
  for (const p of Array.from(panels)) {
@@ -1277,32 +1281,35 @@ function findPanelByLabel(label) {
1277
1281
  }
1278
1282
  return null;
1279
1283
  }
1280
- function TaskbarTabPreview({ label, anchorEl, onMouseEnter, onMouseLeave }) {
1284
+ function ThumbCard({ id, label, maxW, maxH, onClick, onClose }) {
1281
1285
  const previewRef = useRef(null);
1282
- const PREVIEW_W = 240;
1283
- const PREVIEW_H = 150;
1286
+ const [size, setSize] = useState({ w: maxW, h: maxH });
1284
1287
  useEffect(() => {
1285
1288
  const inner = previewRef.current;
1286
1289
  if (!inner) return;
1287
- const target = findPanelByLabel(label);
1290
+ const target = findPanelByWindowKey(id) ?? findPanelByLabel(label);
1288
1291
  if (!target) return;
1289
- const rect2 = target.getBoundingClientRect();
1290
- if (rect2.width === 0 || rect2.height === 0) return;
1291
- const scale = Math.min(PREVIEW_W / rect2.width, PREVIEW_H / rect2.height);
1292
+ const rect = target.getBoundingClientRect();
1293
+ if (rect.width === 0 || rect.height === 0) return;
1294
+ const ratio = Math.min(maxW / rect.width, maxH / rect.height);
1295
+ const cardW = Math.max(80, Math.round(rect.width * ratio));
1296
+ const cardH = Math.max(60, Math.round(rect.height * ratio));
1297
+ setSize({ w: cardW, h: cardH });
1292
1298
  const clone = target.cloneNode(true);
1293
1299
  clone.style.position = "absolute";
1294
1300
  clone.style.top = "0";
1295
1301
  clone.style.left = "0";
1296
1302
  clone.style.right = "auto";
1297
1303
  clone.style.bottom = "auto";
1298
- clone.style.width = rect2.width + "px";
1299
- clone.style.height = rect2.height + "px";
1300
- clone.style.transform = `scale(${scale})`;
1304
+ clone.style.width = rect.width + "px";
1305
+ clone.style.height = rect.height + "px";
1306
+ clone.style.transform = `scale(${ratio})`;
1301
1307
  clone.style.transformOrigin = "top left";
1302
1308
  clone.style.pointerEvents = "none";
1303
1309
  clone.style.animation = "none";
1304
1310
  clone.removeAttribute("data-modal-panel");
1305
1311
  clone.removeAttribute("data-modal-id");
1312
+ clone.removeAttribute("data-window-key");
1306
1313
  clone.querySelectorAll('[role="dialog"], [data-portal]').forEach((el) => {
1307
1314
  el.style.display = "none";
1308
1315
  });
@@ -1311,30 +1318,66 @@ function TaskbarTabPreview({ label, anchorEl, onMouseEnter, onMouseLeave }) {
1311
1318
  return () => {
1312
1319
  inner.innerHTML = "";
1313
1320
  };
1314
- }, [label]);
1321
+ }, [id, label, maxW, maxH]);
1322
+ return /* @__PURE__ */ jsxs(
1323
+ "div",
1324
+ {
1325
+ style: { width: size.w, height: size.h },
1326
+ className: "relative rounded-md overflow-hidden bg-white/95 border border-gray-300 shadow-md cursor-pointer hover:ring-2 hover:ring-blue-400 transition shrink-0",
1327
+ onClick,
1328
+ children: [
1329
+ /* @__PURE__ */ jsx("div", { ref: previewRef, className: "absolute inset-0 overflow-hidden" }),
1330
+ /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 px-2 py-1 text-[10px] font-medium text-white bg-gradient-to-t from-black/80 to-transparent truncate pointer-events-none", children: label }),
1331
+ onClose && /* @__PURE__ */ jsx(
1332
+ "button",
1333
+ {
1334
+ onClick: (e) => {
1335
+ e.stopPropagation();
1336
+ onClose();
1337
+ },
1338
+ className: "absolute top-1 right-1 h-4 w-4 rounded-full bg-black/40 hover:bg-red-500/90 text-white flex items-center justify-center",
1339
+ title: "Close window",
1340
+ children: /* @__PURE__ */ jsx("svg", { className: "h-2.5 w-2.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 3, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) })
1341
+ }
1342
+ )
1343
+ ]
1344
+ }
1345
+ );
1346
+ }
1347
+ function TaskbarTabPreview({ items, anchorEl, onActivate, onClose, onMouseEnter, onMouseLeave }) {
1348
+ const MAX_W = 240;
1349
+ const MAX_H = 160;
1350
+ const isGroup = items.length > 1;
1315
1351
  const rect = anchorEl.getBoundingClientRect();
1316
1352
  const taskbarPos = getComputedStyle(document.documentElement).getPropertyValue("--taskbar-position")?.trim() || "bottom";
1317
- const left = Math.max(8, Math.min(rect.left + rect.width / 2 - PREVIEW_W / 2, window.innerWidth - PREVIEW_W - 8));
1318
- const top = taskbarPos === "top" ? rect.bottom + 8 : taskbarPos === "bottom" ? rect.top - PREVIEW_H - 8 : rect.top + rect.height / 2 - PREVIEW_H / 2;
1319
- const adjustedLeft = taskbarPos === "left" ? rect.right + 8 : taskbarPos === "right" ? rect.left - PREVIEW_W - 8 : left;
1353
+ const top = taskbarPos === "top" ? rect.bottom + 8 : taskbarPos === "bottom" ? Math.max(8, rect.top - MAX_H - 24) : rect.top + rect.height / 2 - MAX_H / 2;
1354
+ const left = taskbarPos === "left" || taskbarPos === "right" ? taskbarPos === "left" ? rect.right + 8 : rect.left - MAX_W - 8 : Math.max(8, rect.left + rect.width / 2 - (isGroup ? MAX_W : MAX_W / 2));
1320
1355
  return createPortal(
1321
- /* @__PURE__ */ jsxs(
1356
+ /* @__PURE__ */ jsx(
1322
1357
  "div",
1323
1358
  {
1324
- style: { position: "fixed", left: adjustedLeft, top, width: PREVIEW_W, height: PREVIEW_H, zIndex: 9999 },
1325
- className: "rounded-lg overflow-hidden bg-white/95 backdrop-blur-sm border border-gray-300 shadow-2xl",
1359
+ style: { position: "fixed", left, top, zIndex: 9999, maxWidth: "calc(100vw - 16px)" },
1360
+ className: isGroup ? "flex gap-2 p-2 rounded-lg bg-white/40 backdrop-blur-sm border border-white/30 shadow-2xl flex-wrap" : "",
1326
1361
  onMouseEnter,
1327
1362
  onMouseLeave,
1328
- children: [
1329
- /* @__PURE__ */ jsx("div", { ref: previewRef, className: "absolute inset-0 overflow-hidden" }),
1330
- /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 px-2 py-1 text-[11px] font-medium text-white bg-gradient-to-t from-black/80 to-transparent truncate pointer-events-none", children: label })
1331
- ]
1363
+ children: items.map((it) => /* @__PURE__ */ jsx(
1364
+ ThumbCard,
1365
+ {
1366
+ id: it.id,
1367
+ label: it.label,
1368
+ maxW: MAX_W,
1369
+ maxH: MAX_H,
1370
+ onClick: () => onActivate(it.id),
1371
+ onClose: () => onClose(it.id)
1372
+ },
1373
+ it.id
1374
+ ))
1332
1375
  }
1333
1376
  ),
1334
1377
  document.body
1335
1378
  );
1336
1379
  }
1337
- function TaskbarWindows({ openWindows, onRemove, onCloseAll, onSplitView, onActivate }) {
1380
+ function TaskbarWindows({ openWindows, onRemove, onCloseAll, onSplitView, onActivate, onActivateById }) {
1338
1381
  const [target, setTarget] = useState(null);
1339
1382
  useEffect(() => {
1340
1383
  const el = document.getElementById("taskbar-windows");
@@ -1351,16 +1394,27 @@ function TaskbarWindows({ openWindows, onRemove, onCloseAll, onSplitView, onActi
1351
1394
  }
1352
1395
  }, []);
1353
1396
  const activeModalId = useSyncExternalStore(subscribeActive, getActiveModalId);
1354
- const [hoveredLabel, setHoveredLabel] = useState(null);
1397
+ const [, forceTick] = useState(0);
1398
+ useEffect(() => {
1399
+ const onTitle = () => forceTick((t) => t + 1);
1400
+ window.addEventListener("window-title-update", onTitle);
1401
+ return () => window.removeEventListener("window-title-update", onTitle);
1402
+ }, []);
1403
+ const liveTitle = (label) => {
1404
+ const panel = findPanelByLabel(label);
1405
+ const titleEl = panel?.querySelector(".text-lg, .text-sm.font-medium");
1406
+ return titleEl?.textContent?.trim() || label;
1407
+ };
1408
+ const [hoveredItems, setHoveredItems] = useState(null);
1355
1409
  const [hoveredAnchor, setHoveredAnchor] = useState(null);
1356
1410
  const hoverTimerRef = useRef(null);
1357
- const handleEnter = (label, el) => {
1411
+ const handleEnter = (items, el) => {
1358
1412
  if (hoverTimerRef.current) {
1359
1413
  clearTimeout(hoverTimerRef.current);
1360
1414
  hoverTimerRef.current = null;
1361
1415
  }
1362
1416
  hoverTimerRef.current = setTimeout(() => {
1363
- setHoveredLabel(label);
1417
+ setHoveredItems(items);
1364
1418
  setHoveredAnchor(el);
1365
1419
  }, 350);
1366
1420
  };
@@ -1370,7 +1424,7 @@ function TaskbarWindows({ openWindows, onRemove, onCloseAll, onSplitView, onActi
1370
1424
  hoverTimerRef.current = null;
1371
1425
  }
1372
1426
  hoverTimerRef.current = setTimeout(() => {
1373
- setHoveredLabel(null);
1427
+ setHoveredItems(null);
1374
1428
  setHoveredAnchor(null);
1375
1429
  }, 150);
1376
1430
  };
@@ -1382,45 +1436,63 @@ function TaskbarWindows({ openWindows, onRemove, onCloseAll, onSplitView, onActi
1382
1436
  };
1383
1437
  const tabWindows = openWindows.filter((item) => !item.route || !WINDOW_REGISTRY[item.route]?.utility);
1384
1438
  if (!target || tabWindows.length === 0) return null;
1439
+ const groups = [];
1440
+ const idx = /* @__PURE__ */ new Map();
1441
+ for (const item of tabWindows) {
1442
+ const key = item.route ?? `entity:${item.id}`;
1443
+ const i = idx.get(key);
1444
+ if (i !== void 0) {
1445
+ groups[i].items.push(item);
1446
+ } else {
1447
+ idx.set(key, groups.length);
1448
+ const registryLabel = item.route ? WINDOW_REGISTRY[item.route]?.label : void 0;
1449
+ groups.push({ key, route: item.route, label: registryLabel ?? item.label, items: [item] });
1450
+ }
1451
+ }
1385
1452
  return createPortal(
1386
1453
  /* @__PURE__ */ jsxs(Fragment, { children: [
1387
- tabWindows.map((item) => {
1388
- const icon = item.route ? navIcons[item.route] : null;
1454
+ groups.map((group) => {
1455
+ const icon = group.route ? navIcons[group.route] : null;
1456
+ const primary = group.items[group.items.length - 1];
1389
1457
  let isActive = false;
1390
1458
  if (activeModalId) {
1391
1459
  const panel = document.querySelector(`[data-modal-id="${activeModalId}"]`);
1392
1460
  if (panel) {
1393
1461
  const titleEl = panel.querySelector(".text-lg, .text-sm.font-medium");
1394
- if (titleEl?.textContent?.includes(item.label)) isActive = true;
1462
+ const titleText = titleEl?.textContent ?? "";
1463
+ isActive = group.items.some((it) => titleText.includes(it.label));
1395
1464
  }
1396
1465
  }
1466
+ const isGrouped = group.items.length > 1;
1397
1467
  return /* @__PURE__ */ jsxs(
1398
1468
  "button",
1399
1469
  {
1400
- onClick: () => onActivate(item.label),
1401
- onMouseEnter: (e) => handleEnter(item.label, e.currentTarget),
1470
+ onClick: () => onActivateById(primary.id),
1471
+ onMouseEnter: (e) => handleEnter(group.items, e.currentTarget),
1402
1472
  onMouseLeave: handleLeave,
1403
1473
  onDoubleClick: (e) => {
1404
1474
  e.stopPropagation();
1405
- window.dispatchEvent(new CustomEvent("modal-center", { detail: { label: item.label } }));
1475
+ window.dispatchEvent(new CustomEvent("modal-center", { detail: { label: primary.label } }));
1406
1476
  },
1407
1477
  onContextMenu: (e) => {
1408
1478
  e.preventDefault();
1409
1479
  e.stopPropagation();
1410
- window.dispatchEvent(new CustomEvent("modal-context-menu", { detail: { label: item.label, x: e.clientX, y: e.clientY } }));
1480
+ window.dispatchEvent(new CustomEvent("modal-context-menu", { detail: { label: primary.label, x: e.clientX, y: e.clientY } }));
1411
1481
  },
1412
1482
  style: { width: "var(--window-tab-width, 200px)", fontSize: "var(--window-tab-font-size, 12px)" },
1413
- className: `group flex items-center gap-1.5 rounded-lg px-3 py-2 font-medium transition-all min-w-0 shrink ${isActive ? "bg-blue-100/60 border border-blue-400/60 text-blue-700" : "bg-gray-50/40 border border-gray-200/40 text-gray-700 hover:bg-gray-200/40"}`,
1483
+ "data-tab-group": group.key,
1484
+ className: `group relative flex items-center gap-1.5 rounded-lg px-3 py-2 font-medium transition-all min-w-0 shrink ${isActive ? "bg-blue-100/60 border border-blue-400/60 text-blue-700" : "bg-gray-50/40 border border-gray-200/40 text-gray-700 hover:bg-gray-200/40"}`,
1414
1485
  children: [
1415
1486
  icon && isValidElement(icon) ? cloneElement(icon, { className: `h-3.5 w-3.5 shrink-0 ${isActive ? "text-blue-600" : "text-gray-400"}` }) : /* @__PURE__ */ jsx("svg", { className: `h-3.5 w-3.5 shrink-0 ${isActive ? "text-blue-600" : "text-gray-400"}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" }) }),
1416
- /* @__PURE__ */ jsx("span", { className: "truncate flex-1", children: item.label }),
1417
- /* @__PURE__ */ jsx("span", { role: "button", onClick: (e) => {
1487
+ /* @__PURE__ */ jsx("span", { className: "truncate flex-1", children: isGrouped ? group.label : liveTitle(primary.label) }),
1488
+ isGrouped && /* @__PURE__ */ jsx("span", { className: "shrink-0 px-1.5 py-0.5 rounded-full bg-blue-500/80 text-white text-[10px] font-bold leading-none", children: group.items.length }),
1489
+ !isGrouped && /* @__PURE__ */ jsx("span", { role: "button", onClick: (e) => {
1418
1490
  e.stopPropagation();
1419
- onRemove(item.id);
1491
+ onRemove(primary.id);
1420
1492
  }, className: "ml-auto text-gray-400 hover:text-red-500 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ jsx("svg", { className: "h-3 w-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) })
1421
1493
  ]
1422
1494
  },
1423
- item.id
1495
+ group.key
1424
1496
  );
1425
1497
  }),
1426
1498
  /* @__PURE__ */ jsx("div", { className: "flex-1" }),
@@ -1435,11 +1507,21 @@ function TaskbarWindows({ openWindows, onRemove, onCloseAll, onSplitView, onActi
1435
1507
  ]
1436
1508
  }
1437
1509
  ),
1438
- hoveredLabel && hoveredAnchor && /* @__PURE__ */ jsx(
1510
+ hoveredItems && hoveredAnchor && /* @__PURE__ */ jsx(
1439
1511
  TaskbarTabPreview,
1440
1512
  {
1441
- label: hoveredLabel,
1513
+ items: hoveredItems,
1442
1514
  anchorEl: hoveredAnchor,
1515
+ onActivate: (id) => {
1516
+ onActivateById(id);
1517
+ setHoveredItems(null);
1518
+ setHoveredAnchor(null);
1519
+ },
1520
+ onClose: (id) => {
1521
+ onRemove(id);
1522
+ setHoveredItems(null);
1523
+ setHoveredAnchor(null);
1524
+ },
1443
1525
  onMouseEnter: cancelLeave,
1444
1526
  onMouseLeave: handleLeave
1445
1527
  }
@@ -1492,7 +1574,7 @@ function WindowManagerProvider({ children }) {
1492
1574
  setTimeout(() => {
1493
1575
  const panels = document.querySelectorAll("[data-modal-panel]");
1494
1576
  panels.forEach((p) => {
1495
- const titleEl = p.querySelector(".text-lg");
1577
+ const titleEl = p.querySelector(".text-lg, .text-sm.font-medium");
1496
1578
  if (titleEl?.textContent?.includes(existing.label)) {
1497
1579
  const mid = p.getAttribute("data-modal-id");
1498
1580
  if (mid) activateModal(mid);
@@ -1516,6 +1598,17 @@ function WindowManagerProvider({ children }) {
1516
1598
  if (!WINDOW_REGISTRY[path] || !isPageEntry(WINDOW_REGISTRY[path])) return;
1517
1599
  const entry = WINDOW_REGISTRY[path];
1518
1600
  setOpenWindows((prev) => {
1601
+ if (entry.multiInstance) {
1602
+ const instanceCount = prev.filter((m) => m.type === "page" && m.route === path).length;
1603
+ const nextNum = instanceCount + 1;
1604
+ const id = `page:${path}:${Math.random().toString(36).slice(2, 8)}`;
1605
+ return [...prev, {
1606
+ id,
1607
+ type: "page",
1608
+ label: instanceCount === 0 ? entry.label : `${entry.label} ${nextNum}`,
1609
+ route: path
1610
+ }];
1611
+ }
1519
1612
  const existing = prev.find((m) => m.type === "page" && m.route === path);
1520
1613
  if (existing) {
1521
1614
  if (entry.widget) {
@@ -1524,7 +1617,7 @@ function WindowManagerProvider({ children }) {
1524
1617
  setTimeout(() => {
1525
1618
  const panels = document.querySelectorAll("[data-modal-panel]");
1526
1619
  panels.forEach((p) => {
1527
- const titleEl = p.querySelector(".text-lg");
1620
+ const titleEl = p.querySelector(".text-lg, .text-sm.font-medium");
1528
1621
  if (titleEl?.textContent?.includes(existing.label)) {
1529
1622
  const mid = p.getAttribute("data-modal-id");
1530
1623
  if (mid) activateModal(mid);
@@ -1559,12 +1652,17 @@ function WindowManagerProvider({ children }) {
1559
1652
  onActivate: (label) => {
1560
1653
  const panels = document.querySelectorAll("[data-modal-panel]");
1561
1654
  panels.forEach((p) => {
1562
- const titleEl = p.querySelector(".text-lg");
1655
+ const titleEl = p.querySelector(".text-lg, .text-sm.font-medium");
1563
1656
  if (titleEl?.textContent?.includes(label)) {
1564
1657
  const mid = p.getAttribute("data-modal-id");
1565
1658
  if (mid) activateModal(mid);
1566
1659
  }
1567
1660
  });
1661
+ },
1662
+ onActivateById: (id) => {
1663
+ const panel = document.querySelector(`[data-modal-panel][data-window-key="${id}"]`);
1664
+ const mid = panel?.getAttribute("data-modal-id");
1665
+ if (mid) activateModal(mid);
1568
1666
  }
1569
1667
  }
1570
1668
  ),
@@ -1582,5 +1680,5 @@ function WindowManagerProvider({ children }) {
1582
1680
  }
1583
1681
 
1584
1682
  export { CancelButton, CopyButton, DocFavStar, GLASS_DIVIDER, GLASS_INPUT_BG, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowManagerProvider, WindowTitle, client_default, glassStyle, isEntityEntry, isPageEntry, isSection, navIcons, navSections, sectionIcons, setShellApiClient, setShellNavIcons, setShellWindowRegistry, startMenuCategories, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
1585
- //# sourceMappingURL=chunk-OVUT6VRS.js.map
1586
- //# sourceMappingURL=chunk-OVUT6VRS.js.map
1683
+ //# sourceMappingURL=chunk-ZR2DVGZI.js.map
1684
+ //# sourceMappingURL=chunk-ZR2DVGZI.js.map