(demoSession);
+ const authentication = React.useMemo(() => {
+ return {
+ signIn: () => {
+ setSession(demoSession);
+ },
+ signOut: () => {
+ setSession(null);
+ },
+ };
+ }, []);
+
+ return (
+
+
+
+
+
+ );
+}
diff --git a/docs/data/toolpad/core/components/account/AccountSlotsWallet.tsx.preview b/docs/data/toolpad/core/components/account/AccountSlotsWallet.tsx.preview
new file mode 100644
index 00000000000..7241ae7a264
--- /dev/null
+++ b/docs/data/toolpad/core/components/account/AccountSlotsWallet.tsx.preview
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/account/account.md b/docs/data/toolpad/core/components/account/account.md
index a706c176a50..90c84b27c6f 100644
--- a/docs/data/toolpad/core/components/account/account.md
+++ b/docs/data/toolpad/core/components/account/account.md
@@ -66,3 +66,11 @@ You can build advanced menus – such as a tenant switcher – by passing in a c
You can pass in custom labels – including of different languages – using the `localeText` prop.
{{"demo": "AccountCustomLocaleText.js", "bg": "outlined" }}
+
+### Session
+
+You can use the `useSession` hook to extend the existing session and add additional user details:
+
+{{"demo": "./AccountCustomUserDetails.js", "bg": "outlined", "defaultCodeOpen": false}}
+
+You can find more details on the [`useSession` docs page](/toolopad/core/react-use-session/).
diff --git a/docs/data/toolpad/core/components/use-session/use-session-api.md b/docs/data/toolpad/core/components/use-session/use-session-api.md
new file mode 100644
index 00000000000..24a5182b7b7
--- /dev/null
+++ b/docs/data/toolpad/core/components/use-session/use-session-api.md
@@ -0,0 +1,42 @@
+# useSession API
+
+API reference for the useSession hook.
+
+:::success
+For examples and details on the usage of this React hook, visit the demo pages:
+
+- [Account](/toolpad/core/react-account/)
+- [useSession](/toolpad/core/react-use-Session/)
+
+:::
+
+## Import
+
+```js
+import useSession from '@toolpad/core/useSession';
+// or
+import { useSession } from '@toolpad/core';
+```
+
+Learn about the difference by reading this [guide](https://mui.com/material-ui/guides/minimizing-bundle-size/) on minimizing bundle size.
+
+## Usage
+
+You can get access to the current value of the `SessionContext` inside Toolpad Core components by invoking the hook:
+
+```js
+const session = useSession();
+```
+
+The default `Session` interface exported by `@toolpad/core` has the following fields:
+
+```ts
+export interface Session {
+ user?: {
+ id?: string | null;
+ name?: string | null;
+ image?: string | null;
+ email?: string | null;
+ };
+}
+```
diff --git a/docs/data/toolpad/core/components/use-session/use-session.md b/docs/data/toolpad/core/components/use-session/use-session.md
new file mode 100644
index 00000000000..c477ea77682
--- /dev/null
+++ b/docs/data/toolpad/core/components/use-session/use-session.md
@@ -0,0 +1,54 @@
+---
+productId: toolpad-core
+title: useSession
+---
+
+# useSession
+
+Toolpad Core exposes an API to access the current authentication session, regardless of the underlying authentication provider used.
+
+:::info
+If this is your first time using Toolpad Core, it's recommended to read about the [basic concepts](/toolpad/core/introduction/base-concepts/) first.
+:::
+
+## Usage
+
+When using authentication features inside Toolpad Core, a `SessionContext` is created to share session information among all Toolpad Core components. This accepts a default value from the `session` prop of the `AppProvider`.
+
+```js
+{props.children}
+```
+
+The `session` can be created using any authentication provider of your choice. You can access the current value of the `SessionContext` inside Toolpad Core components by invoking the hook:
+
+```js
+const session = useSession();
+```
+
+If your session has additional data which you want to display in the account popover, you an create custom components for user information display with the session object:
+
+```ts
+interface CustomSession {
+ org: {
+ name: string;
+ url: string;
+ logo: string;
+ };
+}
+
+function CustomAccountDetails() {
+
+ const session = useSession();
+ return (
+ // Use `session.org`
+ )
+}
+```
+
+The following example demonstrates this behaviour clearly:
+
+{{"demo": "../account/AccountCustomUserDetails.js", "bg":"outlined"}}
+
+## Hook API
+
+- [`useSession()`](/toolpad/core/react-use-session/api/)
diff --git a/docs/data/toolpad/core/pages.ts b/docs/data/toolpad/core/pages.ts
index e0fb156d619..0a9e9f1d595 100644
--- a/docs/data/toolpad/core/pages.ts
+++ b/docs/data/toolpad/core/pages.ts
@@ -128,6 +128,10 @@ const pages: MuiPage[] = [
pathname: '/toolpad/core/react-use-notifications',
title: 'useNotifications',
},
+ {
+ pathname: '/toolpad/core/react-use-session',
+ title: 'useSession',
+ },
{
pathname: '/toolpad/core/react-persistent-state',
title: 'Persisted state',
@@ -161,6 +165,10 @@ const pages: MuiPage[] = [
pathname: '/toolpad/core/react-persistent-state/use-local-storage-state-api',
title: 'useLocalStorageState',
},
+ {
+ pathname: '/toolpad/core/react-use-session/api',
+ title: 'useSession',
+ },
{
pathname: '/toolpad/core/react-persistent-state/use-session-storage-state-api',
title: 'useSessionStorageState',
diff --git a/docs/pages/toolpad/core/react-use-session/api.js b/docs/pages/toolpad/core/react-use-session/api.js
new file mode 100644
index 00000000000..d583ed0de3e
--- /dev/null
+++ b/docs/pages/toolpad/core/react-use-session/api.js
@@ -0,0 +1,7 @@
+import * as React from 'react';
+import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
+import * as pageProps from 'docs-toolpad/data/toolpad/core/components/use-session/use-session-api.md?muiMarkdown';
+
+export default function Page() {
+ return ;
+}
diff --git a/docs/pages/toolpad/core/react-use-session/index.js b/docs/pages/toolpad/core/react-use-session/index.js
new file mode 100644
index 00000000000..b77a30a4fe5
--- /dev/null
+++ b/docs/pages/toolpad/core/react-use-session/index.js
@@ -0,0 +1,7 @@
+import * as React from 'react';
+import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
+import * as pageProps from 'docs-toolpad/data/toolpad/core/components/use-session/use-session.md?muiMarkdown';
+
+export default function Page() {
+ return ;
+}
diff --git a/packages/toolpad-core/src/Account/Account.tsx b/packages/toolpad-core/src/Account/Account.tsx
index b4aace2f797..0c6a105f5e1 100644
--- a/packages/toolpad-core/src/Account/Account.tsx
+++ b/packages/toolpad-core/src/Account/Account.tsx
@@ -60,6 +60,7 @@ export interface AccountProps {
*/
localeText?: Partial>;
}
+
/**
*
* Demos:
diff --git a/packages/toolpad-core/src/index.ts b/packages/toolpad-core/src/index.ts
index dcb98090703..123c479d6c3 100644
--- a/packages/toolpad-core/src/index.ts
+++ b/packages/toolpad-core/src/index.ts
@@ -16,6 +16,8 @@ export * from './useNotifications';
export * from './useLocalStorageState';
+export * from './useSession';
+
export * from './useSessionStorageState';
export * from './persistence/codec';
diff --git a/packages/toolpad-core/src/useSession/index.ts b/packages/toolpad-core/src/useSession/index.ts
new file mode 100644
index 00000000000..c47a6987dd9
--- /dev/null
+++ b/packages/toolpad-core/src/useSession/index.ts
@@ -0,0 +1 @@
+export * from './useSession';
diff --git a/packages/toolpad-core/src/useSession/useSession.test.tsx b/packages/toolpad-core/src/useSession/useSession.test.tsx
new file mode 100644
index 00000000000..d0add057a91
--- /dev/null
+++ b/packages/toolpad-core/src/useSession/useSession.test.tsx
@@ -0,0 +1,45 @@
+/**
+ * @vitest-environment jsdom
+ */
+
+import * as React from 'react';
+import { renderHook } from '@testing-library/react';
+import { describe, test, expect } from 'vitest';
+import { useSession } from './useSession';
+import { Session, SessionContext } from '../AppProvider/AppProvider';
+
+// Mock the session data
+const mockSession = {
+ user: {
+ name: 'Bharat Kashyap',
+ email: 'bharat@mui.com',
+ image: 'https://avatars.githubusercontent.com/u/19550456',
+ },
+};
+
+interface TestWrapperProps {
+ session: Session | null;
+ children: React.ReactNode;
+}
+
+function TestWrapper({ children, session }: TestWrapperProps) {
+ return {children};
+}
+
+describe('useSession hook', () => {
+ test('should return session data when authenticated', () => {
+ const { result } = renderHook(() => useSession(), {
+ wrapper: ({ children }) => {children},
+ });
+
+ expect(result.current).toEqual(mockSession);
+ });
+
+ test('should return null session when not authenticated', () => {
+ const { result } = renderHook(() => useSession(), {
+ wrapper: ({ children }) => {children},
+ });
+
+ expect(result.current).toBeNull();
+ });
+});
diff --git a/packages/toolpad-core/src/useSession/useSession.ts b/packages/toolpad-core/src/useSession/useSession.ts
new file mode 100644
index 00000000000..41742b233c6
--- /dev/null
+++ b/packages/toolpad-core/src/useSession/useSession.ts
@@ -0,0 +1,11 @@
+import * as React from 'react';
+import { SessionContext, Session } from '../AppProvider';
+
+/**
+ * Hook to access the current Toolpad Core session.
+ * @returns The current session object or null if no session is available.
+ */
+export function useSession(): T | null {
+ const session = React.useContext(SessionContext);
+ return session as T | null;
+}