Skip to main content

Login

Customizable React login component that validates against a default or custom Zod schema.

login component

Features

  • Displays and handles client and serverside errors
  • Custom fields and schema
  • Show a success component and/or provide an onSuccess function to redirect, set state, etc.
  • Show social logins either above or below email login with optional separator
  • Custom header/footer
  • Loader (default or custom)
  • Show a link to registration
  • Show a forgot password link
  • Client router support for links
  • Toast support

Demo

https://npm-library-demo.vercel.app/login

Install

npm install @unleashit/login

Peer dependencies: react, react-hook-form, @hookform/resolvers and zod.

Example

import Login, { FormValues, ServerResponse } from '@unleashit/login';
import { useNavigate } from 'react-router-dom';

function LoginDemo() {
const navigate = useNavigate();

const loginHandler = async (values: FormValues): Promise<ServerResponse> => {
// server should return a ServerResponse
// success property of true indicates all validations pass
// errors named after field names will display with fields
// error with property of "root" will display at the top or sent to toast
return await fetch('https://api.example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(values),
}).then((resp) => resp.json());
};

const onSuccess = (resp: ServerResponse) => {
// Redirect or set auth state, etc.
// resp has full server response from loginHandler()
navigate('/');
};

return <Login handler={loginHandler} onSuccess={onSuccess} />;
}

With Social Logins

Adding social logins is easy. Simply include them as children and they will display (by default) under the main login with a nice separator.

import {
GithubLoginButton,
TwitterLoginButton,
} from 'react-social-login-buttons';

<Login handler={/* ... */}>
<TwitterLoginButton onClick={() => alert('Hello')}>
Sign in with Twitter
</TwitterLoginButton>
<GithubLoginButton onClick={() => alert('Hello')}>
Sign in with Github
</GithubLoginButton>
</Login>

Custom Fields

You can easily customize the form fields, attribute, behavior and more my supplying a custom fields object and a zod schema to match. See Custom Fields for more info.

CSS

By default, all components come with basic css styling in two formats: standard (BEM namespaced) and a CSS Module friendly version.

To use the standard version, import it like: import '@unleashit/login/dist/login.css'. Or if you are using CSS Modules you can import css from '@unleashit/login/dist/login.module.css' and provide to the cssModule prop and/or use your own custom module targeting the internal class names.

See styling-and-theming for more info.

CSS Custom Properties

You can get pretty far without having to write any custom CSS. By supplying a cssVars prop, you can override any of the CSS variables of the default css.

See styling-and-theming for more info.

Dark mode

Setting the darkMode prop activates dark mode.

See Dark Mode for more info.

API

LoginProps (extends BaseFormProps)

Props for the Login component. LoginFormProps extends BaseFormProps. The only required prop is handler.

export type LoginProps = BaseFormProps & {
/**
* Override the signup link inside the default header
* Note: if you provide a header prop, the signup link will not appear
*/
signupLink?: ComponentType | ReactNode;
/**
* Override default link to the forgot password route
* or false to disable
*/
forgotPasswordLink?: ComponentType | ReactNode | false;
/**
* Add a separator between email and
* social logins (children required)
*/
orLine?: boolean;
/** CSS custom property overrides */
cssVars?: CSSVars<typeof varNames>;
/** Position of children */
childrenPosition?: 'top' | 'bottom';
/** Social logins or other content to display */
children?: React.ReactNode;
};
export type BaseFormProps = {
/** Handler to submit form. Receives form values and returns Promise with ServerResponse */
handler: <T extends ZodTypeAny>(
values: FormValues<T>,
event?: Event,
) => Promise<BaseServerResponse<FormValues<T>>>;
/** Handler that fires upon successful server validation */
onSuccess?: <T extends ZodTypeAny, Meta extends Record<string, any>>(
resp: BaseServerResponse<FormValues<T>, Meta>,
) => void;
/**
* Custom header component or
* false to disable the default header
*/
header?: ComponentType<any> | ReactNode | false;
/** Header text for default header */
headerText?: string;
/** Custom loader component */
loader?: ComponentType<DefaultLoaderProps>;
/** Label for form submit button */
buttonText?: string;
/** Custom fields to override default fields */
customFields?: CustomField[];
/** Custom schema to override default schema */
customSchema?: z.AnyZodObject | z.ZodEffects<any>;
/**
* Optionally send root server error message and/or
* handler exceptions to toast
*/
toast?: (msg: string) => void;
/** Override the default catch error shown to user */
failMsg?: string;
/** Override or remove the default success message */
successMessage?: ComponentType<any> | string | false;
/** Disable/override initial form focus if set */
isFocused?: boolean;
/**
* Boolean to toggle component's data-theme attribute
* between light and dark mode
*/
darkMode?: boolean;
/** CSS module to target internal styles */
cssModule?: Record<string, string>;
};

ServerResponse

handler function's promise should resolve a ServerResponse.

export type ServerResponse<
TFormValues extends Record<string, any> = FormValues,
Meta extends Record<string, any> = Record<string, any>,
> = BaseServerResponse<TFormValues, Meta>;
export type BaseServerResponse<
TFormValues extends Record<string, string | string[]> = Record<string, any>,
Meta extends Record<string, any> = Record<string, any>,
> = {
/* success key informs client whether server validation passed or failed */
success: boolean;
/* errors only display if success=false */
errors?: {
/* Optional error msg to print in header
* or send to toast when server validation fails
*/
root?: string | string[];
/*
* pass any failing formValues
* as key=name of field, value=message or array of messages to print
*/
} & Partial<TFormValues>;
} & Meta;