react-os-shell 0.5.0 → 0.6.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.
- package/dist/{Browser-PIKJVKWD.js → Browser-XZEAEJLW.js} +4 -4
- package/dist/{Browser-PIKJVKWD.js.map → Browser-XZEAEJLW.js.map} +1 -1
- package/dist/{Calculator-3RMMEJOR.js → Calculator-Y7TKDGFS.js} +5 -5
- package/dist/{Calculator-3RMMEJOR.js.map → Calculator-Y7TKDGFS.js.map} +1 -1
- package/dist/{Calendar-YI2OPWBN.js → Calendar-LUQWUGFY.js} +4 -4
- package/dist/{Calendar-YI2OPWBN.js.map → Calendar-LUQWUGFY.js.map} +1 -1
- package/dist/{CurrencyConverter-QW6RYH3K.js → CurrencyConverter-GZFBW5PE.js} +5 -5
- package/dist/{CurrencyConverter-QW6RYH3K.js.map → CurrencyConverter-GZFBW5PE.js.map} +1 -1
- package/dist/{Documents-U3SM3I5H.js → Documents-IT4EQ5CF.js} +4 -4
- package/dist/{Documents-U3SM3I5H.js.map → Documents-IT4EQ5CF.js.map} +1 -1
- package/dist/{Email-F7P3EDVG.js → Email-SNA6KIKR.js} +4 -4
- package/dist/{Email-F7P3EDVG.js.map → Email-SNA6KIKR.js.map} +1 -1
- package/dist/Files-E4XEDYAP.js +11 -0
- package/dist/{Files-NR2ZZRGK.js.map → Files-E4XEDYAP.js.map} +1 -1
- package/dist/{Minesweeper-GG66GIOY.js → Minesweeper-6GUVR7CV.js} +4 -4
- package/dist/{Minesweeper-GG66GIOY.js.map → Minesweeper-6GUVR7CV.js.map} +1 -1
- package/dist/{Notepad-OSHH77DS.js → Notepad-PQHDQH2L.js} +4 -4
- package/dist/{Notepad-OSHH77DS.js.map → Notepad-PQHDQH2L.js.map} +1 -1
- package/dist/{PomodoroTimer-LTXRM4QE.js → PomodoroTimer-3W7AYUDV.js} +5 -5
- package/dist/{PomodoroTimer-LTXRM4QE.js.map → PomodoroTimer-3W7AYUDV.js.map} +1 -1
- package/dist/Preview-BUVU7RTT.js +8 -0
- package/dist/{Preview-Z2ANAYNJ.js.map → Preview-BUVU7RTT.js.map} +1 -1
- package/dist/{Sidebar-SHNDADVO.js → Sidebar-Q3PRJ2FP.js} +20 -11
- package/dist/Sidebar-Q3PRJ2FP.js.map +1 -0
- package/dist/Spreadsheet-G4HT4C7B.js +6 -0
- package/dist/{Spreadsheet-MYOVKLI2.js.map → Spreadsheet-G4HT4C7B.js.map} +1 -1
- package/dist/{Weather-5HJCLITK.js → Weather-CXK57AZW.js} +5 -5
- package/dist/{Weather-5HJCLITK.js.map → Weather-CXK57AZW.js.map} +1 -1
- package/dist/{WorldClock-IJLE7IOF.js → WorldClock-LBWQKKOA.js} +5 -5
- package/dist/{WorldClock-IJLE7IOF.js.map → WorldClock-LBWQKKOA.js.map} +1 -1
- package/dist/apps/index.js +20 -20
- package/dist/{chunk-2TNV3ODP.js → chunk-3RQ5TVEL.js} +3 -3
- package/dist/{chunk-2TNV3ODP.js.map → chunk-3RQ5TVEL.js.map} +1 -1
- package/dist/{chunk-BRWWUKPE.js → chunk-HG3O6XHN.js} +3 -3
- package/dist/{chunk-BRWWUKPE.js.map → chunk-HG3O6XHN.js.map} +1 -1
- package/dist/{chunk-JKPSKZGZ.js → chunk-KSRZU3GT.js} +3 -3
- package/dist/{chunk-JKPSKZGZ.js.map → chunk-KSRZU3GT.js.map} +1 -1
- package/dist/{chunk-YSMCY46G.js → chunk-MGPY5446.js} +4 -4
- package/dist/{chunk-YSMCY46G.js.map → chunk-MGPY5446.js.map} +1 -1
- package/dist/{chunk-6FNC3APL.js → chunk-NVAWKCAI.js} +3 -3
- package/dist/{chunk-6FNC3APL.js.map → chunk-NVAWKCAI.js.map} +1 -1
- package/dist/{chunk-K5ZMTKZC.js → chunk-XNXIIGHP.js} +4 -4
- package/dist/{chunk-K5ZMTKZC.js.map → chunk-XNXIIGHP.js.map} +1 -1
- package/dist/{chunk-YJONGQLG.js → chunk-ZF6AYO4G.js} +3 -3
- package/dist/chunk-ZF6AYO4G.js.map +1 -0
- package/dist/index.d.ts +13 -1
- package/dist/index.js +57 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/Files-NR2ZZRGK.js +0 -11
- package/dist/Preview-Z2ANAYNJ.js +0 -8
- package/dist/Sidebar-SHNDADVO.js.map +0 -1
- package/dist/Spreadsheet-MYOVKLI2.js +0 -6
- package/dist/chunk-YJONGQLG.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { setPdfPreview } from './chunk-
|
|
1
|
+
import { setPdfPreview } from './chunk-HG3O6XHN.js';
|
|
2
2
|
import { toast_default } from './chunk-WIJ45SYD.js';
|
|
3
|
-
import { setSpreadsheetPreview } from './chunk-
|
|
3
|
+
import { setSpreadsheetPreview } from './chunk-NVAWKCAI.js';
|
|
4
4
|
|
|
5
5
|
// src/utils/openPreviewFile.ts
|
|
6
6
|
var PREVIEW_OPENED_EVENT = "react-os-shell:preview-opened";
|
|
@@ -42,5 +42,5 @@ async function openPreviewFile(opts) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export { PREVIEW_OPENED_EVENT, openPreviewFile };
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-XNXIIGHP.js.map
|
|
46
|
+
//# sourceMappingURL=chunk-XNXIIGHP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/openPreviewFile.ts"],"names":[],"mappings":";;;;;AA6BO,IAAM,oBAAA,GAAuB;AAQpC,SAAS,SAAA,GAAY;AACnB,EAAA,MAAM,QAAA,GAAY,OAAO,MAAA,KAAW,WAAA,IAAgB,MAAA,CAAe,8BAAA;AACnE,EAAA,OAAA,CAAQ,QAAA,IAAY,uBAAA,EAAyB,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAChE;AAEA,eAAsB,gBAAgB,IAAA,EAA6C;AACjF,EAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA,EAAM,UAAS,GAAI,IAAA;AAC/C,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAAM,KAAA;AAAA,MAChB,GAAG,SAAA,EAAW,CAAA,eAAA,EAAkB,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,MAC5D,EAAE,aAAa,SAAA;AAAU,KAC3B;AACA,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,aAAA,CAAM,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAC7C,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,EAAK;AAC7B,MAAA,qBAAA,CAAsB,EAAE,GAAA,EAAK,IAAA,EAAM,QAAA,EAAU,CAAA;AAC7C,MAAA,QAAA,GAAW,cAAc,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,MAAA,aAAA,CAAc,EAAE,GAAA,EAAK,QAAA,EAAU,IAAA,EAAM,CAAA;AACrC,MAAA,QAAA,GAAW,UAAU,CAAA;AAAA,IACvB;AACA,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,MAAA,CAAO,aAAA,CAAc,IAAI,WAAA,CAAiC,oBAAA,EAAsB;AAAA,QAC9E,MAAA,EAAQ,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA;AAAK,OACpC,CAAC,CAAA;AAAA,IACJ;AACA,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,CAAA,EAAQ;AACf,IAAA,aAAA,CAAM,KAAA,CAAM,CAAA,EAAG,OAAA,IAAW,aAAa,CAAA;AACvC,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/utils/openPreviewFile.ts"],"names":[],"mappings":";;;;;AA6BO,IAAM,oBAAA,GAAuB;AAQpC,SAAS,SAAA,GAAY;AACnB,EAAA,MAAM,QAAA,GAAY,OAAO,MAAA,KAAW,WAAA,IAAgB,MAAA,CAAe,8BAAA;AACnE,EAAA,OAAA,CAAQ,QAAA,IAAY,uBAAA,EAAyB,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAChE;AAEA,eAAsB,gBAAgB,IAAA,EAA6C;AACjF,EAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA,EAAM,UAAS,GAAI,IAAA;AAC/C,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAAM,KAAA;AAAA,MAChB,GAAG,SAAA,EAAW,CAAA,eAAA,EAAkB,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,MAC5D,EAAE,aAAa,SAAA;AAAU,KAC3B;AACA,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,aAAA,CAAM,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAC7C,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,EAAK;AAC7B,MAAA,qBAAA,CAAsB,EAAE,GAAA,EAAK,IAAA,EAAM,QAAA,EAAU,CAAA;AAC7C,MAAA,QAAA,GAAW,cAAc,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,MAAA,aAAA,CAAc,EAAE,GAAA,EAAK,QAAA,EAAU,IAAA,EAAM,CAAA;AACrC,MAAA,QAAA,GAAW,UAAU,CAAA;AAAA,IACvB;AACA,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,MAAA,CAAO,aAAA,CAAc,IAAI,WAAA,CAAiC,oBAAA,EAAsB;AAAA,QAC9E,MAAA,EAAQ,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA;AAAK,OACpC,CAAC,CAAA;AAAA,IACJ;AACA,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,CAAA,EAAQ;AACf,IAAA,aAAA,CAAM,KAAA,CAAM,CAAA,EAAG,OAAA,IAAW,aAAa,CAAA;AACvC,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"chunk-XNXIIGHP.js","sourcesContent":["/**\n * Fetch a file from the user's file-server and route it into the right\n * preview window. Shared by the Files app and the desktop Documents\n * folder's shortcut click-through.\n *\n * On success, dispatches `react-os-shell:preview-opened` so Desktop can\n * record the file as a shortcut without this util needing access to the\n * prefs adapter.\n */\nimport toast from '../shell/toast';\nimport { setPdfPreview } from '../apps/Preview';\nimport { setSpreadsheetPreview } from '../apps/Spreadsheet';\n\nexport type PreviewFileKind = 'pdf' | 'dxf' | '3d' | 'image' | 'csv';\n\nexport interface OpenPreviewFileOpts {\n /** Server-relative path, e.g. \"/reports/Q1.pdf\". */\n filePath: string;\n /** Display name (also used as the download filename). */\n filename: string;\n /** Which viewer to route into. CSV opens in Spreadsheet; the rest open in Preview. */\n kind: PreviewFileKind;\n /** Optional callback invoked after staging the preview, with the route to\n * open (e.g. '/preview' or '/spreadsheet'). The caller is responsible\n * for actually opening the page since the window manager hook is\n * React-scoped. */\n onStaged?: (route: '/preview' | '/spreadsheet') => void;\n}\n\nexport const PREVIEW_OPENED_EVENT = 'react-os-shell:preview-opened';\n\nexport interface PreviewOpenedDetail {\n filePath: string;\n filename: string;\n kind: PreviewFileKind;\n}\n\nfunction getServer() {\n const override = (typeof window !== 'undefined' && (window as any).__REACT_OS_SHELL_FILE_SERVER__) as string | undefined;\n return (override || 'http://localhost:4000').replace(/\\/$/, '');\n}\n\nexport async function openPreviewFile(opts: OpenPreviewFileOpts): Promise<boolean> {\n const { filePath, filename, kind, onStaged } = opts;\n try {\n const res = await fetch(\n `${getServer()}/api/file?path=${encodeURIComponent(filePath)}`,\n { credentials: 'include' },\n );\n if (!res.ok) {\n toast.error(`Download failed (${res.status})`);\n return false;\n }\n const blob = await res.blob();\n if (kind === 'csv') {\n const text = await blob.text();\n setSpreadsheetPreview({ csv: text, filename });\n onStaged?.('/spreadsheet');\n } else {\n const url = URL.createObjectURL(blob);\n setPdfPreview({ url, filename, kind });\n onStaged?.('/preview');\n }\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent<PreviewOpenedDetail>(PREVIEW_OPENED_EVENT, {\n detail: { filePath, filename, kind },\n }));\n }\n return true;\n } catch (e: any) {\n toast.error(e?.message || 'Open failed');\n return false;\n }\n}\n"]}
|
|
@@ -26,7 +26,7 @@ function setShellNavIcons(icons) {
|
|
|
26
26
|
}
|
|
27
27
|
var sectionIcons = {};
|
|
28
28
|
var navSections = [];
|
|
29
|
-
var startMenuCategories = { erp: [], system: [], virtual: [] };
|
|
29
|
+
var startMenuCategories = { erp: [], system: [], virtual: [], footer: [] };
|
|
30
30
|
|
|
31
31
|
// src/utils/glass.ts
|
|
32
32
|
function getMenuOpacity() {
|
|
@@ -67,5 +67,5 @@ var GLASS_DIVIDER = "border-white/20";
|
|
|
67
67
|
var GLASS_INPUT_BG = "glass-input-bg";
|
|
68
68
|
|
|
69
69
|
export { GLASS_DIVIDER, GLASS_INPUT_BG, glassStyle, isSection, navIcons, navSections, sectionIcons, setShellNavIcons, startMenuCategories };
|
|
70
|
-
//# sourceMappingURL=chunk-
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
70
|
+
//# sourceMappingURL=chunk-ZF6AYO4G.js.map
|
|
71
|
+
//# sourceMappingURL=chunk-ZF6AYO4G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shell/nav-types.ts","../src/shell-config/nav.tsx","../src/utils/glass.ts"],"names":[],"mappings":";AAkDO,SAAS,UAAU,IAAA,EAAgD;AACxE,EAAA,OAAO,OAAA,IAAW,IAAA;AACpB;;;ACpCA,IAAM,YAAuC,EAAC;AACvC,IAAM,QAAA,GAAsC,IAAI,KAAA,CAAM,SAAA,EAAW;AAAA,EACtE,GAAA,CAAI,IAAI,CAAA,EAAW;AAAE,IAAA,OAAO,UAAU,CAAC,CAAA;AAAA,EAAG,CAAA;AAAA,EAC1C,GAAA,CAAI,IAAI,CAAA,EAAW;AAAE,IAAA,OAAO,CAAA,IAAK,SAAA;AAAA,EAAW,CAAA;AAAA,EAC5C,OAAA,GAAU;AAAE,IAAA,OAAO,MAAA,CAAO,KAAK,SAAS,CAAA;AAAA,EAAG,CAAA;AAAA,EAC3C,wBAAA,CAAyB,IAAI,CAAA,EAAW;AACtC,IAAA,IAAI,CAAA,IAAK,SAAA,EAAW,OAAO,EAAE,YAAA,EAAc,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,KAAA,EAAO,SAAA,CAAU,CAAC,CAAA,EAAE;AACvF,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAC;AACM,SAAS,iBAAiB,KAAA,EAAwC;AACvE,EAAA,KAAA,MAAW,KAAK,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,EAAG,OAAO,UAAU,CAAC,CAAA;AAC1D,EAAA,MAAA,CAAO,MAAA,CAAO,WAAW,KAAK,CAAA;AAChC;AAEO,IAAM,eAA0C;AAChD,IAAM,cAAwC;AAC9C,IAAM,mBAAA,GAA2C,EAAE,GAAA,EAAK,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAG,OAAA,EAAS,EAAC,EAAG,MAAA,EAAQ,EAAC;;;AC9BrG,SAAS,cAAA,GAAyB;AAChC,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,iBAAiB,QAAA,CAAS,eAAe,EAAE,gBAAA,CAAiB,gBAAgB,GAAG,IAAA,EAAK;AAChG,IAAA,IAAI,GAAA,EAAK,OAAO,UAAA,CAAW,GAAG,CAAA;AAAA,EAChC,CAAA,CAAA,MAAQ;AAAA,EAAC;AACT,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,WAAA,GAAuB;AAC9B,EAAA,IAAI;AACF,IAAA,OAAO,QAAA,CAAS,eAAA,CAAgB,YAAA,CAAa,YAAY,CAAA,KAAM,MAAA;AAAA,EACjE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAKO,SAAS,WAAW,OAAA,EAAiC;AAC1D,EAAA,MAAM,CAAA,GAAI,WAAW,cAAA,EAAe;AACpC,EAAA,IAAI,aAAY,EAAG;AAGjB,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,yCAAyC,CAAA,GAAI,IAAI,uBAAuB,CAAA,GAAI,IAAI,CAAA,qBAAA,EAAwB,CAAA,GAAI,IAAI,CAAA,OAAA,CAAA;AAAA,MAC5H,cAAA,EAAgB,0BAAA;AAAA,MAChB,oBAAA,EAAsB,0BAAA;AAAA,MACtB,MAAA,EAAQ,kCAAA;AAAA,MACR,SAAA,EAAW;AAAA,KACb;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,4CAA4C,CAAA,GAAI,IAAI,0BAA0B,CAAA,GAAI,IAAI,CAAA,wBAAA,EAA2B,CAAA,GAAI,IAAI,CAAA,OAAA,CAAA;AAAA,IACrI,cAAA,EAAgB,0BAAA;AAAA,IAChB,oBAAA,EAAsB,0BAAA;AAAA,IACtB,MAAA,EAAQ,kCAAA;AAAA,IACR,SAAA,EAAW;AAAA,GACb;AACF;AAGO,IAAM,aAAA,GAAgB;AAKtB,IAAM,cAAA,GAAiB","file":"chunk-ZF6AYO4G.js","sourcesContent":["/**\n * Nav data types used by <Layout> + <StartMenu>. The actual sections, icons,\n * and categories are consumer-supplied via Layout props — the package never\n * ships nav DATA, only the shape it expects.\n */\nimport type { ReactNode } from 'react';\n\nexport interface NavItem {\n to: string;\n label: string;\n perms?: string[];\n dividerAfter?: boolean;\n /** Optional 3rd-level sub-items. Hovering the parent in <StartMenu> opens\n * a nested flyout; in <Sidebar> the parent becomes an inline sub-accordion. */\n children?: NavItem[];\n}\n\nexport interface NavSection {\n label: string;\n items: NavItem[];\n perms?: string[];\n /** Optional landing route for clicks on the section title itself\n * (e.g. R&D's `/rd` dashboard). */\n to?: string;\n}\n\nexport interface VirtualSection {\n label: string;\n items: NavItem[];\n icon?: ReactNode;\n}\n\nexport interface StartMenuCategories {\n /** Section labels rendered in the \"ERP\" group (bold, with section icon). */\n erp: string[];\n /** Section labels rendered in the \"system\" group. */\n system: string[];\n /** Optional virtual flyouts (e.g. a \"Utilities\" tray). */\n virtual?: VirtualSection[];\n /** Optional section labels pinned to the bottom of the menu, next to the user\n * profile, separated from the ERP group by a divider. */\n footer?: string[];\n /** Optional flat top-level items pinned to the bottom of the menu, next to\n * the user profile, separated from the ERP group by a divider. Unlike\n * `footer` (section labels rendered as flyouts), these render as direct\n * clickable rows — use for standalone destinations like System Preferences\n * or a bug-report link. */\n footerItems?: NavItem[];\n}\n\nexport function isSection(item: NavSection | NavItem): item is NavSection {\n return 'items' in item;\n}\n","/**\n * INTERNAL stub — package-side compatibility for files that legacy-imported\n * default nav data from `shell-config/nav`. The package never ships nav\n * DATA; consumers always supply `navSections` / `navIcons` / `sectionIcons` /\n * `categories` as Layout props.\n *\n * Empty defaults exported here so the copied files compile during the\n * extraction transition. Each consumer-facing field is also re-exported as\n * a TYPE alias for code that only needed the shape.\n */\nimport type { ReactNode } from 'react';\nimport type { NavItem, NavSection, StartMenuCategories, VirtualSection } from '../shell/nav-types';\n\n// Live proxy: WindowManager reads window-title icons from this module-level\n// map. Consumers register their full icon set once at app startup so the\n// title bars show the same glyphs as the start menu.\nconst _navIcons: Record<string, ReactNode> = {};\nexport const navIcons: Record<string, ReactNode> = new Proxy(_navIcons, {\n get(_t, k: string) { return _navIcons[k]; },\n has(_t, k: string) { return k in _navIcons; },\n ownKeys() { return Object.keys(_navIcons); },\n getOwnPropertyDescriptor(_t, k: string) {\n if (k in _navIcons) return { configurable: true, enumerable: true, value: _navIcons[k] };\n return undefined;\n },\n});\nexport function setShellNavIcons(icons: Record<string, ReactNode>): void {\n for (const k of Object.keys(_navIcons)) delete _navIcons[k];\n Object.assign(_navIcons, icons);\n}\n\nexport const sectionIcons: Record<string, ReactNode> = {};\nexport const navSections: (NavSection | NavItem)[] = [];\nexport const startMenuCategories: StartMenuCategories = { erp: [], system: [], virtual: [], footer: [] };\n\nexport { isSection } from '../shell/nav-types';\nexport type { NavItem, NavSection, StartMenuCategories, VirtualSection };\n","import type { CSSProperties } from 'react';\n\n/** Read the system menu opacity from CSS custom property set by Layout */\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 isDarkTheme(): boolean {\n try {\n return document.documentElement.getAttribute('data-theme') === 'dark';\n } catch {\n return false;\n }\n}\n\n/** Frosted glass style — shared across all menus, popups, and glass UI elements.\n * Reads --menu-opacity CSS variable set by the theme system, and adapts the\n * base tint to dark mode so menus don't stay light-cream when text is light. */\nexport function glassStyle(opacity?: number): CSSProperties {\n const o = opacity ?? getMenuOpacity();\n if (isDarkTheme()) {\n // Dark frosted glass — Catppuccin-aligned base (#1e1e2e / 30,30,46) with\n // a subtle gradient and lighter inner highlight.\n return {\n background: `linear-gradient(135deg, rgba(30,30,46,${o * 0.85}) 0%, rgba(24,24,37,${o * 0.75}) 50%, rgba(30,30,46,${o * 0.85}) 100%)`,\n backdropFilter: 'blur(40px) saturate(1.6)',\n WebkitBackdropFilter: 'blur(40px) saturate(1.6)',\n border: '1px solid rgba(255,255,255,0.08)',\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.06), inset 0 -1px 0 rgba(0,0,0,0.4), 0 8px 32px rgba(0,0,0,0.5), 0 2px 8px rgba(0,0,0,0.3)',\n };\n }\n return {\n background: `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 backdropFilter: 'blur(40px) saturate(1.8)',\n WebkitBackdropFilter: 'blur(40px) saturate(1.8)',\n border: '1px solid rgba(255,255,255,0.35)',\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.4), inset 0 -1px 0 rgba(255,255,255,0.1), 0 8px 32px rgba(0,0,0,0.15), 0 2px 8px rgba(0,0,0,0.08)',\n };\n}\n\n/** Glass divider border color */\nexport const GLASS_DIVIDER = 'border-white/20';\n\n/** Glass input/search bar background — declared in styles.css so it can adapt\n * to dark mode (a flat `bg-white/15` reads as a too-bright tile on the dark\n * glass gradient). */\nexport const GLASS_INPUT_BG = 'glass-input-bg';\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -57,6 +57,15 @@ interface StartMenuCategories {
|
|
|
57
57
|
system: string[];
|
|
58
58
|
/** Optional virtual flyouts (e.g. a "Utilities" tray). */
|
|
59
59
|
virtual?: VirtualSection[];
|
|
60
|
+
/** Optional section labels pinned to the bottom of the menu, next to the user
|
|
61
|
+
* profile, separated from the ERP group by a divider. */
|
|
62
|
+
footer?: string[];
|
|
63
|
+
/** Optional flat top-level items pinned to the bottom of the menu, next to
|
|
64
|
+
* the user profile, separated from the ERP group by a divider. Unlike
|
|
65
|
+
* `footer` (section labels rendered as flyouts), these render as direct
|
|
66
|
+
* clickable rows — use for standalone destinations like System Preferences
|
|
67
|
+
* or a bug-report link. */
|
|
68
|
+
footerItems?: NavItem[];
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
/**
|
|
@@ -708,8 +717,11 @@ interface LayoutProps {
|
|
|
708
717
|
* the shell. The shell renders the node as-is — keep it small (a
|
|
709
718
|
* single icon-sized button) so it fits the existing tray rhythm. */
|
|
710
719
|
taskbarTrayLeft?: ReactNode;
|
|
720
|
+
/** Show the Mail & Calendar connect button in the system tray.
|
|
721
|
+
* Defaults to true. Set false for portals with no mail integration. */
|
|
722
|
+
showMail?: boolean;
|
|
711
723
|
}
|
|
712
|
-
declare function Layout({ productName, productIcon, wallpapers, navSections, navIcons, sectionIcons, categories, notifications, search, taskbarTrayLeft, }?: LayoutProps): react_jsx_runtime.JSX.Element;
|
|
724
|
+
declare function Layout({ productName, productIcon, wallpapers, navSections, navIcons, sectionIcons, categories, notifications, search, taskbarTrayLeft, showMail, }?: LayoutProps): react_jsx_runtime.JSX.Element;
|
|
713
725
|
|
|
714
726
|
interface StartMenuProps {
|
|
715
727
|
open: boolean;
|
package/dist/index.js
CHANGED
|
@@ -6,21 +6,21 @@ export { setShellMailServer, useMailAuth } from './chunk-VBFB3ZIN.js';
|
|
|
6
6
|
import { subscribePomo, getPomoSnapshot } from './chunk-MK3HLUO4.js';
|
|
7
7
|
import { useShellPrefs } from './chunk-36VM54SC.js';
|
|
8
8
|
export { ShellPrefsProvider, useLocalStoragePrefs, useShellPrefs } from './chunk-36VM54SC.js';
|
|
9
|
-
import { PREVIEW_OPENED_EVENT, openPreviewFile } from './chunk-
|
|
9
|
+
import { PREVIEW_OPENED_EVENT, openPreviewFile } from './chunk-XNXIIGHP.js';
|
|
10
10
|
import { playNotification, playStartup, soundsEnabled, getSoundConfig, SOUND_PACK_KEYS, SOUND_PACKS, SOUND_TYPES, SOUND_TYPE_LABELS, setSoundForType, previewSound, setAllSounds, playLogout } from './chunk-D7PYW2QS.js';
|
|
11
|
-
import { setPdfPreview } from './chunk-
|
|
11
|
+
import { setPdfPreview } from './chunk-HG3O6XHN.js';
|
|
12
12
|
import './chunk-KUIPWCTJ.js';
|
|
13
13
|
import { toast_default } from './chunk-WIJ45SYD.js';
|
|
14
14
|
export { toast_default as toast } from './chunk-WIJ45SYD.js';
|
|
15
|
-
export { EditableGrid } from './chunk-
|
|
16
|
-
import { useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, ModalActions, useIsMobile, useModalActive, client_default, LoadingSpinner, WINDOW_REGISTRY, isPageEntry, ThumbCard, activateModal } from './chunk-
|
|
17
|
-
export { CancelButton, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowManagerProvider, WindowTitle, commitExposeHighlight, exitExposeMode, getActiveWindowRoute, getExposeHighlight, isEntityEntry, isPageEntry, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, subscribeExposeHighlight, toggleExposeMode, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-
|
|
15
|
+
export { EditableGrid } from './chunk-NVAWKCAI.js';
|
|
16
|
+
import { useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, ModalActions, useIsMobile, useModalActive, client_default, LoadingSpinner, WINDOW_REGISTRY, isPageEntry, ThumbCard, activateModal } from './chunk-3RQ5TVEL.js';
|
|
17
|
+
export { CancelButton, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowManagerProvider, WindowTitle, commitExposeHighlight, exitExposeMode, getActiveWindowRoute, getExposeHighlight, isEntityEntry, isPageEntry, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, subscribeExposeHighlight, toggleExposeMode, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-3RQ5TVEL.js';
|
|
18
18
|
import { confirm } from './chunk-PLGHQ7QW.js';
|
|
19
19
|
export { ConfirmProvider, confirm, confirmDestructive, prompt } from './chunk-PLGHQ7QW.js';
|
|
20
20
|
import { useAuth, useShellAuth } from './chunk-ADJ3CERD.js';
|
|
21
21
|
export { ShellAuthProvider, setShellAuthBridge, useShellAuth } from './chunk-ADJ3CERD.js';
|
|
22
|
-
import { glassStyle, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, sectionIcons } from './chunk-
|
|
23
|
-
export { GLASS_DIVIDER, GLASS_INPUT_BG, glassStyle, setShellNavIcons } from './chunk-
|
|
22
|
+
import { glassStyle, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, sectionIcons } from './chunk-ZF6AYO4G.js';
|
|
23
|
+
export { GLASS_DIVIDER, GLASS_INPUT_BG, glassStyle, setShellNavIcons } from './chunk-ZF6AYO4G.js';
|
|
24
24
|
import { createContext, lazy, useState, useRef, useEffect, useCallback, useLayoutEffect, useContext, Suspense, isValidElement, cloneElement, useMemo, useSyncExternalStore } from 'react';
|
|
25
25
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
26
26
|
import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';
|
|
@@ -915,7 +915,7 @@ function StatusBadge({ status }) {
|
|
|
915
915
|
}
|
|
916
916
|
|
|
917
917
|
// src/version.ts
|
|
918
|
-
var VERSION = "0.
|
|
918
|
+
var VERSION = "0.6.1" ;
|
|
919
919
|
var APP_VERSION = VERSION;
|
|
920
920
|
|
|
921
921
|
// src/changelog.ts
|
|
@@ -2887,11 +2887,13 @@ function StartMenu({
|
|
|
2887
2887
|
}) {
|
|
2888
2888
|
const erpLabels = new Set(categories.erp);
|
|
2889
2889
|
const systemLabels = new Set(categories.system);
|
|
2890
|
+
const footerLabels = new Set(categories.footer ?? []);
|
|
2890
2891
|
const virtualSections = categories.virtual ?? [];
|
|
2891
2892
|
const virtualByLabel = Object.fromEntries(
|
|
2892
2893
|
virtualSections.map((v) => [v.label, v])
|
|
2893
2894
|
);
|
|
2894
2895
|
const { hasAnyPerm } = useAuth();
|
|
2896
|
+
const footerItems = (categories.footerItems ?? []).filter((item) => !item.perms || hasAnyPerm(item.perms));
|
|
2895
2897
|
const isMobile = useIsMobile();
|
|
2896
2898
|
const [hoveredSection, setHoveredSection] = useState(null);
|
|
2897
2899
|
const [hoveredY, setHoveredY] = useState(0);
|
|
@@ -2953,6 +2955,7 @@ function StartMenu({
|
|
|
2953
2955
|
pushItem(entry);
|
|
2954
2956
|
}
|
|
2955
2957
|
}
|
|
2958
|
+
for (const it of footerItems) pushItem(it);
|
|
2956
2959
|
const filtered = search.length >= 1 ? allItems.filter(({ item }) => item.label.toLowerCase().includes(search.toLowerCase())) : allItems;
|
|
2957
2960
|
return /* @__PURE__ */ jsxs(
|
|
2958
2961
|
"div",
|
|
@@ -3003,6 +3006,7 @@ function StartMenu({
|
|
|
3003
3006
|
const topItems = navSections2.filter((item) => !isSection(item));
|
|
3004
3007
|
const erpSections = navSections2.filter((item) => isSection(item) && erpLabels.has(item.label));
|
|
3005
3008
|
const systemSections = navSections2.filter((item) => isSection(item) && systemLabels.has(item.label));
|
|
3009
|
+
const footerSections = navSections2.filter((item) => isSection(item) && footerLabels.has(item.label));
|
|
3006
3010
|
const getVisibleItems = (section) => section.items.filter((item) => !item.perms || hasAnyPerm(item.perms));
|
|
3007
3011
|
const matchTree = (it, sectionLabel) => {
|
|
3008
3012
|
if (it.perms && !hasAnyPerm(it.perms)) return [];
|
|
@@ -3015,13 +3019,16 @@ function StartMenu({
|
|
|
3015
3019
|
}
|
|
3016
3020
|
return hits;
|
|
3017
3021
|
};
|
|
3018
|
-
const searchResults = search.length >= 2 ?
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3022
|
+
const searchResults = search.length >= 2 ? [
|
|
3023
|
+
...navSections2.flatMap((item) => {
|
|
3024
|
+
if (isSection(item)) {
|
|
3025
|
+
const sec = item;
|
|
3026
|
+
return sec.items.flatMap((i) => matchTree(i, sec.label));
|
|
3027
|
+
}
|
|
3028
|
+
return matchTree(item, "");
|
|
3029
|
+
}),
|
|
3030
|
+
...footerItems.flatMap((item) => matchTree(item, ""))
|
|
3031
|
+
] : [];
|
|
3025
3032
|
const posStyle = taskbarPosition === "top" ? { top: taskbarH + 8, left: 8 } : taskbarPosition === "left" ? { top: 8, left: taskbarW + 8 } : taskbarPosition === "right" ? { top: 8, right: taskbarW + 8 } : { bottom: taskbarH + 8, left: 8 };
|
|
3026
3033
|
const iconEl = (path) => {
|
|
3027
3034
|
const icon = navIcons2[path];
|
|
@@ -3034,7 +3041,7 @@ function StartMenu({
|
|
|
3034
3041
|
return null;
|
|
3035
3042
|
};
|
|
3036
3043
|
const hoveredVirtual = hoveredSection ? virtualByLabel[hoveredSection] : void 0;
|
|
3037
|
-
const hoveredData = hoveredVirtual ? null : hoveredSection ? [...erpSections, ...systemSections].find((s) => s.label === hoveredSection) : null;
|
|
3044
|
+
const hoveredData = hoveredVirtual ? null : hoveredSection ? [...erpSections, ...systemSections, ...footerSections].find((s) => s.label === hoveredSection) : null;
|
|
3038
3045
|
const flyoutItems = hoveredVirtual ? hoveredVirtual.items : hoveredData ? getVisibleItems(hoveredData) : [];
|
|
3039
3046
|
const menuDensity = typeof document !== "undefined" ? getComputedStyle(document.documentElement).getPropertyValue("--menu-density")?.trim() || "normal" : "normal";
|
|
3040
3047
|
const tight = menuDensity === "tight";
|
|
@@ -3148,6 +3155,20 @@ function StartMenu({
|
|
|
3148
3155
|
i
|
|
3149
3156
|
)) }) : /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-1 pb-1 flex flex-col", children: [
|
|
3150
3157
|
isVertical && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3158
|
+
footerItems.map((item) => /* @__PURE__ */ jsxs(
|
|
3159
|
+
"button",
|
|
3160
|
+
{
|
|
3161
|
+
onClick: () => handleClick(item.to),
|
|
3162
|
+
className: `${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`,
|
|
3163
|
+
children: [
|
|
3164
|
+
iconEl(item.to),
|
|
3165
|
+
/* @__PURE__ */ jsx("span", { children: item.label })
|
|
3166
|
+
]
|
|
3167
|
+
},
|
|
3168
|
+
item.to
|
|
3169
|
+
)),
|
|
3170
|
+
footerSections.map((s) => renderSection(s, false)),
|
|
3171
|
+
(footerSections.length > 0 || footerItems.length > 0) && /* @__PURE__ */ jsx("div", { className: "border-t border-white/20 my-1.5 mx-2" }),
|
|
3151
3172
|
erpSections.map((s) => renderSection(s, true)),
|
|
3152
3173
|
/* @__PURE__ */ jsx("div", { className: "border-t border-white/20 my-1.5 mx-2" }),
|
|
3153
3174
|
topItems.map((item) => /* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -3193,7 +3214,21 @@ function StartMenu({
|
|
|
3193
3214
|
systemSections.map((s) => renderSection(s, false)),
|
|
3194
3215
|
virtualSections.map((v) => renderVirtualSection(v)),
|
|
3195
3216
|
/* @__PURE__ */ jsx("div", { className: "border-t border-white/20 my-1.5 mx-2" }),
|
|
3196
|
-
erpSections.map((s) => renderSection(s, true))
|
|
3217
|
+
erpSections.map((s) => renderSection(s, true)),
|
|
3218
|
+
(footerSections.length > 0 || footerItems.length > 0) && /* @__PURE__ */ jsx("div", { className: "border-t border-white/20 my-1.5 mx-2" }),
|
|
3219
|
+
footerSections.map((s) => renderSection(s, false)),
|
|
3220
|
+
footerItems.map((item) => /* @__PURE__ */ jsxs(
|
|
3221
|
+
"button",
|
|
3222
|
+
{
|
|
3223
|
+
onClick: () => handleClick(item.to),
|
|
3224
|
+
className: `${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`,
|
|
3225
|
+
children: [
|
|
3226
|
+
iconEl(item.to),
|
|
3227
|
+
/* @__PURE__ */ jsx("span", { children: item.label })
|
|
3228
|
+
]
|
|
3229
|
+
},
|
|
3230
|
+
item.to
|
|
3231
|
+
))
|
|
3197
3232
|
] })
|
|
3198
3233
|
] }),
|
|
3199
3234
|
/* @__PURE__ */ jsx("div", { className: `${isVertical ? "border-b" : "border-t"} border-white/20 p-1`, children: /* @__PURE__ */ jsxs(
|
|
@@ -4081,7 +4116,7 @@ function MobileBottomNav({
|
|
|
4081
4116
|
}
|
|
4082
4117
|
);
|
|
4083
4118
|
}
|
|
4084
|
-
var Sidebar = lazy(() => import('./Sidebar-
|
|
4119
|
+
var Sidebar = lazy(() => import('./Sidebar-Q3PRJ2FP.js'));
|
|
4085
4120
|
function useFavorites(wallpapers) {
|
|
4086
4121
|
const { prefs, save } = useShellPrefs();
|
|
4087
4122
|
const favorites = prefs.favorite_pages || [];
|
|
@@ -4278,7 +4313,8 @@ function Layout({
|
|
|
4278
4313
|
categories = startMenuCategories,
|
|
4279
4314
|
notifications,
|
|
4280
4315
|
search,
|
|
4281
|
-
taskbarTrayLeft
|
|
4316
|
+
taskbarTrayLeft,
|
|
4317
|
+
showMail = true
|
|
4282
4318
|
} = {}) {
|
|
4283
4319
|
const bugReport = useBugReport();
|
|
4284
4320
|
const { user, logout, hasAnyPerm } = useAuth();
|
|
@@ -4611,7 +4647,7 @@ function Layout({
|
|
|
4611
4647
|
/* Vertical: clock + mail-connect + bell evenly spaced */
|
|
4612
4648
|
/* @__PURE__ */ jsx("div", { className: "w-full px-2", children: /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-center gap-2 ${taskbarPosition === "right" ? "flex-row-reverse" : ""}`, children: [
|
|
4613
4649
|
/* @__PURE__ */ jsx(TaskbarClock, {}),
|
|
4614
|
-
/* @__PURE__ */ jsx(
|
|
4650
|
+
showMail && /* @__PURE__ */ jsx(
|
|
4615
4651
|
"button",
|
|
4616
4652
|
{
|
|
4617
4653
|
onClick: () => setMailConnectOpen(true),
|
|
@@ -4630,7 +4666,7 @@ function Layout({
|
|
|
4630
4666
|
/* @__PURE__ */ jsx(TaskbarPomodoro, {}),
|
|
4631
4667
|
taskbarTrayLeft,
|
|
4632
4668
|
notifications && /* @__PURE__ */ jsx(NotificationBell, { ...notifications }),
|
|
4633
|
-
/* @__PURE__ */ jsx(
|
|
4669
|
+
showMail && /* @__PURE__ */ jsx(
|
|
4634
4670
|
"button",
|
|
4635
4671
|
{
|
|
4636
4672
|
onClick: () => setMailConnectOpen(true),
|