diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignIn/SignIn.tsx b/packages/react/src/oxygen-ui-react-auth-components/SignIn/SignIn.tsx index 726e995a..c79aa6db 100644 --- a/packages/react/src/oxygen-ui-react-auth-components/SignIn/SignIn.tsx +++ b/packages/react/src/oxygen-ui-react-auth-components/SignIn/SignIn.tsx @@ -18,26 +18,68 @@ import {Box, BoxProps} from '@oxygen-ui/react'; import clsx from 'clsx'; -import {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, forwardRef} from 'react'; +import { + ElementType, + ForwardRefExoticComponent, + MutableRefObject, + ReactElement, + forwardRef, + isValidElement, +} from 'react'; import {WithWrapperProps} from '../models/component'; import SignInAlert from '../SignInAlert/SignInAlert'; -import SignInButton from '../SignInButton/SignInButton'; +import SignInButton, {SignInButtonProps} from '../SignInButton/SignInButton'; import SignInDivider from '../SignInDivider/SignInDivider'; -import SignInLink from '../SignInLink/SignInLink'; +import SignInFooter from '../SignInFooter/SignInFooter'; +import SignInImage from '../SignInImage/SignInImage'; +import SignInLink, {SignInLinkProps} from '../SignInLink/SignInLink'; import SignInPaper from '../SignInPaper/SignInPaper'; -import SignInTextField from '../SignInTextField/SignInTextField'; -import SignInTypography from '../SignInTypography/SignInTypography'; +import SignInPinInput from '../SignInPinInput/SignInPinInput'; +import SignInTextField, {SignInTextFieldProps} from '../SignInTextField/SignInTextField'; +import SignInTypography, {SignInTypographyProps} from '../SignInTypography/SignInTypography'; +import './sign-in.scss'; + +type Footer = + | ReactElement + | { + copyrights?: { + link?: string; + text: string; + }; + locale?: { + text: string; + }; + privacyPolicy?: { + link?: string; + text: string; + }; + termsOfUse?: { + link?: string; + text: string; + }; + }; export type SignInProps = { component?: C; + footer?: Footer; + links?: SignInLinkProps[]; + loginOptions?: SignInButtonProps[]; + logo?: string; + submitButton?: {text: string} & SignInButtonProps; + subtitle?: {text: string} & SignInTypographyProps; + textFields?: SignInTextFieldProps[]; + title?: {text: string} & SignInTypographyProps; } & Omit; type SignInCompoundProps = { Alert: typeof SignInAlert; Button: typeof SignInButton; Divider: typeof SignInDivider; + Footer: typeof SignInFooter; + Image: typeof SignInImage; Link: typeof SignInLink; Paper: typeof SignInPaper; + PinInput: typeof SignInPinInput; TextField: typeof SignInTextField; Typography: typeof SignInTypography; }; @@ -46,11 +88,117 @@ const COMPONENT_NAME: string = 'SignIn'; const SignIn: ForwardRefExoticComponent & WithWrapperProps & SignInCompoundProps = forwardRef( (props: SignInProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; + const { + className, + title, + subtitle, + textFields = [ + { + label: 'username', + name: 'text', + placeholder: 'Enter your username', + }, + { + label: 'Password', + name: 'password', + placeholder: 'Enter your password', + type: 'password', + }, + ], + links, + loginOptions, + logo, + submitButton, + footer, + ...rest + } = props; const classes: string = clsx(`Oxygen${COMPONENT_NAME}`, className); - return ; + /** + * Destructure the title and subtitle props to extract the title and subtitle as both cannot be passed. + */ + const { + children: titleChildren, + text: titleText, + title: titleTitle, + subtitle: titleSubtitle, + ...restTitleProps + } = title ?? {}; + + const { + children: subtitleChildren, + text: subtitleText, + title: subtitleTitle, + subtitle: subtitleSubtitle, + ...restSubtitleProps + } = subtitle ?? {}; + + const {children: submitButtonChildren, text: submitButtonText, ...restSubmitButtonTextProps} = submitButton ?? {}; + + /** + * If SignIn component contains any children render only the outer box. + * Otherwise render the default SignIn component. + */ + if (props?.['children']) { + return ; + } + + return ( + + {logo && } + + + + {titleChildren ?? titleText ?? 'Sign In'} + + + {subtitle && ( + + {subtitleChildren ?? subtitleText} + + )} + + {textFields.map((textFieldProps: SignInTextFieldProps, index: number) => ( + + ))} + + + {submitButtonChildren ?? submitButtonText ?? 'Sign In'} + + + {links && + links.map((linkProps: SignInLinkProps, index: number) => ( +
+ +
+
+ ))} + + {loginOptions && ( + <> + OR + {loginOptions.map((loginOptionProps: SignInButtonProps, index: number) => ( + + ))} + + )} +
+ + {footer && isValidElement(footer) ? ( + footer + ) : ( + {footer?.copyrights?.text}}} + items={[ + {children: {footer?.termsOfUse?.text}}, + {children: {footer?.privacyPolicy?.text}}, + {children: {footer?.locale?.text}}, + ]} + /> + )} +
+ ); }, ) as ForwardRefExoticComponent & WithWrapperProps & SignInCompoundProps; @@ -64,5 +212,8 @@ SignIn.Divider = SignInDivider; SignIn.Link = SignInLink; SignIn.Button = SignInButton; SignIn.TextField = SignInTextField; +SignIn.PinInput = SignInPinInput; +SignIn.Image = SignInImage; +SignIn.Footer = SignInFooter; export default SignIn; diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignIn/sign-in.scss b/packages/react/src/oxygen-ui-react-auth-components/SignIn/sign-in.scss new file mode 100644 index 00000000..0db727a4 --- /dev/null +++ b/packages/react/src/oxygen-ui-react-auth-components/SignIn/sign-in.scss @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +.OxygenSignIn { + display: flex; + flex-flow: column nowrap; + align-content: center; + justify-content: center; + align-items: center; + text-align: left; + padding: 20px; +} diff --git a/packages/react/src/oxygen-ui-react-auth-components/SignInButton/SignInButton.tsx b/packages/react/src/oxygen-ui-react-auth-components/SignInButton/SignInButton.tsx index acfe8b4a..51a8fb98 100644 --- a/packages/react/src/oxygen-ui-react-auth-components/SignInButton/SignInButton.tsx +++ b/packages/react/src/oxygen-ui-react-auth-components/SignInButton/SignInButton.tsx @@ -35,7 +35,7 @@ const SignInButton: ForwardRefExoticComponent & WithWrapperPr let classes: string = clsx(`Oxygen${COMPONENT_NAME}`, className); if (social) { - classes = clsx(classes, `Oxygen${COMPONENT_NAME}Social`); + classes = clsx(classes, `Oxygen${COMPONENT_NAME}-social`); } return