@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,49 @@
1
+ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
+ # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3
+ # https://docs.github.com/en/actions/language-and-framework-guides/publishing-nodejs-packages
4
+
5
+ # Description
6
+ name: Node.js Package
7
+
8
+ # Event to trigger the action
9
+ on:
10
+ [push]
11
+ # release:
12
+ # types: [created]
13
+
14
+ jobs:
15
+ # Publish to NPM
16
+ publish-npm:
17
+ # Condition: previous build is successful
18
+ # needs: Any previous jobs
19
+
20
+ # Operation system
21
+ runs-on: ubuntu-latest
22
+
23
+ steps:
24
+ # https://github.com/actions/checkout, This action checks-out your repository under $GITHUB_WORKSPACE
25
+ # so your workflow can access it.
26
+ - uses: actions/checkout@v4
27
+
28
+ # Set up your GitHub Actions workflow with a specific version of node.js
29
+ # Setup .npmrc file to publish to npm
30
+ - uses: actions/setup-node@v4
31
+ with:
32
+ node-version: "20.x"
33
+ registry-url: "https://registry.npmjs.org"
34
+
35
+ # Named after Continuous Integration, installs dependencies directly from package-lock.json
36
+ # ci vs install
37
+ - run: npm install
38
+
39
+ # Make sure pass the test without any exception
40
+ - run: npm test
41
+
42
+ # Build the package
43
+ - run: npm run build
44
+
45
+ # Publish to npm
46
+ # For scoped package, make it public for free service
47
+ - run: npm publish --access public
48
+ env:
49
+ NODE_AUTH_TOKEN: ${{ secrets.ETSOONpmToken }}
@@ -0,0 +1,3 @@
1
+ {
2
+ "git.ignoreLimitWarning": true
3
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2004-2024 ETSOO ® (亿速思维 ®), https://etsoo.com, https://etsoo.nz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ ## Toolpad
2
+
3
+ It's a project originally cloned from Toolpad Core (https://github.com/mui/toolpad/tree/master/packages/toolpad-core).Toolpad Core is a set of full-stack components for building dashboards, internal tools, and B2B web applications with React. Additional simplicity and new features have been implemented for ETSOO SmartERP SaaS platform development.
4
+
5
+ ## Installation
6
+
7
+ Install the package in your project directory with:
8
+
9
+ ```bash
10
+ npm install @etsoo/toolpad
11
+ ```
@@ -0,0 +1,71 @@
1
+ import * as React from "react";
2
+ import Button from "@mui/material/Button";
3
+ import Popover from "@mui/material/Popover";
4
+ import Stack from "@mui/material/Stack";
5
+ import { SignInButton } from "./SignInButton";
6
+ import { AccountPreviewProps } from "./AccountPreview";
7
+ import { useLocaleText } from "../shared/locales/LocaleContext";
8
+ export interface AccountSlots {
9
+ /**
10
+ * The component used for the account preview
11
+ * @default AccountPreview
12
+ */
13
+ preview?: React.ElementType;
14
+ /**
15
+ * The component used for the account popover menu
16
+ * @default Popover
17
+ */
18
+ popover?: React.ElementType;
19
+ /**
20
+ * The component used for the content of account popover
21
+ * @default Stack
22
+ */
23
+ popoverContent?: React.ElementType;
24
+ /**
25
+ * The component used for the sign in button.
26
+ * @default Button
27
+ */
28
+ signInButton?: React.ElementType;
29
+ /**
30
+ * The component used for the sign out button.
31
+ * @default Button
32
+ */
33
+ signOutButton?: React.ElementType;
34
+ }
35
+ export interface AccountProps {
36
+ /**
37
+ * The components used for each slot inside.
38
+ */
39
+ slots?: AccountSlots;
40
+ /**
41
+ * The props used for each slot inside.
42
+ */
43
+ slotProps?: {
44
+ preview?: AccountPreviewProps;
45
+ popover?: React.ComponentProps<typeof Popover>;
46
+ popoverContent?: React.ComponentProps<typeof Stack>;
47
+ signInButton?: React.ComponentProps<typeof SignInButton>;
48
+ signOutButton?: React.ComponentProps<typeof Button>;
49
+ };
50
+ /**
51
+ * The labels for the account component.
52
+ */
53
+ localeText?: Partial<ReturnType<typeof useLocaleText>>;
54
+ }
55
+ /**
56
+ *
57
+ * Demos:
58
+ *
59
+ * - [Account](https://mui.com/toolpad/core/react-account/)
60
+ * - [Dashboard Layout](https://mui.com/toolpad/core/react-dashboard-layout/)
61
+ * - [Sign-in Page](https://mui.com/toolpad/core/react-sign-in-page/)
62
+ *
63
+ * API:
64
+ *
65
+ * - [Account API](https://mui.com/toolpad/core/api/account)
66
+ */
67
+ declare function Account(props: AccountProps): import("react/jsx-runtime").JSX.Element | null;
68
+ declare namespace Account {
69
+ var propTypes: any;
70
+ }
71
+ export { Account };
@@ -0,0 +1,117 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import PropTypes from "prop-types";
4
+ import Popover from "@mui/material/Popover";
5
+ import Divider from "@mui/material/Divider";
6
+ import Stack from "@mui/material/Stack";
7
+ import { SignInButton } from "./SignInButton";
8
+ import { SignOutButton } from "./SignOutButton";
9
+ import { AccountPreview } from "./AccountPreview";
10
+ import { AccountPopoverHeader } from "./AccountPopoverHeader";
11
+ import { AccountPopoverFooter } from "./AccountPopoverFooter";
12
+ import { SessionContext, AuthenticationContext } from "../AppProvider/AppProvider";
13
+ import { LocaleProvider } from "../shared/locales/LocaleContext";
14
+ /**
15
+ *
16
+ * Demos:
17
+ *
18
+ * - [Account](https://mui.com/toolpad/core/react-account/)
19
+ * - [Dashboard Layout](https://mui.com/toolpad/core/react-dashboard-layout/)
20
+ * - [Sign-in Page](https://mui.com/toolpad/core/react-sign-in-page/)
21
+ *
22
+ * API:
23
+ *
24
+ * - [Account API](https://mui.com/toolpad/core/api/account)
25
+ */
26
+ function Account(props) {
27
+ const { localeText } = props;
28
+ const { slots, slotProps } = props;
29
+ const [anchorEl, setAnchorEl] = React.useState(null);
30
+ const session = React.useContext(SessionContext);
31
+ const authentication = React.useContext(AuthenticationContext);
32
+ const open = Boolean(anchorEl);
33
+ const handleClick = (event) => {
34
+ setAnchorEl(event.currentTarget);
35
+ };
36
+ const handleClose = () => {
37
+ setAnchorEl(null);
38
+ };
39
+ if (!authentication) {
40
+ return null;
41
+ }
42
+ if (!session?.user) {
43
+ return (_jsx(LocaleProvider, { localeText: localeText, children: slots?.signInButton ? (_jsx(slots.signInButton, { onClick: authentication.signIn })) : (_jsx(SignInButton, { ...slotProps?.signInButton })) }));
44
+ }
45
+ return (_jsxs(LocaleProvider, { localeText: localeText, children: [slots?.preview ? (_jsx(slots.preview, { handleClick: handleClick, open: open })) : (_jsx(AccountPreview, { variant: "condensed", handleClick: handleClick, open: open, ...slotProps?.preview })), slots?.popover ? (_jsx(slots.popover, { ...slotProps?.popover })) : (_jsx(Popover, { anchorEl: anchorEl, id: "account-menu", open: open, onClose: handleClose, onClick: handleClose, transformOrigin: { horizontal: "right", vertical: "top" }, anchorOrigin: { horizontal: "right", vertical: "bottom" }, ...slotProps?.popover, slotProps: {
46
+ paper: {
47
+ elevation: 0,
48
+ sx: {
49
+ overflow: "visible",
50
+ filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))",
51
+ mt: 1,
52
+ "&::before": {
53
+ content: '""',
54
+ display: "block",
55
+ position: "absolute",
56
+ top: 0,
57
+ right: 14,
58
+ width: 10,
59
+ height: 10,
60
+ bgcolor: "background.paper",
61
+ transform: "translateY(-50%) rotate(45deg)",
62
+ zIndex: 0
63
+ }
64
+ }
65
+ },
66
+ ...slotProps?.popover?.slotProps
67
+ }, children: slots?.popoverContent ? (_jsx(slots.popoverContent, { ...slotProps?.popoverContent })) : (_jsxs(Stack, { direction: "column", ...slotProps?.popoverContent, children: [_jsx(AccountPopoverHeader, { children: _jsx(AccountPreview, { variant: "expanded" }) }), _jsx(Divider, {}), _jsx(AccountPopoverFooter, { children: _jsx(SignOutButton, { ...slotProps?.signOutButton }) })] })) }))] }));
68
+ }
69
+ Account.propTypes /* remove-proptypes */ = {
70
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
71
+ // │ These PropTypes are generated from the TypeScript type definitions. │
72
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
73
+ // └─────────────────────────────────────────────────────────────────────┘
74
+ /**
75
+ * The labels for the account component.
76
+ */
77
+ localeText: PropTypes.shape({
78
+ iconButtonAriaLabel: PropTypes.string,
79
+ signInLabel: PropTypes.string,
80
+ signOutLabel: PropTypes.string
81
+ }),
82
+ /**
83
+ * The props used for each slot inside.
84
+ */
85
+ slotProps: PropTypes.shape({
86
+ popover: PropTypes.object,
87
+ popoverContent: PropTypes.object,
88
+ preview: PropTypes.shape({
89
+ handleClick: PropTypes.func,
90
+ open: PropTypes.bool,
91
+ slotProps: PropTypes.shape({
92
+ avatar: PropTypes.object,
93
+ avatarIconButton: PropTypes.object,
94
+ moreIconButton: PropTypes.object
95
+ }),
96
+ slots: PropTypes.shape({
97
+ avatar: PropTypes.elementType,
98
+ avatarIconButton: PropTypes.elementType,
99
+ moreIconButton: PropTypes.elementType
100
+ }),
101
+ variant: PropTypes.oneOf(["condensed", "expanded"])
102
+ }),
103
+ signInButton: PropTypes.object,
104
+ signOutButton: PropTypes.object
105
+ }),
106
+ /**
107
+ * The components used for each slot inside.
108
+ */
109
+ slots: PropTypes.shape({
110
+ popover: PropTypes.elementType,
111
+ popoverContent: PropTypes.elementType,
112
+ preview: PropTypes.elementType,
113
+ signInButton: PropTypes.elementType,
114
+ signOutButton: PropTypes.elementType
115
+ })
116
+ };
117
+ export { Account };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, test, expect, vi } from "vitest";
3
+ import { render, screen } from "@testing-library/react";
4
+ import userEvent from "@testing-library/user-event";
5
+ import { Account } from "./Account";
6
+ import describeConformance from "../utils/describeConformance";
7
+ import { AppProvider } from "../AppProvider/AppProviderComponent";
8
+ describe("AppProvider", () => {
9
+ describeConformance(_jsx(Account, {}), () => ({
10
+ skip: ["themeDefaultProps"]
11
+ }));
12
+ test("renders nothing in button when no authentication", async () => {
13
+ render(_jsx(Account, {}));
14
+ expect(screen.queryByRole("button")).not.toBeInTheDocument();
15
+ });
16
+ test("renders log in button when no session", async () => {
17
+ const auth = { signIn: vi.fn(), signOut: vi.fn() };
18
+ render(_jsx(AppProvider, { authentication: auth, children: _jsx(Account, {}) }));
19
+ const loginButton = screen.getByRole("button", { name: "Sign In" });
20
+ await userEvent.click(loginButton);
21
+ expect(auth.signIn).toHaveBeenCalled();
22
+ });
23
+ test("renders content correctly when there is a session", async () => {
24
+ const auth = { signIn: vi.fn(), signOut: vi.fn() };
25
+ const session = { user: { name: "John Doe", email: "john@example.com" } };
26
+ render(_jsx(AppProvider, { authentication: auth, session: session, children: _jsx(Account, {}) }));
27
+ const userButton = screen.getByRole("button", { name: "Current User" });
28
+ await userEvent.click(userButton);
29
+ expect(screen.getByText("John Doe")).toBeInTheDocument();
30
+ expect(screen.getByText("john@example.com")).toBeInTheDocument();
31
+ const signOutButton = screen.getByRole("button", { name: "Sign Out" });
32
+ await userEvent.click(signOutButton);
33
+ expect(auth.signOut).toHaveBeenCalled();
34
+ });
35
+ });
@@ -0,0 +1,6 @@
1
+ import * as React from "react";
2
+ import { BoxProps } from "@mui/material/Box";
3
+ export interface AccountPopoverFooterProps extends BoxProps {
4
+ children?: React.ReactNode;
5
+ }
6
+ export declare function AccountPopoverFooter(props: AccountPopoverFooterProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Box from "@mui/material/Box";
3
+ export /**
4
+ *
5
+ * Demos:
6
+ *
7
+ * - [Account](https://mui.com/toolpad/core/react-account/)
8
+ *
9
+ * API:
10
+ *
11
+ * - [AccountPopoverFooter API](https://mui.com/toolpad/core/api/account-popover-footer)
12
+ */ function AccountPopoverFooter(props) {
13
+ const { children, ...rest } = props;
14
+ return (_jsx(Box, { ...rest, sx: {
15
+ display: "flex",
16
+ flexDirection: "row",
17
+ p: 1,
18
+ justifyContent: "flex-end",
19
+ ...rest.sx
20
+ }, children: children }));
21
+ }
@@ -0,0 +1,6 @@
1
+ import * as React from "react";
2
+ import { StackProps } from "@mui/material/Stack";
3
+ export interface AccountPopoverHeaderProps extends StackProps {
4
+ children?: React.ReactNode;
5
+ }
6
+ export declare function AccountPopoverHeader(props: AccountPopoverHeaderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Stack from "@mui/material/Stack";
3
+ export /**
4
+ *
5
+ * Demos:
6
+ *
7
+ * - [Account](https://mui.com/toolpad/core/react-account/)
8
+ *
9
+ * API:
10
+ *
11
+ * - [AccountPopoverHeader API](https://mui.com/toolpad/core/api/account-popover-header)
12
+ */ function AccountPopoverHeader(props) {
13
+ const { children, ...rest } = props;
14
+ return _jsx(Stack, { ...rest, children: children });
15
+ }
@@ -0,0 +1,67 @@
1
+ import * as React from "react";
2
+ import { AvatarProps } from "@mui/material/Avatar";
3
+ import { IconButtonProps } from "@mui/material/IconButton";
4
+ export type AccountPreviewVariant = "condensed" | "expanded";
5
+ export interface AccountPreviewSlots {
6
+ /**
7
+ * The component used for the Avatar
8
+ * @default Avatar
9
+ */
10
+ avatar?: React.ElementType;
11
+ /**
12
+ * The component used for the overflow icon button in the expanded variant
13
+ * @default IconButton
14
+ */
15
+ moreIconButton?: React.ElementType;
16
+ /**
17
+ * The component used for the avatar icon button in the condensed variant
18
+ * @default IconButton
19
+ */
20
+ avatarIconButton?: React.ElementType;
21
+ }
22
+ export interface AccountPreviewProps {
23
+ /**
24
+ * The components used for each slot inside.
25
+ */
26
+ slots?: AccountPreviewSlots;
27
+ /**
28
+ * The props used for each slot inside.
29
+ */
30
+ slotProps?: {
31
+ avatar?: AvatarProps;
32
+ moreIconButton?: IconButtonProps;
33
+ avatarIconButton?: IconButtonProps;
34
+ };
35
+ /**
36
+ * The type of account details to display.
37
+ * @property {'condensed'} condensed - Shows only the user's avatar.
38
+ * @property {'expanded'} expanded - Displays the user's avatar, name, and email if available.
39
+ * @default 'condensed'
40
+ */
41
+ variant?: AccountPreviewVariant;
42
+ /**
43
+ * The handler used when the preview is expanded
44
+ */
45
+ handleClick?: React.MouseEventHandler<HTMLElement>;
46
+ /**
47
+ * The state of the Account popover
48
+ * @default false
49
+ */
50
+ open?: boolean;
51
+ }
52
+ /**
53
+ * The AccountPreview component displays user account information.
54
+ *
55
+ * Demos:
56
+ *
57
+ * - [Account](https://mui.com/toolpad/core/react-account/)
58
+ *
59
+ * API:
60
+ *
61
+ * - [AccountPreview API](https://mui.com/toolpad/core/api/account-preview)
62
+ */
63
+ declare function AccountPreview(props: AccountPreviewProps): import("react/jsx-runtime").JSX.Element | null;
64
+ declare namespace AccountPreview {
65
+ var propTypes: any;
66
+ }
67
+ export { AccountPreview };
@@ -0,0 +1,76 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import PropTypes from "prop-types";
4
+ import Avatar from "@mui/material/Avatar";
5
+ import Typography from "@mui/material/Typography";
6
+ import Tooltip from "@mui/material/Tooltip";
7
+ import Stack from "@mui/material/Stack";
8
+ import IconButton from "@mui/material/IconButton";
9
+ import MoreVertIcon from "@mui/icons-material/MoreVert";
10
+ import { SessionContext } from "../AppProvider";
11
+ import { useLocaleText } from "../shared/locales/LocaleContext";
12
+ /**
13
+ * The AccountPreview component displays user account information.
14
+ *
15
+ * Demos:
16
+ *
17
+ * - [Account](https://mui.com/toolpad/core/react-account/)
18
+ *
19
+ * API:
20
+ *
21
+ * - [AccountPreview API](https://mui.com/toolpad/core/api/account-preview)
22
+ */
23
+ function AccountPreview(props) {
24
+ const { slots, variant = "condensed", slotProps, open, handleClick } = props;
25
+ const session = React.useContext(SessionContext);
26
+ const localeText = useLocaleText();
27
+ if (!session || !session.user) {
28
+ return null;
29
+ }
30
+ const avatarContent = slots?.avatar ? (_jsx(slots.avatar, {})) : (_jsx(Avatar, { src: session.user?.image || "", alt: session.user?.name || session.user?.email || "", sx: {
31
+ height: variant === "expanded" ? 48 : 32,
32
+ width: variant === "expanded" ? 48 : 32
33
+ }, ...slotProps?.avatar }));
34
+ if (variant === "expanded") {
35
+ return (_jsxs(Stack, { direction: "row", justifyContent: "flex-start", spacing: 2, padding: 2, children: [avatarContent, _jsxs(Stack, { direction: "column", justifyContent: "space-evenly", children: [_jsx(Typography, { variant: "body2", fontWeight: "bolder", noWrap: true, children: session.user?.name }), _jsx(Typography, { variant: "caption", noWrap: true, children: session.user?.email })] }), handleClick &&
36
+ (slots?.moreIconButton ? (_jsx(slots.moreIconButton, {})) : (_jsx(IconButton, { size: "small", onClick: handleClick, ...slotProps?.moreIconButton, sx: { alignSelf: "flex-start", ...slotProps?.moreIconButton?.sx }, children: _jsx(MoreVertIcon, { fontSize: "small" }) })))] }));
37
+ }
38
+ return (_jsx(Tooltip, { title: session.user.name ?? "Account", children: slots?.avatarIconButton ? (_jsx(slots.avatarIconButton, {})) : (_jsx(IconButton, { onClick: handleClick, "aria-label": localeText.iconButtonAriaLabel || "Current User", size: "small", "aria-controls": open ? "account-menu" : undefined, "aria-haspopup": "true", "aria-expanded": open ? "true" : undefined, ...slotProps?.avatarIconButton, children: avatarContent })) }));
39
+ }
40
+ AccountPreview.propTypes /* remove-proptypes */ = {
41
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
42
+ // │ These PropTypes are generated from the TypeScript type definitions. │
43
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
44
+ // └─────────────────────────────────────────────────────────────────────┘
45
+ /**
46
+ * The handler used when the preview is expanded
47
+ */
48
+ handleClick: PropTypes.func,
49
+ /**
50
+ * The state of the Account popover
51
+ * @default false
52
+ */
53
+ open: PropTypes.bool,
54
+ /**
55
+ * The props used for each slot inside.
56
+ */
57
+ slotProps: PropTypes.shape({
58
+ avatar: PropTypes.object,
59
+ avatarIconButton: PropTypes.object,
60
+ moreIconButton: PropTypes.object
61
+ }),
62
+ /**
63
+ * The components used for each slot inside.
64
+ */
65
+ slots: PropTypes.shape({
66
+ avatar: PropTypes.elementType
67
+ }),
68
+ /**
69
+ * The type of account details to display.
70
+ * @property {'condensed'} condensed - Shows only the user's avatar.
71
+ * @property {'expanded'} expanded - Displays the user's avatar, name, and email if available.
72
+ * @default 'condensed'
73
+ */
74
+ variant: PropTypes.oneOf(["condensed", "expanded"])
75
+ };
76
+ export { AccountPreview };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, test, expect, vi } from "vitest";
3
+ import { render, screen } from "@testing-library/react";
4
+ import userEvent from "@testing-library/user-event";
5
+ import { AccountPreview } from "./AccountPreview";
6
+ import { AppProvider } from "../AppProvider/AppProviderComponent";
7
+ describe("AccountPreview", () => {
8
+ const auth = { signIn: vi.fn(), signOut: vi.fn() };
9
+ const session = {
10
+ user: {
11
+ name: "John Doe",
12
+ email: "john@example.com",
13
+ image: "https://example.com/avatar.jpg"
14
+ }
15
+ };
16
+ test("renders nothing when no session is provided", () => {
17
+ render(_jsx(AppProvider, { authentication: auth, children: _jsx(AccountPreview, {}) }));
18
+ expect(screen.queryByRole("button")).not.toBeInTheDocument();
19
+ });
20
+ test("displays condensed variant by default", () => {
21
+ render(_jsx(AppProvider, { authentication: auth, session: session, children: _jsx(AccountPreview, {}) }));
22
+ const avatar = screen.getByRole("img", { name: "John Doe" });
23
+ expect(avatar).toBeInTheDocument();
24
+ expect(screen.queryByText("John Doe")).not.toBeInTheDocument();
25
+ expect(avatar).toHaveAttribute("src", "https://example.com/avatar.jpg");
26
+ });
27
+ test("displays user name, email, and avatar in expanded variant", () => {
28
+ render(_jsx(AppProvider, { authentication: auth, session: session, children: _jsx(AccountPreview, { variant: "expanded" }) }));
29
+ expect(screen.getByText("John Doe")).toBeInTheDocument();
30
+ expect(screen.getByText("john@example.com")).toBeInTheDocument();
31
+ expect(screen.getByRole("img", { name: "John Doe" })).toBeInTheDocument();
32
+ });
33
+ test("calls handleClick when more icon button is clicked in expanded variant", async () => {
34
+ const handleClick = vi.fn();
35
+ render(_jsx(AppProvider, { authentication: auth, session: session, children: _jsx(AccountPreview, { variant: "expanded", handleClick: handleClick }) }));
36
+ const moreButton = screen.getByRole("button");
37
+ await userEvent.click(moreButton);
38
+ expect(handleClick).toHaveBeenCalled();
39
+ });
40
+ test("calls handleClick when avatar is clicked in condensed variant", async () => {
41
+ const handleClick = vi.fn();
42
+ render(_jsx(AppProvider, { authentication: auth, session: session, children: _jsx(AccountPreview, { handleClick: handleClick }) }));
43
+ const avatarButton = screen.getByRole("button", { name: "Current User" });
44
+ await userEvent.click(avatarButton);
45
+ expect(handleClick).toHaveBeenCalled();
46
+ });
47
+ });
@@ -0,0 +1,2 @@
1
+ import { ButtonProps } from "@mui/material/Button";
2
+ export declare function SignInButton(props: ButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import Button from "@mui/material/Button";
4
+ import { AuthenticationContext } from "../AppProvider/AppProvider";
5
+ import { useLocaleText } from "../shared/locales/LocaleContext";
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) {
16
+ const authentication = React.useContext(AuthenticationContext);
17
+ const localeText = useLocaleText();
18
+ return (_jsx(Button, { disableElevation: true, variant: "contained", size: "small", onClick: authentication?.signIn, sx: {
19
+ textTransform: "capitalize",
20
+ filter: "opacity(0.9)",
21
+ transition: "filter 0.2s ease-in",
22
+ "&:hover": {
23
+ filter: "opacity(1)"
24
+ }
25
+ }, ...props, children: localeText?.signInLabel || "Sign In" }));
26
+ }
@@ -0,0 +1,3 @@
1
+ import { ButtonProps } from "@mui/material/Button";
2
+ export type SignOutButtonProps = ButtonProps;
3
+ export declare function SignOutButton(props: SignOutButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import Button from "@mui/material/Button";
4
+ import LogoutIcon from "@mui/icons-material/Logout";
5
+ import { AuthenticationContext } from "../AppProvider/AppProvider";
6
+ import { useLocaleText } from "../shared/locales/LocaleContext";
7
+ export /**
8
+ *
9
+ * Demos:
10
+ *
11
+ * - [Account](https://mui.com/toolpad/core/react-account/)
12
+ *
13
+ * API:
14
+ *
15
+ * - [SignOutButton API](https://mui.com/toolpad/core/api/sign-out-button)
16
+ */ function SignOutButton(props) {
17
+ const authentication = React.useContext(AuthenticationContext);
18
+ const localeText = useLocaleText();
19
+ return (_jsx(Button, { disabled: !authentication, variant: "outlined", size: "small", disableElevation: true, onClick: authentication?.signOut, sx: {
20
+ textTransform: "capitalize",
21
+ fontWeight: "normal",
22
+ filter: "opacity(0.9)",
23
+ transition: "filter 0.2s ease-in",
24
+ "&:hover": {
25
+ filter: "opacity(1)"
26
+ }
27
+ }, startIcon: _jsx(LogoutIcon, {}), ...props, children: localeText.signOutLabel }));
28
+ }
@@ -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,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";