@etsoo/toolpad 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/.github/workflows/main.yml +49 -0
  2. package/.vscode/settings.json +3 -0
  3. package/LICENSE +21 -0
  4. package/README.md +11 -0
  5. package/build/src/Account/Account.d.ts +71 -0
  6. package/build/src/Account/Account.js +117 -0
  7. package/build/src/Account/Account.test.d.ts +1 -0
  8. package/build/src/Account/Account.test.js +35 -0
  9. package/build/src/Account/AccountPopoverFooter.d.ts +6 -0
  10. package/build/src/Account/AccountPopoverFooter.js +21 -0
  11. package/build/src/Account/AccountPopoverHeader.d.ts +6 -0
  12. package/build/src/Account/AccountPopoverHeader.js +15 -0
  13. package/build/src/Account/AccountPreview.d.ts +67 -0
  14. package/build/src/Account/AccountPreview.js +76 -0
  15. package/build/src/Account/AccountPreview.test.d.ts +1 -0
  16. package/build/src/Account/AccountPreview.test.js +47 -0
  17. package/build/src/Account/SignInButton.d.ts +2 -0
  18. package/build/src/Account/SignInButton.js +26 -0
  19. package/build/src/Account/SignOutButton.d.ts +3 -0
  20. package/build/src/Account/SignOutButton.js +28 -0
  21. package/build/src/Account/index.d.ts +6 -0
  22. package/build/src/Account/index.js +6 -0
  23. package/build/src/AppProvider/AppProvider.d.ts +98 -0
  24. package/build/src/AppProvider/AppProvider.js +4 -0
  25. package/build/src/AppProvider/AppProvider.test.d.ts +4 -0
  26. package/build/src/AppProvider/AppProvider.test.js +16 -0
  27. package/build/src/AppProvider/AppProviderComponent.d.ts +17 -0
  28. package/build/src/AppProvider/AppProviderComponent.js +120 -0
  29. package/build/src/AppProvider/AppThemeProvider.d.ts +12 -0
  30. package/build/src/AppProvider/AppThemeProvider.js +73 -0
  31. package/build/src/AppProvider/index.d.ts +1 -0
  32. package/build/src/AppProvider/index.js +1 -0
  33. package/build/src/DashboardLayout/DashboardLayout.d.ts +83 -0
  34. package/build/src/DashboardLayout/DashboardLayout.js +286 -0
  35. package/build/src/DashboardLayout/DashboardLayout.test.d.ts +1 -0
  36. package/build/src/DashboardLayout/DashboardLayout.test.js +291 -0
  37. package/build/src/DashboardLayout/DashboardSidebarSubNavigation.d.ts +16 -0
  38. package/build/src/DashboardLayout/DashboardSidebarSubNavigation.js +149 -0
  39. package/build/src/DashboardLayout/ThemeSwitcher.d.ts +5 -0
  40. package/build/src/DashboardLayout/ThemeSwitcher.js +40 -0
  41. package/build/src/DashboardLayout/ToolbarActions.d.ts +5 -0
  42. package/build/src/DashboardLayout/ToolbarActions.js +9 -0
  43. package/build/src/DashboardLayout/index.d.ts +2 -0
  44. package/build/src/DashboardLayout/index.js +3 -0
  45. package/build/src/DashboardLayout/utils.d.ts +8 -0
  46. package/build/src/DashboardLayout/utils.js +16 -0
  47. package/build/src/PageContainer/PageContainer.d.ts +66 -0
  48. package/build/src/PageContainer/PageContainer.js +97 -0
  49. package/build/src/PageContainer/PageContainer.test.d.ts +1 -0
  50. package/build/src/PageContainer/PageContainer.test.js +127 -0
  51. package/build/src/PageContainer/PageContainerToolbar.d.ts +16 -0
  52. package/build/src/PageContainer/PageContainerToolbar.js +24 -0
  53. package/build/src/PageContainer/PageContainerToolbar.test.d.ts +1 -0
  54. package/build/src/PageContainer/PageContainerToolbar.test.js +10 -0
  55. package/build/src/PageContainer/index.d.ts +2 -0
  56. package/build/src/PageContainer/index.js +2 -0
  57. package/build/src/index.d.ts +8 -0
  58. package/build/src/index.js +8 -0
  59. package/build/src/nextjs/AppProvider.d.ts +6 -0
  60. package/build/src/nextjs/AppProvider.js +16 -0
  61. package/build/src/nextjs/AppProvider.test.d.ts +1 -0
  62. package/build/src/nextjs/AppProvider.test.js +36 -0
  63. package/build/src/nextjs/AppProviderNextApp.d.ts +5 -0
  64. package/build/src/nextjs/AppProviderNextApp.js +27 -0
  65. package/build/src/nextjs/AppProviderNextPages.d.ts +5 -0
  66. package/build/src/nextjs/AppProviderNextPages.js +37 -0
  67. package/build/src/nextjs/index.d.ts +1 -0
  68. package/build/src/nextjs/index.js +1 -0
  69. package/build/src/persistence/codec.d.ts +47 -0
  70. package/build/src/persistence/codec.js +57 -0
  71. package/build/src/persistence/index.d.ts +1 -0
  72. package/build/src/persistence/index.js +1 -0
  73. package/build/src/persistence/useStorageState.d.ts +50 -0
  74. package/build/src/persistence/useStorageState.js +116 -0
  75. package/build/src/persistence/useStorageState.test.d.ts +1 -0
  76. package/build/src/persistence/useStorageState.test.js +61 -0
  77. package/build/src/react-router-dom/AppProvider.d.ts +6 -0
  78. package/build/src/react-router-dom/AppProvider.js +29 -0
  79. package/build/src/react-router-dom/AppProvider.test.d.ts +1 -0
  80. package/build/src/react-router-dom/AppProvider.test.js +12 -0
  81. package/build/src/react-router-dom/index.d.ts +1 -0
  82. package/build/src/react-router-dom/index.js +1 -0
  83. package/build/src/shared/Link.d.ts +8 -0
  84. package/build/src/shared/Link.js +19 -0
  85. package/build/src/shared/branding.d.ts +1 -0
  86. package/build/src/shared/branding.js +6 -0
  87. package/build/src/shared/components.d.ts +5 -0
  88. package/build/src/shared/components.js +23 -0
  89. package/build/src/shared/context.d.ts +12 -0
  90. package/build/src/shared/context.js +10 -0
  91. package/build/src/shared/locales/LocaleContext.d.ts +19 -0
  92. package/build/src/shared/locales/LocaleContext.js +18 -0
  93. package/build/src/shared/locales/en.d.ts +6 -0
  94. package/build/src/shared/locales/en.js +8 -0
  95. package/build/src/shared/navigation.d.ts +16 -0
  96. package/build/src/shared/navigation.js +129 -0
  97. package/build/src/useActivePage/index.d.ts +1 -0
  98. package/build/src/useActivePage/index.js +1 -0
  99. package/build/src/useActivePage/useActivePage.d.ts +11 -0
  100. package/build/src/useActivePage/useActivePage.js +48 -0
  101. package/build/src/useLocalStorageState/index.d.ts +1 -0
  102. package/build/src/useLocalStorageState/index.js +1 -0
  103. package/build/src/useLocalStorageState/useLocalStorageState.d.ts +2 -0
  104. package/build/src/useLocalStorageState/useLocalStorageState.js +14 -0
  105. package/build/src/useSessionStorageState/index.d.ts +1 -0
  106. package/build/src/useSessionStorageState/index.js +1 -0
  107. package/build/src/useSessionStorageState/useSessionStorageState.d.ts +2 -0
  108. package/build/src/useSessionStorageState/useSessionStorageState.js +14 -0
  109. package/build/src/utils/collections.d.ts +44 -0
  110. package/build/src/utils/collections.js +43 -0
  111. package/build/src/utils/describeConformance.d.ts +7 -0
  112. package/build/src/utils/describeConformance.js +3 -0
  113. package/build/src/utils/events.d.ts +27 -0
  114. package/build/src/utils/events.js +54 -0
  115. package/build/src/utils/hooks/index.d.ts +2 -0
  116. package/build/src/utils/hooks/index.js +2 -0
  117. package/build/src/utils/hooks/useBoolean.d.ts +11 -0
  118. package/build/src/utils/hooks/useBoolean.js +11 -0
  119. package/build/src/utils/hooks/useDebounced.d.ts +8 -0
  120. package/build/src/utils/hooks/useDebounced.js +28 -0
  121. package/build/src/utils/hooks/useDebouncedHandler.d.ts +12 -0
  122. package/build/src/utils/hooks/useDebouncedHandler.js +41 -0
  123. package/build/src/utils/hooks/useLatest.d.ts +6 -0
  124. package/build/src/utils/hooks/useLatest.js +9 -0
  125. package/build/src/utils/hooks/usePageTitle.d.ts +4 -0
  126. package/build/src/utils/hooks/usePageTitle.js +13 -0
  127. package/build/src/utils/hooks/useSsr.d.ts +4 -0
  128. package/build/src/utils/hooks/useSsr.js +16 -0
  129. package/build/src/utils/hooks/useStorageState.d.ts +10 -0
  130. package/build/src/utils/hooks/useStorageState.js +51 -0
  131. package/build/src/utils/warnOnce.d.ts +5 -0
  132. package/build/src/utils/warnOnce.js +11 -0
  133. package/build/vitest.setup.d.ts +1 -0
  134. package/build/vitest.setup.js +19 -0
  135. package/package.json +60 -0
  136. package/src/Account/Account.test.tsx +56 -0
  137. package/src/Account/Account.tsx +226 -0
  138. package/src/Account/AccountPopoverFooter.tsx +33 -0
  139. package/src/Account/AccountPopoverHeader.tsx +20 -0
  140. package/src/Account/AccountPreview.test.tsx +79 -0
  141. package/src/Account/AccountPreview.tsx +189 -0
  142. package/src/Account/SignInButton.tsx +38 -0
  143. package/src/Account/SignOutButton.tsx +44 -0
  144. package/src/Account/index.ts +6 -0
  145. package/src/AppProvider/AppProvider.test.tsx +25 -0
  146. package/src/AppProvider/AppProvider.tsx +116 -0
  147. package/src/AppProvider/AppProviderComponent.tsx +162 -0
  148. package/src/AppProvider/AppThemeProvider.tsx +177 -0
  149. package/src/AppProvider/index.ts +1 -0
  150. package/src/DashboardLayout/DashboardLayout.test.tsx +429 -0
  151. package/src/DashboardLayout/DashboardLayout.tsx +558 -0
  152. package/src/DashboardLayout/DashboardSidebarSubNavigation.tsx +301 -0
  153. package/src/DashboardLayout/ThemeSwitcher.tsx +81 -0
  154. package/src/DashboardLayout/ToolbarActions.tsx +11 -0
  155. package/src/DashboardLayout/index.ts +4 -0
  156. package/src/DashboardLayout/utils.ts +23 -0
  157. package/src/PageContainer/PageContainer.test.tsx +194 -0
  158. package/src/PageContainer/PageContainer.tsx +201 -0
  159. package/src/PageContainer/PageContainerToolbar.test.tsx +11 -0
  160. package/src/PageContainer/PageContainerToolbar.tsx +31 -0
  161. package/src/PageContainer/index.ts +2 -0
  162. package/src/index.ts +15 -0
  163. package/src/nextjs/AppProvider.test.tsx +48 -0
  164. package/src/nextjs/AppProvider.tsx +18 -0
  165. package/src/nextjs/AppProviderNextApp.tsx +37 -0
  166. package/src/nextjs/AppProviderNextPages.tsx +52 -0
  167. package/src/nextjs/index.tsx +1 -0
  168. package/src/persistence/codec.tsx +81 -0
  169. package/src/persistence/index.ts +1 -0
  170. package/src/persistence/useStorageState.test.tsx +101 -0
  171. package/src/persistence/useStorageState.tsx +244 -0
  172. package/src/react-router-dom/AppProvider.test.tsx +17 -0
  173. package/src/react-router-dom/AppProvider.tsx +40 -0
  174. package/src/react-router-dom/index.tsx +1 -0
  175. package/src/shared/Link.tsx +37 -0
  176. package/src/shared/branding.ts +7 -0
  177. package/src/shared/components.tsx +46 -0
  178. package/src/shared/context.ts +21 -0
  179. package/src/shared/locales/LocaleContext.tsx +44 -0
  180. package/src/shared/locales/en.tsx +9 -0
  181. package/src/shared/navigation.tsx +197 -0
  182. package/src/useActivePage/index.ts +1 -0
  183. package/src/useActivePage/useActivePage.ts +66 -0
  184. package/src/useLocalStorageState/index.ts +1 -0
  185. package/src/useLocalStorageState/useLocalStorageState.tsx +23 -0
  186. package/src/useSessionStorageState/index.tsx +1 -0
  187. package/src/useSessionStorageState/useSessionStorageState.tsx +23 -0
  188. package/src/utils/collections.ts +125 -0
  189. package/src/utils/describeConformance.ts +14 -0
  190. package/src/utils/events.ts +81 -0
  191. package/src/utils/hooks/index.ts +2 -0
  192. package/src/utils/hooks/useBoolean.ts +12 -0
  193. package/src/utils/hooks/useDebounced.ts +39 -0
  194. package/src/utils/hooks/useDebouncedHandler.ts +71 -0
  195. package/src/utils/hooks/useLatest.ts +16 -0
  196. package/src/utils/hooks/usePageTitle.ts +14 -0
  197. package/src/utils/hooks/useSsr.ts +24 -0
  198. package/src/utils/hooks/useStorageState.ts +130 -0
  199. package/src/utils/warnOnce.ts +12 -0
  200. package/tsconfig.json +19 -0
  201. package/vite.config.ts +27 -0
  202. package/vitest.setup.ts +22 -0
@@ -0,0 +1,189 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import Avatar, { AvatarProps } from "@mui/material/Avatar";
4
+ import Typography from "@mui/material/Typography";
5
+ import Tooltip from "@mui/material/Tooltip";
6
+ import Stack from "@mui/material/Stack";
7
+ import IconButton, { IconButtonProps } from "@mui/material/IconButton";
8
+ import MoreVertIcon from "@mui/icons-material/MoreVert";
9
+ import { SessionContext } from "../AppProvider";
10
+ import { useLocaleText } from "../shared/locales/LocaleContext";
11
+
12
+ export type AccountPreviewVariant = "condensed" | "expanded";
13
+
14
+ export interface AccountPreviewSlots {
15
+ /**
16
+ * The component used for the Avatar
17
+ * @default Avatar
18
+ */
19
+ avatar?: React.ElementType;
20
+ /**
21
+ * The component used for the overflow icon button in the expanded variant
22
+ * @default IconButton
23
+ */
24
+ moreIconButton?: React.ElementType;
25
+ /**
26
+ * The component used for the avatar icon button in the condensed variant
27
+ * @default IconButton
28
+ */
29
+ avatarIconButton?: React.ElementType;
30
+ }
31
+
32
+ export interface AccountPreviewProps {
33
+ /**
34
+ * The components used for each slot inside.
35
+ */
36
+ slots?: AccountPreviewSlots;
37
+ /**
38
+ * The props used for each slot inside.
39
+ */
40
+ slotProps?: {
41
+ avatar?: AvatarProps;
42
+ moreIconButton?: IconButtonProps;
43
+ avatarIconButton?: IconButtonProps;
44
+ };
45
+ /**
46
+ * The type of account details to display.
47
+ * @property {'condensed'} condensed - Shows only the user's avatar.
48
+ * @property {'expanded'} expanded - Displays the user's avatar, name, and email if available.
49
+ * @default 'condensed'
50
+ */
51
+ variant?: AccountPreviewVariant;
52
+ /**
53
+ * The handler used when the preview is expanded
54
+ */
55
+ handleClick?: React.MouseEventHandler<HTMLElement>;
56
+ /**
57
+ * The state of the Account popover
58
+ * @default false
59
+ */
60
+ open?: boolean;
61
+ }
62
+
63
+ /**
64
+ * The AccountPreview component displays user account information.
65
+ *
66
+ * Demos:
67
+ *
68
+ * - [Account](https://mui.com/toolpad/core/react-account/)
69
+ *
70
+ * API:
71
+ *
72
+ * - [AccountPreview API](https://mui.com/toolpad/core/api/account-preview)
73
+ */
74
+ function AccountPreview(props: AccountPreviewProps) {
75
+ const { slots, variant = "condensed", slotProps, open, handleClick } = props;
76
+ const session = React.useContext(SessionContext);
77
+ const localeText = useLocaleText();
78
+
79
+ if (!session || !session.user) {
80
+ return null;
81
+ }
82
+
83
+ const avatarContent = slots?.avatar ? (
84
+ <slots.avatar />
85
+ ) : (
86
+ <Avatar
87
+ src={session.user?.image || ""}
88
+ alt={session.user?.name || session.user?.email || ""}
89
+ sx={{
90
+ height: variant === "expanded" ? 48 : 32,
91
+ width: variant === "expanded" ? 48 : 32
92
+ }}
93
+ {...slotProps?.avatar}
94
+ />
95
+ );
96
+
97
+ if (variant === "expanded") {
98
+ return (
99
+ <Stack
100
+ direction="row"
101
+ justifyContent="flex-start"
102
+ spacing={2}
103
+ padding={2}
104
+ >
105
+ {avatarContent}
106
+ <Stack direction="column" justifyContent="space-evenly">
107
+ <Typography variant="body2" fontWeight="bolder" noWrap>
108
+ {session.user?.name}
109
+ </Typography>
110
+ <Typography variant="caption" noWrap>
111
+ {session.user?.email}
112
+ </Typography>
113
+ </Stack>
114
+ {handleClick &&
115
+ (slots?.moreIconButton ? (
116
+ <slots.moreIconButton />
117
+ ) : (
118
+ <IconButton
119
+ size="small"
120
+ onClick={handleClick}
121
+ {...slotProps?.moreIconButton}
122
+ sx={{ alignSelf: "flex-start", ...slotProps?.moreIconButton?.sx }}
123
+ >
124
+ <MoreVertIcon fontSize="small" />
125
+ </IconButton>
126
+ ))}
127
+ </Stack>
128
+ );
129
+ }
130
+
131
+ return (
132
+ <Tooltip title={session.user.name ?? "Account"}>
133
+ {slots?.avatarIconButton ? (
134
+ <slots.avatarIconButton />
135
+ ) : (
136
+ <IconButton
137
+ onClick={handleClick}
138
+ aria-label={localeText.iconButtonAriaLabel || "Current User"}
139
+ size="small"
140
+ aria-controls={open ? "account-menu" : undefined}
141
+ aria-haspopup="true"
142
+ aria-expanded={open ? "true" : undefined}
143
+ {...slotProps?.avatarIconButton}
144
+ >
145
+ {avatarContent}
146
+ </IconButton>
147
+ )}
148
+ </Tooltip>
149
+ );
150
+ }
151
+
152
+ AccountPreview.propTypes /* remove-proptypes */ = {
153
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
154
+ // │ These PropTypes are generated from the TypeScript type definitions. │
155
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
156
+ // └─────────────────────────────────────────────────────────────────────┘
157
+ /**
158
+ * The handler used when the preview is expanded
159
+ */
160
+ handleClick: PropTypes.func,
161
+ /**
162
+ * The state of the Account popover
163
+ * @default false
164
+ */
165
+ open: PropTypes.bool,
166
+ /**
167
+ * The props used for each slot inside.
168
+ */
169
+ slotProps: PropTypes.shape({
170
+ avatar: PropTypes.object,
171
+ avatarIconButton: PropTypes.object,
172
+ moreIconButton: PropTypes.object
173
+ }),
174
+ /**
175
+ * The components used for each slot inside.
176
+ */
177
+ slots: PropTypes.shape({
178
+ avatar: PropTypes.elementType
179
+ }),
180
+ /**
181
+ * The type of account details to display.
182
+ * @property {'condensed'} condensed - Shows only the user's avatar.
183
+ * @property {'expanded'} expanded - Displays the user's avatar, name, and email if available.
184
+ * @default 'condensed'
185
+ */
186
+ variant: PropTypes.oneOf(["condensed", "expanded"])
187
+ } as any;
188
+
189
+ export { AccountPreview };
@@ -0,0 +1,38 @@
1
+ import * as React from "react";
2
+ import Button, { ButtonProps } from "@mui/material/Button";
3
+ import { AuthenticationContext } from "../AppProvider/AppProvider";
4
+ import { useLocaleText } from "../shared/locales/LocaleContext";
5
+
6
+ export /**
7
+ *
8
+ * Demos:
9
+ *
10
+ * - [Account](https://mui.com/toolpad/core/react-account/)
11
+ *
12
+ * API:
13
+ *
14
+ * - [SignInButton API](https://mui.com/toolpad/core/api/sign-in-button)
15
+ */ function SignInButton(props: ButtonProps) {
16
+ const authentication = React.useContext(AuthenticationContext);
17
+ const localeText = useLocaleText();
18
+
19
+ return (
20
+ <Button
21
+ disableElevation
22
+ variant="contained"
23
+ size="small"
24
+ onClick={authentication?.signIn}
25
+ sx={{
26
+ textTransform: "capitalize",
27
+ filter: "opacity(0.9)",
28
+ transition: "filter 0.2s ease-in",
29
+ "&:hover": {
30
+ filter: "opacity(1)"
31
+ }
32
+ }}
33
+ {...props}
34
+ >
35
+ {localeText?.signInLabel || "Sign In"}
36
+ </Button>
37
+ );
38
+ }
@@ -0,0 +1,44 @@
1
+ import * as React from "react";
2
+ import Button, { ButtonProps } from "@mui/material/Button";
3
+ import LogoutIcon from "@mui/icons-material/Logout";
4
+ import { AuthenticationContext } from "../AppProvider/AppProvider";
5
+ import { useLocaleText } from "../shared/locales/LocaleContext";
6
+
7
+ export type SignOutButtonProps = ButtonProps;
8
+
9
+ export /**
10
+ *
11
+ * Demos:
12
+ *
13
+ * - [Account](https://mui.com/toolpad/core/react-account/)
14
+ *
15
+ * API:
16
+ *
17
+ * - [SignOutButton API](https://mui.com/toolpad/core/api/sign-out-button)
18
+ */ function SignOutButton(props: SignOutButtonProps) {
19
+ const authentication = React.useContext(AuthenticationContext);
20
+ const localeText = useLocaleText();
21
+
22
+ return (
23
+ <Button
24
+ disabled={!authentication}
25
+ variant="outlined"
26
+ size="small"
27
+ disableElevation
28
+ onClick={authentication?.signOut}
29
+ sx={{
30
+ textTransform: "capitalize",
31
+ fontWeight: "normal",
32
+ filter: "opacity(0.9)",
33
+ transition: "filter 0.2s ease-in",
34
+ "&:hover": {
35
+ filter: "opacity(1)"
36
+ }
37
+ }}
38
+ startIcon={<LogoutIcon />}
39
+ {...props}
40
+ >
41
+ {localeText.signOutLabel}
42
+ </Button>
43
+ );
44
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./Account";
2
+ export * from "./AccountPreview";
3
+ export * from "./AccountPopoverHeader";
4
+ export * from "./AccountPopoverFooter";
5
+ export * from "./SignOutButton";
6
+ export * from "./SignInButton";
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @vitest-environment jsdom
3
+ */
4
+
5
+ import * as React from "react";
6
+ import { describe, test, expect } from "vitest";
7
+ import { render, screen } from "@testing-library/react";
8
+ import { createTheme } from "@mui/material/styles";
9
+ import { AppProvider } from "./AppProviderComponent";
10
+
11
+ describe("AppProvider", () => {
12
+ test("renders content correctly", async () => {
13
+ render(<AppProvider>Hello world</AppProvider>);
14
+
15
+ expect(screen.getByText("Hello world")).toBeTruthy();
16
+ });
17
+
18
+ test("renders content correctly when using legacy theme", async () => {
19
+ const legacyTheme = createTheme();
20
+
21
+ render(<AppProvider theme={legacyTheme}>Hello world</AppProvider>);
22
+
23
+ expect(screen.getByText("Hello world")).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,116 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ import { Theme } from "@mui/material/styles";
4
+
5
+ export interface NavigateOptions {
6
+ history?: "auto" | "push" | "replace";
7
+ }
8
+
9
+ export interface Navigate {
10
+ (url: string | URL, options?: NavigateOptions): void;
11
+ }
12
+
13
+ /**
14
+ * Abstract router used by Toolpad components.
15
+ */
16
+ export interface Router {
17
+ pathname: string;
18
+ searchParams: URLSearchParams;
19
+ navigate: Navigate;
20
+ }
21
+
22
+ export interface Branding {
23
+ title?: string;
24
+ logo?: React.ReactNode;
25
+ }
26
+
27
+ export interface NavigationPageItem {
28
+ kind?: "page";
29
+ segment?: string;
30
+ title?: string;
31
+ icon?: React.ReactNode;
32
+ pattern?: string;
33
+ action?: React.ReactNode;
34
+ children?: Navigation;
35
+ }
36
+
37
+ export interface NavigationSubheaderItem {
38
+ kind: "header";
39
+ title: string;
40
+ }
41
+
42
+ export interface NavigationDividerItem {
43
+ kind: "divider";
44
+ }
45
+
46
+ export type NavigationItem =
47
+ | NavigationPageItem
48
+ | NavigationSubheaderItem
49
+ | NavigationDividerItem;
50
+
51
+ export type Navigation = NavigationItem[];
52
+
53
+ export interface Session {
54
+ user?: {
55
+ id?: string | null;
56
+ name?: string | null;
57
+ image?: string | null;
58
+ email?: string | null;
59
+ };
60
+ }
61
+
62
+ export interface Authentication {
63
+ signIn: () => void;
64
+ signOut: () => void;
65
+ }
66
+
67
+ export const AuthenticationContext = React.createContext<Authentication | null>(
68
+ null
69
+ );
70
+
71
+ export const SessionContext = React.createContext<Session | null>(null);
72
+
73
+ export type AppTheme = Theme | { light: Theme; dark: Theme };
74
+
75
+ export interface AppProviderProps {
76
+ /**
77
+ * The content of the app provider.
78
+ */
79
+ children: React.ReactNode;
80
+ /**
81
+ * [Theme or themes](https://mui.com/toolpad/core/react-app-provider/#theming) to be used by the app in light/dark mode. A [CSS variables theme](https://mui.com/material-ui/customization/css-theme-variables/overview/) is recommended.
82
+ * @default createTheme()
83
+ */
84
+ theme?: AppTheme;
85
+ /**
86
+ * Branding options for the app.
87
+ * @default null
88
+ */
89
+ branding?: Branding | null;
90
+ /**
91
+ * Navigation definition for the app.
92
+ * @default []
93
+ */
94
+ navigation?: Navigation;
95
+ /**
96
+ * Router implementation used inside Toolpad components.
97
+ * @default null
98
+ */
99
+ router?: Router;
100
+ /**
101
+ * Session info about the current user.
102
+ * @default null
103
+ */
104
+ session?: Session | null;
105
+ /**
106
+ * Authentication methods.
107
+ * @default null
108
+ */
109
+ authentication?: Authentication | null;
110
+ /**
111
+ * The window where the application is rendered.
112
+ * This is needed when rendering the app inside an iframe, for example.
113
+ * @default window
114
+ */
115
+ window?: Window;
116
+ }
@@ -0,0 +1,162 @@
1
+ "use client";
2
+ import PropTypes from "prop-types";
3
+ import {
4
+ BrandingContext,
5
+ NavigationContext,
6
+ RouterContext,
7
+ WindowContext
8
+ } from "../shared/context";
9
+ import { AppThemeProvider } from "./AppThemeProvider";
10
+ import { createTheme as createMuiTheme, Theme } from "@mui/material/styles";
11
+ import {
12
+ AppProviderProps,
13
+ AuthenticationContext,
14
+ SessionContext
15
+ } from "./AppProvider";
16
+
17
+ function createTheme(): Theme {
18
+ return createMuiTheme({
19
+ cssVariables: {
20
+ colorSchemeSelector: "data-toolpad-color-scheme"
21
+ },
22
+ colorSchemes: { dark: true }
23
+ });
24
+ }
25
+
26
+ /**
27
+ *
28
+ * Demos:
29
+ *
30
+ * - [App Provider](https://mui.com/toolpad/core/react-app-provider/)
31
+ * - [Dashboard Layout](https://mui.com/toolpad/core/react-dashboard-layout/)
32
+ *
33
+ * API:
34
+ *
35
+ * - [AppProvider API](https://mui.com/toolpad/core/api/app-provider)
36
+ */
37
+ function AppProvider(props: AppProviderProps) {
38
+ const {
39
+ children,
40
+ theme = createTheme(),
41
+ branding = null,
42
+ navigation = [],
43
+ router = null,
44
+ authentication = null,
45
+ session = null,
46
+ window: appWindow
47
+ } = props;
48
+
49
+ return (
50
+ <WindowContext.Provider value={appWindow}>
51
+ <AuthenticationContext.Provider value={authentication}>
52
+ <SessionContext.Provider value={session}>
53
+ <RouterContext.Provider value={router}>
54
+ <AppThemeProvider theme={theme} window={appWindow}>
55
+ <BrandingContext.Provider value={branding}>
56
+ <NavigationContext.Provider value={navigation}>
57
+ {children}
58
+ </NavigationContext.Provider>
59
+ </BrandingContext.Provider>
60
+ </AppThemeProvider>
61
+ </RouterContext.Provider>
62
+ </SessionContext.Provider>
63
+ </AuthenticationContext.Provider>
64
+ </WindowContext.Provider>
65
+ );
66
+ }
67
+
68
+ AppProvider.propTypes /* remove-proptypes */ = {
69
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
70
+ // │ These PropTypes are generated from the TypeScript type definitions. │
71
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
72
+ // └─────────────────────────────────────────────────────────────────────┘
73
+ /**
74
+ * Authentication methods.
75
+ * @default null
76
+ */
77
+ authentication: PropTypes.shape({
78
+ signIn: PropTypes.func.isRequired,
79
+ signOut: PropTypes.func.isRequired
80
+ }),
81
+ /**
82
+ * Branding options for the app.
83
+ * @default null
84
+ */
85
+ branding: PropTypes.shape({
86
+ logo: PropTypes.node,
87
+ title: PropTypes.string
88
+ }),
89
+ /**
90
+ * The content of the app provider.
91
+ */
92
+ children: PropTypes.node,
93
+ /**
94
+ * Navigation definition for the app.
95
+ * @default []
96
+ */
97
+ navigation: PropTypes.arrayOf(
98
+ PropTypes.oneOfType([
99
+ PropTypes.shape({
100
+ action: PropTypes.node,
101
+ children: PropTypes.arrayOf(
102
+ PropTypes.oneOfType([
103
+ PropTypes.object,
104
+ PropTypes.shape({
105
+ kind: PropTypes.oneOf(["header"]).isRequired,
106
+ title: PropTypes.string.isRequired
107
+ }),
108
+ PropTypes.shape({
109
+ kind: PropTypes.oneOf(["divider"]).isRequired
110
+ })
111
+ ]).isRequired
112
+ ),
113
+ icon: PropTypes.node,
114
+ kind: PropTypes.oneOf(["page"]),
115
+ pattern: PropTypes.string,
116
+ segment: PropTypes.string,
117
+ title: PropTypes.string
118
+ }),
119
+ PropTypes.shape({
120
+ kind: PropTypes.oneOf(["header"]).isRequired,
121
+ title: PropTypes.string.isRequired
122
+ }),
123
+ PropTypes.shape({
124
+ kind: PropTypes.oneOf(["divider"]).isRequired
125
+ })
126
+ ]).isRequired
127
+ ),
128
+ /**
129
+ * Router implementation used inside Toolpad components.
130
+ * @default null
131
+ */
132
+ router: PropTypes.shape({
133
+ navigate: PropTypes.func.isRequired,
134
+ pathname: PropTypes.string.isRequired,
135
+ searchParams: PropTypes.instanceOf(URLSearchParams).isRequired
136
+ }),
137
+ /**
138
+ * Session info about the current user.
139
+ * @default null
140
+ */
141
+ session: PropTypes.shape({
142
+ user: PropTypes.shape({
143
+ email: PropTypes.string,
144
+ id: PropTypes.string,
145
+ image: PropTypes.string,
146
+ name: PropTypes.string
147
+ })
148
+ }),
149
+ /**
150
+ * [Theme or themes](https://mui.com/toolpad/core/react-app-provider/#theming) to be used by the app in light/dark mode. A [CSS variables theme](https://mui.com/material-ui/customization/css-theme-variables/overview/) is recommended.
151
+ * @default createTheme()
152
+ */
153
+ theme: PropTypes.object,
154
+ /**
155
+ * The window where the application is rendered.
156
+ * This is needed when rendering the app inside an iframe, for example.
157
+ * @default window
158
+ */
159
+ window: PropTypes.object
160
+ } as any;
161
+
162
+ export { AppProvider };