Sign In Block
The SignIn Component is a fully customizable and accessible sign-in form built with React, TypeScript, and MUI. It provides a complete authentication interface with modern design patterns, form validation using react-hook-form, and flexible customization options.
π Installationβ
npm install @nodeblocks/frontend-signin-block@0.3.0
π Usageβ
import {SignIn} from '@nodeblocks/frontend-signin-block';
- Basic Usage
- Advanced Usage
function BasicSignIn() { return ( <SignIn onChange={(setError, getValues, clearErrors) => { const values = getValues(); if (!values.email) { setError('email', {message: 'Email is required', type: 'required'}); } else { clearErrors('email'); } }} onSubmit={formData => { console.log('Form submitted:', formData); }} > <SignIn.SignInTitle>Welcome Back</SignIn.SignInTitle> <SignIn.EmailField label="Email Address" placeholder="Enter your email" /> <SignIn.PasswordField label="Password" placeholder="Enter your password" /> <SignIn.SignInButton>Sign In</SignIn.SignInButton> <SignIn.GotoSignUp> <a href="#signup">Create an account</a> </SignIn.GotoSignUp> <SignIn.ResetPassword> <a href="#reset-password">Forgot password?</a> </SignIn.ResetPassword> </SignIn> ); }
function AdvancedSignIn() { return ( <SignIn onChange={(setError, getValues, clearErrors) => { const values = getValues(); if (!values.email) { setError('email', {message: 'γ‘γΌγ«γ’γγ¬γΉγεΏ θ¦γ§γ', type: 'required'}); } else { clearErrors('email'); } if (!values.password) { setError('password', {message: 'γγΉγ―γΌγγεΏ θ¦γ§γ', type: 'required'}); } else { clearErrors('password'); } }} onSubmit={formData => { console.log('γγ°γ€γ³:', formData); }} sx={{ maxWidth: '500px', margin: '0 auto', background: 'linear-gradient(145deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '20px', border: '1px solid #e2e8f0', }} > {({defaultBlocks, defaultBlockOrder}) => ({ blocks: { ...defaultBlocks, signInTitle: { ...defaultBlocks.signInTitle, props: { ...defaultBlocks.signInTitle.props, sx: { background: 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text', fontSize: '2rem', fontWeight: 'bold', textAlign: 'center', marginBottom: '8px', }, children: 'δΌζ₯γγ°γ€γ³', }, }, emailField: { ...defaultBlocks.emailField, props: { ...defaultBlocks.emailField.props, label: 'γ‘γΌγ«γ’γγ¬γΉ', placeholder: 'δΎ: user@company.com', sx: { '& .MuiOutlinedInput-root': { borderRadius: '10px', }, }, }, }, passwordField: { ...defaultBlocks.passwordField, props: { ...defaultBlocks.passwordField.props, label: 'γγΉγ―γΌγ', placeholder: 'γγΉγ―γΌγγε ₯εγγ¦γγ γγ', sx: { '& .MuiOutlinedInput-root': { borderRadius: '10px', }, }, }, }, signInButton: { ...defaultBlocks.signInButton, props: { ...defaultBlocks.signInButton.props, sx: { background: '#3b82f6', borderRadius: '10px', py: 1.5, '&:hover': {background: '#2563eb'}, }, children: 'γγ°γ€γ³', }, }, gotoSignUp: { ...defaultBlocks.gotoSignUp, props: { ...defaultBlocks.gotoSignUp.props, sx: { textAlign: 'center', }, children: ( <span style={{color: '#64748b', fontSize: '14px'}}> γ’γ«γ¦γ³γγγζγ‘γ§γͺγζΉγ―{' '} <a href="#signup" style={{color: '#3b82f6', textDecoration: 'none', fontWeight: '500'}}> ζ°θ¦η»ι² </a> </span> ), }, }, resetPassword: { ...defaultBlocks.resetPassword, props: { ...defaultBlocks.resetPassword.props, sx: { textAlign: 'center', }, children: ( <a href="#reset-password" style={{color: '#64748b', fontSize: '14px', textDecoration: 'none'}}> γγΉγ―γΌγγγεΏγγ§γγοΌ </a> ), }, }, }, blockOrder: defaultBlockOrder, })} </SignIn> ); }
π§ Props Referenceβ
Main Component Propsβ
| Prop | Type | Default | Description |
|---|---|---|---|
onSubmit | SubmitHandler<T> | Required | Callback function triggered when form is submitted with valid data |
onChange | (setError, getValues, clearErrors) => void | Required | Callback function triggered when form values change. Provides form control functions for validation |
defaultData | DefaultValues<T> | undefined | Default form values to populate fields on initial render |
data | T | undefined | Controlled form values - use this for external form state management |
signupUrl | string | "/auth/signup" | URL for the signup link in GotoSignUp component |
resetPasswordUrl | string | "/auth/resetpassword" | URL for the reset password link |
className | string | undefined | Additional CSS class name for styling the form container |
sx | SxProps | undefined | MUI sx prop for custom styling |
children | BlocksOverride | undefined | Custom block components to override default rendering |
Note: This component extends MUI StackProps<'form'> (excluding children, onChange, and onSubmit). Uses component="form" with default spacing={4}, maxWidth: 496, px: 5, py: 6, and borderRadius: 3.
Sub-Componentsβ
The SignIn component provides several sub-components. All sub-components receive their default values from the main component's context and can override these values through props.
SignIn.SignInTitleβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | "Sign In" | Title content |
className | string | undefined | Additional CSS class name for styling |
variant | string | "h4" | MUI Typography variant |
component | string | "h1" | HTML element to render |
sx | SxProps | undefined | MUI sx prop with default textAlign: 'center' |
Note: This component extends MUI TypographyProps<'h1'>.
SignIn.EmailFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | "email" | Field name used for form data and validation |
label | string | "Email" | Field label displayed above the input |
placeholder | string | "Please enter your email" | Placeholder text shown when field is empty |
autoComplete | string | "username" | Browser autocomplete hint |
required | boolean | true | Whether the field is required |
fullWidth | boolean | true | Whether field takes full width |
className | string | undefined | Additional CSS class name for styling |
Note: This component extends MUI TextFieldProps. Error states and helper text are managed automatically by react-hook-form.
SignIn.PasswordFieldβ
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | "password" | Field name used for form data and validation |
label | string | "Password" | Field label displayed above the input |
placeholder | string | "Please enter your password" | Placeholder text shown when field is empty |
autoComplete | string | "current-password" | Browser autocomplete hint |
required | boolean | true | Whether the field is required |
fullWidth | boolean | true | Whether field takes full width |
className | string | undefined | Additional CSS class name for styling |
Note: This component extends MUI TextFieldProps (excluding type). Includes built-in password visibility toggle with Visibility/VisibilityOff icons.
SignIn.SignInButtonβ
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | "Sign In" | Button text content |
variant | string | "contained" | MUI Button variant |
size | string | "large" | MUI Button size |
type | string | "submit" | HTML button type |
fullWidth | boolean | true | Whether button takes full width |
className | string | undefined | Additional CSS class name for styling |
Note: This component extends MUI ButtonProps.
SignIn.GotoSignUpβ
| Prop | Type | Default | Description |
|---|---|---|---|
signupUrl | string | From context | URL for the signup link |
children | ReactNode | Link to /auth/signup | Content for the signup link section |
className | string | undefined | Additional CSS class name for styling |
sx | SxProps | undefined | MUI sx prop with default textAlign: 'center' and fontSize: body2 |
Note: This component extends MUI BoxProps.
SignIn.ResetPasswordβ
| Prop | Type | Default | Description |
|---|---|---|---|
resetPasswordUrl | string | From context | URL for the reset password link |
children | ReactNode | Link to /auth/resetpassword | Content for the reset password link section |
className | string | undefined | Additional CSS class name for styling |
sx | SxProps | undefined | MUI sx prop with default textAlign: 'center' and fontSize: body2 |
Note: This component extends MUI BoxProps.
π¨ Configuration examplesβ
Custom Validationβ
function ValidationSignIn() {
const handleSubmit = (formData: SignInFormData): void => {
console.log('Validated form submitted:', formData);
};
return (
<SignIn
onChange={(setError, getValues, clearErrors) => {
const {email, password} = getValues();
if (email && !email.includes('@')) {
setError('email', {message: 'Please enter a valid email'});
} else {
clearErrors('email');
}
if (password && password.length < 8) {
setError('password', {message: 'Password must be at least 8 characters'});
} else {
clearErrors('password');
}
}}
onSubmit={handleSubmit}
>
<SignIn.SignInTitle
variant="h3"
sx={{
color: 'primary.main',
fontWeight: 'bold',
}}
>
Welcome Back!
</SignIn.SignInTitle>
<SignIn.EmailField label="Corporate Email" placeholder="name@company.com" />
<SignIn.PasswordField label="Account Password" placeholder="Enter your secure password" />
<SignIn.SignInButton>Sign In</SignIn.SignInButton>
<SignIn.GotoSignUp />
<SignIn.ResetPassword />
</SignIn>
);
}
Block Override Patternβ
function BlockOverrideSignIn() {
return (
<SignIn onSubmit={data => console.log(data)} onChange={() => {}}>
{({defaultBlocks}) => ({
blocks: {
...defaultBlocks,
// Add custom welcome message
welcomeMessage: (
<div
style={{
padding: '12px 16px',
backgroundColor: '#e3f2fd',
borderRadius: '8px',
textAlign: 'center',
color: '#1976d2',
}}
>
Sign in to access your dashboard
</div>
),
},
blockOrder: [
'signInTitle',
'welcomeMessage',
'emailField',
'passwordField',
'signInButton',
'gotoSignUp',
'resetPassword',
],
})}
</SignIn>
);
}
Custom Navigation URLsβ
<SignIn
signupUrl="/register"
resetPasswordUrl="/forgot-password"
onSubmit={handleSubmit}
onChange={handleChange}
/>
π§ TypeScript Supportβ
Full TypeScript support with comprehensive type definitions:
import {SignIn} from '@nodeblocks/frontend-signin-block';
import {
UseFormClearErrors,
UseFormGetValues,
UseFormSetError,
SubmitHandler,
} from 'react-hook-form';
// Default form data structure
type DefaultSignInFormData = {
email?: string;
password?: string;
};
// Extended form data type
type SignInFormData = DefaultSignInFormData & Record<string, unknown>;
// Custom form data with additional fields
interface CustomSignInFormData extends SignInFormData {
rememberMe?: boolean;
}
function TypedSignInExample() {
const handleSubmit: SubmitHandler<CustomSignInFormData> = formData => {
console.log('Form submitted:', formData);
};
const handleChange = (
setError: UseFormSetError<CustomSignInFormData>,
getValues: UseFormGetValues<CustomSignInFormData>,
clearErrors: UseFormClearErrors<CustomSignInFormData>,
): void => {
const values = getValues();
// Custom validation
if (values.email && !values.email.includes('@')) {
setError('email', {message: 'Invalid email format'});
} else {
clearErrors('email');
}
};
return (
<SignIn<CustomSignInFormData>
onSubmit={handleSubmit}
onChange={handleChange}
defaultData={{email: 'user@example.com'}}
signupUrl="/register"
resetPasswordUrl="/forgot-password"
sx={{maxWidth: 480, mx: 'auto'}}
>
<SignIn.SignInTitle>Welcome Back</SignIn.SignInTitle>
<SignIn.EmailField />
<SignIn.PasswordField />
<SignIn.SignInButton>Login</SignIn.SignInButton>
<SignIn.GotoSignUp>
<span>
Don't have an account? <a href="#register">Sign Up</a>
</span>
</SignIn.GotoSignUp>
<SignIn.ResetPassword>
<span>
<a href="#forgot-password">Forgot password?</a>
</span>
</SignIn.ResetPassword>
</SignIn>
);
}
π Notesβ
- The component uses MUI's
Stackcomponent as its base withcomponent="form" - Default spacing is
4withmaxWidth: 496,px: 5,py: 6, andborderRadius: 3 - Form state is managed by
react-hook-formwithmode: 'onBlur'for validation - The
onChangecallback is triggered when form values change (usinguseWatch) - Password field has built-in visibility toggle with MUI's
Visibility/VisibilityOfficons - Error states and helper text are automatically displayed based on validation
- Default blocks are:
signInTitle,emailField,passwordField,signInButton,resetPassword,gotoSignUp - Additional utility fields available:
TextField,TimeField,CheckboxField,SelectField - CSS classes follow BEM-style naming:
nbb-signin,nbb-signin-signin-title,nbb-signin-email-field, etc. - Default signup link points to
/auth/signup - Default reset password link points to
/auth/resetpassword
Built with β€οΈ using React, TypeScript, and MUI.