react-os-shell 2.0.1 → 2.2.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 (51) hide show
  1. package/README.md +1 -1
  2. package/dist/Browser-WBWTTZ3W.js +7 -0
  3. package/dist/{Browser-HGX2YS22.js.map → Browser-WBWTTZ3W.js.map} +1 -1
  4. package/dist/{Calculator-JJZMCBIN.js → Calculator-BQBC6VT5.js} +4 -4
  5. package/dist/{Calculator-JJZMCBIN.js.map → Calculator-BQBC6VT5.js.map} +1 -1
  6. package/dist/{CurrencyConverter-VCZGTULI.js → CurrencyConverter-DTPURMT4.js} +4 -4
  7. package/dist/{CurrencyConverter-VCZGTULI.js.map → CurrencyConverter-DTPURMT4.js.map} +1 -1
  8. package/dist/{Documents-W6JNKYE3.js → Documents-VLN4MNK5.js} +4 -4
  9. package/dist/{Documents-W6JNKYE3.js.map → Documents-VLN4MNK5.js.map} +1 -1
  10. package/dist/Files-VOQ36BX5.js +13 -0
  11. package/dist/{Files-232FHLMO.js.map → Files-VOQ36BX5.js.map} +1 -1
  12. package/dist/{Notepad-G2UOOZOU.js → Notepad-4AHOPIU7.js} +4 -4
  13. package/dist/{Notepad-G2UOOZOU.js.map → Notepad-4AHOPIU7.js.map} +1 -1
  14. package/dist/{PomodoroTimer-TEZJH7E6.js → PomodoroTimer-LIWIBVWC.js} +4 -4
  15. package/dist/{PomodoroTimer-TEZJH7E6.js.map → PomodoroTimer-LIWIBVWC.js.map} +1 -1
  16. package/dist/Preview-ZYVXFIWX.js +9 -0
  17. package/dist/{Preview-QXM6YE7A.js.map → Preview-ZYVXFIWX.js.map} +1 -1
  18. package/dist/Spreadsheet-53RD3BXS.js +7 -0
  19. package/dist/{Spreadsheet-7V6GLIIW.js.map → Spreadsheet-53RD3BXS.js.map} +1 -1
  20. package/dist/{Stock-QVTMAGIU.js → Stock-EHJCICH5.js} +4 -4
  21. package/dist/{Stock-QVTMAGIU.js.map → Stock-EHJCICH5.js.map} +1 -1
  22. package/dist/{Weather-PXUZW22T.js → Weather-3ILCQFSO.js} +4 -4
  23. package/dist/{Weather-PXUZW22T.js.map → Weather-3ILCQFSO.js.map} +1 -1
  24. package/dist/{WorldClock-CRESQVKE.js → WorldClock-TEG2A2UV.js} +4 -4
  25. package/dist/{WorldClock-CRESQVKE.js.map → WorldClock-TEG2A2UV.js.map} +1 -1
  26. package/dist/apps/index.js +19 -19
  27. package/dist/{chunk-XF7JN5E5.js → chunk-34X5YPQT.js} +4 -4
  28. package/dist/{chunk-XF7JN5E5.js.map → chunk-34X5YPQT.js.map} +1 -1
  29. package/dist/{chunk-LXCTOIXP.js → chunk-4F6XJIY3.js} +4 -4
  30. package/dist/{chunk-LXCTOIXP.js.map → chunk-4F6XJIY3.js.map} +1 -1
  31. package/dist/{chunk-5FEW4QE5.js → chunk-BN7GXKEZ.js} +55 -14
  32. package/dist/chunk-BN7GXKEZ.js.map +1 -0
  33. package/dist/{chunk-QESYOYZS.js → chunk-DGPKTNFZ.js} +5 -5
  34. package/dist/{chunk-QESYOYZS.js.map → chunk-DGPKTNFZ.js.map} +1 -1
  35. package/dist/{chunk-JZS5427T.js → chunk-EK4U6LPM.js} +4 -4
  36. package/dist/{chunk-JZS5427T.js.map → chunk-EK4U6LPM.js.map} +1 -1
  37. package/dist/{chunk-Q4EH3NFS.js → chunk-H72L23PH.js} +4 -4
  38. package/dist/{chunk-Q4EH3NFS.js.map → chunk-H72L23PH.js.map} +1 -1
  39. package/dist/{chunk-XO4ZJAUB.js → chunk-IEHKOV3M.js} +4 -4
  40. package/dist/{chunk-XO4ZJAUB.js.map → chunk-IEHKOV3M.js.map} +1 -1
  41. package/dist/{chunk-AYTCQLZ4.js → chunk-YHRVUXLJ.js} +3 -3
  42. package/dist/{chunk-AYTCQLZ4.js.map → chunk-YHRVUXLJ.js.map} +1 -1
  43. package/dist/index.d.ts +80 -2
  44. package/dist/index.js +212 -22
  45. package/dist/index.js.map +1 -1
  46. package/package.json +1 -1
  47. package/dist/Browser-HGX2YS22.js +0 -7
  48. package/dist/Files-232FHLMO.js +0 -13
  49. package/dist/Preview-QXM6YE7A.js +0 -9
  50. package/dist/Spreadsheet-7V6GLIIW.js +0 -7
  51. package/dist/chunk-5FEW4QE5.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { Modal } from './chunk-5FEW4QE5.js';
1
+ import { Modal } from './chunk-BN7GXKEZ.js';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
 
4
4
  var DEFAULT_APPEARANCE = { activeOpacity: 70, inactiveOpacity: 50, activeBlur: 0, inactiveBlur: 0 };
@@ -138,5 +138,5 @@ function WidgetSettingsModal({ open, onClose, title, appearance, onAppearanceCha
138
138
  }
139
139
 
140
140
  export { WidgetSettingsModal, loadAppearance };
141
- //# sourceMappingURL=chunk-AYTCQLZ4.js.map
142
- //# sourceMappingURL=chunk-AYTCQLZ4.js.map
141
+ //# sourceMappingURL=chunk-YHRVUXLJ.js.map
142
+ //# sourceMappingURL=chunk-YHRVUXLJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shell/WidgetSettingsModal.tsx"],"names":[],"mappings":"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","file":"chunk-AYTCQLZ4.js","sourcesContent":["import Modal from './Modal';\n\nexport interface WidgetAppearance {\n activeOpacity: number;\n inactiveOpacity: number;\n activeBlur: number;\n inactiveBlur: number;\n}\n\nexport const DEFAULT_APPEARANCE: WidgetAppearance = { activeOpacity: 70, inactiveOpacity: 50, activeBlur: 0, inactiveBlur: 0 };\n\nexport function loadAppearance(key: string): WidgetAppearance {\n try {\n const saved = JSON.parse(localStorage.getItem(key) || '');\n // Migrate old single `blur` field to activeBlur/inactiveBlur\n if (saved.blur != null && saved.activeBlur == null) {\n saved.activeBlur = saved.blur;\n saved.inactiveBlur = saved.blur;\n delete saved.blur;\n }\n return { ...DEFAULT_APPEARANCE, ...saved };\n }\n catch { return DEFAULT_APPEARANCE; }\n}\n\n/** Reusable settings modal for widgets — renders appearance sliders + optional extra content above */\nexport default function WidgetSettingsModal({ open, onClose, title, appearance, onAppearanceChange, onSave, children }: {\n open: boolean;\n onClose: () => void;\n title: string;\n appearance: WidgetAppearance;\n onAppearanceChange: (a: WidgetAppearance) => void;\n onSave: () => void;\n children?: React.ReactNode;\n}) {\n if (!open) return null;\n\n const inp = 'w-full h-1.5 rounded-full appearance-none bg-gray-200 cursor-pointer accent-blue-500';\n const lbl = 'flex items-center justify-between text-xs text-gray-500';\n\n return (\n <div onPointerDown={e => e.stopPropagation()} onContextMenu={e => e.stopPropagation()}>\n <Modal open={open} onClose={onClose} title={title} size=\"sm\">\n <div className=\"space-y-4\">\n {children}\n\n {/* Appearance */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-3\">Appearance</h3>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <div className=\"text-xs font-medium text-gray-600 mb-2\">Active</div>\n <div className=\"space-y-2\">\n <div>\n <div className={lbl}><span>Opacity</span><span>{appearance.activeOpacity}%</span></div>\n <input type=\"range\" min={20} max={100} value={appearance.activeOpacity}\n onChange={e => onAppearanceChange({ ...appearance, activeOpacity: +e.target.value })} className={inp} />\n </div>\n <div>\n <div className={lbl}><span>Blur</span><span>{appearance.activeBlur}px</span></div>\n <input type=\"range\" min={0} max={20} value={appearance.activeBlur}\n onChange={e => onAppearanceChange({ ...appearance, activeBlur: +e.target.value })} className={inp} />\n </div>\n </div>\n </div>\n <div>\n <div className=\"text-xs font-medium text-gray-600 mb-2\">Inactive</div>\n <div className=\"space-y-2\">\n <div>\n <div className={lbl}><span>Opacity</span><span>{appearance.inactiveOpacity}%</span></div>\n <input type=\"range\" min={20} max={100} value={appearance.inactiveOpacity}\n onChange={e => onAppearanceChange({ ...appearance, inactiveOpacity: +e.target.value })} className={inp} />\n </div>\n <div>\n <div className={lbl}><span>Blur</span><span>{appearance.inactiveBlur}px</span></div>\n <input type=\"range\" min={0} max={20} value={appearance.inactiveBlur}\n onChange={e => onAppearanceChange({ ...appearance, inactiveBlur: +e.target.value })} className={inp} />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex gap-2 pt-2\">\n <button onClick={onSave}\n className=\"flex-1 text-sm font-medium py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition\">Save</button>\n <button onClick={onClose}\n className=\"flex-1 text-sm font-medium py-2 rounded-lg border border-gray-300 text-gray-600 hover:bg-gray-50 transition\">Cancel</button>\n </div>\n </div>\n </Modal>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/shell/WidgetSettingsModal.tsx"],"names":[],"mappings":"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","file":"chunk-YHRVUXLJ.js","sourcesContent":["import Modal from './Modal';\n\nexport interface WidgetAppearance {\n activeOpacity: number;\n inactiveOpacity: number;\n activeBlur: number;\n inactiveBlur: number;\n}\n\nexport const DEFAULT_APPEARANCE: WidgetAppearance = { activeOpacity: 70, inactiveOpacity: 50, activeBlur: 0, inactiveBlur: 0 };\n\nexport function loadAppearance(key: string): WidgetAppearance {\n try {\n const saved = JSON.parse(localStorage.getItem(key) || '');\n // Migrate old single `blur` field to activeBlur/inactiveBlur\n if (saved.blur != null && saved.activeBlur == null) {\n saved.activeBlur = saved.blur;\n saved.inactiveBlur = saved.blur;\n delete saved.blur;\n }\n return { ...DEFAULT_APPEARANCE, ...saved };\n }\n catch { return DEFAULT_APPEARANCE; }\n}\n\n/** Reusable settings modal for widgets — renders appearance sliders + optional extra content above */\nexport default function WidgetSettingsModal({ open, onClose, title, appearance, onAppearanceChange, onSave, children }: {\n open: boolean;\n onClose: () => void;\n title: string;\n appearance: WidgetAppearance;\n onAppearanceChange: (a: WidgetAppearance) => void;\n onSave: () => void;\n children?: React.ReactNode;\n}) {\n if (!open) return null;\n\n const inp = 'w-full h-1.5 rounded-full appearance-none bg-gray-200 cursor-pointer accent-blue-500';\n const lbl = 'flex items-center justify-between text-xs text-gray-500';\n\n return (\n <div onPointerDown={e => e.stopPropagation()} onContextMenu={e => e.stopPropagation()}>\n <Modal open={open} onClose={onClose} title={title} size=\"sm\">\n <div className=\"space-y-4\">\n {children}\n\n {/* Appearance */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-3\">Appearance</h3>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <div className=\"text-xs font-medium text-gray-600 mb-2\">Active</div>\n <div className=\"space-y-2\">\n <div>\n <div className={lbl}><span>Opacity</span><span>{appearance.activeOpacity}%</span></div>\n <input type=\"range\" min={20} max={100} value={appearance.activeOpacity}\n onChange={e => onAppearanceChange({ ...appearance, activeOpacity: +e.target.value })} className={inp} />\n </div>\n <div>\n <div className={lbl}><span>Blur</span><span>{appearance.activeBlur}px</span></div>\n <input type=\"range\" min={0} max={20} value={appearance.activeBlur}\n onChange={e => onAppearanceChange({ ...appearance, activeBlur: +e.target.value })} className={inp} />\n </div>\n </div>\n </div>\n <div>\n <div className=\"text-xs font-medium text-gray-600 mb-2\">Inactive</div>\n <div className=\"space-y-2\">\n <div>\n <div className={lbl}><span>Opacity</span><span>{appearance.inactiveOpacity}%</span></div>\n <input type=\"range\" min={20} max={100} value={appearance.inactiveOpacity}\n onChange={e => onAppearanceChange({ ...appearance, inactiveOpacity: +e.target.value })} className={inp} />\n </div>\n <div>\n <div className={lbl}><span>Blur</span><span>{appearance.inactiveBlur}px</span></div>\n <input type=\"range\" min={0} max={20} value={appearance.inactiveBlur}\n onChange={e => onAppearanceChange({ ...appearance, inactiveBlur: +e.target.value })} className={inp} />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex gap-2 pt-2\">\n <button onClick={onSave}\n className=\"flex-1 text-sm font-medium py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition\">Save</button>\n <button onClick={onClose}\n className=\"flex-1 text-sm font-medium py-2 rounded-lg border border-gray-300 text-gray-600 hover:bg-gray-50 transition\">Cancel</button>\n </div>\n </div>\n </Modal>\n </div>\n );\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { W as WindowRegistry } from './types-BYiS2cc8.js';
2
2
  export { M as ModalRegistryEntry, P as PageRegistryEntry, a as WindowRegistryEntry, i as isEntityEntry, b as isPageEntry, s as setShellWindowRegistry } from './types-BYiS2cc8.js';
3
3
  import * as react from 'react';
4
- import react__default, { ReactNode, CSSProperties, Dispatch, SetStateAction, RefObject } from 'react';
4
+ import react__default, { ReactNode, Component, ErrorInfo, CSSProperties, Dispatch, SetStateAction, RefObject } from 'react';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import * as _tanstack_query_core from '@tanstack/query-core';
7
7
  import { AxiosInstance } from 'axios';
@@ -238,6 +238,42 @@ declare function commitExposeHighlight(): void;
238
238
 
239
239
  declare function Modal({ open, onClose, title, icon, copyText, size, dirty, onNext, onPrev, footer, bodyScroll, onMinimize, initialBox, actions, actionsLeft, allowPinOnTop, initialPosition, widget, compact, appStyle, flushBody, autoHeight, autoMinHeight, widgetMenu, dimensions, windowKey, openedFromKey, children }: ModalProps): react.ReactPortal | null;
240
240
 
241
+ /** Inline crash state rendered in place of a window's content. Centers itself
242
+ * in whatever space the body gives it; `onReload` resets the owning boundary
243
+ * so the content remounts from scratch. */
244
+ declare function WindowCrashedFallback({ error, onReload }: {
245
+ error: Error;
246
+ onReload: () => void;
247
+ }): react_jsx_runtime.JSX.Element;
248
+ interface WindowErrorBoundaryProps {
249
+ children: ReactNode;
250
+ /** Replaces the default inline {@link WindowCrashedFallback}. `reset`
251
+ * clears the caught error so the children remount. */
252
+ fallback?: (error: Error, reset: () => void) => ReactNode;
253
+ }
254
+ /**
255
+ * Error boundary around a window's content. Without it, a page/entity
256
+ * component that throws during render propagates to the root and unmounts the
257
+ * entire desktop. With it, only the crashed window's body is replaced — the
258
+ * window chrome (close/minimize), the taskbar and every other window keep
259
+ * running. Modal wraps its body in one; WindowManager wraps each whole window
260
+ * in another as a last resort for crashes outside the body (e.g. a registry
261
+ * `title()` throwing on malformed data).
262
+ */
263
+ declare class WindowErrorBoundary extends Component<WindowErrorBoundaryProps, {
264
+ error: Error | null;
265
+ }> {
266
+ state: {
267
+ error: Error | null;
268
+ };
269
+ static getDerivedStateFromError(error: unknown): {
270
+ error: Error;
271
+ };
272
+ componentDidCatch(error: Error, info: ErrorInfo): void;
273
+ reset: () => void;
274
+ render(): string | number | boolean | Iterable<ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
275
+ }
276
+
241
277
  /**
242
278
  * Unified popup menu component — used for all context menus, dropdowns, and flyouts.
243
279
  * Reads --menu-density CSS variable: 'tight' or 'normal' (default).
@@ -497,6 +533,48 @@ interface SidebarLayoutProps {
497
533
  }
498
534
  declare function SidebarLayout({ sidebar, children, side, storageKey, defaultWidth, minWidth, maxWidth, className, sidebarClassName, contentClassName, }: SidebarLayoutProps): react_jsx_runtime.JSX.Element;
499
535
 
536
+ interface SearchableOption {
537
+ value: string;
538
+ label: string;
539
+ /** Optional secondary text rendered greyed-out on the right of the
540
+ * option (e.g. an order date next to a proforma number). */
541
+ sublabel?: string;
542
+ }
543
+ interface SearchableSelectProps {
544
+ value: string;
545
+ onChange: (value: string) => void;
546
+ options: SearchableOption[];
547
+ /** Placeholder shown when no value is selected and the field is empty. */
548
+ placeholder?: string;
549
+ /** Fallback placeholder text when no `placeholder` is provided and
550
+ * nothing is selected. Clearing the selection is done via the hover
551
+ * "×" on the input itself. */
552
+ emptyOptionLabel?: string;
553
+ /** Extra Tailwind classes appended to the input (error rings, custom
554
+ * widths…). The base form-input styling is built in. */
555
+ className?: string;
556
+ disabled?: boolean;
557
+ /** Optional id for label-for wiring. */
558
+ id?: string;
559
+ /** When true, the user can submit a value that isn't in `options` —
560
+ * pressing Enter or clicking outside with non-empty search text
561
+ * fires `onChange` with the typed string. The trigger then displays
562
+ * that free-text value as-is. Default false: only listed options
563
+ * can be picked, typing only filters. */
564
+ allowFreeText?: boolean;
565
+ /** Optional notifier fired whenever the user-typed search text changes
566
+ * (including resets to ''). Lets a parent debounce the value and feed
567
+ * a server-side query, so this component can still front a list that
568
+ * is too large to load up-front. */
569
+ onSearchChange?: (text: string) => void;
570
+ /** Optional content rendered inside the trigger's right edge — to the
571
+ * left of the clear button — when the dropdown is closed. Use for
572
+ * compact status pills that should read alongside the selected label.
573
+ * Hidden while the user is typing so the search text stays legible. */
574
+ rightAdornment?: ReactNode;
575
+ }
576
+ declare function SearchableSelect({ value, onChange, options, placeholder, emptyOptionLabel, className, disabled, id, allowFreeText, onSearchChange, rightAdornment, }: SearchableSelectProps): react_jsx_runtime.JSX.Element;
577
+
500
578
  /**
501
579
  * Generic top navigation bar. A horizontal row of tab-style links with an
502
580
  * optional brand on the left and free-form actions on the right. Self-contained
@@ -1532,4 +1610,4 @@ declare function useNewHotkey(callback: () => void): void;
1532
1610
  */
1533
1611
  declare function useEditHotkey(callback: (() => void) | null): void;
1534
1612
 
1535
- export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, BehaviorPanel, type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps, type BugReport, type BugReportConfig, BugReportConfigProvider, BugReportDetail, type BugReportExtraField, type BugReportExtraSelectField, BugReportProvider, type BugReportSubmission, type BugReportSubmitPayload, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CancelButton, type CellStyle, type ChangelogEntry, type ClockCalendarConfig, type ColumnDef, ConfirmProvider, CopyButton, Customization, type CustomizationOmitSection, type CustomizationProps, type CustomizationSection, DEV_BANNER_TEXT, Desktop, type DesktopContextMenuItem, type DesktopHostConfig, DesktopHostProvider, DevIndicator, DocFavStar, ENTER, EditableGrid, type EditableGridProps, type EntityFetcher, EntityList, type EntityListColumn, type EntityListProps, GLASS_DIVIDER, GLASS_INPUT_BG, GlobalSearch, type GridColumn, HelpCenter, type HelpCenterDoc, type HelpCenterProps, Kanban, type KanbanColumn, type KanbanProps, Layout, type LayoutProps, ListFooter, MOD, Markdown, type MarkdownProps, Modal, ModalActions, NotificationBell, type NotificationsConfig, type PaginatedResponse, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, type ReportType, ResizableTable, SHIFT, type SearchConfig, type SearchProvider, type SearchResult, type SemanticGroup, type ShellAuth, ShellAuthProvider, ShellEntityFetcherProvider, type ShellNotification, type ShellPrefsAdapter, ShellPrefsProvider, ShortcutHelp, SidebarLayout, type SidebarLayoutProps, type SortState, SoundsPanel, StartMenu, StatusBadge, StatusBadgeProvider, type StickyEntityRef, type StickyResolver, SystemPreferences, type SystemPreferencesProps, type SystemPreferencesSection, type TodoProvider, type TodoTask, TopNav, type TopNavItem, type TopNavProps, VERSION, WidgetManager, WindowManagerProvider, WindowRegistry, WindowTitle, applyDevTitle, commitExposeHighlight, confirm, confirmDestructive, createWindowRegistry, exitExposeMode, formatDate, getActiveWindowRoute, getExposeHighlight, getWindowPosition, glassStyle, isDevEnv, isMac, openBugReportDialog, prompt, reportBug, setExposeHighlight, setShellApiClient, setShellAuthBridge, setShellNavIcons, setShellTodoProvider, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toast, toggleExposeMode, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useLocalStoragePrefs, useModalActive, useNewHotkey, useShellAuth, useShellEntityFetcher, useShellPrefs, useSort, useTableNav, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
1613
+ export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, BehaviorPanel, type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps, type BugReport, type BugReportConfig, BugReportConfigProvider, BugReportDetail, type BugReportExtraField, type BugReportExtraSelectField, BugReportProvider, type BugReportSubmission, type BugReportSubmitPayload, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CancelButton, type CellStyle, type ChangelogEntry, type ClockCalendarConfig, type ColumnDef, ConfirmProvider, CopyButton, Customization, type CustomizationOmitSection, type CustomizationProps, type CustomizationSection, DEV_BANNER_TEXT, Desktop, type DesktopContextMenuItem, type DesktopHostConfig, DesktopHostProvider, DevIndicator, DocFavStar, ENTER, EditableGrid, type EditableGridProps, type EntityFetcher, EntityList, type EntityListColumn, type EntityListProps, GLASS_DIVIDER, GLASS_INPUT_BG, GlobalSearch, type GridColumn, HelpCenter, type HelpCenterDoc, type HelpCenterProps, Kanban, type KanbanColumn, type KanbanProps, Layout, type LayoutProps, ListFooter, MOD, Markdown, type MarkdownProps, Modal, ModalActions, NotificationBell, type NotificationsConfig, type PaginatedResponse, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, type ReportType, ResizableTable, SHIFT, type SearchConfig, type SearchProvider, type SearchResult, type SearchableOption, SearchableSelect, type SearchableSelectProps, type SemanticGroup, type ShellAuth, ShellAuthProvider, ShellEntityFetcherProvider, type ShellNotification, type ShellPrefsAdapter, ShellPrefsProvider, ShortcutHelp, SidebarLayout, type SidebarLayoutProps, type SortState, SoundsPanel, StartMenu, StatusBadge, StatusBadgeProvider, type StickyEntityRef, type StickyResolver, SystemPreferences, type SystemPreferencesProps, type SystemPreferencesSection, type TodoProvider, type TodoTask, TopNav, type TopNavItem, type TopNavProps, VERSION, WidgetManager, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowRegistry, WindowTitle, applyDevTitle, commitExposeHighlight, confirm, confirmDestructive, createWindowRegistry, exitExposeMode, formatDate, getActiveWindowRoute, getExposeHighlight, getWindowPosition, glassStyle, isDevEnv, isMac, openBugReportDialog, prompt, reportBug, setExposeHighlight, setShellApiClient, setShellAuthBridge, setShellNavIcons, setShellTodoProvider, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toast, toggleExposeMode, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useLocalStoragePrefs, useModalActive, useNewHotkey, useShellAuth, useShellEntityFetcher, useShellPrefs, useSort, useTableNav, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
package/dist/index.js CHANGED
@@ -2,20 +2,20 @@ import { subscribePomo, getPomoSnapshot } from './chunk-5X5LQNOX.js';
2
2
  export { setShellTodoProvider } from './chunk-5X5LQNOX.js';
3
3
  import { useShellPrefs } from './chunk-36VM54SC.js';
4
4
  export { ShellPrefsProvider, useLocalStoragePrefs, useShellPrefs } from './chunk-36VM54SC.js';
5
- import { PREVIEW_OPENED_EVENT, publishDesktopFolders, requestFilesTrashView, FolderGlyph, openPreviewFile, requestFilesDesktopFolderView, FileIconTile, hashGradient } from './chunk-Q4EH3NFS.js';
6
- export { Breadcrumbs } from './chunk-Q4EH3NFS.js';
5
+ import { PREVIEW_OPENED_EVENT, publishDesktopFolders, requestFilesTrashView, FolderGlyph, openPreviewFile, requestFilesDesktopFolderView, FileIconTile, hashGradient } from './chunk-H72L23PH.js';
6
+ export { Breadcrumbs } from './chunk-H72L23PH.js';
7
7
  import { SidebarLayout } from './chunk-VGTEM5RZ.js';
8
8
  export { SidebarLayout } from './chunk-VGTEM5RZ.js';
9
9
  import { playNotification, playStartup, soundsEnabled, getSoundConfig, SOUND_PACK_KEYS, SOUND_PACKS, SOUND_TYPES, SOUND_TYPE_LABELS, setSoundForType, previewSound, setAllSounds, playLogout } from './chunk-D7PYW2QS.js';
10
- import { setPdfPreview } from './chunk-XO4ZJAUB.js';
10
+ import { setPdfPreview } from './chunk-IEHKOV3M.js';
11
11
  import './chunk-KUIPWCTJ.js';
12
12
  import { toast_default } from './chunk-WIJ45SYD.js';
13
13
  export { toast_default as toast } from './chunk-WIJ45SYD.js';
14
- export { EditableGrid } from './chunk-LXCTOIXP.js';
15
- import { APP_VERSION } from './chunk-JZS5427T.js';
16
- export { VERSION } from './chunk-JZS5427T.js';
17
- import { useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, WINDOW_REGISTRY, isPageEntry, useIsMobile, ModalActions, useModalActive, client_default, LoadingSpinner, setWindowPosition, ThumbCard, activateModal } from './chunk-5FEW4QE5.js';
18
- export { CancelButton, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowManagerProvider, WindowTitle, commitExposeHighlight, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-5FEW4QE5.js';
14
+ export { EditableGrid } from './chunk-4F6XJIY3.js';
15
+ import { APP_VERSION } from './chunk-EK4U6LPM.js';
16
+ export { VERSION } from './chunk-EK4U6LPM.js';
17
+ import { useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, WINDOW_REGISTRY, isPageEntry, useIsMobile, ModalActions, useModalActive, client_default, LoadingSpinner, setWindowPosition, ThumbCard, activateModal } from './chunk-BN7GXKEZ.js';
18
+ export { CancelButton, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, commitExposeHighlight, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-BN7GXKEZ.js';
19
19
  import { confirm } from './chunk-UBN4IUDE.js';
20
20
  export { ConfirmProvider, confirm, confirmDestructive, prompt } from './chunk-UBN4IUDE.js';
21
21
  import { useAuth, useShellAuth } from './chunk-ADJ3CERD.js';
@@ -563,6 +563,182 @@ function HelpCenter({
563
563
  ] }) : /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center px-6 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: loading ? "Loading\u2026" : "Pick a help article from the left." }) }) })
564
564
  ] });
565
565
  }
566
+ function useClickOutside(ref, onClose) {
567
+ useEffect(() => {
568
+ const handler = (e) => {
569
+ if (ref.current && !ref.current.contains(e.target)) onClose();
570
+ };
571
+ document.addEventListener("mousedown", handler);
572
+ return () => document.removeEventListener("mousedown", handler);
573
+ }, [ref, onClose]);
574
+ }
575
+ function useDropdownAlignment(triggerRef, open, maxWidth) {
576
+ const [alignRight, setAlignRight] = useState(false);
577
+ useLayoutEffect(() => {
578
+ if (!open) return;
579
+ const rect = triggerRef.current?.getBoundingClientRect();
580
+ if (!rect) return;
581
+ setAlignRight(window.innerWidth - rect.left < maxWidth);
582
+ }, [open, maxWidth, triggerRef]);
583
+ return alignRight;
584
+ }
585
+ function ClearButton({ onClear, ariaLabel = "Clear selection" }) {
586
+ return /* @__PURE__ */ jsx(
587
+ "button",
588
+ {
589
+ type: "button",
590
+ "aria-label": ariaLabel,
591
+ onMouseDown: (e) => {
592
+ e.preventDefault();
593
+ e.stopPropagation();
594
+ onClear();
595
+ },
596
+ className: "absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity text-base leading-none",
597
+ children: "\xD7"
598
+ }
599
+ );
600
+ }
601
+ var INPUT_BASE = "block w-full rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm text-gray-800 placeholder:text-gray-400 shadow-sm focus:border-blue-400 focus:outline-none focus:ring-2 focus:ring-blue-400/30";
602
+ function SearchableSelect({
603
+ value,
604
+ onChange,
605
+ options,
606
+ placeholder,
607
+ emptyOptionLabel = "\u2014 None \u2014",
608
+ className = "",
609
+ disabled,
610
+ id,
611
+ allowFreeText = false,
612
+ onSearchChange,
613
+ rightAdornment
614
+ }) {
615
+ const [open, setOpen] = useState(false);
616
+ const [search, setSearchState] = useState("");
617
+ const setSearch = (next) => {
618
+ setSearchState(next);
619
+ onSearchChange?.(next);
620
+ };
621
+ const wrapRef = useRef(null);
622
+ const triggerRef = useRef(null);
623
+ const adornRef = useRef(null);
624
+ const [adornPad, setAdornPad] = useState(null);
625
+ useLayoutEffect(() => {
626
+ if (!rightAdornment || open) {
627
+ setAdornPad(null);
628
+ return;
629
+ }
630
+ const w = adornRef.current?.offsetWidth ?? 0;
631
+ setAdornPad(w ? w + (value && !disabled ? 32 : 8) + 6 : null);
632
+ });
633
+ const POPUP_MAX_WIDTH = 448;
634
+ const alignRight = useDropdownAlignment(triggerRef, open, POPUP_MAX_WIDTH);
635
+ const selectedLabel = useMemo(() => {
636
+ const match = options.find((o) => o.value === value);
637
+ if (match) return match.label;
638
+ return allowFreeText ? value : "";
639
+ }, [options, value, allowFreeText]);
640
+ useClickOutside(wrapRef, () => {
641
+ if (allowFreeText && search.trim() && search.trim() !== value) {
642
+ onChange(search.trim());
643
+ }
644
+ setOpen(false);
645
+ setSearch("");
646
+ });
647
+ const dedupedOptions = useMemo(() => {
648
+ const seen = /* @__PURE__ */ new Set();
649
+ const out = [];
650
+ for (const o of options) {
651
+ if (seen.has(o.value)) continue;
652
+ seen.add(o.value);
653
+ out.push(o);
654
+ }
655
+ return out;
656
+ }, [options]);
657
+ const filtered = useMemo(() => {
658
+ const q = search.trim().toLowerCase();
659
+ if (!q) return dedupedOptions;
660
+ return dedupedOptions.filter(
661
+ (o) => o.label.toLowerCase().includes(q) || (o.sublabel?.toLowerCase().includes(q) ?? false)
662
+ );
663
+ }, [dedupedOptions, search]);
664
+ return /* @__PURE__ */ jsxs("div", { ref: wrapRef, className: "relative group", children: [
665
+ /* @__PURE__ */ jsx(
666
+ "input",
667
+ {
668
+ id,
669
+ ref: triggerRef,
670
+ type: "text",
671
+ autoComplete: "off",
672
+ role: "combobox",
673
+ "aria-expanded": open,
674
+ value: open ? search : selectedLabel,
675
+ onChange: (e) => {
676
+ setSearch(e.target.value);
677
+ setOpen(true);
678
+ },
679
+ onFocus: () => {
680
+ if (!disabled) {
681
+ setSearch("");
682
+ setOpen(true);
683
+ }
684
+ },
685
+ onKeyDown: (e) => {
686
+ if (e.key === "Enter") {
687
+ e.preventDefault();
688
+ if (filtered.length === 1) {
689
+ onChange(filtered[0].value);
690
+ setOpen(false);
691
+ setSearch("");
692
+ } else if (allowFreeText && search.trim()) {
693
+ onChange(search.trim());
694
+ setOpen(false);
695
+ setSearch("");
696
+ triggerRef.current?.blur();
697
+ }
698
+ } else if (e.key === "Escape") {
699
+ setOpen(false);
700
+ setSearch("");
701
+ triggerRef.current?.blur();
702
+ }
703
+ },
704
+ placeholder: placeholder || (emptyOptionLabel || "Select\u2026"),
705
+ className: `${INPUT_BASE} ${className} ${value ? "pr-8" : ""} ${disabled ? "bg-gray-50 text-gray-400 cursor-not-allowed" : ""} truncate`,
706
+ style: adornPad ? { paddingRight: adornPad } : void 0,
707
+ disabled
708
+ }
709
+ ),
710
+ value && !disabled && /* @__PURE__ */ jsx(ClearButton, { onClear: () => {
711
+ onChange("");
712
+ setOpen(false);
713
+ setSearch("");
714
+ } }),
715
+ rightAdornment && !open && /* @__PURE__ */ jsx("div", { ref: adornRef, className: `absolute top-1/2 -translate-y-1/2 ${value && !disabled ? "right-8" : "right-2"} flex items-center gap-1 flex-nowrap justify-end pointer-events-none`, children: rightAdornment }),
716
+ open && /* @__PURE__ */ jsx(
717
+ "div",
718
+ {
719
+ className: `absolute z-[200] mt-1 rounded-2xl overflow-hidden ${alignRight ? "right-0" : "left-0"} min-w-full max-w-[28rem] w-max`,
720
+ style: glassStyle(),
721
+ children: /* @__PURE__ */ jsx("div", { className: "max-h-60 overflow-y-auto", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-3 text-sm text-gray-400 text-center", children: "No matches" }) : filtered.map((o) => /* @__PURE__ */ jsxs(
722
+ "button",
723
+ {
724
+ type: "button",
725
+ onMouseDown: () => {
726
+ onChange(o.value);
727
+ setOpen(false);
728
+ setSearch("");
729
+ },
730
+ className: `w-full text-left px-3 py-1.5 text-sm hover:bg-gray-50 flex items-center justify-between gap-2 whitespace-nowrap ${value === o.value ? "text-blue-600 font-medium bg-blue-50/50" : "text-gray-700"}`,
731
+ children: [
732
+ /* @__PURE__ */ jsx("span", { children: o.label }),
733
+ o.sublabel && /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-400 shrink-0", children: o.sublabel })
734
+ ]
735
+ },
736
+ o.value
737
+ )) })
738
+ }
739
+ )
740
+ ] });
741
+ }
566
742
  function TopNav({ items, activeKey, onSelect, brand, actions, className }) {
567
743
  return /* @__PURE__ */ jsxs(
568
744
  "div",
@@ -1726,7 +1902,7 @@ function Desktop({ profile }) {
1726
1902
  const dragEntriesRef = useRef([]);
1727
1903
  const startDrag = (type, idx, e) => {
1728
1904
  if (e.button !== 0) return;
1729
- const primaryKey = `${type}-${idx}`;
1905
+ const primaryKey = type === "trash" ? "trash" : `${type}-${idx}`;
1730
1906
  const draggingMulti = selected.has(primaryKey) && selected.size > 1;
1731
1907
  const keys = draggingMulti ? Array.from(selected) : [primaryKey];
1732
1908
  const entries = [];
@@ -1745,6 +1921,12 @@ function Desktop({ profile }) {
1745
1921
  const pos = getFolderPos(f, i);
1746
1922
  const el = document.querySelector(`[data-desktop-icon="${key}"]`);
1747
1923
  entries.push({ key, type: "folder", idx: i, origX: pos.right, origY: pos.top, el });
1924
+ } else if (key === "trash") {
1925
+ const el = document.querySelector('[data-desktop-icon="trash"]');
1926
+ if (!el) continue;
1927
+ const right = parseFloat(el.style.right || "0") || 0;
1928
+ const bottom = parseFloat(el.style.bottom || "0") || 0;
1929
+ entries.push({ key, type: "trash", idx: 0, origX: right, origY: bottom, el });
1748
1930
  }
1749
1931
  }
1750
1932
  dragEntriesRef.current = entries;
@@ -1763,8 +1945,12 @@ function Desktop({ profile }) {
1763
1945
  for (const entry of entries) {
1764
1946
  if (!entry.el) continue;
1765
1947
  entry.el.style.right = `${entry.origX - dx}px`;
1766
- entry.el.style.top = `${entry.origY + dy}px`;
1767
- entry.el.style.left = "auto";
1948
+ if (entry.type === "trash") {
1949
+ entry.el.style.bottom = `${entry.origY - dy}px`;
1950
+ } else {
1951
+ entry.el.style.top = `${entry.origY + dy}px`;
1952
+ entry.el.style.left = "auto";
1953
+ }
1768
1954
  entry.el.style.zIndex = "100";
1769
1955
  entry.el.style.opacity = "0.7";
1770
1956
  }
@@ -1795,7 +1981,7 @@ function Desktop({ profile }) {
1795
1981
  const hoveredFolder = liveHoverIdx != null ? folders[liveHoverIdx] : null;
1796
1982
  hoverFolderIdxRef.current = null;
1797
1983
  setHoverFolderIdx(null);
1798
- const computedPositions = entries.map((entry) => {
1984
+ const computedPositions = entries.filter((en) => en.type !== "trash").map((entry) => {
1799
1985
  let finalRight = entry.origX - dx;
1800
1986
  let finalTop = Math.max(0, entry.origY + dy);
1801
1987
  if (snapEnabled) {
@@ -1806,6 +1992,15 @@ function Desktop({ profile }) {
1806
1992
  finalRight = Math.max(0, finalRight);
1807
1993
  return { entry, finalRight, finalTop };
1808
1994
  });
1995
+ const trashEntry = entries.find((en) => en.type === "trash");
1996
+ if (trashEntry) {
1997
+ saveShellPrefs({
1998
+ desktop_trash_position: {
1999
+ right: Math.max(0, trashEntry.origX - dx),
2000
+ bottom: Math.max(0, trashEntry.origY - dy)
2001
+ }
2002
+ });
2003
+ }
1809
2004
  const itemMoves = computedPositions.filter((p) => p.entry.type === "item");
1810
2005
  if (itemMoves.length > 0) {
1811
2006
  const updated = [...favDocs];
@@ -2177,6 +2372,10 @@ function Desktop({ profile }) {
2177
2372
  if (e.button !== 0) return;
2178
2373
  e.preventDefault();
2179
2374
  e.stopPropagation();
2375
+ if (selected.has("trash") && selected.size > 1) {
2376
+ startDrag("trash", 0, e);
2377
+ return;
2378
+ }
2180
2379
  const el = e.currentTarget;
2181
2380
  const startX = e.clientX, startY = e.clientY;
2182
2381
  let moved = false;
@@ -2742,15 +2941,6 @@ function useTheme() {
2742
2941
  }, [accentColor, customBgColor, customTitleColor, customWindowColor, customButtonColor]);
2743
2942
  return { theme: saved, resolved };
2744
2943
  }
2745
- function useClickOutside(ref, onClose) {
2746
- useEffect(() => {
2747
- const handler = (e) => {
2748
- if (ref.current && !ref.current.contains(e.target)) onClose();
2749
- };
2750
- document.addEventListener("mousedown", handler);
2751
- return () => document.removeEventListener("mousedown", handler);
2752
- }, [ref, onClose]);
2753
- }
2754
2944
  function StartupAnimation({ onComplete, ready = false, productName = "react-os-shell", subtitle }) {
2755
2945
  const [phase, setPhase] = useState("logo");
2756
2946
  const [minTimePassed, setMinTimePassed] = useState(false);
@@ -6307,6 +6497,6 @@ function useEditHotkey(callback) {
6307
6497
  }, [callback, isActive]);
6308
6498
  }
6309
6499
 
6310
- export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, BehaviorPanel, BugReportConfigProvider, BugReportDetail, BugReportProvider, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, Customization, DEV_BANNER_TEXT, Desktop, DesktopHostProvider, DevIndicator, ENTER, EntityList, GlobalSearch, HelpCenter, Kanban, Layout, ListFooter, MOD, Markdown, NotificationBell, ResizableTable, SHIFT, ShellEntityFetcherProvider, ShortcutHelp, SoundsPanel, StartMenu, StatusBadge, StatusBadgeProvider, SystemPreferences, TopNav, WidgetManager, applyDevTitle, createWindowRegistry, formatDate, isDevEnv, isMac, openBugReportDialog, reportBug, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useNewHotkey, useShellEntityFetcher, useSort, useTableNav };
6500
+ export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, BehaviorPanel, BugReportConfigProvider, BugReportDetail, BugReportProvider, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, Customization, DEV_BANNER_TEXT, Desktop, DesktopHostProvider, DevIndicator, ENTER, EntityList, GlobalSearch, HelpCenter, Kanban, Layout, ListFooter, MOD, Markdown, NotificationBell, ResizableTable, SHIFT, SearchableSelect, ShellEntityFetcherProvider, ShortcutHelp, SoundsPanel, StartMenu, StatusBadge, StatusBadgeProvider, SystemPreferences, TopNav, WidgetManager, applyDevTitle, createWindowRegistry, formatDate, isDevEnv, isMac, openBugReportDialog, reportBug, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useNewHotkey, useShellEntityFetcher, useSort, useTableNav };
6311
6501
  //# sourceMappingURL=index.js.map
6312
6502
  //# sourceMappingURL=index.js.map