react-os-shell 2.8.1 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/{Browser-RNO4KYSE.js → Browser-HDKOMCUA.js} +4 -4
  2. package/dist/{Browser-RNO4KYSE.js.map → Browser-HDKOMCUA.js.map} +1 -1
  3. package/dist/{Documents-L7CTOPIN.js → Documents-JXLU2ILH.js} +4 -4
  4. package/dist/{Documents-L7CTOPIN.js.map → Documents-JXLU2ILH.js.map} +1 -1
  5. package/dist/Files-Q2YCSHYG.js +13 -0
  6. package/dist/{Files-FJL2BZDI.js.map → Files-Q2YCSHYG.js.map} +1 -1
  7. package/dist/ImageAnnotator-55NPWJ2R.js +4 -0
  8. package/dist/{ImageAnnotator-CTTMAY5Z.js.map → ImageAnnotator-55NPWJ2R.js.map} +1 -1
  9. package/dist/{Notepad-2OJ53Q7M.js → Notepad-TBAF2SHJ.js} +4 -4
  10. package/dist/{Notepad-2OJ53Q7M.js.map → Notepad-TBAF2SHJ.js.map} +1 -1
  11. package/dist/{PomodoroTimer-M7MDQTVN.js → PomodoroTimer-CDAJC2NX.js} +4 -4
  12. package/dist/{PomodoroTimer-M7MDQTVN.js.map → PomodoroTimer-CDAJC2NX.js.map} +1 -1
  13. package/dist/Preview-CHYOTNEP.js +9 -0
  14. package/dist/{Preview-65VPPGWD.js.map → Preview-CHYOTNEP.js.map} +1 -1
  15. package/dist/{Spreadsheet-VIYNZ6KJ.js → Spreadsheet-I2GJKC6Y.js} +4 -4
  16. package/dist/{Spreadsheet-VIYNZ6KJ.js.map → Spreadsheet-I2GJKC6Y.js.map} +1 -1
  17. package/dist/apps/index.js +15 -15
  18. package/dist/{chunk-ZEMXT6BR.js → chunk-75YZMM5Q.js} +5 -5
  19. package/dist/{chunk-ZEMXT6BR.js.map → chunk-75YZMM5Q.js.map} +1 -1
  20. package/dist/{chunk-WG3PMYDQ.js → chunk-DF6TNR4B.js} +5 -5
  21. package/dist/{chunk-WG3PMYDQ.js.map → chunk-DF6TNR4B.js.map} +1 -1
  22. package/dist/{chunk-YQWFKXWH.js → chunk-EHB2QYJX.js} +3 -3
  23. package/dist/{chunk-YQWFKXWH.js.map → chunk-EHB2QYJX.js.map} +1 -1
  24. package/dist/{chunk-P75EON66.js → chunk-FIUUGSGJ.js} +3 -3
  25. package/dist/{chunk-P75EON66.js.map → chunk-FIUUGSGJ.js.map} +1 -1
  26. package/dist/{chunk-IXW6775F.js → chunk-IONOMHM2.js} +3 -3
  27. package/dist/{chunk-IXW6775F.js.map → chunk-IONOMHM2.js.map} +1 -1
  28. package/dist/{chunk-KUIPWCTJ.js → chunk-NUPYEVU4.js} +3 -3
  29. package/dist/{chunk-KUIPWCTJ.js.map → chunk-NUPYEVU4.js.map} +1 -1
  30. package/dist/{chunk-5HXHD62G.js → chunk-QFOOSV3I.js} +5 -5
  31. package/dist/{chunk-5HXHD62G.js.map → chunk-QFOOSV3I.js.map} +1 -1
  32. package/dist/{chunk-V6N2NXHQ.js → chunk-RADCIHYG.js} +3 -3
  33. package/dist/{chunk-V6N2NXHQ.js.map → chunk-RADCIHYG.js.map} +1 -1
  34. package/dist/{chunk-WIJ45SYD.js → chunk-VENYVK3L.js} +18 -10
  35. package/dist/chunk-VENYVK3L.js.map +1 -0
  36. package/dist/index.d.ts +12 -3
  37. package/dist/index.js +26 -23
  38. package/dist/index.js.map +1 -1
  39. package/package.json +1 -1
  40. package/dist/Files-FJL2BZDI.js +0 -13
  41. package/dist/ImageAnnotator-CTTMAY5Z.js +0 -4
  42. package/dist/Preview-65VPPGWD.js +0 -9
  43. package/dist/chunk-WIJ45SYD.js.map +0 -1
@@ -28,17 +28,22 @@ var GLASS_COMMON = `
28
28
  border: 1px solid rgba(255,255,255,0.35);
29
29
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), 0 8px 32px rgba(0,0,0,0.15), 0 2px 8px rgba(0,0,0,0.08);
30
30
  `;
31
- function showToast(variant, message) {
31
+ function showToast(variant, message, opts) {
32
32
  import('./sounds-NT4DEZGD.js').then((s) => {
33
33
  if (variant === "success") s.playSuccess();
34
- else s.playError();
34
+ else if (variant === "error") s.playError();
35
+ else s.playNotification();
35
36
  }).catch(() => {
36
37
  });
37
38
  const container = getOrCreate(TOAST_CONTAINER_ID, "fixed top-4 left-1/2 -translate-x-1/2 z-[9999] flex flex-col gap-2 items-center pointer-events-none");
38
39
  const o = getMenuOpacity();
39
- const isSuccess = variant === "success";
40
- const color = isSuccess ? "#22c55e" : "#ef4444";
41
- const icon = isSuccess ? '<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="' + color + '" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>' : '<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="' + color + '" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>';
40
+ const color = variant === "success" ? "#22c55e" : variant === "error" ? "#ef4444" : "#3b82f6";
41
+ const icons = {
42
+ success: '<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="' + color + '" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>',
43
+ error: '<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="' + color + '" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>',
44
+ info: '<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="' + color + '" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>'
45
+ };
46
+ const icon = icons[variant];
42
47
  const el = document.createElement("div");
43
48
  el.className = "pointer-events-auto";
44
49
  el.style.cssText = `
@@ -48,7 +53,7 @@ function showToast(variant, message) {
48
53
  transition: opacity ${FADE_MS}ms ease, transform ${FADE_MS}ms ease;
49
54
  display: flex; align-items: center; gap: 8px;
50
55
  font-size: 13px; font-weight: 500; color: rgb(55,65,81);
51
- white-space: nowrap;
56
+ max-width: min(90vw, 460px);
52
57
  `;
53
58
  el.innerHTML = icon;
54
59
  const span = document.createElement("span");
@@ -59,11 +64,12 @@ function showToast(variant, message) {
59
64
  el.style.opacity = "1";
60
65
  el.style.transform = "translateY(0) scale(1)";
61
66
  });
67
+ const duration = opts?.duration ?? (variant === "info" ? 4500 : 3e3);
62
68
  setTimeout(() => {
63
69
  el.style.opacity = "0";
64
70
  el.style.transform = "translateY(-10px) scale(0.95)";
65
71
  setTimeout(() => el.remove(), FADE_MS);
66
- }, 3e3);
72
+ }, duration);
67
73
  }
68
74
  function showNotification(message, opts) {
69
75
  import('./sounds-NT4DEZGD.js').then((s) => s.playNotification()).catch(() => {
@@ -111,10 +117,12 @@ function showNotification(message, opts) {
111
117
  var toast = {
112
118
  success: (message) => showToast("success", message),
113
119
  error: (message) => showToast("error", message),
114
- info: (message, opts) => showNotification(message, opts)
120
+ info: (message, opts) => showToast("info", message, opts),
121
+ // Persistent top-right notification card (the old toast.info presentation).
122
+ notify: (message, opts) => showNotification(message, opts)
115
123
  };
116
124
  var toast_default = toast;
117
125
 
118
126
  export { toast_default };
119
- //# sourceMappingURL=chunk-WIJ45SYD.js.map
120
- //# sourceMappingURL=chunk-WIJ45SYD.js.map
127
+ //# sourceMappingURL=chunk-VENYVK3L.js.map
128
+ //# sourceMappingURL=chunk-VENYVK3L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shell/toast.ts"],"names":[],"mappings":"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","file":"chunk-VENYVK3L.js","sourcesContent":["/**\n * Two presentations:\n *\n * 1. toast.success / error / info — brief operation feedback, top-center,\n * auto-dismiss (success/error ~3s, info ~4.5s). The everyday \"what just\n * happened\" feedback — most messages want this.\n * 2. toast.notify — system notification, top-right card, stays 10s, dismissible.\n * For an alert worth lingering on; reach for it deliberately, not by default.\n *\n * (Historically `toast.info` rendered the top-right notification card; it now\n * renders a brief toast — that persistent card moved to `toast.notify`.)\n */\n\nconst TOAST_CONTAINER_ID = 'toast-container';\nconst NOTIF_CONTAINER_ID = 'notif-container';\nconst FADE_MS = 300;\n\nfunction getOrCreate(id: string, className: string): HTMLElement {\n let el = document.getElementById(id);\n if (!el) {\n el = document.createElement('div');\n el.id = id;\n el.className = className;\n document.body.appendChild(el);\n }\n return el;\n}\n\nfunction getMenuOpacity(): number {\n try {\n const val = getComputedStyle(document.documentElement).getPropertyValue('--menu-opacity')?.trim();\n if (val) return parseFloat(val);\n } catch {}\n return 0.95;\n}\n\nfunction glassBackground(o: number): string {\n return `linear-gradient(135deg, rgba(255,255,255,${o * 0.85}) 0%, rgba(255,255,255,${o * 0.65}) 50%, rgba(255,255,255,${o * 0.75}) 100%)`;\n}\n\nconst GLASS_COMMON = `\n backdrop-filter: blur(40px) saturate(1.8); -webkit-backdrop-filter: blur(40px) saturate(1.8);\n border: 1px solid rgba(255,255,255,0.35);\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), 0 8px 32px rgba(0,0,0,0.15), 0 2px 8px rgba(0,0,0,0.08);\n`;\n\n// ── Toast (operation feedback) — top-center, brief ──\n\nfunction showToast(variant: 'success' | 'error' | 'info', message: string,\n opts?: { duration?: number }) {\n import('../utils/sounds').then(s => {\n if (variant === 'success') s.playSuccess();\n else if (variant === 'error') s.playError();\n else s.playNotification();\n }).catch(() => {});\n\n const container = getOrCreate(TOAST_CONTAINER_ID, 'fixed top-4 left-1/2 -translate-x-1/2 z-[9999] flex flex-col gap-2 items-center pointer-events-none');\n const o = getMenuOpacity();\n const color = variant === 'success' ? '#22c55e' : variant === 'error' ? '#ef4444' : '#3b82f6';\n const icons = {\n success: '<svg class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"' + color + '\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M5 13l4 4L19 7\"/></svg>',\n error: '<svg class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"' + color + '\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"/></svg>',\n info: '<svg class=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"' + color + '\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/></svg>',\n };\n const icon = icons[variant];\n\n const el = document.createElement('div');\n el.className = 'pointer-events-auto';\n el.style.cssText = `\n padding: 8px 20px; border-radius: 12px;\n background: ${glassBackground(o)}; ${GLASS_COMMON}\n opacity: 0; transform: translateY(-10px) scale(0.95);\n transition: opacity ${FADE_MS}ms ease, transform ${FADE_MS}ms ease;\n display: flex; align-items: center; gap: 8px;\n font-size: 13px; font-weight: 500; color: rgb(55,65,81);\n max-width: min(90vw, 460px);\n `;\n el.innerHTML = icon;\n const span = document.createElement('span');\n span.textContent = message;\n el.appendChild(span);\n\n container.appendChild(el);\n requestAnimationFrame(() => { el.style.opacity = '1'; el.style.transform = 'translateY(0) scale(1)'; });\n\n // Info messages are usually a sentence (\"no matches — check X\"); give them a\n // beat longer to read than the terse success/error confirmations.\n const duration = opts?.duration ?? (variant === 'info' ? 4500 : 3000);\n setTimeout(() => {\n el.style.opacity = '0';\n el.style.transform = 'translateY(-10px) scale(0.95)';\n setTimeout(() => el.remove(), FADE_MS);\n }, duration);\n}\n\n// ── Notification (system alert) — top-right, stays longer ──\n\nfunction showNotification(message: string, opts?: { duration?: number }) {\n import('../utils/sounds').then(s => s.playNotification()).catch(() => {});\n\n const container = getOrCreate(NOTIF_CONTAINER_ID, 'fixed top-4 right-4 z-[9999] flex flex-col gap-3 items-end pointer-events-none');\n const o = getMenuOpacity();\n\n const el = document.createElement('div');\n el.className = 'pointer-events-auto cursor-pointer';\n el.style.cssText = `\n min-width: 280px; max-width: 380px; padding: 12px 16px; border-radius: 16px;\n background: ${glassBackground(o)}; ${GLASS_COMMON}\n opacity: 0; transform: translateX(30px) scale(0.95);\n transition: opacity ${FADE_MS}ms cubic-bezier(0.4,0,0.2,1), transform ${FADE_MS}ms cubic-bezier(0.4,0,0.2,1);\n display: flex; align-items: flex-start; gap: 12px;\n `;\n\n el.innerHTML = `\n <div style=\"width: 36px; height: 36px; border-radius: 10px; background: rgba(59,130,246,0.15); display: flex; align-items: center; justify-content: center; flex-shrink: 0;\">\n <svg class=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"#3b82f6\" stroke-width=\"2\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0\"/></svg>\n </div>\n <div style=\"flex: 1; min-width: 0;\">\n <div style=\"font-size: 11px; font-weight: 600; color: #3b82f6; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2px;\">Notification</div>\n <div class=\"notif-msg\" style=\"font-size: 13px; font-weight: 500; color: rgb(55,65,81); line-height: 1.4;\"></div>\n </div>\n <button style=\"flex-shrink: 0; padding: 4px; color: rgb(156,163,175); font-size: 18px; line-height: 1; transition: color 0.2s;\" onmouseenter=\"this.style.color='rgb(75,85,99)'\" onmouseleave=\"this.style.color='rgb(156,163,175)'\">&times;</button>\n `;\n\n const msgEl = el.querySelector('.notif-msg');\n if (msgEl) msgEl.textContent = message;\n\n const dismiss = () => {\n el.style.opacity = '0';\n el.style.transform = 'translateX(30px) scale(0.95)';\n setTimeout(() => el.remove(), FADE_MS);\n };\n\n el.querySelector('button')?.addEventListener('click', (e) => { e.stopPropagation(); dismiss(); });\n el.addEventListener('click', dismiss);\n\n container.appendChild(el);\n requestAnimationFrame(() => { el.style.opacity = '1'; el.style.transform = 'translateX(0) scale(1)'; });\n\n setTimeout(dismiss, opts?.duration ?? 10000);\n}\n\nconst toast = {\n success: (message: string) => showToast('success', message),\n error: (message: string) => showToast('error', message),\n info: (message: string, opts?: { duration?: number }) => showToast('info', message, opts),\n // Persistent top-right notification card (the old toast.info presentation).\n notify: (message: string, opts?: { duration?: number }) => showNotification(message, opts),\n};\n\nexport default toast;\n"]}
package/dist/index.d.ts CHANGED
@@ -436,10 +436,16 @@ declare const ALT_SHIFT_E: string;
436
436
  declare const ALT_SHIFT_N: string;
437
437
 
438
438
  /**
439
- * Two notification systems:
439
+ * Two presentations:
440
440
  *
441
- * 1. toast.success/error — operation feedback, top-center, auto-dismiss 3s
442
- * 2. toast.info system notification, top-right, stays 10s, dismissible
441
+ * 1. toast.success / error / info brief operation feedback, top-center,
442
+ * auto-dismiss (success/error ~3s, info ~4.5s). The everyday "what just
443
+ * happened" feedback — most messages want this.
444
+ * 2. toast.notify — system notification, top-right card, stays 10s, dismissible.
445
+ * For an alert worth lingering on; reach for it deliberately, not by default.
446
+ *
447
+ * (Historically `toast.info` rendered the top-right notification card; it now
448
+ * renders a brief toast — that persistent card moved to `toast.notify`.)
443
449
  */
444
450
  declare const toast: {
445
451
  success: (message: string) => void;
@@ -447,6 +453,9 @@ declare const toast: {
447
453
  info: (message: string, opts?: {
448
454
  duration?: number;
449
455
  }) => void;
456
+ notify: (message: string, opts?: {
457
+ duration?: number;
458
+ }) => void;
450
459
  };
451
460
 
452
461
  interface GridColumn {
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
- import { subscribePomo, getPomoSnapshot } from './chunk-P75EON66.js';
2
- export { setShellTodoProvider } from './chunk-P75EON66.js';
3
- import { PREVIEW_OPENED_EVENT, publishDesktopFolders, requestFilesTrashView, FolderGlyph, openPreviewFile, requestFilesDesktopFolderView, FileIconTile, hashGradient } from './chunk-ZEMXT6BR.js';
4
- export { Breadcrumbs } from './chunk-ZEMXT6BR.js';
1
+ import { subscribePomo, getPomoSnapshot } from './chunk-FIUUGSGJ.js';
2
+ export { setShellTodoProvider } from './chunk-FIUUGSGJ.js';
3
+ import { PREVIEW_OPENED_EVENT, publishDesktopFolders, requestFilesTrashView, FolderGlyph, openPreviewFile, requestFilesDesktopFolderView, FileIconTile, hashGradient } from './chunk-75YZMM5Q.js';
4
+ export { Breadcrumbs } from './chunk-75YZMM5Q.js';
5
5
  import { SidebarLayout } from './chunk-VGTEM5RZ.js';
6
6
  export { SidebarLayout } from './chunk-VGTEM5RZ.js';
7
7
  import { playNotification, playStartup, soundsEnabled, getSoundConfig, SOUND_PACK_KEYS, SOUND_PACKS, SOUND_TYPES, SOUND_TYPE_LABELS, setSoundForType, previewSound, setAllSounds, playLogout } from './chunk-D7PYW2QS.js';
8
- import { setPdfPreview } from './chunk-WG3PMYDQ.js';
9
- import './chunk-KUIPWCTJ.js';
10
- import { toast_default } from './chunk-WIJ45SYD.js';
11
- export { toast_default as toast } from './chunk-WIJ45SYD.js';
12
- export { EditableGrid } from './chunk-V6N2NXHQ.js';
13
- import { APP_VERSION } from './chunk-IXW6775F.js';
14
- export { VERSION } from './chunk-IXW6775F.js';
8
+ import { setPdfPreview } from './chunk-DF6TNR4B.js';
9
+ import './chunk-NUPYEVU4.js';
10
+ import { toast_default } from './chunk-VENYVK3L.js';
11
+ export { toast_default as toast } from './chunk-VENYVK3L.js';
12
+ export { EditableGrid } from './chunk-RADCIHYG.js';
13
+ import { APP_VERSION } from './chunk-IONOMHM2.js';
14
+ export { VERSION } from './chunk-IONOMHM2.js';
15
15
  import { useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, WINDOW_REGISTRY, isPageEntry, useShellPrefs, useIsMobile, ModalActions, useModalActive, client_default, LoadingSpinner, setWindowPosition, ThumbCard, activateModal } from './chunk-JNF5VRPB.js';
16
16
  export { CancelButton, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ShellPrefsProvider, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, commitExposeHighlight, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, registerModalEscapeInterceptor, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useLocalStoragePrefs, useModalActive, useShellPrefs, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-JNF5VRPB.js';
17
17
  import { confirm } from './chunk-UBN4IUDE.js';
@@ -1221,7 +1221,7 @@ function BugReportProvider({ children }) {
1221
1221
  )
1222
1222
  ] });
1223
1223
  }
1224
- var LazyImageAnnotator = lazy(() => import('./ImageAnnotator-CTTMAY5Z.js'));
1224
+ var LazyImageAnnotator = lazy(() => import('./ImageAnnotator-55NPWJ2R.js'));
1225
1225
  function UploadDropZone({ onSelect }) {
1226
1226
  const inputRef = useRef(null);
1227
1227
  const [hover, setHover] = useState(false);
@@ -3295,12 +3295,14 @@ function StartMenu({
3295
3295
  const flyoutEstH = flyoutItems.length * sizeConfig.itemH + 12;
3296
3296
  const flyoutH = measuredFlyout?.key === hoveredSection ? measuredFlyout.h : flyoutEstH;
3297
3297
  const menuWidth = sizeConfig.mw;
3298
- const menuRect = menuRef.current?.getBoundingClientRect();
3299
- const minTop = menuRect ? menuRect.top : taskbarPosition === "top" ? taskbarH + 4 : 4;
3300
- const maxBottom = menuRect ? menuRect.bottom : taskbarPosition === "bottom" ? window.innerHeight - taskbarH - 4 : window.innerHeight - 4;
3301
- let flyoutTop = hoveredY - flyoutH / 2;
3298
+ const viewportH = typeof window !== "undefined" ? window.innerHeight : 800;
3299
+ const minTop = (taskbarPosition === "top" ? taskbarH : 0) + 8;
3300
+ const maxBottom = viewportH - (taskbarPosition === "bottom" ? taskbarH : 0) - 8;
3301
+ const availH = Math.max(0, maxBottom - minTop);
3302
+ const flyoutBoxH = Math.min(flyoutH, availH);
3303
+ let flyoutTop = hoveredY - flyoutBoxH / 2;
3302
3304
  if (flyoutTop < minTop) flyoutTop = minTop;
3303
- if (flyoutTop + flyoutH > maxBottom) flyoutTop = Math.max(minTop, maxBottom - flyoutH);
3305
+ if (flyoutTop + flyoutBoxH > maxBottom) flyoutTop = Math.max(minTop, maxBottom - flyoutBoxH);
3304
3306
  const handleSectionHover = (label, e) => {
3305
3307
  clearTimeout(hoverTimeout.current);
3306
3308
  const rect = e.currentTarget.getBoundingClientRect();
@@ -3509,7 +3511,7 @@ function StartMenu({
3509
3511
  setHoveredChild(null);
3510
3512
  }, 200);
3511
3513
  },
3512
- children: /* @__PURE__ */ jsx("div", { className: "py-1 px-1", children: flyoutItems.map((item) => {
3514
+ children: /* @__PURE__ */ jsx("div", { className: "py-1 px-1 overflow-y-auto overscroll-contain", style: { maxHeight: availH }, children: flyoutItems.map((item) => {
3513
3515
  const hasChildren = !!item.children && item.children.length > 0;
3514
3516
  const isChildHovered = hoveredChild === item.to;
3515
3517
  return /* @__PURE__ */ jsxs(
@@ -3553,9 +3555,10 @@ function StartMenu({
3553
3555
  const subLeft = flyoutRect ? flyoutRect.right + 4 : 0;
3554
3556
  const subEstH = kids.length * sizeConfig.itemH + 12;
3555
3557
  const subH = measuredSub?.key === hoveredChild ? measuredSub.h : subEstH;
3556
- let subTop = hoveredChildY - subH / 2;
3558
+ const subBoxH = Math.min(subH, availH);
3559
+ let subTop = hoveredChildY - subBoxH / 2;
3557
3560
  if (subTop < minTop) subTop = minTop;
3558
- if (subTop + subH > maxBottom) subTop = Math.max(minTop, maxBottom - subH);
3561
+ if (subTop + subBoxH > maxBottom) subTop = Math.max(minTop, maxBottom - subBoxH);
3559
3562
  return /* @__PURE__ */ jsx(
3560
3563
  "div",
3561
3564
  {
@@ -3569,7 +3572,7 @@ function StartMenu({
3569
3572
  onMouseLeave: () => {
3570
3573
  childHoverTimeout.current = setTimeout(() => setHoveredChild(null), 200);
3571
3574
  },
3572
- children: /* @__PURE__ */ jsx("div", { className: "py-1 px-1", children: kids.map((child) => /* @__PURE__ */ jsxs("div", { children: [
3575
+ children: /* @__PURE__ */ jsx("div", { className: "py-1 px-1 overflow-y-auto overscroll-contain", style: { maxHeight: availH }, children: kids.map((child) => /* @__PURE__ */ jsxs("div", { children: [
3573
3576
  /* @__PURE__ */ jsxs(
3574
3577
  "button",
3575
3578
  {
@@ -5687,14 +5690,14 @@ function SystemPreferences({
5687
5690
  maxWidth: 360,
5688
5691
  className,
5689
5692
  sidebarClassName: "border-r border-gray-200 bg-gray-50",
5690
- sidebar: /* @__PURE__ */ jsx("nav", { className: "py-1.5", children: sections2.map((item) => {
5693
+ sidebar: /* @__PURE__ */ jsx("nav", { className: "px-1 py-1.5 space-y-0.5", children: sections2.map((item) => {
5691
5694
  const isActive = item.key === selected;
5692
5695
  return /* @__PURE__ */ jsxs(
5693
5696
  "button",
5694
5697
  {
5695
5698
  type: "button",
5696
5699
  onClick: () => setSelected(item.key),
5697
- className: `w-full text-left px-3 py-2.5 text-sm transition-colors flex items-start gap-2.5 ${isActive ? "bg-blue-50 text-blue-700" : "hover:bg-gray-100 text-gray-700"}`,
5700
+ className: `w-full text-left rounded-lg px-3 py-2.5 text-sm transition-colors flex items-start gap-2.5 ${isActive ? "bg-blue-50 text-blue-700" : "hover:bg-gray-100 text-gray-700"}`,
5698
5701
  children: [
5699
5702
  item.icon && /* @__PURE__ */ jsx("span", { className: `mt-0.5 ${isActive ? "text-blue-600" : "text-gray-400"}`, children: item.icon }),
5700
5703
  /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [