Skip to content

Commit

Permalink
[SignInPage] Allow slotProps to override all labels (#4418)
Browse files Browse the repository at this point in the history
  • Loading branch information
bharatkashyap authored Nov 21, 2024
1 parent 1826da5 commit 3ecf527
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 133 deletions.
12 changes: 11 additions & 1 deletion docs/data/toolpad/core/components/sign-in-page/customTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export const inputsCustomizations = {
boxSizing: 'border-box',
transition: 'all 100ms ease-in',
'&:focus-visible': {
outline: `3px solid ${alpha(theme.palette.primary.main, 0.5)}`,
outline: `2px solid ${alpha(theme.palette.primary.main, 0.5)}`,
outlineOffset: '2px',
},
}),
Expand Down Expand Up @@ -501,6 +501,16 @@ export const inputsCustomizations = {
}),
},
},
MuiInputLabel: {
styleOverrides: {
root: {
transform: 'translate(4px, -11px) scale(0.75)',
[`&.${outlinedInputClasses.focused}`]: {
transform: 'translate(4px, -12px) scale(0.75)',
},
},
},
},
MuiOutlinedInput: {
styleOverrides: {
input: {
Expand Down
13 changes: 11 additions & 2 deletions docs/data/toolpad/core/components/sign-in-page/customTheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ export const inputsCustomizations: Components<Theme> = {
boxSizing: 'border-box',
transition: 'all 100ms ease-in',
'&:focus-visible': {
outline: `3px solid ${alpha(theme.palette.primary.main, 0.5)}`,
outline: `2px solid ${alpha(theme.palette.primary.main, 0.5)}`,
outlineOffset: '2px',
},
}),
Expand Down Expand Up @@ -532,7 +532,16 @@ export const inputsCustomizations: Components<Theme> = {
}),
},
},

MuiInputLabel: {
styleOverrides: {
root: {
transform: 'translate(4px, -11px) scale(0.75)',
[`&.${outlinedInputClasses.focused}`]: {
transform: 'translate(4px, -12px) scale(0.75)',
},
},
},
},
MuiOutlinedInput: {
styleOverrides: {
input: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import { useRouter } from 'next/router';
import { authOptions } from '../api/auth/[...nextauth]';

function ForgotPasswordLink() {
return <Link href="/auth/forgot-password">Forgot password?</Link>;
return (
<Link href="/auth/forgot-password" fontSize={14}>
Forgot password?
</Link>
);
}

function SignUpLink() {
Expand Down
12 changes: 11 additions & 1 deletion examples/core/auth-nextjs-themed/theme/customizations/inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,16 @@ export const inputsCustomizations: Components<Theme> = {
},
},
},
MuiInputLabel: {
styleOverrides: {
root: {
transform: 'translate(4px, -11px) scale(0.75)',
[`&.${outlinedInputClasses.focused}`]: {
transform: 'translate(4px, -12px) scale(0.75)',
},
},
},
},
MuiOutlinedInput: {
styleOverrides: {
input: {
Expand All @@ -403,7 +413,7 @@ export const inputsCustomizations: Components<Theme> = {
borderColor: gray[400],
},
[`&.${outlinedInputClasses.focused}`]: {
outline: `3px solid ${alpha(brand[500], 0.5)}`,
outline: `2px solid ${alpha(brand[500], 0.5)}`,
borderColor: brand[400],
},
...theme.applyStyles('dark', {
Expand Down
242 changes: 116 additions & 126 deletions packages/toolpad-core/src/SignInPage/SignInPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ 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 InputLabel from '@mui/material/InputLabel';
import FormControlLabel from '@mui/material/FormControlLabel';
import TextField, { TextFieldProps } from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
Expand All @@ -17,7 +16,7 @@ import GitHubIcon from '@mui/icons-material/GitHub';
import PasswordIcon from '@mui/icons-material/Password';
import FingerprintIcon from '@mui/icons-material/Fingerprint';
import AppleIcon from '@mui/icons-material/Apple';
import { alpha, useTheme, SxProps } from '@mui/material/styles';
import { alpha, useTheme, SxProps, type Theme } from '@mui/material/styles';
import { LinkProps } from '@mui/material/Link';
import GoogleIcon from './icons/Google';
import FacebookIcon from './icons/Facebook';
Expand All @@ -40,6 +39,49 @@ import FusionAuthIcon from './icons/FusionAuth';
import { BrandingContext, RouterContext } from '../shared/context';
import { DocsContext } from '../internal/context';

const mergeSlotSx = (defaultSx: SxProps<Theme>, slotProps?: { sx?: SxProps<Theme> }) => {
if (Array.isArray(slotProps?.sx)) {
return [defaultSx, ...slotProps.sx];
}

if (slotProps?.sx) {
return [defaultSx, slotProps?.sx];
}

return [defaultSx];
};

const getCommonTextFieldProps = (theme: Theme, baseProps: TextFieldProps = {}): TextFieldProps => ({
required: true,
fullWidth: true,
...baseProps,
slotProps: {
...baseProps.slotProps,
htmlInput: {
...baseProps.slotProps?.htmlInput,
sx: mergeSlotSx(
{
paddingTop: theme.spacing(1),
paddingBottom: theme.spacing(1),
},
typeof baseProps.slotProps?.htmlInput === 'function' ? {} : baseProps.slotProps?.htmlInput,
),
},
inputLabel: {
...baseProps.slotProps?.inputLabel,
sx: mergeSlotSx(
{
lineHeight: theme.typography.pxToRem(12),
fontSize: theme.typography.pxToRem(14),
},
typeof baseProps.slotProps?.inputLabel === 'function'
? {}
: baseProps.slotProps?.inputLabel,
),
},
},
});

type SupportedOAuthProvider =
| 'github'
| 'google'
Expand Down Expand Up @@ -380,37 +422,19 @@ function SignInPage(props: SignInPageProps) {
{slots?.emailField ? (
<slots.emailField {...slotProps?.emailField} />
) : (
<Box sx={{ marginBottom: theme.spacing(1) }}>
<InputLabel shrink htmlFor="email-passkey" sx={{ marginBottom: 0 }}>
Email
</InputLabel>
<TextField
required
slotProps={{
htmlInput: {
sx: {
paddingTop: theme.spacing(1),
paddingBottom: theme.spacing(1),
},
},
inputLabel: {
sx: {
lineHeight: theme.typography.pxToRem(12),
},
},
}}
fullWidth
placeholder="[email protected]"
id="email-passkey"
name="email"
type="email"
autoComplete="email-webauthn"
autoFocus={docs ? false : singleProvider}
{...slotProps?.emailField}
/>
</Box>
<TextField
{...getCommonTextFieldProps(theme, {
label: 'Email',
placeholder: '[email protected]',
id: 'email-passkey',
name: 'email',
type: 'email',
autoComplete: 'email-webauthn',
autoFocus: docs ? false : singleProvider,
...slotProps?.emailField,
})}
/>
)}

{slots?.submitButton ? (
<slots.submitButton {...slotProps?.submitButton} />
) : (
Expand Down Expand Up @@ -469,36 +493,22 @@ function SignInPage(props: SignInPageProps) {
}));
}}
>
<Box sx={{ marginBottom: theme.spacing(1) }}>
<InputLabel shrink htmlFor="email-nodemailer" sx={{ marginBottom: 0 }}>
Email
</InputLabel>
{slots?.emailField ? (
<slots.emailField {...slotProps?.emailField} />
) : (
<TextField
required
slotProps={{
htmlInput: {
sx: {
paddingTop: theme.spacing(1),
paddingBottom: theme.spacing(1),
},
},
inputLabel: {
sx: {
lineHeight: theme.typography.pxToRem(12),
},
},
}}
fullWidth
placeholder="[email protected]"
name="email"
id="email-nodemailer"
type="email"
autoComplete="email-nodemailer"
autoFocus={docs ? false : singleProvider}
{...slotProps?.emailField}
{...getCommonTextFieldProps(theme, {
label: 'Email',
placeholder: '[email protected]',
name: 'email',
id: 'email-nodemailer',
type: 'email',
autoComplete: 'email-nodemailer',
autoFocus: docs ? false : singleProvider,
...slotProps?.emailField,
})}
/>
</Box>

)}
{slots?.submitButton ? (
<slots.submitButton {...slotProps?.submitButton} />
) : (
Expand Down Expand Up @@ -555,84 +565,64 @@ function SignInPage(props: SignInPageProps) {
}));
}}
>
{slots?.emailField ? (
<slots.emailField {...slotProps?.emailField} />
) : (
<Box sx={{ marginBottom: theme.spacing(1) }}>
<InputLabel shrink htmlFor="email" sx={{ marginBottom: 0 }}>
Email
</InputLabel>
<Stack direction="column" spacing={2} sx={{ mb: 2 }}>
{slots?.emailField ? (
<slots.emailField {...slotProps?.emailField} />
) : (
<TextField
required
slotProps={{
htmlInput: {
sx: {
paddingTop: theme.spacing(1),
paddingBottom: theme.spacing(1),
},
},
inputLabel: {
sx: {
lineHeight: theme.typography.pxToRem(12),
},
},
}}
placeholder="[email protected]"
fullWidth
id="email"
name="email"
type="email"
autoComplete="email"
autoFocus={docs ? false : singleProvider}
{...slotProps?.emailField}
{...getCommonTextFieldProps(theme, {
label: 'Email',
placeholder: '[email protected]',
id: 'email',
name: 'email',
type: 'email',
autoComplete: 'email',
autoFocus: docs ? false : singleProvider,
...slotProps?.emailField,
})}
/>
</Box>
)}

{slots?.passwordField ? (
<slots.passwordField {...slotProps?.passwordField} />
) : (
<React.Fragment>
<InputLabel shrink htmlFor="password" sx={{ marginBottom: 0 }}>
Password
</InputLabel>

)}
{slots?.passwordField ? (
<slots.passwordField {...slotProps?.passwordField} />
) : (
<TextField
required
fullWidth
slotProps={{
htmlInput: {
sx: {
paddingTop: theme.spacing(1),
paddingBottom: theme.spacing(1),
},
},
inputLabel: {
sx: {
lineHeight: theme.typography.pxToRem(16),
},
},
}}
name="password"
type="password"
id="password"
placeholder="******"
autoComplete="current-password"
{...slotProps?.passwordField}
{...getCommonTextFieldProps(theme, {
name: 'password',
type: 'password',
label: 'Password',
id: 'password',
placeholder: '*****',
autoComplete: 'current-password',
...slotProps?.passwordField,
})}
/>
</React.Fragment>
)}

)}
</Stack>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
spacing={1}
sx={{
justifyContent: 'space-between',
}}
>
<FormControlLabel
control={<Checkbox name="remember" value="true" color="primary" />}
control={
<Checkbox
name="remember"
value="true"
color="primary"
sx={{ padding: 0.5, '& .MuiSvgIcon-root': { fontSize: 20 } }}
/>
}
label="Remember me"
slotProps={{ typography: { color: 'textSecondary' } }}
slotProps={{
typography: {
color: 'textSecondary',
fontSize: theme.typography.pxToRem(14),
},
}}
/>
{slots?.forgotPasswordLink ? (
<slots.forgotPasswordLink {...slotProps?.forgotPasswordLink} />
Expand Down
Loading

0 comments on commit 3ecf527

Please sign in to comment.