@fluid-app/portal-core 0.1.16
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/chunk-CKQMccvm.cjs +28 -0
- package/dist/data-sources/DataAwareWidget.cjs +50 -0
- package/dist/data-sources/DataAwareWidget.cjs.map +1 -0
- package/dist/data-sources/DataAwareWidget.d.cts +24 -0
- package/dist/data-sources/DataAwareWidget.d.cts.map +1 -0
- package/dist/data-sources/DataAwareWidget.d.mts +24 -0
- package/dist/data-sources/DataAwareWidget.d.mts.map +1 -0
- package/dist/data-sources/DataAwareWidget.mjs +48 -0
- package/dist/data-sources/DataAwareWidget.mjs.map +1 -0
- package/dist/data-sources/ErrorState.cjs +20 -0
- package/dist/data-sources/ErrorState.cjs.map +1 -0
- package/dist/data-sources/ErrorState.d.cts +7 -0
- package/dist/data-sources/ErrorState.d.cts.map +1 -0
- package/dist/data-sources/ErrorState.d.mts +7 -0
- package/dist/data-sources/ErrorState.d.mts.map +1 -0
- package/dist/data-sources/ErrorState.mjs +18 -0
- package/dist/data-sources/ErrorState.mjs.map +1 -0
- package/dist/data-sources/context.cjs +24 -0
- package/dist/data-sources/context.cjs.map +1 -0
- package/dist/data-sources/context.d.cts +21 -0
- package/dist/data-sources/context.d.cts.map +1 -0
- package/dist/data-sources/context.d.mts +21 -0
- package/dist/data-sources/context.d.mts.map +1 -0
- package/dist/data-sources/context.mjs +21 -0
- package/dist/data-sources/context.mjs.map +1 -0
- package/dist/data-sources/fetchers/api.cjs +65 -0
- package/dist/data-sources/fetchers/api.cjs.map +1 -0
- package/dist/data-sources/fetchers/api.d.cts +10 -0
- package/dist/data-sources/fetchers/api.d.cts.map +1 -0
- package/dist/data-sources/fetchers/api.d.mts +10 -0
- package/dist/data-sources/fetchers/api.d.mts.map +1 -0
- package/dist/data-sources/fetchers/api.mjs +64 -0
- package/dist/data-sources/fetchers/api.mjs.map +1 -0
- package/dist/data-sources/fetchers/custom.cjs +108 -0
- package/dist/data-sources/fetchers/custom.cjs.map +1 -0
- package/dist/data-sources/fetchers/custom.d.cts +17 -0
- package/dist/data-sources/fetchers/custom.d.cts.map +1 -0
- package/dist/data-sources/fetchers/custom.d.mts +17 -0
- package/dist/data-sources/fetchers/custom.d.mts.map +1 -0
- package/dist/data-sources/fetchers/custom.mjs +107 -0
- package/dist/data-sources/fetchers/custom.mjs.map +1 -0
- package/dist/data-sources/fetchers/static.cjs +161 -0
- package/dist/data-sources/fetchers/static.cjs.map +1 -0
- package/dist/data-sources/fetchers/static.d.cts +40 -0
- package/dist/data-sources/fetchers/static.d.cts.map +1 -0
- package/dist/data-sources/fetchers/static.d.mts +40 -0
- package/dist/data-sources/fetchers/static.d.mts.map +1 -0
- package/dist/data-sources/fetchers/static.mjs +158 -0
- package/dist/data-sources/fetchers/static.mjs.map +1 -0
- package/dist/data-sources/preview-context.cjs +21 -0
- package/dist/data-sources/preview-context.cjs.map +1 -0
- package/dist/data-sources/preview-context.d.cts +13 -0
- package/dist/data-sources/preview-context.d.cts.map +1 -0
- package/dist/data-sources/preview-context.d.mts +13 -0
- package/dist/data-sources/preview-context.d.mts.map +1 -0
- package/dist/data-sources/preview-context.mjs +18 -0
- package/dist/data-sources/preview-context.mjs.map +1 -0
- package/dist/data-sources/registry-context.cjs +53 -0
- package/dist/data-sources/registry-context.cjs.map +1 -0
- package/dist/data-sources/registry-context.d.cts +48 -0
- package/dist/data-sources/registry-context.d.cts.map +1 -0
- package/dist/data-sources/registry-context.d.mts +48 -0
- package/dist/data-sources/registry-context.d.mts.map +1 -0
- package/dist/data-sources/registry-context.mjs +49 -0
- package/dist/data-sources/registry-context.mjs.map +1 -0
- package/dist/data-sources/registry.cjs +31 -0
- package/dist/data-sources/registry.cjs.map +1 -0
- package/dist/data-sources/registry.d.cts +19 -0
- package/dist/data-sources/registry.d.cts.map +1 -0
- package/dist/data-sources/registry.d.mts +19 -0
- package/dist/data-sources/registry.d.mts.map +1 -0
- package/dist/data-sources/registry.mjs +29 -0
- package/dist/data-sources/registry.mjs.map +1 -0
- package/dist/data-sources/transformers.cjs +154 -0
- package/dist/data-sources/transformers.cjs.map +1 -0
- package/dist/data-sources/transformers.d.cts +10 -0
- package/dist/data-sources/transformers.d.cts.map +1 -0
- package/dist/data-sources/transformers.d.mts +10 -0
- package/dist/data-sources/transformers.d.mts.map +1 -0
- package/dist/data-sources/transformers.mjs +153 -0
- package/dist/data-sources/transformers.mjs.map +1 -0
- package/dist/data-sources/types.cjs +0 -0
- package/dist/data-sources/types.d.cts +2 -0
- package/dist/data-sources/types.d.mts +2 -0
- package/dist/data-sources/types.mjs +1 -0
- package/dist/data-sources/use-widget-data.cjs +111 -0
- package/dist/data-sources/use-widget-data.cjs.map +1 -0
- package/dist/data-sources/use-widget-data.d.cts +17 -0
- package/dist/data-sources/use-widget-data.d.cts.map +1 -0
- package/dist/data-sources/use-widget-data.d.mts +17 -0
- package/dist/data-sources/use-widget-data.d.mts.map +1 -0
- package/dist/data-sources/use-widget-data.mjs +109 -0
- package/dist/data-sources/use-widget-data.mjs.map +1 -0
- package/dist/index-B5cTNde-.d.cts +246 -0
- package/dist/index-B5cTNde-.d.cts.map +1 -0
- package/dist/index-Cqt2JzkQ.d.mts +246 -0
- package/dist/index-Cqt2JzkQ.d.mts.map +1 -0
- package/dist/registries/index.cjs +243 -0
- package/dist/registries/index.cjs.map +1 -0
- package/dist/registries/index.d.cts +338 -0
- package/dist/registries/index.d.cts.map +1 -0
- package/dist/registries/index.d.mts +338 -0
- package/dist/registries/index.d.mts.map +1 -0
- package/dist/registries/index.mjs +229 -0
- package/dist/registries/index.mjs.map +1 -0
- package/dist/shell/AppShellLayout.cjs +49 -0
- package/dist/shell/AppShellLayout.cjs.map +1 -0
- package/dist/shell/AppShellLayout.d.cts +39 -0
- package/dist/shell/AppShellLayout.d.cts.map +1 -0
- package/dist/shell/AppShellLayout.d.mts +39 -0
- package/dist/shell/AppShellLayout.d.mts.map +1 -0
- package/dist/shell/AppShellLayout.mjs +46 -0
- package/dist/shell/AppShellLayout.mjs.map +1 -0
- package/dist/shell/ScreenHeader.cjs +44 -0
- package/dist/shell/ScreenHeader.cjs.map +1 -0
- package/dist/shell/ScreenHeader.d.cts +12 -0
- package/dist/shell/ScreenHeader.d.cts.map +1 -0
- package/dist/shell/ScreenHeader.d.mts +12 -0
- package/dist/shell/ScreenHeader.d.mts.map +1 -0
- package/dist/shell/ScreenHeader.mjs +42 -0
- package/dist/shell/ScreenHeader.mjs.map +1 -0
- package/dist/shell/ScreenHeaderContext.cjs +91 -0
- package/dist/shell/ScreenHeaderContext.cjs.map +1 -0
- package/dist/shell/ScreenHeaderContext.d.cts +35 -0
- package/dist/shell/ScreenHeaderContext.d.cts.map +1 -0
- package/dist/shell/ScreenHeaderContext.d.mts +35 -0
- package/dist/shell/ScreenHeaderContext.d.mts.map +1 -0
- package/dist/shell/ScreenHeaderContext.mjs +86 -0
- package/dist/shell/ScreenHeaderContext.mjs.map +1 -0
- package/dist/shell/ThemeModeContext.cjs +70 -0
- package/dist/shell/ThemeModeContext.cjs.map +1 -0
- package/dist/shell/ThemeModeContext.d.cts +33 -0
- package/dist/shell/ThemeModeContext.d.cts.map +1 -0
- package/dist/shell/ThemeModeContext.d.mts +33 -0
- package/dist/shell/ThemeModeContext.d.mts.map +1 -0
- package/dist/shell/ThemeModeContext.mjs +66 -0
- package/dist/shell/ThemeModeContext.mjs.map +1 -0
- package/dist/shell/index.cjs +43 -0
- package/dist/shell/index.d.cts +7 -0
- package/dist/shell/index.d.mts +7 -0
- package/dist/shell/index.mjs +7 -0
- package/dist/shell/sidebar.cjs +390 -0
- package/dist/shell/sidebar.cjs.map +1 -0
- package/dist/shell/sidebar.d.cts +85 -0
- package/dist/shell/sidebar.d.cts.map +1 -0
- package/dist/shell/sidebar.d.mts +85 -0
- package/dist/shell/sidebar.d.mts.map +1 -0
- package/dist/shell/sidebar.mjs +364 -0
- package/dist/shell/sidebar.mjs.map +1 -0
- package/dist/shell/use-mobile.cjs +51 -0
- package/dist/shell/use-mobile.cjs.map +1 -0
- package/dist/shell/use-mobile.d.cts +7 -0
- package/dist/shell/use-mobile.d.cts.map +1 -0
- package/dist/shell/use-mobile.d.mts +7 -0
- package/dist/shell/use-mobile.d.mts.map +1 -0
- package/dist/shell/use-mobile.mjs +47 -0
- package/dist/shell/use-mobile.mjs.map +1 -0
- package/dist/theme/index.cjs +758 -0
- package/dist/theme/index.cjs.map +1 -0
- package/dist/theme/index.d.cts +131 -0
- package/dist/theme/index.d.cts.map +1 -0
- package/dist/theme/index.d.mts +131 -0
- package/dist/theme/index.d.mts.map +1 -0
- package/dist/theme/index.mjs +728 -0
- package/dist/theme/index.mjs.map +1 -0
- package/dist/types/index.cjs +18 -0
- package/dist/types/index.d.cts +4 -0
- package/dist/types/index.d.mts +4 -0
- package/dist/types/index.mjs +2 -0
- package/dist/types-27AHMek-.d.cts +85 -0
- package/dist/types-27AHMek-.d.cts.map +1 -0
- package/dist/types-BXFX9bXp.cjs +303 -0
- package/dist/types-BXFX9bXp.cjs.map +1 -0
- package/dist/types-Bjmd7Fdx.mjs +208 -0
- package/dist/types-Bjmd7Fdx.mjs.map +1 -0
- package/dist/types-C5Zs5V3E.d.mts +155 -0
- package/dist/types-C5Zs5V3E.d.mts.map +1 -0
- package/dist/types-CeCPKvOv.d.mts +85 -0
- package/dist/types-CeCPKvOv.d.mts.map +1 -0
- package/dist/types-DrzvahW8.d.cts +155 -0
- package/dist/types-DrzvahW8.d.cts.map +1 -0
- package/dist/widget-schema-BKZgsNG7.d.mts +119 -0
- package/dist/widget-schema-BKZgsNG7.d.mts.map +1 -0
- package/dist/widget-schema-BSX2fVhW.d.cts +119 -0
- package/dist/widget-schema-BSX2fVhW.d.cts.map +1 -0
- package/dist/widget-utils/index.cjs +130 -0
- package/dist/widget-utils/index.cjs.map +1 -0
- package/dist/widget-utils/index.d.cts +47 -0
- package/dist/widget-utils/index.d.cts.map +1 -0
- package/dist/widget-utils/index.d.mts +47 -0
- package/dist/widget-utils/index.d.mts.map +1 -0
- package/dist/widget-utils/index.mjs +119 -0
- package/dist/widget-utils/index.mjs.map +1 -0
- package/package.json +200 -0
- package/src/styles/globals.css +1 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/shell/AppShellLayout.d.ts
|
|
4
|
+
interface AppShellLayoutProps {
|
|
5
|
+
/** Navigation content rendered inside the sidebar's scrollable area */
|
|
6
|
+
sidebarContent: React$1.ReactNode;
|
|
7
|
+
/** Header content rendered above the main content area */
|
|
8
|
+
headerContent: React$1.ReactNode;
|
|
9
|
+
/** Main page content */
|
|
10
|
+
children: React$1.ReactNode;
|
|
11
|
+
/** Optional slot at the top of the sidebar (e.g. logo, search) */
|
|
12
|
+
sidebarHeader?: React$1.ReactNode;
|
|
13
|
+
/** Optional slot at the bottom of the sidebar (e.g. user info) */
|
|
14
|
+
sidebarFooter?: React$1.ReactNode;
|
|
15
|
+
/** Content rendered after SidebarInset (e.g. MobileBottomNav) */
|
|
16
|
+
afterContent?: React$1.ReactNode;
|
|
17
|
+
/** Enable bottom nav mode (hides sidebar on mobile, adds bottom padding) */
|
|
18
|
+
useBottomNav?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Pure visual frame that replicates the RepApp layout:
|
|
22
|
+
* - 13rem collapsible sidebar
|
|
23
|
+
* - 52px header area
|
|
24
|
+
* - rounded-xl bg-background shadow-lg content area with bg-muted gutters
|
|
25
|
+
*
|
|
26
|
+
* This component handles zero business logic — it simply provides the visual shell.
|
|
27
|
+
*/
|
|
28
|
+
declare function AppShellLayout({
|
|
29
|
+
sidebarContent,
|
|
30
|
+
headerContent,
|
|
31
|
+
children,
|
|
32
|
+
sidebarHeader,
|
|
33
|
+
sidebarFooter,
|
|
34
|
+
afterContent,
|
|
35
|
+
useBottomNav
|
|
36
|
+
}: AppShellLayoutProps): React$1.JSX.Element;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { AppShellLayout, AppShellLayoutProps };
|
|
39
|
+
//# sourceMappingURL=AppShellLayout.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppShellLayout.d.cts","names":[],"sources":["../../src/shell/AppShellLayout.tsx"],"mappings":";;;UAYiB,mBAAA;;EAEf,cAAA,EAAgB,OAAA,CAAM,SAAA;EAFP;EAIf,aAAA,EAAe,OAAA,CAAM,SAAA;;EAErB,QAAA,EAAU,OAAA,CAAM,SAAA;;EAEhB,aAAA,GAAgB,OAAA,CAAM,SAAA;;EAEtB,aAAA,GAAgB,OAAA,CAAM,SAAA;;EAEtB,YAAA,GAAe,OAAA,CAAM,SAAA;;EAErB,YAAA;AAAA;;;;;;;;;iBAWc,cAAA,CAAA;EACd,cAAA;EACA,aAAA;EACA,QAAA;EACA,aAAA;EACA,aAAA;EACA,YAAA;EACA;AAAA,GACC,mBAAA,GAAsB,OAAA,CAAM,GAAA,CAAI,OAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/shell/AppShellLayout.d.ts
|
|
4
|
+
interface AppShellLayoutProps {
|
|
5
|
+
/** Navigation content rendered inside the sidebar's scrollable area */
|
|
6
|
+
sidebarContent: React$1.ReactNode;
|
|
7
|
+
/** Header content rendered above the main content area */
|
|
8
|
+
headerContent: React$1.ReactNode;
|
|
9
|
+
/** Main page content */
|
|
10
|
+
children: React$1.ReactNode;
|
|
11
|
+
/** Optional slot at the top of the sidebar (e.g. logo, search) */
|
|
12
|
+
sidebarHeader?: React$1.ReactNode;
|
|
13
|
+
/** Optional slot at the bottom of the sidebar (e.g. user info) */
|
|
14
|
+
sidebarFooter?: React$1.ReactNode;
|
|
15
|
+
/** Content rendered after SidebarInset (e.g. MobileBottomNav) */
|
|
16
|
+
afterContent?: React$1.ReactNode;
|
|
17
|
+
/** Enable bottom nav mode (hides sidebar on mobile, adds bottom padding) */
|
|
18
|
+
useBottomNav?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Pure visual frame that replicates the RepApp layout:
|
|
22
|
+
* - 13rem collapsible sidebar
|
|
23
|
+
* - 52px header area
|
|
24
|
+
* - rounded-xl bg-background shadow-lg content area with bg-muted gutters
|
|
25
|
+
*
|
|
26
|
+
* This component handles zero business logic — it simply provides the visual shell.
|
|
27
|
+
*/
|
|
28
|
+
declare function AppShellLayout({
|
|
29
|
+
sidebarContent,
|
|
30
|
+
headerContent,
|
|
31
|
+
children,
|
|
32
|
+
sidebarHeader,
|
|
33
|
+
sidebarFooter,
|
|
34
|
+
afterContent,
|
|
35
|
+
useBottomNav
|
|
36
|
+
}: AppShellLayoutProps): React$1.JSX.Element;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { AppShellLayout, AppShellLayoutProps };
|
|
39
|
+
//# sourceMappingURL=AppShellLayout.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppShellLayout.d.mts","names":[],"sources":["../../src/shell/AppShellLayout.tsx"],"mappings":";;;UAYiB,mBAAA;;EAEf,cAAA,EAAgB,OAAA,CAAM,SAAA;EAFP;EAIf,aAAA,EAAe,OAAA,CAAM,SAAA;;EAErB,QAAA,EAAU,OAAA,CAAM,SAAA;;EAEhB,aAAA,GAAgB,OAAA,CAAM,SAAA;;EAEtB,aAAA,GAAgB,OAAA,CAAM,SAAA;;EAEtB,YAAA,GAAe,OAAA,CAAM,SAAA;;EAErB,YAAA;AAAA;;;;;;;;;iBAWc,cAAA,CAAA;EACd,cAAA;EACA,aAAA;EACA,QAAA;EACA,aAAA;EACA,aAAA;EACA,YAAA;EACA;AAAA,GACC,mBAAA,GAAsB,OAAA,CAAM,GAAA,CAAI,OAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarInset, SidebarProvider } from "./sidebar.mjs";
|
|
3
|
+
import "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/shell/AppShellLayout.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Pure visual frame that replicates the RepApp layout:
|
|
8
|
+
* - 13rem collapsible sidebar
|
|
9
|
+
* - 52px header area
|
|
10
|
+
* - rounded-xl bg-background shadow-lg content area with bg-muted gutters
|
|
11
|
+
*
|
|
12
|
+
* This component handles zero business logic — it simply provides the visual shell.
|
|
13
|
+
*/
|
|
14
|
+
function AppShellLayout({ sidebarContent, headerContent, children, sidebarHeader, sidebarFooter, afterContent, useBottomNav = false }) {
|
|
15
|
+
return /* @__PURE__ */ jsx(SidebarProvider, {
|
|
16
|
+
useBottomNav,
|
|
17
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
18
|
+
className: "bg-muted relative flex max-h-dvh w-full overflow-hidden",
|
|
19
|
+
children: [
|
|
20
|
+
/* @__PURE__ */ jsxs(Sidebar, { children: [
|
|
21
|
+
sidebarHeader && /* @__PURE__ */ jsx(SidebarHeader, { children: sidebarHeader }),
|
|
22
|
+
/* @__PURE__ */ jsx(SidebarContent, {
|
|
23
|
+
className: "p-4",
|
|
24
|
+
children: sidebarContent
|
|
25
|
+
}),
|
|
26
|
+
sidebarFooter && /* @__PURE__ */ jsx(SidebarFooter, { children: sidebarFooter })
|
|
27
|
+
] }),
|
|
28
|
+
/* @__PURE__ */ jsxs(SidebarInset, {
|
|
29
|
+
className: "flex flex-1 flex-col overflow-hidden",
|
|
30
|
+
children: [headerContent, /* @__PURE__ */ jsx("div", {
|
|
31
|
+
className: `bg-muted flex-1 overflow-hidden md:pr-4 md:pb-4 ${useBottomNav ? "max-md:pb-[calc(4rem+env(safe-area-inset-bottom))]" : ""}`,
|
|
32
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
33
|
+
className: "scrollbar-none bg-background text-foreground h-full overflow-auto rounded-xl shadow-lg",
|
|
34
|
+
children
|
|
35
|
+
})
|
|
36
|
+
})]
|
|
37
|
+
}),
|
|
38
|
+
afterContent
|
|
39
|
+
]
|
|
40
|
+
})
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { AppShellLayout };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=AppShellLayout.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppShellLayout.mjs","names":[],"sources":["../../src/shell/AppShellLayout.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarInset,\n SidebarProvider,\n} from \"./sidebar\";\n\nexport interface AppShellLayoutProps {\n /** Navigation content rendered inside the sidebar's scrollable area */\n sidebarContent: React.ReactNode;\n /** Header content rendered above the main content area */\n headerContent: React.ReactNode;\n /** Main page content */\n children: React.ReactNode;\n /** Optional slot at the top of the sidebar (e.g. logo, search) */\n sidebarHeader?: React.ReactNode;\n /** Optional slot at the bottom of the sidebar (e.g. user info) */\n sidebarFooter?: React.ReactNode;\n /** Content rendered after SidebarInset (e.g. MobileBottomNav) */\n afterContent?: React.ReactNode;\n /** Enable bottom nav mode (hides sidebar on mobile, adds bottom padding) */\n useBottomNav?: boolean;\n}\n\n/**\n * Pure visual frame that replicates the RepApp layout:\n * - 13rem collapsible sidebar\n * - 52px header area\n * - rounded-xl bg-background shadow-lg content area with bg-muted gutters\n *\n * This component handles zero business logic — it simply provides the visual shell.\n */\nexport function AppShellLayout({\n sidebarContent,\n headerContent,\n children,\n sidebarHeader,\n sidebarFooter,\n afterContent,\n useBottomNav = false,\n}: AppShellLayoutProps): React.JSX.Element {\n return (\n <SidebarProvider useBottomNav={useBottomNav}>\n <div className=\"bg-muted relative flex max-h-dvh w-full overflow-hidden\">\n {/* Navigation Sidebar */}\n <Sidebar>\n {sidebarHeader && <SidebarHeader>{sidebarHeader}</SidebarHeader>}\n <SidebarContent className=\"p-4\">{sidebarContent}</SidebarContent>\n {sidebarFooter && <SidebarFooter>{sidebarFooter}</SidebarFooter>}\n </Sidebar>\n\n {/* Main Content Area */}\n <SidebarInset className=\"flex flex-1 flex-col overflow-hidden\">\n {/* Header */}\n {headerContent}\n\n {/* Screen Content */}\n <div\n className={`bg-muted flex-1 overflow-hidden md:pr-4 md:pb-4 ${useBottomNav ? \"max-md:pb-[calc(4rem+env(safe-area-inset-bottom))]\" : \"\"}`}\n >\n <div className=\"scrollbar-none bg-background text-foreground h-full overflow-auto rounded-xl shadow-lg\">\n {children}\n </div>\n </div>\n </SidebarInset>\n\n {/* After content (e.g. MobileBottomNav) */}\n {afterContent}\n </div>\n </SidebarProvider>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAqCA,SAAgB,eAAe,EAC7B,gBACA,eACA,UACA,eACA,eACA,cACA,eAAe,SAC0B;AACzC,QACE,oBAAC,iBAAD;EAA+B;YAC7B,qBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,qBAAC,SAAD,EAAA,UAAA;KACG,iBAAiB,oBAAC,eAAD,EAAA,UAAgB,eAA8B,CAAA;KAChE,oBAAC,gBAAD;MAAgB,WAAU;gBAAO;MAAgC,CAAA;KAChE,iBAAiB,oBAAC,eAAD,EAAA,UAAgB,eAA8B,CAAA;KACxD,EAAA,CAAA;IAGV,qBAAC,cAAD;KAAc,WAAU;eAAxB,CAEG,eAGD,oBAAC,OAAD;MACE,WAAW,mDAAmD,eAAe,uDAAuD;gBAEpI,oBAAC,OAAD;OAAK,WAAU;OACZ;OACG,CAAA;MACF,CAAA,CACO;;IAGd;IACG;;EACU,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
require("../chunk-CKQMccvm.cjs");
|
|
4
|
+
const require_shell_sidebar = require("./sidebar.cjs");
|
|
5
|
+
const require_shell_ScreenHeaderContext = require("./ScreenHeaderContext.cjs");
|
|
6
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
|
+
let _fortawesome_pro_regular_svg_icons = require("@fortawesome/pro-regular-svg-icons");
|
|
8
|
+
let _fortawesome_react_fontawesome = require("@fortawesome/react-fontawesome");
|
|
9
|
+
//#region src/shell/ScreenHeader.tsx
|
|
10
|
+
function ScreenHeader({ title }) {
|
|
11
|
+
const { toggleSidebar, isMobile } = require_shell_sidebar.useSidebar();
|
|
12
|
+
const { actions, breadcrumbs } = require_shell_ScreenHeaderContext.useScreenHeaderContext();
|
|
13
|
+
if (!title && !breadcrumbs) return null;
|
|
14
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
15
|
+
className: "border-border bg-background sticky top-0 z-10 flex flex-row items-center border-b px-4 py-3 md:px-6",
|
|
16
|
+
children: [
|
|
17
|
+
!isMobile && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
18
|
+
type: "button",
|
|
19
|
+
onClick: toggleSidebar,
|
|
20
|
+
className: "text-muted-foreground hover:text-foreground -ml-1 inline-flex items-center justify-center rounded-md p-1",
|
|
21
|
+
"aria-label": "Toggle Sidebar",
|
|
22
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fortawesome_react_fontawesome.FontAwesomeIcon, {
|
|
23
|
+
icon: _fortawesome_pro_regular_svg_icons.faTableLayout,
|
|
24
|
+
className: "size-4"
|
|
25
|
+
})
|
|
26
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "bg-border mx-2 h-4 w-px" })] }),
|
|
27
|
+
breadcrumbs ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
28
|
+
className: "min-w-0 flex-1",
|
|
29
|
+
children: breadcrumbs
|
|
30
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
|
|
31
|
+
className: "text-foreground text-lg font-semibold",
|
|
32
|
+
children: title
|
|
33
|
+
}),
|
|
34
|
+
actions && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
35
|
+
className: "ml-auto flex items-center gap-2",
|
|
36
|
+
children: actions
|
|
37
|
+
})
|
|
38
|
+
]
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
exports.ScreenHeader = ScreenHeader;
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=ScreenHeader.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenHeader.cjs","names":["useSidebar","useScreenHeaderContext","FontAwesomeIcon","faTableLayout"],"sources":["../../src/shell/ScreenHeader.tsx"],"sourcesContent":["\"use client\";\n\nimport type React from \"react\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { faTableLayout } from \"@fortawesome/pro-regular-svg-icons\";\nimport { useSidebar } from \"./sidebar\";\nimport { useScreenHeaderContext } from \"./ScreenHeaderContext\";\n\nexport interface ScreenHeaderProps {\n title?: string;\n}\n\nexport function ScreenHeader({\n title,\n}: ScreenHeaderProps): React.JSX.Element | null {\n const { toggleSidebar, isMobile } = useSidebar();\n const { actions, breadcrumbs } = useScreenHeaderContext();\n\n if (!title && !breadcrumbs) return null;\n\n return (\n <div className=\"border-border bg-background sticky top-0 z-10 flex flex-row items-center border-b px-4 py-3 md:px-6\">\n {!isMobile && (\n <>\n <button\n type=\"button\"\n onClick={toggleSidebar}\n className=\"text-muted-foreground hover:text-foreground -ml-1 inline-flex items-center justify-center rounded-md p-1\"\n aria-label=\"Toggle Sidebar\"\n >\n <FontAwesomeIcon icon={faTableLayout} className=\"size-4\" />\n </button>\n <div className=\"bg-border mx-2 h-4 w-px\" />\n </>\n )}\n {breadcrumbs ? (\n <div className=\"min-w-0 flex-1\">{breadcrumbs}</div>\n ) : (\n <h1 className=\"text-foreground text-lg font-semibold\">{title}</h1>\n )}\n {actions && (\n <div className=\"ml-auto flex items-center gap-2\">{actions}</div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,aAAa,EAC3B,SAC8C;CAC9C,MAAM,EAAE,eAAe,aAAaA,sBAAAA,YAAY;CAChD,MAAM,EAAE,SAAS,gBAAgBC,kCAAAA,wBAAwB;AAEzD,KAAI,CAAC,SAAS,CAAC,YAAa,QAAO;AAEnC,QACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;EAAK,WAAU;YAAf;GACG,CAAC,YACA,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,WAAU;IACV,cAAW;cAEX,iBAAA,GAAA,kBAAA,KAACC,+BAAAA,iBAAD;KAAiB,MAAMC,mCAAAA;KAAe,WAAU;KAAW,CAAA;IACpD,CAAA,EACT,iBAAA,GAAA,kBAAA,KAAC,OAAD,EAAK,WAAU,2BAA4B,CAAA,CAC1C,EAAA,CAAA;GAEJ,cACC,iBAAA,GAAA,kBAAA,KAAC,OAAD;IAAK,WAAU;cAAkB;IAAkB,CAAA,GAEnD,iBAAA,GAAA,kBAAA,KAAC,MAAD;IAAI,WAAU;cAAyC;IAAW,CAAA;GAEnE,WACC,iBAAA,GAAA,kBAAA,KAAC,OAAD;IAAK,WAAU;cAAmC;IAAc,CAAA;GAE9D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/shell/ScreenHeader.d.ts
|
|
4
|
+
interface ScreenHeaderProps {
|
|
5
|
+
title?: string;
|
|
6
|
+
}
|
|
7
|
+
declare function ScreenHeader({
|
|
8
|
+
title
|
|
9
|
+
}: ScreenHeaderProps): React.JSX.Element | null;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ScreenHeader, ScreenHeaderProps };
|
|
12
|
+
//# sourceMappingURL=ScreenHeader.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenHeader.d.cts","names":[],"sources":["../../src/shell/ScreenHeader.tsx"],"mappings":";;;UAQiB,iBAAA;EACf,KAAA;AAAA;AAAA,iBAGc,YAAA,CAAA;EACd;AAAA,GACC,iBAAA,GAAoB,KAAA,CAAM,GAAA,CAAI,OAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/shell/ScreenHeader.d.ts
|
|
4
|
+
interface ScreenHeaderProps {
|
|
5
|
+
title?: string;
|
|
6
|
+
}
|
|
7
|
+
declare function ScreenHeader({
|
|
8
|
+
title
|
|
9
|
+
}: ScreenHeaderProps): React.JSX.Element | null;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ScreenHeader, ScreenHeaderProps };
|
|
12
|
+
//# sourceMappingURL=ScreenHeader.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenHeader.d.mts","names":[],"sources":["../../src/shell/ScreenHeader.tsx"],"mappings":";;;UAQiB,iBAAA;EACf,KAAA;AAAA;AAAA,iBAGc,YAAA,CAAA;EACd;AAAA,GACC,iBAAA,GAAoB,KAAA,CAAM,GAAA,CAAI,OAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useSidebar } from "./sidebar.mjs";
|
|
3
|
+
import { useScreenHeaderContext } from "./ScreenHeaderContext.mjs";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { faTableLayout } from "@fortawesome/pro-regular-svg-icons";
|
|
6
|
+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
7
|
+
//#region src/shell/ScreenHeader.tsx
|
|
8
|
+
function ScreenHeader({ title }) {
|
|
9
|
+
const { toggleSidebar, isMobile } = useSidebar();
|
|
10
|
+
const { actions, breadcrumbs } = useScreenHeaderContext();
|
|
11
|
+
if (!title && !breadcrumbs) return null;
|
|
12
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
13
|
+
className: "border-border bg-background sticky top-0 z-10 flex flex-row items-center border-b px-4 py-3 md:px-6",
|
|
14
|
+
children: [
|
|
15
|
+
!isMobile && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
|
|
16
|
+
type: "button",
|
|
17
|
+
onClick: toggleSidebar,
|
|
18
|
+
className: "text-muted-foreground hover:text-foreground -ml-1 inline-flex items-center justify-center rounded-md p-1",
|
|
19
|
+
"aria-label": "Toggle Sidebar",
|
|
20
|
+
children: /* @__PURE__ */ jsx(FontAwesomeIcon, {
|
|
21
|
+
icon: faTableLayout,
|
|
22
|
+
className: "size-4"
|
|
23
|
+
})
|
|
24
|
+
}), /* @__PURE__ */ jsx("div", { className: "bg-border mx-2 h-4 w-px" })] }),
|
|
25
|
+
breadcrumbs ? /* @__PURE__ */ jsx("div", {
|
|
26
|
+
className: "min-w-0 flex-1",
|
|
27
|
+
children: breadcrumbs
|
|
28
|
+
}) : /* @__PURE__ */ jsx("h1", {
|
|
29
|
+
className: "text-foreground text-lg font-semibold",
|
|
30
|
+
children: title
|
|
31
|
+
}),
|
|
32
|
+
actions && /* @__PURE__ */ jsx("div", {
|
|
33
|
+
className: "ml-auto flex items-center gap-2",
|
|
34
|
+
children: actions
|
|
35
|
+
})
|
|
36
|
+
]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { ScreenHeader };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=ScreenHeader.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenHeader.mjs","names":[],"sources":["../../src/shell/ScreenHeader.tsx"],"sourcesContent":["\"use client\";\n\nimport type React from \"react\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { faTableLayout } from \"@fortawesome/pro-regular-svg-icons\";\nimport { useSidebar } from \"./sidebar\";\nimport { useScreenHeaderContext } from \"./ScreenHeaderContext\";\n\nexport interface ScreenHeaderProps {\n title?: string;\n}\n\nexport function ScreenHeader({\n title,\n}: ScreenHeaderProps): React.JSX.Element | null {\n const { toggleSidebar, isMobile } = useSidebar();\n const { actions, breadcrumbs } = useScreenHeaderContext();\n\n if (!title && !breadcrumbs) return null;\n\n return (\n <div className=\"border-border bg-background sticky top-0 z-10 flex flex-row items-center border-b px-4 py-3 md:px-6\">\n {!isMobile && (\n <>\n <button\n type=\"button\"\n onClick={toggleSidebar}\n className=\"text-muted-foreground hover:text-foreground -ml-1 inline-flex items-center justify-center rounded-md p-1\"\n aria-label=\"Toggle Sidebar\"\n >\n <FontAwesomeIcon icon={faTableLayout} className=\"size-4\" />\n </button>\n <div className=\"bg-border mx-2 h-4 w-px\" />\n </>\n )}\n {breadcrumbs ? (\n <div className=\"min-w-0 flex-1\">{breadcrumbs}</div>\n ) : (\n <h1 className=\"text-foreground text-lg font-semibold\">{title}</h1>\n )}\n {actions && (\n <div className=\"ml-auto flex items-center gap-2\">{actions}</div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAYA,SAAgB,aAAa,EAC3B,SAC8C;CAC9C,MAAM,EAAE,eAAe,aAAa,YAAY;CAChD,MAAM,EAAE,SAAS,gBAAgB,wBAAwB;AAEzD,KAAI,CAAC,SAAS,CAAC,YAAa,QAAO;AAEnC,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACG,CAAC,YACA,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,WAAU;IACV,cAAW;cAEX,oBAAC,iBAAD;KAAiB,MAAM;KAAe,WAAU;KAAW,CAAA;IACpD,CAAA,EACT,oBAAC,OAAD,EAAK,WAAU,2BAA4B,CAAA,CAC1C,EAAA,CAAA;GAEJ,cACC,oBAAC,OAAD;IAAK,WAAU;cAAkB;IAAkB,CAAA,GAEnD,oBAAC,MAAD;IAAI,WAAU;cAAyC;IAAW,CAAA;GAEnE,WACC,oBAAC,OAAD;IAAK,WAAU;cAAmC;IAAc,CAAA;GAE9D"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
require("../chunk-CKQMccvm.cjs");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
|
+
//#region src/shell/ScreenHeaderContext.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Split into separate read/write contexts so that components calling
|
|
9
|
+
* useScreenHeaderActions (writers) don't re-render when the actions
|
|
10
|
+
* state changes — only the ScreenHeader (reader) re-renders.
|
|
11
|
+
*/
|
|
12
|
+
const ScreenHeaderWriteContext = (0, react.createContext)(null);
|
|
13
|
+
const ScreenHeaderReadContext = (0, react.createContext)(null);
|
|
14
|
+
const ScreenHeaderBreadcrumbsWriteContext = (0, react.createContext)(null);
|
|
15
|
+
const ScreenHeaderBreadcrumbsReadContext = (0, react.createContext)(null);
|
|
16
|
+
function ScreenHeaderProvider({ children }) {
|
|
17
|
+
const [actions, setActions] = (0, react.useState)(null);
|
|
18
|
+
const [breadcrumbs, setBreadcrumbs] = (0, react.useState)(null);
|
|
19
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScreenHeaderWriteContext.Provider, {
|
|
20
|
+
value: setActions,
|
|
21
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScreenHeaderReadContext.Provider, {
|
|
22
|
+
value: actions,
|
|
23
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScreenHeaderBreadcrumbsWriteContext.Provider, {
|
|
24
|
+
value: setBreadcrumbs,
|
|
25
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScreenHeaderBreadcrumbsReadContext.Provider, {
|
|
26
|
+
value: breadcrumbs,
|
|
27
|
+
children
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Sets actions to display in the ScreenHeader.
|
|
35
|
+
* Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),
|
|
36
|
+
* `false` otherwise. Pages can use this boolean to conditionally skip
|
|
37
|
+
* rendering their own PageHeader.
|
|
38
|
+
*
|
|
39
|
+
* Cleans up actions on unmount so navigating away doesn't leave stale actions.
|
|
40
|
+
*/
|
|
41
|
+
function useScreenHeaderActions(actions) {
|
|
42
|
+
const setActions = (0, react.useContext)(ScreenHeaderWriteContext);
|
|
43
|
+
const setActionsRef = (0, react.useRef)(setActions);
|
|
44
|
+
setActionsRef.current = setActions;
|
|
45
|
+
(0, react.useEffect)(() => {
|
|
46
|
+
if (!setActions) return;
|
|
47
|
+
setActions(actions);
|
|
48
|
+
}, [actions, setActions]);
|
|
49
|
+
(0, react.useEffect)(() => {
|
|
50
|
+
return () => setActionsRef.current?.(null);
|
|
51
|
+
}, []);
|
|
52
|
+
return setActions !== null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Sets breadcrumbs to display in the ScreenHeader (in place of the plain title).
|
|
56
|
+
* Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),
|
|
57
|
+
* `false` otherwise.
|
|
58
|
+
*
|
|
59
|
+
* Cleans up breadcrumbs on unmount so navigating away doesn't leave stale breadcrumbs.
|
|
60
|
+
*/
|
|
61
|
+
function useScreenHeaderBreadcrumbs(breadcrumbs) {
|
|
62
|
+
const setBreadcrumbs = (0, react.useContext)(ScreenHeaderBreadcrumbsWriteContext);
|
|
63
|
+
const setBreadcrumbsRef = (0, react.useRef)(setBreadcrumbs);
|
|
64
|
+
setBreadcrumbsRef.current = setBreadcrumbs;
|
|
65
|
+
(0, react.useEffect)(() => {
|
|
66
|
+
if (!setBreadcrumbs) return;
|
|
67
|
+
setBreadcrumbs(breadcrumbs);
|
|
68
|
+
}, [breadcrumbs, setBreadcrumbs]);
|
|
69
|
+
(0, react.useEffect)(() => {
|
|
70
|
+
return () => setBreadcrumbsRef.current?.(null);
|
|
71
|
+
}, []);
|
|
72
|
+
return setBreadcrumbs !== null;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reads the current screen header actions and breadcrumbs. Used internally by ScreenHeader.
|
|
76
|
+
*/
|
|
77
|
+
function useScreenHeaderContext() {
|
|
78
|
+
const actions = (0, react.useContext)(ScreenHeaderReadContext);
|
|
79
|
+
const breadcrumbs = (0, react.useContext)(ScreenHeaderBreadcrumbsReadContext);
|
|
80
|
+
return {
|
|
81
|
+
actions: actions ?? null,
|
|
82
|
+
breadcrumbs: breadcrumbs ?? null
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
exports.ScreenHeaderProvider = ScreenHeaderProvider;
|
|
87
|
+
exports.useScreenHeaderActions = useScreenHeaderActions;
|
|
88
|
+
exports.useScreenHeaderBreadcrumbs = useScreenHeaderBreadcrumbs;
|
|
89
|
+
exports.useScreenHeaderContext = useScreenHeaderContext;
|
|
90
|
+
|
|
91
|
+
//# sourceMappingURL=ScreenHeaderContext.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenHeaderContext.cjs","names":[],"sources":["../../src/shell/ScreenHeaderContext.tsx"],"sourcesContent":["\"use client\";\n\nimport type React from \"react\";\nimport {\n createContext,\n useContext,\n useState,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\";\n\ntype SetActions = (actions: ReactNode) => void;\ntype SetBreadcrumbs = (breadcrumbs: ReactNode) => void;\n\n/**\n * Split into separate read/write contexts so that components calling\n * useScreenHeaderActions (writers) don't re-render when the actions\n * state changes — only the ScreenHeader (reader) re-renders.\n */\nconst ScreenHeaderWriteContext = createContext<SetActions | null>(null);\nconst ScreenHeaderReadContext = createContext<ReactNode>(null);\n\nconst ScreenHeaderBreadcrumbsWriteContext =\n createContext<SetBreadcrumbs | null>(null);\nconst ScreenHeaderBreadcrumbsReadContext = createContext<ReactNode>(null);\n\nexport function ScreenHeaderProvider({\n children,\n}: {\n children: ReactNode;\n}): React.JSX.Element {\n const [actions, setActions] = useState<ReactNode>(null);\n const [breadcrumbs, setBreadcrumbs] = useState<ReactNode>(null);\n\n return (\n <ScreenHeaderWriteContext.Provider value={setActions}>\n <ScreenHeaderReadContext.Provider value={actions}>\n <ScreenHeaderBreadcrumbsWriteContext.Provider value={setBreadcrumbs}>\n <ScreenHeaderBreadcrumbsReadContext.Provider value={breadcrumbs}>\n {children}\n </ScreenHeaderBreadcrumbsReadContext.Provider>\n </ScreenHeaderBreadcrumbsWriteContext.Provider>\n </ScreenHeaderReadContext.Provider>\n </ScreenHeaderWriteContext.Provider>\n );\n}\n\n/**\n * Sets actions to display in the ScreenHeader.\n * Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),\n * `false` otherwise. Pages can use this boolean to conditionally skip\n * rendering their own PageHeader.\n *\n * Cleans up actions on unmount so navigating away doesn't leave stale actions.\n */\nexport function useScreenHeaderActions(actions: ReactNode): boolean {\n const setActions = useContext(ScreenHeaderWriteContext);\n const setActionsRef = useRef(setActions);\n setActionsRef.current = setActions;\n\n // Update actions when the value changes\n useEffect(() => {\n if (!setActions) return;\n setActions(actions);\n }, [actions, setActions]);\n\n // Clear actions only on unmount\n useEffect(() => {\n return () => setActionsRef.current?.(null);\n }, []);\n\n return setActions !== null;\n}\n\n/**\n * Sets breadcrumbs to display in the ScreenHeader (in place of the plain title).\n * Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),\n * `false` otherwise.\n *\n * Cleans up breadcrumbs on unmount so navigating away doesn't leave stale breadcrumbs.\n */\nexport function useScreenHeaderBreadcrumbs(breadcrumbs: ReactNode): boolean {\n const setBreadcrumbs = useContext(ScreenHeaderBreadcrumbsWriteContext);\n const setBreadcrumbsRef = useRef(setBreadcrumbs);\n setBreadcrumbsRef.current = setBreadcrumbs;\n\n // Update breadcrumbs when the value changes\n useEffect(() => {\n if (!setBreadcrumbs) return;\n setBreadcrumbs(breadcrumbs);\n }, [breadcrumbs, setBreadcrumbs]);\n\n // Clear breadcrumbs only on unmount\n useEffect(() => {\n return () => setBreadcrumbsRef.current?.(null);\n }, []);\n\n return setBreadcrumbs !== null;\n}\n\n/**\n * Reads the current screen header actions and breadcrumbs. Used internally by ScreenHeader.\n */\nexport function useScreenHeaderContext(): {\n actions: ReactNode;\n breadcrumbs: ReactNode;\n} {\n const actions = useContext(ScreenHeaderReadContext);\n const breadcrumbs = useContext(ScreenHeaderBreadcrumbsReadContext);\n return { actions: actions ?? null, breadcrumbs: breadcrumbs ?? null };\n}\n"],"mappings":";;;;;;;;;;;AAoBA,MAAM,4BAAA,GAAA,MAAA,eAA4D,KAAK;AACvE,MAAM,2BAAA,GAAA,MAAA,eAAmD,KAAK;AAE9D,MAAM,uCAAA,GAAA,MAAA,eACiC,KAAK;AAC5C,MAAM,sCAAA,GAAA,MAAA,eAA8D,KAAK;AAEzE,SAAgB,qBAAqB,EACnC,YAGoB;CACpB,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,UAAkC,KAAK;CACvD,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,UAAsC,KAAK;AAE/D,QACE,iBAAA,GAAA,kBAAA,KAAC,yBAAyB,UAA1B;EAAmC,OAAO;YACxC,iBAAA,GAAA,kBAAA,KAAC,wBAAwB,UAAzB;GAAkC,OAAO;aACvC,iBAAA,GAAA,kBAAA,KAAC,oCAAoC,UAArC;IAA8C,OAAO;cACnD,iBAAA,GAAA,kBAAA,KAAC,mCAAmC,UAApC;KAA6C,OAAO;KACjD;KAC2C,CAAA;IACD,CAAA;GACd,CAAA;EACD,CAAA;;;;;;;;;;AAYxC,SAAgB,uBAAuB,SAA6B;CAClE,MAAM,cAAA,GAAA,MAAA,YAAwB,yBAAyB;CACvD,MAAM,iBAAA,GAAA,MAAA,QAAuB,WAAW;AACxC,eAAc,UAAU;AAGxB,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAI,CAAC,WAAY;AACjB,aAAW,QAAQ;IAClB,CAAC,SAAS,WAAW,CAAC;AAGzB,EAAA,GAAA,MAAA,iBAAgB;AACd,eAAa,cAAc,UAAU,KAAK;IACzC,EAAE,CAAC;AAEN,QAAO,eAAe;;;;;;;;;AAUxB,SAAgB,2BAA2B,aAAiC;CAC1E,MAAM,kBAAA,GAAA,MAAA,YAA4B,oCAAoC;CACtE,MAAM,qBAAA,GAAA,MAAA,QAA2B,eAAe;AAChD,mBAAkB,UAAU;AAG5B,EAAA,GAAA,MAAA,iBAAgB;AACd,MAAI,CAAC,eAAgB;AACrB,iBAAe,YAAY;IAC1B,CAAC,aAAa,eAAe,CAAC;AAGjC,EAAA,GAAA,MAAA,iBAAgB;AACd,eAAa,kBAAkB,UAAU,KAAK;IAC7C,EAAE,CAAC;AAEN,QAAO,mBAAmB;;;;;AAM5B,SAAgB,yBAGd;CACA,MAAM,WAAA,GAAA,MAAA,YAAqB,wBAAwB;CACnD,MAAM,eAAA,GAAA,MAAA,YAAyB,mCAAmC;AAClE,QAAO;EAAE,SAAS,WAAW;EAAM,aAAa,eAAe;EAAM"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/shell/ScreenHeaderContext.d.ts
|
|
4
|
+
declare function ScreenHeaderProvider({
|
|
5
|
+
children
|
|
6
|
+
}: {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Sets actions to display in the ScreenHeader.
|
|
11
|
+
* Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),
|
|
12
|
+
* `false` otherwise. Pages can use this boolean to conditionally skip
|
|
13
|
+
* rendering their own PageHeader.
|
|
14
|
+
*
|
|
15
|
+
* Cleans up actions on unmount so navigating away doesn't leave stale actions.
|
|
16
|
+
*/
|
|
17
|
+
declare function useScreenHeaderActions(actions: ReactNode): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Sets breadcrumbs to display in the ScreenHeader (in place of the plain title).
|
|
20
|
+
* Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),
|
|
21
|
+
* `false` otherwise.
|
|
22
|
+
*
|
|
23
|
+
* Cleans up breadcrumbs on unmount so navigating away doesn't leave stale breadcrumbs.
|
|
24
|
+
*/
|
|
25
|
+
declare function useScreenHeaderBreadcrumbs(breadcrumbs: ReactNode): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Reads the current screen header actions and breadcrumbs. Used internally by ScreenHeader.
|
|
28
|
+
*/
|
|
29
|
+
declare function useScreenHeaderContext(): {
|
|
30
|
+
actions: ReactNode;
|
|
31
|
+
breadcrumbs: ReactNode;
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { ScreenHeaderProvider, useScreenHeaderActions, useScreenHeaderBreadcrumbs, useScreenHeaderContext };
|
|
35
|
+
//# sourceMappingURL=ScreenHeaderContext.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenHeaderContext.d.cts","names":[],"sources":["../../src/shell/ScreenHeaderContext.tsx"],"mappings":";;;iBA2BgB,oBAAA,CAAA;EACd;AAAA;EAEA,QAAA,EAAU,SAAA;AAAA,IACR,KAAA,CAAM,GAAA,CAAI,OAAA;;;;;;;;;iBAyBE,sBAAA,CAAuB,OAAA,EAAS,SAAA;;;;;;;AAAhD;iBA0BgB,0BAAA,CAA2B,WAAA,EAAa,SAAA;;;;iBAsBxC,sBAAA,CAAA;EACd,OAAA,EAAS,SAAA;EACT,WAAA,EAAa,SAAA;AAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/shell/ScreenHeaderContext.d.ts
|
|
4
|
+
declare function ScreenHeaderProvider({
|
|
5
|
+
children
|
|
6
|
+
}: {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Sets actions to display in the ScreenHeader.
|
|
11
|
+
* Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),
|
|
12
|
+
* `false` otherwise. Pages can use this boolean to conditionally skip
|
|
13
|
+
* rendering their own PageHeader.
|
|
14
|
+
*
|
|
15
|
+
* Cleans up actions on unmount so navigating away doesn't leave stale actions.
|
|
16
|
+
*/
|
|
17
|
+
declare function useScreenHeaderActions(actions: ReactNode): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Sets breadcrumbs to display in the ScreenHeader (in place of the plain title).
|
|
20
|
+
* Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),
|
|
21
|
+
* `false` otherwise.
|
|
22
|
+
*
|
|
23
|
+
* Cleans up breadcrumbs on unmount so navigating away doesn't leave stale breadcrumbs.
|
|
24
|
+
*/
|
|
25
|
+
declare function useScreenHeaderBreadcrumbs(breadcrumbs: ReactNode): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Reads the current screen header actions and breadcrumbs. Used internally by ScreenHeader.
|
|
28
|
+
*/
|
|
29
|
+
declare function useScreenHeaderContext(): {
|
|
30
|
+
actions: ReactNode;
|
|
31
|
+
breadcrumbs: ReactNode;
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { ScreenHeaderProvider, useScreenHeaderActions, useScreenHeaderBreadcrumbs, useScreenHeaderContext };
|
|
35
|
+
//# sourceMappingURL=ScreenHeaderContext.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenHeaderContext.d.mts","names":[],"sources":["../../src/shell/ScreenHeaderContext.tsx"],"mappings":";;;iBA2BgB,oBAAA,CAAA;EACd;AAAA;EAEA,QAAA,EAAU,SAAA;AAAA,IACR,KAAA,CAAM,GAAA,CAAI,OAAA;;;;;;;;;iBAyBE,sBAAA,CAAuB,OAAA,EAAS,SAAA;;;;;;;AAAhD;iBA0BgB,0BAAA,CAA2B,WAAA,EAAa,SAAA;;;;iBAsBxC,sBAAA,CAAA;EACd,OAAA,EAAS,SAAA;EACT,WAAA,EAAa,SAAA;AAAA"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/shell/ScreenHeaderContext.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Split into separate read/write contexts so that components calling
|
|
7
|
+
* useScreenHeaderActions (writers) don't re-render when the actions
|
|
8
|
+
* state changes — only the ScreenHeader (reader) re-renders.
|
|
9
|
+
*/
|
|
10
|
+
const ScreenHeaderWriteContext = createContext(null);
|
|
11
|
+
const ScreenHeaderReadContext = createContext(null);
|
|
12
|
+
const ScreenHeaderBreadcrumbsWriteContext = createContext(null);
|
|
13
|
+
const ScreenHeaderBreadcrumbsReadContext = createContext(null);
|
|
14
|
+
function ScreenHeaderProvider({ children }) {
|
|
15
|
+
const [actions, setActions] = useState(null);
|
|
16
|
+
const [breadcrumbs, setBreadcrumbs] = useState(null);
|
|
17
|
+
return /* @__PURE__ */ jsx(ScreenHeaderWriteContext.Provider, {
|
|
18
|
+
value: setActions,
|
|
19
|
+
children: /* @__PURE__ */ jsx(ScreenHeaderReadContext.Provider, {
|
|
20
|
+
value: actions,
|
|
21
|
+
children: /* @__PURE__ */ jsx(ScreenHeaderBreadcrumbsWriteContext.Provider, {
|
|
22
|
+
value: setBreadcrumbs,
|
|
23
|
+
children: /* @__PURE__ */ jsx(ScreenHeaderBreadcrumbsReadContext.Provider, {
|
|
24
|
+
value: breadcrumbs,
|
|
25
|
+
children
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Sets actions to display in the ScreenHeader.
|
|
33
|
+
* Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),
|
|
34
|
+
* `false` otherwise. Pages can use this boolean to conditionally skip
|
|
35
|
+
* rendering their own PageHeader.
|
|
36
|
+
*
|
|
37
|
+
* Cleans up actions on unmount so navigating away doesn't leave stale actions.
|
|
38
|
+
*/
|
|
39
|
+
function useScreenHeaderActions(actions) {
|
|
40
|
+
const setActions = useContext(ScreenHeaderWriteContext);
|
|
41
|
+
const setActionsRef = useRef(setActions);
|
|
42
|
+
setActionsRef.current = setActions;
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (!setActions) return;
|
|
45
|
+
setActions(actions);
|
|
46
|
+
}, [actions, setActions]);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
return () => setActionsRef.current?.(null);
|
|
49
|
+
}, []);
|
|
50
|
+
return setActions !== null;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Sets breadcrumbs to display in the ScreenHeader (in place of the plain title).
|
|
54
|
+
* Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),
|
|
55
|
+
* `false` otherwise.
|
|
56
|
+
*
|
|
57
|
+
* Cleans up breadcrumbs on unmount so navigating away doesn't leave stale breadcrumbs.
|
|
58
|
+
*/
|
|
59
|
+
function useScreenHeaderBreadcrumbs(breadcrumbs) {
|
|
60
|
+
const setBreadcrumbs = useContext(ScreenHeaderBreadcrumbsWriteContext);
|
|
61
|
+
const setBreadcrumbsRef = useRef(setBreadcrumbs);
|
|
62
|
+
setBreadcrumbsRef.current = setBreadcrumbs;
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (!setBreadcrumbs) return;
|
|
65
|
+
setBreadcrumbs(breadcrumbs);
|
|
66
|
+
}, [breadcrumbs, setBreadcrumbs]);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
return () => setBreadcrumbsRef.current?.(null);
|
|
69
|
+
}, []);
|
|
70
|
+
return setBreadcrumbs !== null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Reads the current screen header actions and breadcrumbs. Used internally by ScreenHeader.
|
|
74
|
+
*/
|
|
75
|
+
function useScreenHeaderContext() {
|
|
76
|
+
const actions = useContext(ScreenHeaderReadContext);
|
|
77
|
+
const breadcrumbs = useContext(ScreenHeaderBreadcrumbsReadContext);
|
|
78
|
+
return {
|
|
79
|
+
actions: actions ?? null,
|
|
80
|
+
breadcrumbs: breadcrumbs ?? null
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
export { ScreenHeaderProvider, useScreenHeaderActions, useScreenHeaderBreadcrumbs, useScreenHeaderContext };
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=ScreenHeaderContext.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenHeaderContext.mjs","names":[],"sources":["../../src/shell/ScreenHeaderContext.tsx"],"sourcesContent":["\"use client\";\n\nimport type React from \"react\";\nimport {\n createContext,\n useContext,\n useState,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\";\n\ntype SetActions = (actions: ReactNode) => void;\ntype SetBreadcrumbs = (breadcrumbs: ReactNode) => void;\n\n/**\n * Split into separate read/write contexts so that components calling\n * useScreenHeaderActions (writers) don't re-render when the actions\n * state changes — only the ScreenHeader (reader) re-renders.\n */\nconst ScreenHeaderWriteContext = createContext<SetActions | null>(null);\nconst ScreenHeaderReadContext = createContext<ReactNode>(null);\n\nconst ScreenHeaderBreadcrumbsWriteContext =\n createContext<SetBreadcrumbs | null>(null);\nconst ScreenHeaderBreadcrumbsReadContext = createContext<ReactNode>(null);\n\nexport function ScreenHeaderProvider({\n children,\n}: {\n children: ReactNode;\n}): React.JSX.Element {\n const [actions, setActions] = useState<ReactNode>(null);\n const [breadcrumbs, setBreadcrumbs] = useState<ReactNode>(null);\n\n return (\n <ScreenHeaderWriteContext.Provider value={setActions}>\n <ScreenHeaderReadContext.Provider value={actions}>\n <ScreenHeaderBreadcrumbsWriteContext.Provider value={setBreadcrumbs}>\n <ScreenHeaderBreadcrumbsReadContext.Provider value={breadcrumbs}>\n {children}\n </ScreenHeaderBreadcrumbsReadContext.Provider>\n </ScreenHeaderBreadcrumbsWriteContext.Provider>\n </ScreenHeaderReadContext.Provider>\n </ScreenHeaderWriteContext.Provider>\n );\n}\n\n/**\n * Sets actions to display in the ScreenHeader.\n * Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),\n * `false` otherwise. Pages can use this boolean to conditionally skip\n * rendering their own PageHeader.\n *\n * Cleans up actions on unmount so navigating away doesn't leave stale actions.\n */\nexport function useScreenHeaderActions(actions: ReactNode): boolean {\n const setActions = useContext(ScreenHeaderWriteContext);\n const setActionsRef = useRef(setActions);\n setActionsRef.current = setActions;\n\n // Update actions when the value changes\n useEffect(() => {\n if (!setActions) return;\n setActions(actions);\n }, [actions, setActions]);\n\n // Clear actions only on unmount\n useEffect(() => {\n return () => setActionsRef.current?.(null);\n }, []);\n\n return setActions !== null;\n}\n\n/**\n * Sets breadcrumbs to display in the ScreenHeader (in place of the plain title).\n * Returns `true` if inside a ScreenHeaderProvider (i.e., in the portal shell),\n * `false` otherwise.\n *\n * Cleans up breadcrumbs on unmount so navigating away doesn't leave stale breadcrumbs.\n */\nexport function useScreenHeaderBreadcrumbs(breadcrumbs: ReactNode): boolean {\n const setBreadcrumbs = useContext(ScreenHeaderBreadcrumbsWriteContext);\n const setBreadcrumbsRef = useRef(setBreadcrumbs);\n setBreadcrumbsRef.current = setBreadcrumbs;\n\n // Update breadcrumbs when the value changes\n useEffect(() => {\n if (!setBreadcrumbs) return;\n setBreadcrumbs(breadcrumbs);\n }, [breadcrumbs, setBreadcrumbs]);\n\n // Clear breadcrumbs only on unmount\n useEffect(() => {\n return () => setBreadcrumbsRef.current?.(null);\n }, []);\n\n return setBreadcrumbs !== null;\n}\n\n/**\n * Reads the current screen header actions and breadcrumbs. Used internally by ScreenHeader.\n */\nexport function useScreenHeaderContext(): {\n actions: ReactNode;\n breadcrumbs: ReactNode;\n} {\n const actions = useContext(ScreenHeaderReadContext);\n const breadcrumbs = useContext(ScreenHeaderBreadcrumbsReadContext);\n return { actions: actions ?? null, breadcrumbs: breadcrumbs ?? null };\n}\n"],"mappings":";;;;;;;;;AAoBA,MAAM,2BAA2B,cAAiC,KAAK;AACvE,MAAM,0BAA0B,cAAyB,KAAK;AAE9D,MAAM,sCACJ,cAAqC,KAAK;AAC5C,MAAM,qCAAqC,cAAyB,KAAK;AAEzE,SAAgB,qBAAqB,EACnC,YAGoB;CACpB,MAAM,CAAC,SAAS,cAAc,SAAoB,KAAK;CACvD,MAAM,CAAC,aAAa,kBAAkB,SAAoB,KAAK;AAE/D,QACE,oBAAC,yBAAyB,UAA1B;EAAmC,OAAO;YACxC,oBAAC,wBAAwB,UAAzB;GAAkC,OAAO;aACvC,oBAAC,oCAAoC,UAArC;IAA8C,OAAO;cACnD,oBAAC,mCAAmC,UAApC;KAA6C,OAAO;KACjD;KAC2C,CAAA;IACD,CAAA;GACd,CAAA;EACD,CAAA;;;;;;;;;;AAYxC,SAAgB,uBAAuB,SAA6B;CAClE,MAAM,aAAa,WAAW,yBAAyB;CACvD,MAAM,gBAAgB,OAAO,WAAW;AACxC,eAAc,UAAU;AAGxB,iBAAgB;AACd,MAAI,CAAC,WAAY;AACjB,aAAW,QAAQ;IAClB,CAAC,SAAS,WAAW,CAAC;AAGzB,iBAAgB;AACd,eAAa,cAAc,UAAU,KAAK;IACzC,EAAE,CAAC;AAEN,QAAO,eAAe;;;;;;;;;AAUxB,SAAgB,2BAA2B,aAAiC;CAC1E,MAAM,iBAAiB,WAAW,oCAAoC;CACtE,MAAM,oBAAoB,OAAO,eAAe;AAChD,mBAAkB,UAAU;AAG5B,iBAAgB;AACd,MAAI,CAAC,eAAgB;AACrB,iBAAe,YAAY;IAC1B,CAAC,aAAa,eAAe,CAAC;AAGjC,iBAAgB;AACd,eAAa,kBAAkB,UAAU,KAAK;IAC7C,EAAE,CAAC;AAEN,QAAO,mBAAmB;;;;;AAM5B,SAAgB,yBAGd;CACA,MAAM,UAAU,WAAW,wBAAwB;CACnD,MAAM,cAAc,WAAW,mCAAmC;AAClE,QAAO;EAAE,SAAS,WAAW;EAAM,aAAa,eAAe;EAAM"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
require("../chunk-CKQMccvm.cjs");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
|
+
//#region src/shell/ThemeModeContext.tsx
|
|
7
|
+
const ThemeModeContext = (0, react.createContext)(null);
|
|
8
|
+
const darkMediaQuery = typeof window !== "undefined" ? window.matchMedia("(prefers-color-scheme: dark)") : null;
|
|
9
|
+
function subscribeToPrefersColorScheme(callback) {
|
|
10
|
+
darkMediaQuery?.addEventListener("change", callback);
|
|
11
|
+
return () => darkMediaQuery?.removeEventListener("change", callback);
|
|
12
|
+
}
|
|
13
|
+
function getSystemPrefersDark() {
|
|
14
|
+
return darkMediaQuery?.matches ?? false;
|
|
15
|
+
}
|
|
16
|
+
function getServerSnapshot() {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
function ThemeModeProvider({ children, mode, onModeChange, autoModeEnabled = true }) {
|
|
20
|
+
const systemMode = (0, react.useSyncExternalStore)(subscribeToPrefersColorScheme, getSystemPrefersDark, getServerSnapshot) ? "dark" : "light";
|
|
21
|
+
const displayMode = mode === "auto" ? systemMode : mode;
|
|
22
|
+
const cycleMode = (0, react.useCallback)(() => {
|
|
23
|
+
if (autoModeEnabled) {
|
|
24
|
+
const target = displayMode === "light" ? "dark" : "light";
|
|
25
|
+
onModeChange(target === systemMode ? "auto" : target);
|
|
26
|
+
} else onModeChange(mode === "light" ? "dark" : "light");
|
|
27
|
+
}, [
|
|
28
|
+
mode,
|
|
29
|
+
displayMode,
|
|
30
|
+
systemMode,
|
|
31
|
+
onModeChange,
|
|
32
|
+
autoModeEnabled
|
|
33
|
+
]);
|
|
34
|
+
const dataAttribute = getThemeModeAttribute(mode);
|
|
35
|
+
const value = (0, react.useMemo)(() => ({
|
|
36
|
+
mode,
|
|
37
|
+
displayMode,
|
|
38
|
+
setMode: onModeChange,
|
|
39
|
+
autoModeEnabled,
|
|
40
|
+
cycleMode,
|
|
41
|
+
dataAttribute
|
|
42
|
+
}), [
|
|
43
|
+
mode,
|
|
44
|
+
displayMode,
|
|
45
|
+
onModeChange,
|
|
46
|
+
autoModeEnabled,
|
|
47
|
+
cycleMode,
|
|
48
|
+
dataAttribute
|
|
49
|
+
]);
|
|
50
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThemeModeContext.Provider, {
|
|
51
|
+
value,
|
|
52
|
+
children
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** Access the current theme mode, setter, and cycle helper. Must be used within a `ThemeModeProvider`. */
|
|
56
|
+
function useThemeMode() {
|
|
57
|
+
const ctx = (0, react.useContext)(ThemeModeContext);
|
|
58
|
+
if (!ctx) throw new Error("useThemeMode must be used within a ThemeModeProvider");
|
|
59
|
+
return ctx;
|
|
60
|
+
}
|
|
61
|
+
/** Maps a ThemeMode to the value for `data-theme-mode`. Returns undefined for "auto". */
|
|
62
|
+
function getThemeModeAttribute(mode) {
|
|
63
|
+
return mode === "auto" ? void 0 : mode;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
exports.ThemeModeProvider = ThemeModeProvider;
|
|
67
|
+
exports.getThemeModeAttribute = getThemeModeAttribute;
|
|
68
|
+
exports.useThemeMode = useThemeMode;
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=ThemeModeContext.cjs.map
|