react-os-shell 3.26.0 → 4.0.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.
Files changed (49) hide show
  1. package/dist/{Browser-OYJVFNED.js → Browser-YRYIHBS5.js} +5 -5
  2. package/dist/{Browser-OYJVFNED.js.map → Browser-YRYIHBS5.js.map} +1 -1
  3. package/dist/{Calculator-DMOIIGKO.js → Calculator-ZB3PBT4Y.js} +4 -4
  4. package/dist/{Calculator-DMOIIGKO.js.map → Calculator-ZB3PBT4Y.js.map} +1 -1
  5. package/dist/ConfirmDialog-YEYQG4TI.js +4 -0
  6. package/dist/{ConfirmDialog-3RUHJG5R.js.map → ConfirmDialog-YEYQG4TI.js.map} +1 -1
  7. package/dist/{CurrencyConverter-ROSY6A3Q.js → CurrencyConverter-LARMJEQO.js} +4 -4
  8. package/dist/{CurrencyConverter-ROSY6A3Q.js.map → CurrencyConverter-LARMJEQO.js.map} +1 -1
  9. package/dist/{Documents-VLKG4D22.js → Documents-LNKBJNNL.js} +5 -5
  10. package/dist/{Documents-VLKG4D22.js.map → Documents-LNKBJNNL.js.map} +1 -1
  11. package/dist/{Files-WRMJX4QG.js → Files-SAV2TFVZ.js} +7 -7
  12. package/dist/{Files-WRMJX4QG.js.map → Files-SAV2TFVZ.js.map} +1 -1
  13. package/dist/{Notepad-JVB7OIPO.js → Notepad-V3Y6YWWL.js} +5 -5
  14. package/dist/{Notepad-JVB7OIPO.js.map → Notepad-V3Y6YWWL.js.map} +1 -1
  15. package/dist/{PomodoroTimer-RVNX4CYS.js → PomodoroTimer-IFNOHNFU.js} +5 -5
  16. package/dist/{PomodoroTimer-RVNX4CYS.js.map → PomodoroTimer-IFNOHNFU.js.map} +1 -1
  17. package/dist/{Preview-DUADZWDA.js → Preview-FFBHSUHL.js} +5 -5
  18. package/dist/{Preview-DUADZWDA.js.map → Preview-FFBHSUHL.js.map} +1 -1
  19. package/dist/{Spreadsheet-EIWL7RIF.js → Spreadsheet-6WDNXIAL.js} +5 -5
  20. package/dist/{Spreadsheet-EIWL7RIF.js.map → Spreadsheet-6WDNXIAL.js.map} +1 -1
  21. package/dist/{Stock-7BIHXBPQ.js → Stock-QVCSPVG2.js} +4 -4
  22. package/dist/{Stock-7BIHXBPQ.js.map → Stock-QVCSPVG2.js.map} +1 -1
  23. package/dist/{Weather-7KUHPWTZ.js → Weather-LJLGXB5M.js} +4 -4
  24. package/dist/{Weather-7KUHPWTZ.js.map → Weather-LJLGXB5M.js.map} +1 -1
  25. package/dist/{WorldClock-I24ASGUI.js → WorldClock-N5CTLHPG.js} +4 -4
  26. package/dist/{WorldClock-I24ASGUI.js.map → WorldClock-N5CTLHPG.js.map} +1 -1
  27. package/dist/apps/index.js +17 -17
  28. package/dist/{chunk-NQ2QVUVX.js → chunk-63Y56L3Z.js} +3 -3
  29. package/dist/{chunk-NQ2QVUVX.js.map → chunk-63Y56L3Z.js.map} +1 -1
  30. package/dist/{chunk-MU7UZXAS.js → chunk-PG2PMKTJ.js} +3 -3
  31. package/dist/{chunk-MU7UZXAS.js.map → chunk-PG2PMKTJ.js.map} +1 -1
  32. package/dist/{chunk-LRVPNWRE.js → chunk-QXWBHX7J.js} +3 -3
  33. package/dist/chunk-QXWBHX7J.js.map +1 -0
  34. package/dist/{chunk-AA24QYTD.js → chunk-RVUMXSQE.js} +3 -3
  35. package/dist/{chunk-AA24QYTD.js.map → chunk-RVUMXSQE.js.map} +1 -1
  36. package/dist/{chunk-FPDVIPLM.js → chunk-V45E4R5P.js} +4 -4
  37. package/dist/{chunk-FPDVIPLM.js.map → chunk-V45E4R5P.js.map} +1 -1
  38. package/dist/chunk-YIDTMPOP.js +7 -0
  39. package/dist/{chunk-4BOGLRCL.js.map → chunk-YIDTMPOP.js.map} +1 -1
  40. package/dist/{chunk-E6ZOCXEA.js → chunk-YJJDW4GG.js} +87 -25
  41. package/dist/chunk-YJJDW4GG.js.map +1 -0
  42. package/dist/index.d.ts +66 -5
  43. package/dist/index.js +580 -824
  44. package/dist/index.js.map +1 -1
  45. package/package.json +1 -1
  46. package/dist/ConfirmDialog-3RUHJG5R.js +0 -4
  47. package/dist/chunk-4BOGLRCL.js +0 -7
  48. package/dist/chunk-E6ZOCXEA.js.map +0 -1
  49. package/dist/chunk-LRVPNWRE.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/_about.tsx"],"names":[],"mappings":"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","file":"chunk-FPDVIPLM.js","sourcesContent":["/**\n * Shared \"About\" dialog for the bundled apps.\n *\n * Each bundled app carries its own version (independent of the package\n * version) so app-level changes can be tracked without bumping every app at\n * once. `<AboutApp app=\"…\" />` registers an \"About <Name>\" item in the\n * window title menu and renders the dialog: app icon, name, app version and\n * the react-os-shell attribution + shell version.\n *\n * Bump an app's version in `BUILTIN_APP_INFO` whenever that app's behaviour\n * changes, alongside the package-level CHANGELOG entry.\n */\nimport { useCallback, useState, isValidElement, cloneElement, type ReactElement } from 'react';\nimport Modal, { useWindowMenuItem } from '../shell/Modal';\nimport { navIcons } from '../shell-config/nav';\nimport { VERSION } from '../version';\n\nexport interface BuiltinAppInfo {\n /** Display name — matches the window-registry label. */\n name: string;\n /** App version, independent of the package version. */\n version: string;\n /** One-line summary shown in the About dialog. */\n description: string;\n /** Registry route — used to look up the consumer-registered nav icon. */\n route: string;\n}\n\nexport const BUILTIN_APP_INFO = {\n spreadsheet: {\n name: 'Spreadsheets',\n version: '1.1.0',\n route: '/spreadsheet',\n description: 'Multi-sheet spreadsheet editor with CSV / TSV import and export.',\n },\n notepad: {\n name: 'Notepad',\n version: '1.0.0',\n route: '/notepad',\n description: 'Color-coded notes with checklists, desktop stickies and entity autolinking.',\n },\n documents: {\n name: 'Documents',\n version: '1.1.0',\n route: '/documents',\n description: 'Letter-page editor for Word documents and plain-text files — images, lists, alignment.',\n },\n preview: {\n name: 'Preview',\n version: '1.2.1',\n route: '/preview',\n description: 'Viewer for PDF documents, images, DXF drawings and 3D models — CAD-style measuring with object snap and an AutoCAD-like command bar.',\n },\n files: {\n name: 'Files',\n version: '1.1.0',\n route: '/files',\n description: 'Personal file manager with folders, uploads, quota, trash and desktop shortcut folders.',\n },\n browser: {\n name: 'Browser',\n version: '1.0.1',\n route: '/browser',\n description: 'Minimal web browser with bookmarks, history and navigation bar.',\n },\n} satisfies Record<string, BuiltinAppInfo>;\n\nexport type BuiltinAppId = keyof typeof BUILTIN_APP_INFO;\n\nconst ABOUT_MENU_ICON = (\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\" />\n </svg>\n);\n\n// Generic window glyph shown when the consumer hasn't registered a nav icon\n// for the app's route (same fallback shape as the Modal title bar).\nconst FALLBACK_APP_ICON = (\n <svg className=\"h-9 w-9\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6.75A2.25 2.25 0 016 4.5h12a2.25 2.25 0 012.25 2.25v10.5A2.25 2.25 0 0118 19.5H6a2.25 2.25 0 01-2.25-2.25V6.75z M3.75 9h16.5\" />\n </svg>\n);\n\n/** Registers \"About <Name>\" in the window title menu and renders the dialog.\n * Render anywhere inside the app's window. */\nexport default function AboutApp({ app }: { app: BuiltinAppId }) {\n const info = BUILTIN_APP_INFO[app];\n const [open, setOpen] = useState(false);\n const openDialog = useCallback(() => setOpen(true), []);\n useWindowMenuItem(`About ${info.name}`, openDialog, ABOUT_MENU_ICON);\n\n if (!open) return null;\n\n const registered = navIcons[info.route];\n const appIcon = isValidElement(registered)\n ? cloneElement(registered as ReactElement, { className: 'h-9 w-9' } as any)\n : FALLBACK_APP_ICON;\n\n return (\n <Modal open onClose={() => setOpen(false)} title={`About ${info.name}`} size=\"sm\" compact bodyScroll={false} autoHeight dimensions={[320, 320]}>\n <div className=\"flex flex-col items-center text-center px-5 pt-5 pb-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-gray-100 text-gray-600 shrink-0\">\n {appIcon}\n </div>\n <h2 className=\"mt-3 text-lg font-bold text-gray-900\">{info.name}</h2>\n <p className=\"text-[11px] font-mono text-gray-400\">Version {info.version}</p>\n <p className=\"mt-2 text-xs text-gray-500 leading-relaxed\">{info.description}</p>\n <div className=\"mt-4 pt-3 border-t border-gray-200 w-full\">\n <p className=\"text-[11px] text-gray-500\">\n Part of the <span className=\"font-medium text-gray-700\">react-os-shell</span> desktop environment\n </p>\n {VERSION && <p className=\"mt-0.5 text-[10px] font-mono text-gray-400\">shell v{VERSION}</p>}\n </div>\n </div>\n </Modal>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/_about.tsx"],"names":[],"mappings":"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","file":"chunk-V45E4R5P.js","sourcesContent":["/**\n * Shared \"About\" dialog for the bundled apps.\n *\n * Each bundled app carries its own version (independent of the package\n * version) so app-level changes can be tracked without bumping every app at\n * once. `<AboutApp app=\"…\" />` registers an \"About <Name>\" item in the\n * window title menu and renders the dialog: app icon, name, app version and\n * the react-os-shell attribution + shell version.\n *\n * Bump an app's version in `BUILTIN_APP_INFO` whenever that app's behaviour\n * changes, alongside the package-level CHANGELOG entry.\n */\nimport { useCallback, useState, isValidElement, cloneElement, type ReactElement } from 'react';\nimport Modal, { useWindowMenuItem } from '../shell/Modal';\nimport { navIcons } from '../shell-config/nav';\nimport { VERSION } from '../version';\n\nexport interface BuiltinAppInfo {\n /** Display name — matches the window-registry label. */\n name: string;\n /** App version, independent of the package version. */\n version: string;\n /** One-line summary shown in the About dialog. */\n description: string;\n /** Registry route — used to look up the consumer-registered nav icon. */\n route: string;\n}\n\nexport const BUILTIN_APP_INFO = {\n spreadsheet: {\n name: 'Spreadsheets',\n version: '1.1.0',\n route: '/spreadsheet',\n description: 'Multi-sheet spreadsheet editor with CSV / TSV import and export.',\n },\n notepad: {\n name: 'Notepad',\n version: '1.0.0',\n route: '/notepad',\n description: 'Color-coded notes with checklists, desktop stickies and entity autolinking.',\n },\n documents: {\n name: 'Documents',\n version: '1.1.0',\n route: '/documents',\n description: 'Letter-page editor for Word documents and plain-text files — images, lists, alignment.',\n },\n preview: {\n name: 'Preview',\n version: '1.2.1',\n route: '/preview',\n description: 'Viewer for PDF documents, images, DXF drawings and 3D models — CAD-style measuring with object snap and an AutoCAD-like command bar.',\n },\n files: {\n name: 'Files',\n version: '1.1.0',\n route: '/files',\n description: 'Personal file manager with folders, uploads, quota, trash and desktop shortcut folders.',\n },\n browser: {\n name: 'Browser',\n version: '1.0.1',\n route: '/browser',\n description: 'Minimal web browser with bookmarks, history and navigation bar.',\n },\n} satisfies Record<string, BuiltinAppInfo>;\n\nexport type BuiltinAppId = keyof typeof BUILTIN_APP_INFO;\n\nconst ABOUT_MENU_ICON = (\n <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z\" />\n </svg>\n);\n\n// Generic window glyph shown when the consumer hasn't registered a nav icon\n// for the app's route (same fallback shape as the Modal title bar).\nconst FALLBACK_APP_ICON = (\n <svg className=\"h-9 w-9\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 6.75A2.25 2.25 0 016 4.5h12a2.25 2.25 0 012.25 2.25v10.5A2.25 2.25 0 0118 19.5H6a2.25 2.25 0 01-2.25-2.25V6.75z M3.75 9h16.5\" />\n </svg>\n);\n\n/** Registers \"About <Name>\" in the window title menu and renders the dialog.\n * Render anywhere inside the app's window. */\nexport default function AboutApp({ app }: { app: BuiltinAppId }) {\n const info = BUILTIN_APP_INFO[app];\n const [open, setOpen] = useState(false);\n const openDialog = useCallback(() => setOpen(true), []);\n useWindowMenuItem(`About ${info.name}`, openDialog, ABOUT_MENU_ICON);\n\n if (!open) return null;\n\n const registered = navIcons[info.route];\n const appIcon = isValidElement(registered)\n ? cloneElement(registered as ReactElement, { className: 'h-9 w-9' } as any)\n : FALLBACK_APP_ICON;\n\n return (\n <Modal open onClose={() => setOpen(false)} title={`About ${info.name}`} size=\"sm\" compact bodyScroll={false} autoHeight dimensions={[320, 320]}>\n <div className=\"flex flex-col items-center text-center px-5 pt-5 pb-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-gray-100 text-gray-600 shrink-0\">\n {appIcon}\n </div>\n <h2 className=\"mt-3 text-lg font-bold text-gray-900\">{info.name}</h2>\n <p className=\"text-[11px] font-mono text-gray-400\">Version {info.version}</p>\n <p className=\"mt-2 text-xs text-gray-500 leading-relaxed\">{info.description}</p>\n <div className=\"mt-4 pt-3 border-t border-gray-200 w-full\">\n <p className=\"text-[11px] text-gray-500\">\n Part of the <span className=\"font-medium text-gray-700\">react-os-shell</span> desktop environment\n </p>\n {VERSION && <p className=\"mt-0.5 text-[10px] font-mono text-gray-400\">shell v{VERSION}</p>}\n </div>\n </div>\n </Modal>\n );\n}\n"]}
@@ -0,0 +1,7 @@
1
+ // src/version.ts
2
+ var VERSION = "4.0.0" ;
3
+ var APP_VERSION = VERSION;
4
+
5
+ export { APP_VERSION, VERSION };
6
+ //# sourceMappingURL=chunk-YIDTMPOP.js.map
7
+ //# sourceMappingURL=chunk-YIDTMPOP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"names":[],"mappings":";AAIO,IAAM,OAAA,GAAwD,QAAA;AAG9D,IAAM,WAAA,GAAc","file":"chunk-4BOGLRCL.js","sourcesContent":["declare const __PKG_VERSION__: string | undefined;\n\n/** Package version, injected by tsup at build time. Stays as an empty\n * string when the source is consumed without a build (e.g. tests). */\nexport const VERSION: string = typeof __PKG_VERSION__ === 'string' ? __PKG_VERSION__ : '';\n\n/** Legacy alias kept so existing consumers do not break. */\nexport const APP_VERSION = VERSION;\n"]}
1
+ {"version":3,"sources":["../src/version.ts"],"names":[],"mappings":";AAIO,IAAM,OAAA,GAAwD,OAAA;AAG9D,IAAM,WAAA,GAAc","file":"chunk-YIDTMPOP.js","sourcesContent":["declare const __PKG_VERSION__: string | undefined;\n\n/** Package version, injected by tsup at build time. Stays as an empty\n * string when the source is consumed without a build (e.g. tests). */\nexport const VERSION: string = typeof __PKG_VERSION__ === 'string' ? __PKG_VERSION__ : '';\n\n/** Legacy alias kept so existing consumers do not break. */\nexport const APP_VERSION = VERSION;\n"]}
@@ -1,5 +1,5 @@
1
1
  import { glassStyle, GLASS_DIVIDER, navIcons } from './chunk-GW3RA6IS.js';
2
- import { createContext, Component, useContext, useRef, useState, useLayoutEffect, useEffect, useCallback, useSyncExternalStore, isValidElement, cloneElement, Suspense } from 'react';
2
+ import { createContext, Component, useContext, useState, useRef, useEffect, useCallback, useSyncExternalStore, useLayoutEffect, isValidElement, cloneElement, Suspense } from 'react';
3
3
  import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';
4
4
  import { XMarkIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline';
5
5
  import { createPortal } from 'react-dom';
@@ -36,6 +36,30 @@ var apiClient = new Proxy({}, {
36
36
  });
37
37
  var client_default = apiClient;
38
38
 
39
+ // src/shell/entityFetchPolicy.ts
40
+ var RETRYABLE_CLIENT_STATUSES = /* @__PURE__ */ new Set([
41
+ 408,
42
+ // Request Timeout
43
+ 429
44
+ // Too Many Requests
45
+ ]);
46
+ var ENTITY_FETCH_MAX_RETRIES = 3;
47
+ var ENTITY_REFETCH_INTERVAL_MS = 6e4;
48
+ function isPermanentClientError(error) {
49
+ const status = error?.response?.status;
50
+ if (typeof status !== "number") return false;
51
+ return status >= 400 && status < 500 && !RETRYABLE_CLIENT_STATUSES.has(status);
52
+ }
53
+ function shouldRetryEntityFetch(failureCount, error) {
54
+ return !isPermanentClientError(error) && failureCount < ENTITY_FETCH_MAX_RETRIES;
55
+ }
56
+ function entityRefetchInterval(error) {
57
+ return isPermanentClientError(error) ? false : ENTITY_REFETCH_INTERVAL_MS;
58
+ }
59
+ function entityDetailUrl(endpoint, entityId) {
60
+ return `${endpoint}${encodeURIComponent(entityId)}/`;
61
+ }
62
+
39
63
  // src/windowRegistry/types.ts
40
64
  function isPageEntry(entry) {
41
65
  return "component" in entry;
@@ -167,7 +191,7 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
167
191
  const isDraft = typeof item.entityId === "string" && item.entityId.startsWith("new-");
168
192
  const { data: entity, isLoading, refetch } = useQuery({
169
193
  queryKey: [qkPrefix, item.entityId],
170
- queryFn: () => client_default.get(`${entry.endpoint}${item.entityId}/`).then((r) => r.data),
194
+ queryFn: () => client_default.get(entityDetailUrl(entry.endpoint, String(item.entityId))).then((r) => r.data),
171
195
  initialData: item.entitySnapshot,
172
196
  initialDataUpdatedAt: 0,
173
197
  // Treat snapshot as stale so query refetches immediately
@@ -175,9 +199,12 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
175
199
  staleTime: 0,
176
200
  refetchOnWindowFocus: true,
177
201
  refetchOnMount: "always",
178
- refetchInterval: 6e4,
179
- // Fallback polling; WebSocket provides instant updates
180
- refetchIntervalInBackground: false
202
+ // Fallback polling; WebSocket provides instant updates. A window whose
203
+ // entity the server says is not there stops polling instead of asking
204
+ // every 60s forever — see entityFetchPolicy.
205
+ refetchInterval: (query) => entityRefetchInterval(query.state.error),
206
+ refetchIntervalInBackground: false,
207
+ retry: shouldRetryEntityFetch
181
208
  });
182
209
  useEffect(() => {
183
210
  if (entry.selfFetching || isDuplicate || isDraft) return;
@@ -1035,6 +1062,35 @@ function useShellPrefs() {
1035
1062
  return { prefs: {}, save: () => {
1036
1063
  } };
1037
1064
  }
1065
+
1066
+ // src/shell/workArea.ts
1067
+ var SIDEBAR_STRIP_W = 280;
1068
+ function computeMaximizedBox() {
1069
+ const cs = getComputedStyle(document.documentElement);
1070
+ const taskbarH = parseInt(cs.getPropertyValue("--taskbar-height")) || 0;
1071
+ const taskbarW = parseInt(cs.getPropertyValue("--taskbar-width")) || 0;
1072
+ const tbPos = cs.getPropertyValue("--taskbar-position")?.trim() || "bottom";
1073
+ const sidebarW = parseInt(cs.getPropertyValue("--sidebar-width")) || 0;
1074
+ return {
1075
+ x: (tbPos === "left" ? taskbarW : 0) + sidebarW,
1076
+ y: tbPos === "top" ? taskbarH : 0,
1077
+ w: window.innerWidth - (tbPos === "left" || tbPos === "right" ? taskbarW : 0) - sidebarW,
1078
+ h: window.innerHeight - (tbPos === "top" || tbPos === "bottom" ? taskbarH : 0)
1079
+ };
1080
+ }
1081
+ function boxFillsWorkArea(box, workArea2, sidebarReserved) {
1082
+ const TOL = 4;
1083
+ const otherW = sidebarReserved ? workArea2.w + SIDEBAR_STRIP_W : workArea2.w - SIDEBAR_STRIP_W;
1084
+ const fillsWidth = Math.abs(box.w - workArea2.w) <= TOL || Math.abs(box.w - otherW) <= TOL;
1085
+ return Math.abs(box.h - workArea2.h) <= TOL && fillsWidth;
1086
+ }
1087
+ function isSidebarStripReserved() {
1088
+ return (parseInt(getComputedStyle(document.documentElement).getPropertyValue("--sidebar-width")) || 0) > 0;
1089
+ }
1090
+ function readAlwaysMaximizedFlag() {
1091
+ if (typeof document === "undefined") return false;
1092
+ return getComputedStyle(document.documentElement).getPropertyValue("--layout-mode")?.trim() === "sidebar";
1093
+ }
1038
1094
  var ModalIdContext = createContext("");
1039
1095
  var WindowShortcutContext = createContext(null);
1040
1096
  function WindowShortcutProvider({ spec, children }) {
@@ -1148,7 +1204,7 @@ function CancelButton({ onClick, children, className }) {
1148
1204
  const ctx = useContext(ModalActionsContext);
1149
1205
  const handleClick = async () => {
1150
1206
  if (ctx?.isDirty) {
1151
- const { confirm: confirm2 } = await import('./ConfirmDialog-3RUHJG5R.js');
1207
+ const { confirm: confirm2 } = await import('./ConfirmDialog-YEYQG4TI.js');
1152
1208
  const ok = await confirm2({
1153
1209
  title: "Discard changes?",
1154
1210
  message: "You have unsaved changes. Are you sure you want to cancel? All changes will be lost.",
@@ -1217,6 +1273,18 @@ function setWindowPosition(key, pos) {
1217
1273
  _windowPositions[key] = pos;
1218
1274
  _savePositionsDebounced();
1219
1275
  }
1276
+ function forgetMaximizedWindowBoxes() {
1277
+ const workArea2 = computeMaximizedBox();
1278
+ const sidebarReserved = isSidebarStripReserved();
1279
+ let changed = false;
1280
+ for (const key of Object.keys(_windowPositions)) {
1281
+ if (boxFillsWorkArea(_windowPositions[key], workArea2, sidebarReserved)) {
1282
+ delete _windowPositions[key];
1283
+ changed = true;
1284
+ }
1285
+ }
1286
+ if (changed) _savePositionsDebounced();
1287
+ }
1220
1288
  var sizeDefaults = {
1221
1289
  sm: 384,
1222
1290
  md: 512,
@@ -1857,17 +1925,7 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
1857
1925
  };
1858
1926
  }, [open]);
1859
1927
  const isNested = useRef(false);
1860
- const calcMaximized = useCallback(() => {
1861
- const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--taskbar-height")) || 0;
1862
- const taskbarW = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--taskbar-width")) || 0;
1863
- const tbPos = getComputedStyle(document.documentElement).getPropertyValue("--taskbar-position")?.trim() || "bottom";
1864
- const sidebarW = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--sidebar-width")) || 0;
1865
- const x = (tbPos === "left" ? taskbarW : 0) + sidebarW;
1866
- const y = tbPos === "top" ? taskbarH : 0;
1867
- const w = window.innerWidth - (tbPos === "left" || tbPos === "right" ? taskbarW : 0) - sidebarW;
1868
- const h = window.innerHeight - (tbPos === "top" || tbPos === "bottom" ? taskbarH : 0);
1869
- return { x, y, w, h };
1870
- }, []);
1928
+ const calcMaximized = useCallback(computeMaximizedBox, []);
1871
1929
  const calcWindowed = useCallback(() => {
1872
1930
  const sw = 0;
1873
1931
  const taskbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--taskbar-height")) || 0;
@@ -2004,11 +2062,6 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
2004
2062
  return openMaximized ? calcMaximized() : calcWindowed();
2005
2063
  });
2006
2064
  const [autoHeightResolved, setAutoHeightResolved] = useState(() => !autoHeight);
2007
- const readAlwaysMaximizedFlag = () => {
2008
- if (typeof document === "undefined") return false;
2009
- const mode = getComputedStyle(document.documentElement).getPropertyValue("--layout-mode")?.trim();
2010
- return mode === "sidebar";
2011
- };
2012
2065
  const [alwaysMaximizedRaw, setAlwaysMaximizedRaw] = useState(() => readAlwaysMaximizedFlag());
2013
2066
  useEffect(() => {
2014
2067
  const refresh = () => setAlwaysMaximizedRaw(readAlwaysMaximizedFlag());
@@ -2087,6 +2140,15 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
2087
2140
  setBox(calcMaximized());
2088
2141
  }
2089
2142
  }, [alwaysMaximized, calcMaximized]);
2143
+ useEffect(() => {
2144
+ if (widget) return;
2145
+ const restore = () => {
2146
+ setMaximized(false);
2147
+ setBox(calcWindowed());
2148
+ };
2149
+ window.addEventListener("react-os-shell:restore-windowed", restore);
2150
+ return () => window.removeEventListener("react-os-shell:restore-windowed", restore);
2151
+ }, [widget, calcWindowed]);
2090
2152
  useEffect(() => {
2091
2153
  if (open && boxKey) {
2092
2154
  _windowPositions[boxKey] = box;
@@ -3113,6 +3175,6 @@ function ConfirmProvider({ children }) {
3113
3175
  ] });
3114
3176
  }
3115
3177
 
3116
- export { CancelButton, ConfirmProvider, CopyButton, DocFavStar, LoadingSpinner, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ShellPrefsProvider, ThumbCard, WINDOW_REGISTRY, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, activateModal, client_default, commitExposeHighlight, confirm, confirmDestructive, exitExposeMode, getActiveModalId, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, isShellApiClientConfigured, prompt, registerModalEscapeInterceptor, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useConfirm, useIsMobile, useLocalStoragePrefs, useModalActive, useShellPrefs, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
3117
- //# sourceMappingURL=chunk-E6ZOCXEA.js.map
3118
- //# sourceMappingURL=chunk-E6ZOCXEA.js.map
3178
+ export { CancelButton, ConfirmProvider, CopyButton, DocFavStar, LoadingSpinner, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, SIDEBAR_STRIP_W, ShellPrefsProvider, WINDOW_REGISTRY, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, client_default, commitExposeHighlight, confirm, confirmDestructive, exitExposeMode, forgetMaximizedWindowBoxes, getActiveModalId, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, isShellApiClientConfigured, prompt, registerModalEscapeInterceptor, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useConfirm, useIsMobile, useLocalStoragePrefs, useModalActive, useShellPrefs, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
3179
+ //# sourceMappingURL=chunk-YJJDW4GG.js.map
3180
+ //# sourceMappingURL=chunk-YJJDW4GG.js.map