@heymarco/next-auth
Version:
A complete authentication solution for web applications.
124 lines (123 loc) • 5.3 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, TextInput, 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 FieldUsername = (props) => {
// rest props:
const {
// states:
isActiveSection, isActionApplied,
// components:
usernameInputComponent = React.createElement(InputWithLabel, { icon: 'person', inputComponent: React.createElement(TextInput, null) }), usernameTooltipComponent = React.createElement(Tooltip, { theme: 'warning', floatingPlacement: 'top' }), usernameValidationListComponent = React.createElement(List, { listStyle: 'flat' }), usernameValidationListItemComponent = React.createElement(ListItem, { size: 'sm', outlined: true }), usernameValidationIconComponent = React.createElement(Icon, { size: 'sm', icon: undefined }), } = props;
// states:
const {
// constraints:
usernameMinLength, usernameMaxLength, usernameFormatHint, usernameProhibitedHint,
// states:
isBusy,
// fields & validations:
userInteracted, usernameRef, username, usernameHandlers, usernameFocused, usernameValid, usernameValidLength, usernameValidFormat, usernameValidAvailable, usernameValidNotProhibited, } = useSignInState();
const specificValidations = {
usernameValidLength,
usernameValidFormat,
usernameValidAvailable,
usernameValidNotProhibited,
};
// validations:
const usernameValidationMap = {
Length: React.createElement(React.Fragment, null,
"Must be ",
usernameMinLength,
"-",
usernameMaxLength,
" characters."),
Format: usernameFormatHint,
Available: React.createElement(React.Fragment, null, "Must have never been registered."),
NotProhibited: usernameProhibitedHint,
};
// refs:
const mergedUsernameInputRef = useMergeRefs(
// preserves the original `elmRef` from `usernameInputComponent`:
usernameInputComponent.props.elmRef, (isActiveSection ? usernameRef : undefined));
// jsx:
return (React.createElement(React.Fragment, null,
React.cloneElement(usernameInputComponent,
// props:
{
// refs:
elmRef: mergedUsernameInputRef,
// classes:
className: usernameInputComponent.props.className ?? 'username',
// accessibilities:
placeholder: usernameInputComponent.props.placeholder ?? 'Username',
// values:
value: usernameInputComponent.props.value ?? username,
// validations:
isValid: usernameInputComponent.props.isValid ?? (usernameValid === true),
required: usernameInputComponent.props.required ?? true,
// formats:
autoComplete: usernameInputComponent.props.autoComplete ?? 'username',
// handlers:
...usernameHandlers,
}),
!!usernameTooltipComponent && React.cloneElement(usernameTooltipComponent,
// props:
{
// states:
expanded: usernameTooltipComponent.props.expanded ?? (usernameFocused && userInteracted && !isBusy && isActiveSection && !isActionApplied),
// floatable:
floatingOn: usernameTooltipComponent.props.floatingOn ?? usernameRef,
},
// children:
/* <List> */
React.cloneElement(usernameValidationListComponent,
// props:
undefined,
// children:
(usernameValidationListComponent.props.children ?? Object.entries(usernameValidationMap).map(([validationType, text], index) => {
// conditions:
if (!text)
return null; // disabled => ignore
// fn props:
const isValid = specificValidations?.[`usernameValid${validationType}`];
if (isValid === undefined)
return null;
// jsx:
return React.cloneElement(usernameValidationListItemComponent,
// props:
{
// identifiers:
key: usernameValidationListItemComponent.key ?? index,
// variants:
theme: usernameValidationListItemComponent.props.theme ?? getValidityTheme(isValid),
},
// children:
usernameValidationListItemComponent.props.children ?? React.createElement(React.Fragment, null,
React.cloneElement(usernameValidationIconComponent,
// props:
{
// appearances:
icon: usernameValidationIconComponent.props.icon ?? getValidityIcon(isValid),
}),
"\u00A0",
text));
}))))));
};