UNPKG

@heymarco/next-auth

Version:

A complete authentication solution for web applications.

127 lines (126 loc) 5.63 kB
'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, PasswordInput, 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 FieldPassword = (props) => { // rest props: const { // behaviors: isPasswordEntry = true, // states: isActiveSection, isActionApplied, // components: passwordInputComponent = React.createElement(InputWithLabel, { icon: 'lock', inputComponent: React.createElement(PasswordInput, null) }), passwordTooltipComponent = React.createElement(Tooltip, { theme: 'warning', floatingPlacement: 'top' }), passwordValidationListComponent = React.createElement(List, { listStyle: 'flat' }), passwordValidationListItemComponent = React.createElement(ListItem, { size: 'sm', outlined: true }), passwordValidationIconComponent = React.createElement(Icon, { size: 'sm', icon: undefined }), } = props; // states: const { // constraints: passwordMinLength, passwordMaxLength, passwordHasUppercase, passwordHasLowercase, passwordProhibitedHint, // states: isBusy, // fields & validations: userInteracted, passwordRef, password, passwordHandlers, passwordFocused, passwordValid, passwordValidLength, passwordValidUppercase, passwordValidLowercase, passwordValidNotProhibited, } = useSignInState(); const specificValidations = { passwordValidLength, passwordValidUppercase, passwordValidLowercase, passwordValidNotProhibited, }; // validations: const passwordValidationMap = { Length: React.createElement(React.Fragment, null, "Must be ", passwordMinLength, "-", passwordMaxLength, " characters."), Uppercase: !!passwordHasUppercase && React.createElement(React.Fragment, null, "At least one capital letter."), Lowercase: !!passwordHasLowercase && React.createElement(React.Fragment, null, "At least one non-capital letter."), // Match : <>Exact match to previous password.</>, NotProhibited: passwordProhibitedHint, }; // refs: const mergedPasswordInputRef = useMergeRefs( // preserves the original `elmRef` from `passwordInputComponent`: passwordInputComponent.props.elmRef, (isActiveSection ? passwordRef : undefined)); // jsx: return (React.createElement(React.Fragment, null, React.cloneElement(passwordInputComponent, // props: { // refs: elmRef: mergedPasswordInputRef, // classes: className: passwordInputComponent.props.className ?? 'password', // accessibilities: placeholder: passwordInputComponent.props.placeholder ?? (isPasswordEntry ? 'New Password' : 'Password'), // values: value: passwordInputComponent.props.value ?? password, // validations: isValid: passwordInputComponent.props.isValid ?? (passwordValid === true), required: passwordInputComponent.props.required ?? true, // formats: autoComplete: passwordInputComponent.props.autoComplete ?? (isPasswordEntry ? 'new-password' : 'password'), // handlers: ...passwordHandlers, }), !!passwordTooltipComponent && React.cloneElement(passwordTooltipComponent, // props: { // states: expanded: passwordTooltipComponent.props.expanded ?? (passwordFocused && userInteracted && !isBusy && isActiveSection && !isActionApplied), // floatable: floatingOn: passwordTooltipComponent.props.floatingOn ?? passwordRef, }, // children: /* <List> */ React.cloneElement(passwordValidationListComponent, // props: undefined, // children: (passwordValidationListComponent.props.children ?? Object.entries(passwordValidationMap).map(([validationType, text], index) => { // conditions: if (!text) return null; // disabled => ignore // fn props: const isValid = specificValidations?.[`passwordValid${validationType}`]; if (isValid === undefined) return null; // jsx: return React.cloneElement(passwordValidationListItemComponent, // props: { // identifiers: key: passwordValidationListItemComponent.key ?? index, // variants: theme: passwordValidationListItemComponent.props.theme ?? getValidityTheme(isValid), }, // children: passwordValidationListItemComponent.props.children ?? React.createElement(React.Fragment, null, React.cloneElement(passwordValidationIconComponent, // props: { // appearances: icon: passwordValidationIconComponent.props.icon ?? getValidityIcon(isValid), }), "\u00A0", text)); })))))); };