@heymarco/next-auth
Version:
A complete authentication solution for web applications.
125 lines (124 loc) • 5.13 kB
JavaScript
'use client';
// react:
import {
// react:
default as React, } from 'react';
// reusable-ui core:
import {
// react helper hooks:
useMergeRefs, } from '@reusable-ui/core'; // a set of reusable-ui packages which are responsible for building any component
// reusable-ui components:
import { Icon, EmailInput, ListItem, List, Tooltip, } from '@reusable-ui/components'; // a set of official Reusable-UI components
// internal components:
import {
// react components:
InputWithLabel, } from './InputWithLabel.js';
// internals:
import {
// states:
useSignInState, } from './states/signInState.js';
import {
// utilities:
getValidityTheme, getValidityIcon, } from './utilities.js';
export const FieldEmail = (props) => {
// rest props:
const {
// accessibilities:
emailReadOnly = false,
// states:
isActiveSection, isActionApplied,
// components:
emailInputComponent = React.createElement(InputWithLabel, { icon: 'alternate_email', inputComponent: React.createElement(EmailInput, null) }), emailTooltipComponent = React.createElement(Tooltip, { theme: 'warning', floatingPlacement: 'top' }), emailValidationListComponent = React.createElement(List, { listStyle: 'flat' }), emailValidationListItemComponent = React.createElement(ListItem, { size: 'sm', outlined: true }), emailValidationIconComponent = React.createElement(Icon, { size: 'sm', icon: undefined }), } = props;
// states:
const {
// constraints:
emailMinLength, emailMaxLength, emailFormatHint,
// states:
isBusy,
// fields & validations:
userInteracted, emailRef, email, emailHandlers, emailFocused, emailValid, emailValidLength, emailValidFormat, emailValidAvailable, } = useSignInState();
const specificValidations = {
emailValidLength,
emailValidFormat,
emailValidAvailable,
};
// validations:
const emailValidationMap = {
Length: React.createElement(React.Fragment, null,
"Must be ",
emailMinLength,
"-",
emailMaxLength,
" characters."),
Format: emailFormatHint,
Available: React.createElement(React.Fragment, null, "Must have never been registered."),
};
// refs:
const mergedEmailInputRef = useMergeRefs(
// preserves the original `elmRef` from `emailInputComponent`:
emailInputComponent.props.elmRef, (isActiveSection ? emailRef : undefined));
// jsx:
return (React.createElement(React.Fragment, null,
React.cloneElement(emailInputComponent,
// props:
{
// refs:
elmRef: mergedEmailInputRef,
// classes:
className: emailInputComponent.props.className ?? 'email',
// accessibilities:
readOnly: emailInputComponent.props.readOnly ?? emailReadOnly,
placeholder: emailInputComponent.props.placeholder ?? 'Email',
// values:
value: emailInputComponent.props.value ?? email,
// validations:
isValid: emailInputComponent.props.isValid ?? (emailValid === true),
required: emailInputComponent.props.required ?? true,
// formats:
autoComplete: emailInputComponent.props.autoComplete ?? 'email',
// handlers:
...emailHandlers,
}),
!!emailTooltipComponent && React.cloneElement(emailTooltipComponent,
// props:
{
// states:
expanded: emailTooltipComponent.props.expanded ?? (emailFocused && userInteracted && !isBusy && isActiveSection && !isActionApplied),
// floatable:
floatingOn: emailTooltipComponent.props.floatingOn ?? emailRef,
},
// children:
/* <List> */
React.cloneElement(emailValidationListComponent,
// props:
undefined,
// children:
(emailValidationListComponent.props.children ?? Object.entries(emailValidationMap).map(([validationType, text], index) => {
// conditions:
if (!text)
return null; // disabled => ignore
// fn props:
const isValid = specificValidations?.[`emailValid${validationType}`];
if (isValid === undefined)
return null;
// jsx:
return React.cloneElement(emailValidationListItemComponent,
// props:
{
// identifiers:
key: emailValidationListItemComponent.key ?? index,
// variants:
theme: emailValidationListItemComponent.props.theme ?? getValidityTheme(isValid),
},
// children:
emailValidationListItemComponent.props.children ?? React.createElement(React.Fragment, null,
React.cloneElement(emailValidationIconComponent,
// props:
{
// appearances:
icon: emailValidationIconComponent.props.icon ?? getValidityIcon(isValid),
}),
"\u00A0",
text));
}))))));
};