UNPKG

@heymarco/next-auth

Version:

A complete authentication solution for web applications.

290 lines (286 loc) 16.3 kB
'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, };