@heymarco/next-auth
Version:
A complete authentication solution for web applications.
290 lines (286 loc) • 16.3 kB
JavaScript
'use client';
// react:
import {
// react:
default as React,
// hooks:
useId, } from 'react';
// cssfn:
import {
// style sheets:
dynamicStyleSheet, } from '@cssfn/cssfn-react'; // writes css in react hook
// reusable-ui core:
import {
// react helper hooks:
useEvent, useMergeEvents, } from '@reusable-ui/core'; // a set of reusable-ui packages which are responsible for building any component
// reusable-ui components:
import {
// base-content-components:
Content, ButtonIcon, TabPanel, Tab,
// utility-components:
VisuallyHidden, } from '@reusable-ui/components'; // a set of official Reusable-UI components
// internal components:
import { TabSignUp, } from './TabSignUp.js';
import { TabSignIn, } from './TabSignIn.js';
import { TabRecover, } from './TabRecover.js';
import { TabReset, } from './TabReset.js';
import { SignInStateProvider, useSignInState, } from './states/signInState.js';
// styles:
export const useSignInStyleSheet = dynamicStyleSheet(() => import(/* webpackPrefetch: true */ './styles/styles.js'), { id: 'mhxnjino7v' }); // a unique salt for SSR support, ensures the server-side & client-side have the same generated class names
const SignIn = (props) => {
return (React.createElement(SignInStateProvider, { ...props },
React.createElement(SignInInternal, { ...props })));
};
const SignInInternal = (props) => {
// styles:
const styleSheet = useSignInStyleSheet();
// rest props:
const {
// configs:
credentialsConfigClient: _credentialsConfigClient, // remove
// auths:
authConfigClient, providers, resolveProviderName: _resolveProviderName, // remove
basePath: _basePath, // remove
// pages:
homepagePath: _homepagePath, // remove
defaultCallbackUrl: _defaultCallbackUrl, // remove
// tabs:
defaultSection: _defaultSection, section: _section, onSectionChange: _onSectionChange,
// components:
signInWithDialogComponent: _signInWithDialogComponent, // remove
bodyComponent = React.createElement(Content, { mild: true }), tabComponent = React.createElement(Tab, { headerComponent: null }, undefined), signUpTabPanelComponent = React.createElement(TabPanel, null), signInTabPanelComponent = React.createElement(TabPanel, null), recoverTabPanelComponent = React.createElement(TabPanel, null), resetTabPanelComponent = React.createElement(TabPanel, null), signUpTitleComponent, signInTitleComponent, recoverTitleComponent, resetTitleComponent, nameInputComponent, nameTooltipComponent, nameValidationListComponent, nameValidationListItemComponent, nameValidationIconComponent, emailInputComponent, emailTooltipComponent, emailValidationListComponent, emailValidationListItemComponent, emailValidationIconComponent, usernameInputComponent, usernameTooltipComponent, usernameValidationListComponent, usernameValidationListItemComponent, usernameValidationIconComponent, usernameOrEmailInputComponent, passwordInputComponent, passwordTooltipComponent, passwordValidationListComponent, passwordValidationListItemComponent, passwordValidationIconComponent, password2InputComponent, password2TooltipComponent, password2ValidationListComponent, password2ValidationListItemComponent, password2ValidationIconComponent, signUpButtonComponent, signInButtonComponent, signInWithButtonComponent, sendRecoverLinkButtonComponent, passwordResetButtonComponent, alternateSignInSeparatorComponent, tokenValidationDialogComponent, emailValidationDialogComponent, switchSignUpButtonComponent = React.createElement(ButtonIcon, { icon: 'account_box', buttonStyle: 'link', size: 'sm', iconPosition: 'end' }), switchSignInButtonComponent = React.createElement(ButtonIcon, { icon: 'login', buttonStyle: 'link', size: 'sm', iconPosition: 'end' }), gotoSignInButtonComponent = React.createElement(ButtonIcon, { icon: 'arrow_back', buttonStyle: 'link', size: 'sm' }), gotoRecoverButtonComponent = React.createElement(ButtonIcon, { icon: 'help_center', buttonStyle: 'link', size: 'sm' }), gotoHomeButtonComponent = React.createElement(ButtonIcon, { icon: 'home', buttonStyle: 'link', size: 'sm' }), ...restBasicProps } = props;
const { signUp: { enabled: signUpEnabled, }, reset: { enabled: resetEnabled, }, } = authConfigClient;
// identifiers:
const defaultId = useId();
// states:
const {
// states:
section,
// navigations:
gotoSignUp, gotoSignIn, gotoRecover, gotoHome, } = useSignInState();
// handlers:
const switchSignUpButtonHandleClickInternal = useEvent((event) => {
// conditions:
if (event.defaultPrevented)
return; // the event was already handled by user => nothing to do
event.preventDefault();
// actions:
gotoSignUp();
});
const switchSignUpButtonHandleClick = useMergeEvents(
// preserves the original `onClick` from `switchSignUpButtonComponent`:
switchSignUpButtonComponent.props.onClick,
// actions:
switchSignUpButtonHandleClickInternal);
const switchSignInButtonHandleClickInternal = useEvent((event) => {
// conditions:
if (event.defaultPrevented)
return; // the event was already handled by user => nothing to do
event.preventDefault();
// actions:
gotoSignIn();
});
const switchSignInButtonHandleClick = useMergeEvents(
// preserves the original `onClick` from `switchSignInButtonComponent`:
switchSignInButtonComponent.props.onClick,
// actions:
switchSignInButtonHandleClickInternal);
const gotoSignInButtonHandleClickInternal = useEvent((event) => {
// conditions:
if (event.defaultPrevented)
return; // the event was already handled by user => nothing to do
event.preventDefault();
// actions:
gotoSignIn();
});
const gotoSignInButtonHandleClick = useMergeEvents(
// preserves the original `onClick` from `gotoSignInButtonComponent`:
gotoSignInButtonComponent.props.onClick,
// actions:
gotoSignInButtonHandleClickInternal);
const gotoRecoverButtonHandleClickInternal = useEvent((event) => {
// conditions:
if (event.defaultPrevented)
return; // the event was already handled by user => nothing to do
event.preventDefault();
// actions:
gotoRecover();
});
const gotoRecoverButtonHandleClick = useMergeEvents(
// preserves the original `onClick` from `gotoRecoverButtonComponent`:
gotoRecoverButtonComponent.props.onClick,
// actions:
gotoRecoverButtonHandleClickInternal);
const gotoHomeButtonHandleClickInternal = useEvent((event) => {
// conditions:
if (event.defaultPrevented)
return; // the event was already handled by user => nothing to do
event.preventDefault();
// actions:
gotoHome();
});
const gotoHomeButtonHandleClick = useMergeEvents(
// preserves the original `onClick` from `gotoHomeButtonComponent`:
gotoHomeButtonComponent?.props.onClick,
// actions:
gotoHomeButtonHandleClickInternal);
// nested components:
const SwitchSignUpButton = useEvent(() => React.cloneElement(switchSignUpButtonComponent,
// props:
{
// classes:
className: switchSignUpButtonComponent.props.className ?? 'switchSignUp',
// handlers:
onClick: switchSignUpButtonHandleClick,
},
// children:
switchSignUpButtonComponent.props.children ?? React.createElement(React.Fragment, null,
"Don't have an account? ",
React.createElement("strong", null, "Sign Up"))));
const SwitchSignInButton = useEvent(() => React.cloneElement(switchSignInButtonComponent,
// props:
{
// classes:
className: switchSignInButtonComponent.props.className ?? 'switchSignIn',
// handlers:
onClick: switchSignInButtonHandleClick,
},
// children:
switchSignInButtonComponent.props.children ?? React.createElement(React.Fragment, null,
"Already have an account? ",
React.createElement("strong", null, "Sign In"))));
const GotoSignInButton = useEvent(() => React.cloneElement(gotoSignInButtonComponent,
// props:
{
// classes:
className: gotoSignInButtonComponent.props.className ?? 'gotoSignIn',
// handlers:
onClick: gotoSignInButtonHandleClick,
},
// children:
gotoSignInButtonComponent.props.children ?? 'Back to Sign In'));
const GotoRecoverButton = useEvent(() => React.cloneElement(gotoRecoverButtonComponent,
// props:
{
// classes:
className: gotoRecoverButtonComponent.props.className ?? 'gotoRecover',
// handlers:
onClick: gotoRecoverButtonHandleClick,
},
// children:
gotoRecoverButtonComponent.props.children ?? 'Forgot Password?'));
const GotoHomeButton = useEvent(() => gotoHomeButtonComponent ? React.cloneElement(gotoHomeButtonComponent,
// props:
{
// classes:
className: gotoHomeButtonComponent.props.className ?? 'gotoHome',
// handlers:
onClick: gotoHomeButtonHandleClick,
},
// children:
gotoHomeButtonComponent.props.children ?? 'Back to Home') : React.createElement(VisuallyHidden, { className: 'gotoHome visually-hidden' }));
// jsx:
/* <Tab> */
return React.cloneElement(tabComponent,
// props:
{
// identifiers:
id: tabComponent.props.id ?? defaultId,
// states:
expandedTabIndex: tabComponent.props.expandedTabIndex ?? (() => {
/*
The [signUp] tab is located *before* [signIn] tab,
so the existance *shifts* the tabIndex of [signIn] [recover] [reset] tabs.
The [recover] [reset] tabs are located *after* [signIn] tab,
so the existance doesn't change the tabIndex of [signUp] [signIn] tabs.
without signUp:
[signIn] [recover] [reset]
0 1 2
with signUp:
[signUp] [signIn] [recover] [reset]
0 1 2 3
*/
switch (section) {
case 'signUp': return 0;
case 'recover': return 1 + (+signUpEnabled);
case 'reset': return 2 + (+signUpEnabled);
case 'signIn':
default: return 0 + (+signUpEnabled);
} // switch
})(),
// components:
bodyComponent: tabComponent.props.bodyComponent ?? (
/* <Content> */
React.cloneElement(bodyComponent,
// props:
{
// other props:
...restBasicProps,
...bodyComponent.props, // overwrites restBasicProps (if any conflics)
// classes:
mainClass: bodyComponent.props.mainClass ?? props.mainClass ?? styleSheet.main
})),
},
// children:
tabComponent.props.children ?? [
(!!signUpEnabled && React.cloneElement(signUpTabPanelComponent,
// props:
{
// identifiers:
key: signUpTabPanelComponent.key ?? 'signUp',
// classes:
className: signUpTabPanelComponent.props.className ?? 'signUp',
},
// children:
React.createElement(TabSignUp
// components:
, {
// components:
signUpTitleComponent: signUpTitleComponent, nameInputComponent: nameInputComponent, nameTooltipComponent: nameTooltipComponent, nameValidationListComponent: nameValidationListComponent, nameValidationListItemComponent: nameValidationListItemComponent, nameValidationIconComponent: nameValidationIconComponent, emailInputComponent: emailInputComponent, emailTooltipComponent: emailTooltipComponent, emailValidationListComponent: emailValidationListComponent, emailValidationListItemComponent: emailValidationListItemComponent, emailValidationIconComponent: emailValidationIconComponent, usernameInputComponent: usernameInputComponent, usernameTooltipComponent: usernameTooltipComponent, usernameValidationListComponent: usernameValidationListComponent, usernameValidationListItemComponent: usernameValidationListItemComponent, usernameValidationIconComponent: usernameValidationIconComponent, passwordInputComponent: passwordInputComponent, passwordTooltipComponent: passwordTooltipComponent, passwordValidationListComponent: passwordValidationListComponent, passwordValidationListItemComponent: passwordValidationListItemComponent, passwordValidationIconComponent: passwordValidationIconComponent, password2InputComponent: password2InputComponent, password2TooltipComponent: password2TooltipComponent, password2ValidationListComponent: password2ValidationListComponent, password2ValidationListItemComponent: password2ValidationListItemComponent, password2ValidationIconComponent: password2ValidationIconComponent, signUpButtonComponent: signUpButtonComponent }), React.createElement(SwitchSignInButton, null), React.createElement(GotoHomeButton, null))),
React.cloneElement(signInTabPanelComponent,
// props:
{
// identifiers:
key: signInTabPanelComponent.key ?? 'signIn',
// classes:
className: signInTabPanelComponent.props.className ?? 'signIn',
},
// children:
React.createElement(TabSignIn
// auths:
, {
// auths:
providers: providers,
// components:
signInTitleComponent: signInTitleComponent, usernameOrEmailInputComponent: usernameOrEmailInputComponent, passwordInputComponent: passwordInputComponent, signInButtonComponent: signInButtonComponent, signInWithButtonComponent: signInWithButtonComponent, alternateSignInSeparatorComponent: alternateSignInSeparatorComponent, emailValidationDialogComponent: emailValidationDialogComponent }), (!!signUpEnabled ? React.createElement(SwitchSignUpButton, null) : React.createElement(VisuallyHidden, { className: 'switchSignUp visually-hidden' })), (!!resetEnabled ? React.createElement(GotoRecoverButton, null) : React.createElement(VisuallyHidden, { className: 'gotoRecover visually-hidden' })), React.createElement(GotoHomeButton, null)),
(!!resetEnabled && React.cloneElement(recoverTabPanelComponent,
// props:
{
// identifiers:
key: recoverTabPanelComponent.key ?? 'recover',
// classes:
className: recoverTabPanelComponent.props.className ?? 'recover',
},
// children:
React.createElement(TabRecover
// components:
, {
// components:
recoverTitleComponent: recoverTitleComponent, usernameOrEmailInputComponent: usernameOrEmailInputComponent, sendRecoverLinkButtonComponent: sendRecoverLinkButtonComponent }), React.createElement(GotoSignInButton, null))),
(!!resetEnabled && React.cloneElement(resetTabPanelComponent,
// props:
{
// identifiers:
key: resetTabPanelComponent.key ?? 'reset',
// classes:
className: resetTabPanelComponent.props.className ?? 'reset',
},
// children:
React.createElement(TabReset
// components:
, {
// components:
resetTitleComponent: resetTitleComponent, emailInputComponent: emailInputComponent, passwordInputComponent: passwordInputComponent, passwordTooltipComponent: passwordTooltipComponent, passwordValidationListComponent: passwordValidationListComponent, passwordValidationListItemComponent: passwordValidationListItemComponent, passwordValidationIconComponent: passwordValidationIconComponent, password2InputComponent: password2InputComponent, password2TooltipComponent: password2TooltipComponent, password2ValidationListComponent: password2ValidationListComponent, password2ValidationListItemComponent: password2ValidationListItemComponent, password2ValidationIconComponent: password2ValidationIconComponent, passwordResetButtonComponent: passwordResetButtonComponent, tokenValidationDialogComponent: tokenValidationDialogComponent }), React.createElement(GotoSignInButton, null))),
]);
};
export { SignIn, SignIn as default, };