diff --git a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.js
index 801f21ff7af..536b3b76da4 100644
--- a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.js
@@ -35,7 +35,7 @@ export default function BrandingSignInPage() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx
index 61fcf280ade..f3d758e7263 100644
--- a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx
@@ -35,7 +35,7 @@ export default function BrandingSignInPage() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx.preview b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx.preview
index 73da124c69b..3e0e5aa6efe 100644
--- a/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx.preview
+++ b/docs/data/toolpad/core/components/sign-in-page/BrandingSignInPage.tsx.preview
@@ -15,6 +15,6 @@ const BRANDING = {
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.js
index 379664289ff..01d5cfe3684 100644
--- a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.js
@@ -27,7 +27,7 @@ export default function CredentialsSignInPage() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx
index 7ebe5d41a12..07e0fb1b9c4 100644
--- a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx
@@ -30,7 +30,7 @@ export default function CredentialsSignInPage() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx.preview b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx.preview
index 636373e5404..16fd91f00e2 100644
--- a/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx.preview
+++ b/docs/data/toolpad/core/components/sign-in-page/CredentialsSignInPage.tsx.preview
@@ -6,6 +6,6 @@ const providers = [{ id: 'credentials', name: 'Email and Password' }];
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.js
index f9c46a79762..73800c4d07b 100644
--- a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.js
@@ -27,7 +27,7 @@ export default function MagicLinkAlertSignInPage() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx
index 1097b0bda9f..f7e674890a2 100644
--- a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx
@@ -36,7 +36,7 @@ export default function MagicLinkAlertSignInPage() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx.preview b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx.preview
index 9de4b1c4e93..0c70a80c4b8 100644
--- a/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx.preview
+++ b/docs/data/toolpad/core/components/sign-in-page/MagicLinkAlertSignInPage.tsx.preview
@@ -8,6 +8,6 @@ resolve({
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.js b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.js
index 326abcc3c64..575370713a5 100644
--- a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.js
+++ b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.js
@@ -32,7 +32,7 @@ export default function NotificationsSignInPageError() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx
index 8035b294386..373d8f60c03 100644
--- a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx
@@ -39,7 +39,7 @@ export default function NotificationsSignInPageError() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx.preview b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx.preview
index 30677d0d20c..e6e444e2beb 100644
--- a/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx.preview
+++ b/docs/data/toolpad/core/components/sign-in-page/NotificationsSignInPageError.tsx.preview
@@ -9,6 +9,6 @@ resolve({
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.js b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.js
index f15f1cceded..ec39c35ddda 100644
--- a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.js
@@ -24,7 +24,7 @@ export default function PasskeySignInPage() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx
index c69a3758ecf..352bdc93677 100644
--- a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx
@@ -24,7 +24,7 @@ export default function PasskeySignInPage() {
// preview-end
diff --git a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx.preview b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx.preview
index 5c2239d907e..6d8ac519206 100644
--- a/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx.preview
+++ b/docs/data/toolpad/core/components/sign-in-page/PasskeySignInPage.tsx.preview
@@ -6,6 +6,6 @@ const providers = [{ id: 'passkey', name: 'Passkey' }];
\ No newline at end of file
diff --git a/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.js b/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.js
index 4a4c1a833f9..ee0aacbd621 100644
--- a/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.js
+++ b/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.js
@@ -1,32 +1,47 @@
import * as React from 'react';
import Checkbox from '@mui/material/Checkbox';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage, RememberMeCheckbox } from '@toolpad/core/SignInPage';
import { useTheme } from '@mui/material/styles';
-const providers = [{ id: 'credentials', name: 'Email and Password' }];
+const providers = [
+ { id: 'github', name: 'GitHub' },
+ { id: 'credentials', name: 'Email and Password' },
+];
export default function SlotPropsSignIn() {
const theme = useTheme();
return (
- alert(
- `Signing in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')} and checkbox value: ${formData.get('tandc')}`,
- )
- }
+ signIn={(provider, formData) => {
+ if (provider.id === 'credentials') {
+ alert(
+ `Signing in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')} and checkbox value: ${formData.get('tandc')}`,
+ );
+ } else {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve({ error: 'This is a fake error' });
+ }, 1000);
+ });
+ }
+ return undefined;
+ }}
+ slots={{ rememberMe: RememberMeCheckbox }}
slotProps={{
+ form: { noValidate: true },
emailField: { variant: 'standard', autoFocus: false },
passwordField: { variant: 'standard' },
submitButton: { variant: 'outlined' },
+ oauthButton: { variant: 'contained' },
rememberMe: {
control: (
),
color: 'textSecondary',
diff --git a/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.tsx b/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.tsx
index 4a4c1a833f9..ee0aacbd621 100644
--- a/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/SlotPropsSignIn.tsx
@@ -1,32 +1,47 @@
import * as React from 'react';
import Checkbox from '@mui/material/Checkbox';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage, RememberMeCheckbox } from '@toolpad/core/SignInPage';
import { useTheme } from '@mui/material/styles';
-const providers = [{ id: 'credentials', name: 'Email and Password' }];
+const providers = [
+ { id: 'github', name: 'GitHub' },
+ { id: 'credentials', name: 'Email and Password' },
+];
export default function SlotPropsSignIn() {
const theme = useTheme();
return (
- alert(
- `Signing in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')} and checkbox value: ${formData.get('tandc')}`,
- )
- }
+ signIn={(provider, formData) => {
+ if (provider.id === 'credentials') {
+ alert(
+ `Signing in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')} and checkbox value: ${formData.get('tandc')}`,
+ );
+ } else {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve({ error: 'This is a fake error' });
+ }, 1000);
+ });
+ }
+ return undefined;
+ }}
+ slots={{ rememberMe: RememberMeCheckbox }}
slotProps={{
+ form: { noValidate: true },
emailField: { variant: 'standard', autoFocus: false },
passwordField: { variant: 'standard' },
submitButton: { variant: 'outlined' },
+ oauthButton: { variant: 'contained' },
rememberMe: {
control: (
),
color: 'textSecondary',
diff --git a/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.js b/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.js
index f67f1a9f1aa..54e6cab2e6e 100644
--- a/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.js
+++ b/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.js
@@ -2,8 +2,6 @@ import * as React from 'react';
import {
Button,
FormControl,
- FormControlLabel,
- Checkbox,
InputLabel,
OutlinedInput,
TextField,
@@ -16,7 +14,7 @@ import AccountCircle from '@mui/icons-material/AccountCircle';
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage, RememberMeCheckbox } from '@toolpad/core/SignInPage';
import { useTheme } from '@mui/material/styles';
const providers = [{ id: 'credentials', name: 'Email and Password' }];
@@ -125,34 +123,12 @@ function Title() {
function Subtitle() {
return (
-
+
We are investigating an ongoing outage.
);
}
-function AgreeWithTerms() {
- return (
-
- }
- slotProps={{
- typography: {
- fontSize: 14,
- },
- }}
- color="textSecondary"
- label="I agree with the T&C"
- />
- );
-}
-
export default function SlotsSignIn() {
const theme = useTheme();
return (
@@ -160,7 +136,7 @@ export default function SlotsSignIn() {
alert(
- `Logging in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')}, and checkbox value: ${formData.get('tandc')}`,
+ `Logging in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')}, and checkbox value: ${formData.get('remember')}`,
)
}
slots={{
@@ -170,9 +146,10 @@ export default function SlotsSignIn() {
passwordField: CustomPasswordField,
submitButton: CustomButton,
signUpLink: SignUpLink,
- rememberMe: AgreeWithTerms,
+ rememberMe: RememberMeCheckbox,
forgotPasswordLink: ForgotPasswordLink,
}}
+ slotProps={{ form: { noValidate: true } }}
providers={providers}
/>
diff --git a/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.tsx b/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.tsx
index 7925f2c030b..8b083c36f0e 100644
--- a/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/SlotsSignIn.tsx
@@ -2,8 +2,6 @@ import * as React from 'react';
import {
Button,
FormControl,
- FormControlLabel,
- Checkbox,
InputLabel,
OutlinedInput,
TextField,
@@ -16,7 +14,7 @@ import AccountCircle from '@mui/icons-material/AccountCircle';
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
import { AppProvider } from '@toolpad/core/AppProvider';
-import { SignInPage } from '@toolpad/core/SignInPage';
+import { SignInPage, RememberMeCheckbox } from '@toolpad/core/SignInPage';
import { useTheme } from '@mui/material/styles';
const providers = [{ id: 'credentials', name: 'Email and Password' }];
@@ -125,34 +123,12 @@ function Title() {
function Subtitle() {
return (
-
+
We are investigating an ongoing outage.
);
}
-function AgreeWithTerms() {
- return (
-
- }
- slotProps={{
- typography: {
- fontSize: 14,
- },
- }}
- color="textSecondary"
- label="I agree with the T&C"
- />
- );
-}
-
export default function SlotsSignIn() {
const theme = useTheme();
return (
@@ -160,7 +136,7 @@ export default function SlotsSignIn() {
alert(
- `Logging in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')}, and checkbox value: ${formData.get('tandc')}`,
+ `Logging in with "${provider.name}" and credentials: ${formData.get('email')}, ${formData.get('password')}, and checkbox value: ${formData.get('remember')}`,
)
}
slots={{
@@ -170,9 +146,10 @@ export default function SlotsSignIn() {
passwordField: CustomPasswordField,
submitButton: CustomButton,
signUpLink: SignUpLink,
- rememberMe: AgreeWithTerms,
+ rememberMe: RememberMeCheckbox,
forgotPasswordLink: ForgotPasswordLink,
}}
+ slotProps={{ form: { noValidate: true } }}
providers={providers}
/>
diff --git a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.js b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.js
index 38d573b4453..14d3091fd3a 100644
--- a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.js
+++ b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.js
@@ -44,6 +44,7 @@ export default function ThemeSignInPage() {
.MuiStack-root': {
marginTop: '2rem',
diff --git a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx
index d9ce9dc1702..675906f8dae 100644
--- a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx
+++ b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx
@@ -50,6 +50,7 @@ export default function ThemeSignInPage() {
.MuiStack-root': {
marginTop: '2rem',
diff --git a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx.preview b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx.preview
index 511c40e2811..493c55d7468 100644
--- a/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx.preview
+++ b/docs/data/toolpad/core/components/sign-in-page/ThemeSignInPage.tsx.preview
@@ -15,6 +15,7 @@ const THEME = createTheme({
.MuiStack-root': {
marginTop: '2rem',
diff --git a/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md b/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md
index 9abf4d7bef6..69d9f437a42 100644
--- a/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md
+++ b/docs/data/toolpad/core/components/sign-in-page/sign-in-page.md
@@ -1,7 +1,7 @@
---
productId: toolpad-core
title: Sign-in Page
-components: SignInPage, Account, NotificationsProvider
+components: SignInPage, Account, RememberMeCheckbox, NotificationsProvider
---
# Sign-in Page
@@ -260,7 +260,7 @@ To enable deep customization beyond what is possible with custom props, the `Sig
{{"demo": "SlotsSignIn.js", "iframe": true, "height": 540 }}
-You can use the `slotProps` prop to pass props to the underlying components of each slot:
+You can use the `slotProps` prop to pass props to the underlying components of each slot, and also to the `form` element:
{{"demo": "SlotPropsSignIn.js", "iframe": true, "height": 600 }}
diff --git a/docs/data/toolpad/core/pagesApi.js b/docs/data/toolpad/core/pagesApi.js
index c36b8e189db..90e52eabf82 100644
--- a/docs/data/toolpad/core/pagesApi.js
+++ b/docs/data/toolpad/core/pagesApi.js
@@ -10,6 +10,7 @@ module.exports = [
{ pathname: '/toolpad/core/api/page-container' },
{ pathname: '/toolpad/core/api/page-header' },
{ pathname: '/toolpad/core/api/page-header-toolbar' },
+ { pathname: '/toolpad/core/api/remember-me-checkbox' },
{ pathname: '/toolpad/core/api/sign-in-button' },
{ pathname: '/toolpad/core/api/sign-in-page' },
{ pathname: '/toolpad/core/api/sign-out-button' },
diff --git a/docs/pages/toolpad/core/api/remember-me-checkbox.js b/docs/pages/toolpad/core/api/remember-me-checkbox.js
new file mode 100644
index 00000000000..cdb270120c4
--- /dev/null
+++ b/docs/pages/toolpad/core/api/remember-me-checkbox.js
@@ -0,0 +1,23 @@
+import * as React from 'react';
+import ApiPage from 'docs/src/modules/components/ApiPage';
+import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations';
+import jsonPageContent from './remember-me-checkbox.json';
+
+export default function Page(props) {
+ const { descriptions, pageContent } = props;
+ return ;
+}
+
+Page.getInitialProps = () => {
+ const req = require.context(
+ 'docs-toolpad/translations/api-docs/remember-me-checkbox',
+ false,
+ /\.\/remember-me-checkbox.*.json$/,
+ );
+ const descriptions = mapApiPageTranslations(req);
+
+ return {
+ descriptions,
+ pageContent: jsonPageContent,
+ };
+};
diff --git a/docs/pages/toolpad/core/api/remember-me-checkbox.json b/docs/pages/toolpad/core/api/remember-me-checkbox.json
new file mode 100644
index 00000000000..04b78ce1ec7
--- /dev/null
+++ b/docs/pages/toolpad/core/api/remember-me-checkbox.json
@@ -0,0 +1,72 @@
+{
+ "props": {
+ "control": { "type": { "name": "element" }, "required": true },
+ "slotProps": {
+ "type": { "name": "shape", "description": "{ typography?: func
| object }" },
+ "default": "{}"
+ }
+ },
+ "name": "RememberMeCheckbox",
+ "imports": ["import { RememberMeCheckbox } from '@toolpad/core/SignInPage';"],
+ "classes": [
+ {
+ "key": "asterisk",
+ "className": "",
+ "description": "Styles applied to the asterisk element.",
+ "isGlobal": false
+ },
+ {
+ "key": "disabled",
+ "className": "",
+ "description": "State class applied to the root element if `disabled={true}`.",
+ "isGlobal": false
+ },
+ {
+ "key": "error",
+ "className": "",
+ "description": "State class applied to the root element if `error={true}`.",
+ "isGlobal": false
+ },
+ {
+ "key": "label",
+ "className": "",
+ "description": "Styles applied to the label's Typography component.",
+ "isGlobal": false
+ },
+ {
+ "key": "labelPlacementBottom",
+ "className": "",
+ "description": "Styles applied to the root element if `labelPlacement=\"bottom\"`.",
+ "isGlobal": false
+ },
+ {
+ "key": "labelPlacementStart",
+ "className": "",
+ "description": "Styles applied to the root element if `labelPlacement=\"start\"`.",
+ "isGlobal": false
+ },
+ {
+ "key": "labelPlacementTop",
+ "className": "",
+ "description": "Styles applied to the root element if `labelPlacement=\"top\"`.",
+ "isGlobal": false
+ },
+ {
+ "key": "required",
+ "className": "",
+ "description": "State class applied to the root element if `required={true}`.",
+ "isGlobal": false
+ },
+ {
+ "key": "root",
+ "className": "",
+ "description": "Styles applied to the root element.",
+ "isGlobal": false
+ }
+ ],
+ "muiName": "RememberMeCheckbox",
+ "filename": "/packages/toolpad-core/src/SignInPage/RememberMeCheckbox.tsx",
+ "inheritance": null,
+ "demos": "",
+ "cssComponent": false
+}
diff --git a/docs/pages/toolpad/core/api/sign-in-page.json b/docs/pages/toolpad/core/api/sign-in-page.json
index 132fb1607bc..0a131fa2fcd 100644
--- a/docs/pages/toolpad/core/api/sign-in-page.json
+++ b/docs/pages/toolpad/core/api/sign-in-page.json
@@ -15,7 +15,7 @@
"slotProps": {
"type": {
"name": "shape",
- "description": "{ emailField?: object, forgotPasswordLink?: object, passwordField?: object, rememberMe?: object, signUpLink?: object, submitButton?: object }"
+ "description": "{ emailField?: object, forgotPasswordLink?: object, form?: object, oauthButton?: object, passwordField?: object, rememberMe?: object, signUpLink?: object, submitButton?: object }"
},
"default": "{}"
},
@@ -85,7 +85,7 @@
},
{
"name": "rememberMe",
- "description": "A component to override the default \"Remember me\" checkbox in the Credentials form",
+ "description": "A custom checkbox placed in the credentials form",
"default": "FormControlLabel",
"class": null
}
diff --git a/docs/translations/api-docs/remember-me-checkbox/remember-me-checkbox.json b/docs/translations/api-docs/remember-me-checkbox/remember-me-checkbox.json
new file mode 100644
index 00000000000..d789570c685
--- /dev/null
+++ b/docs/translations/api-docs/remember-me-checkbox/remember-me-checkbox.json
@@ -0,0 +1,50 @@
+{
+ "componentDescription": "",
+ "propDescriptions": {
+ "control": {
+ "description": "A control element. For instance, it can be a Radio
, a Switch
or a Checkbox
."
+ },
+ "slotProps": { "description": "The props used for each slot inside." }
+ },
+ "classDescriptions": {
+ "asterisk": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "the asterisk element"
+ },
+ "disabled": {
+ "description": "State class applied to {{nodeName}} if {{conditions}}.",
+ "nodeName": "the root element",
+ "conditions": "disabled={true}
"
+ },
+ "error": {
+ "description": "State class applied to {{nodeName}} if {{conditions}}.",
+ "nodeName": "the root element",
+ "conditions": "error={true}
"
+ },
+ "label": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "the label's Typography component"
+ },
+ "labelPlacementBottom": {
+ "description": "Styles applied to {{nodeName}} if {{conditions}}.",
+ "nodeName": "the root element",
+ "conditions": "labelPlacement=\"bottom\"
"
+ },
+ "labelPlacementStart": {
+ "description": "Styles applied to {{nodeName}} if {{conditions}}.",
+ "nodeName": "the root element",
+ "conditions": "labelPlacement=\"start\"
"
+ },
+ "labelPlacementTop": {
+ "description": "Styles applied to {{nodeName}} if {{conditions}}.",
+ "nodeName": "the root element",
+ "conditions": "labelPlacement=\"top\"
"
+ },
+ "required": {
+ "description": "State class applied to {{nodeName}} if {{conditions}}.",
+ "nodeName": "the root element",
+ "conditions": "required={true}
"
+ },
+ "root": { "description": "Styles applied to the root element." }
+ }
+}
diff --git a/docs/translations/api-docs/sign-in-page/sign-in-page.json b/docs/translations/api-docs/sign-in-page/sign-in-page.json
index de36472fb55..31c9dbd4593 100644
--- a/docs/translations/api-docs/sign-in-page/sign-in-page.json
+++ b/docs/translations/api-docs/sign-in-page/sign-in-page.json
@@ -21,7 +21,7 @@
"emailField": "The custom email field component used in the credentials form.",
"forgotPasswordLink": "The custom forgot password link component used in the credentials form.",
"passwordField": "The custom password field component used in the credentials form.",
- "rememberMe": "A component to override the default "Remember me" checkbox in the Credentials form",
+ "rememberMe": "A custom checkbox placed in the credentials form",
"signUpLink": "The custom sign up link component used in the credentials form.",
"submitButton": "The custom submit button component used in the credentials form.",
"subtitle": "A component to override the default subtitle section",
diff --git a/packages/toolpad-core/src/SignInPage/RememberMeCheckbox.tsx b/packages/toolpad-core/src/SignInPage/RememberMeCheckbox.tsx
new file mode 100644
index 00000000000..bbbaf090644
--- /dev/null
+++ b/packages/toolpad-core/src/SignInPage/RememberMeCheckbox.tsx
@@ -0,0 +1,62 @@
+import * as React from 'react';
+import PropTypes from 'prop-types';
+import { Checkbox, FormControlLabel, FormControlLabelProps } from '@mui/material';
+import { useTheme } from '@mui/material/styles';
+
+/**
+ *
+ * Demos:
+ *
+ * - [Sign-in Page](https://mui.com/toolpad/core/react-sign-in-page/)
+ *
+ * API:
+ *
+ * - [RememberMeCheckbox API](https://mui.com/toolpad/core/api/remember-me-checkbox)
+ */
+function RememberMeCheckbox(props: Partial) {
+ const theme = useTheme();
+ return (
+
+ )
+ }
+ slotProps={{
+ ...props.slotProps,
+ typography: {
+ color: 'textSecondary',
+ fontSize: theme.typography.pxToRem(14),
+ ...props?.slotProps?.typography,
+ },
+ }}
+ />
+ );
+}
+
+RememberMeCheckbox.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * A control element. For instance, it can be a `Radio`, a `Switch` or a `Checkbox`.
+ */
+ control: PropTypes.element.isRequired,
+ /**
+ * The props used for each slot inside.
+ * @default {}
+ */
+ slotProps: PropTypes.shape({
+ typography: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+ }),
+} as any;
+
+export { RememberMeCheckbox };
diff --git a/packages/toolpad-core/src/SignInPage/SignInPage.tsx b/packages/toolpad-core/src/SignInPage/SignInPage.tsx
index 5a5c489d992..3170e1659ec 100644
--- a/packages/toolpad-core/src/SignInPage/SignInPage.tsx
+++ b/packages/toolpad-core/src/SignInPage/SignInPage.tsx
@@ -5,10 +5,9 @@ import PropTypes from 'prop-types';
import Alert from '@mui/material/Alert';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
-import Checkbox from '@mui/material/Checkbox';
import Container from '@mui/material/Container';
import Divider from '@mui/material/Divider';
-import FormControlLabel, { FormControlLabelProps } from '@mui/material/FormControlLabel';
+import { FormControlLabelProps } from '@mui/material/FormControlLabel';
import TextField, { TextFieldProps } from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import LoadingButton, { LoadingButtonProps } from '@mui/lab/LoadingButton';
@@ -209,7 +208,7 @@ export interface SignInPageSlots {
*/
subtitle?: React.ElementType;
/**
- * A component to override the default "Remember me" checkbox in the Credentials form
+ * A custom checkbox placed in the credentials form
* @default FormControlLabel
*/
rememberMe?: React.ElementType;
@@ -252,9 +251,11 @@ export interface SignInPageProps {
emailField?: TextFieldProps;
passwordField?: TextFieldProps;
submitButton?: LoadingButtonProps;
+ oauthButton?: LoadingButtonProps;
forgotPasswordLink?: LinkProps;
signUpLink?: LinkProps;
rememberMe?: Partial;
+ form?: Partial>;
};
/**
* The prop used to customize the styles on the `SignInPage` container
@@ -312,7 +313,7 @@ function SignInPage(props: SignInPageProps) {
}}
>
-
)}
-
+
{error && isOauthProvider(selectedProviderId) ? (
{error}
@@ -374,6 +375,7 @@ function SignInPage(props: SignInPageProps) {
error: oauthResponse?.error,
}));
}}
+ {...slotProps?.form}
>
Sign in with {provider.name}
@@ -402,7 +405,7 @@ function SignInPage(props: SignInPageProps) {
{singleProvider ? null : or}
{error && selectedProviderId === 'passkey' ? (
-
+
{error}
) : null}
@@ -423,6 +426,7 @@ function SignInPage(props: SignInPageProps) {
error: passkeyResponse?.error,
}));
}}
+ {...slotProps?.form}
>
{slots?.emailField ? (
@@ -436,6 +440,7 @@ function SignInPage(props: SignInPageProps) {
type: 'email',
autoComplete: 'email-webauthn',
autoFocus: singleProvider,
+ sx: { mt: 1 },
...slotProps?.emailField,
})}
/>
@@ -470,12 +475,12 @@ function SignInPage(props: SignInPageProps) {
{singleProvider ? null : or}
{error && selectedProviderId === 'nodemailer' ? (
-
+
{error}
) : null}
{success && selectedProviderId === 'nodemailer' ? (
-
+
{success}
) : null}
@@ -497,6 +502,7 @@ function SignInPage(props: SignInPageProps) {
success: emailResponse?.success,
}));
}}
+ {...slotProps?.form}
>
{slots?.emailField ? (
@@ -508,6 +514,7 @@ function SignInPage(props: SignInPageProps) {
name: 'email',
id: 'email-nodemailer',
type: 'email',
+ sx: { mt: 1 },
autoComplete: 'email-nodemailer',
autoFocus: singleProvider,
...slotProps?.emailField,
@@ -544,7 +551,7 @@ function SignInPage(props: SignInPageProps) {
{singleProvider ? null : or}
{error && selectedProviderId === 'credentials' ? (
-
+
{error}
) : null}
@@ -569,8 +576,9 @@ function SignInPage(props: SignInPageProps) {
error: credentialsResponse?.error,
}));
}}
+ {...slotProps?.form}
>
-
+
{slots?.emailField ? (
) : (
@@ -603,42 +611,23 @@ function SignInPage(props: SignInPageProps) {
/>
)}
-
- {slots?.rememberMe ? (
-
- ) : (
-
- }
- label="Remember me"
- {...slotProps?.rememberMe}
- slotProps={{
- typography: {
- color: 'textSecondary',
- fontSize: theme.typography.pxToRem(14),
- },
- ...slotProps?.rememberMe?.slotProps,
- }}
- />
- )}
- {slots?.forgotPasswordLink ? (
-
- ) : null}
-
+ {slots?.forgotPasswordLink || slots?.rememberMe ? (
+
+ {slots?.rememberMe ? : null}
+ {slots?.forgotPasswordLink ? (
+
+ ) : null}
+
+ ) : null}
{slots?.submitButton ? (
) : (
@@ -670,7 +659,7 @@ function SignInPage(props: SignInPageProps) {
) : null}
-
+
);
@@ -710,6 +699,8 @@ SignInPage.propTypes /* remove-proptypes */ = {
slotProps: PropTypes.shape({
emailField: PropTypes.object,
forgotPasswordLink: PropTypes.object,
+ form: PropTypes.object,
+ oauthButton: PropTypes.object,
passwordField: PropTypes.object,
rememberMe: PropTypes.object,
signUpLink: PropTypes.object,
diff --git a/packages/toolpad-core/src/SignInPage/index.ts b/packages/toolpad-core/src/SignInPage/index.ts
index aa485859b44..c4976180061 100644
--- a/packages/toolpad-core/src/SignInPage/index.ts
+++ b/packages/toolpad-core/src/SignInPage/index.ts
@@ -1 +1,2 @@
export * from './SignInPage';
+export * from './RememberMeCheckbox';
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8914f6a1033..ecd717ee3b0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -201,7 +201,7 @@ importers:
version: 7.37.3(eslint@8.57.1)
eslint-plugin-react-compiler:
specifier: latest
- version: 19.0.0-beta-decd7b8-20250118(eslint@8.57.1)
+ version: 19.0.0-beta-27714ef-20250124(eslint@8.57.1)
eslint-plugin-react-hooks:
specifier: 5.1.0
version: 5.1.0(eslint@8.57.1)
@@ -6090,8 +6090,8 @@ packages:
peerDependencies:
eslint: '>=7.0.0'
- eslint-plugin-react-compiler@19.0.0-beta-decd7b8-20250118:
- resolution: {integrity: sha512-qfs+Xo+VcYPbbVLI2tCP+KBGwm0oksAhjFJO1GwOvP+4b18LLcPZu7xopRhUTOaNd+nn1vOp9EQLZC1wMNxSrQ==}
+ eslint-plugin-react-compiler@19.0.0-beta-27714ef-20250124:
+ resolution: {integrity: sha512-8/NaV8E+eQ+BiKGeWg5wIizuKwEXLo+n/lgiyTLmJnZj8eoFW3G7NGJf3Nke4ji3Rndy34LK5Qi5TF6BPiZlSQ==}
engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0}
peerDependencies:
eslint: '>=7'
@@ -7542,6 +7542,7 @@ packages:
lodash.get@4.4.2:
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
+ deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
lodash.groupby@4.6.0:
resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==}
@@ -7554,6 +7555,7 @@ packages:
lodash.isequal@4.5.0:
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
+ deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead.
lodash.isfunction@3.0.9:
resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==}
@@ -7599,6 +7601,7 @@ packages:
lodash.omit@4.5.0:
resolution: {integrity: sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==}
+ deprecated: This package is deprecated. Use destructuring assignment syntax instead.
lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
@@ -16276,7 +16279,7 @@ snapshots:
globals: 13.24.0
rambda: 7.5.0
- eslint-plugin-react-compiler@19.0.0-beta-decd7b8-20250118(eslint@8.57.1):
+ eslint-plugin-react-compiler@19.0.0-beta-27714ef-20250124(eslint@8.57.1):
dependencies:
'@babel/core': 7.26.0
'@babel/parser': 7.26.2