feat(SW-3672): Update PasswordInput component * Update PasswordInput component * Removed some tests not working as expected * Remove IconButton from PasswordInput * Remove IconButton from Input * Merge branch 'master' into feat/new-passwordinput-component Approved-by: Linus Flood
127 lines
3.1 KiB
TypeScript
127 lines
3.1 KiB
TypeScript
import { useIntl } from 'react-intl'
|
|
|
|
import { passwordValidators } from '@scandic-hotels/common/utils/zod/passwordValidator'
|
|
import type { PasswordValidatorKey } from '@scandic-hotels/common/utils/zod/newPassword'
|
|
import { MaterialIcon } from '../Icons/MaterialIcon'
|
|
import { Typography } from '../Typography'
|
|
|
|
import styles from './passwordInput.module.css'
|
|
|
|
export function NewPasswordValidation({
|
|
value,
|
|
errors,
|
|
id,
|
|
}: {
|
|
value: string
|
|
errors: string[]
|
|
id: string
|
|
}) {
|
|
const intl = useIntl()
|
|
|
|
if (!value) return null
|
|
|
|
function getErrorMessage(key: PasswordValidatorKey) {
|
|
switch (key) {
|
|
case 'length':
|
|
return intl.formatMessage(
|
|
{
|
|
id: 'passwordInput.lengthRequirement',
|
|
defaultMessage: '{min} to {max} characters',
|
|
},
|
|
{
|
|
min: 10,
|
|
max: 40,
|
|
}
|
|
)
|
|
case 'hasUppercase':
|
|
return intl.formatMessage(
|
|
{
|
|
id: 'passwordInput.uppercaseRequirement',
|
|
defaultMessage: '{count} uppercase letter',
|
|
},
|
|
{ count: 1 }
|
|
)
|
|
case 'hasLowercase':
|
|
return intl.formatMessage(
|
|
{
|
|
id: 'passwordInput.lowercaseRequirement',
|
|
defaultMessage: '{count} lowercase letter',
|
|
},
|
|
{ count: 1 }
|
|
)
|
|
case 'hasNumber':
|
|
return intl.formatMessage(
|
|
{
|
|
id: 'passwordInput.numberRequirement',
|
|
defaultMessage: '{count} number',
|
|
},
|
|
{ count: 1 }
|
|
)
|
|
case 'hasSpecialChar':
|
|
return intl.formatMessage(
|
|
{
|
|
id: 'passwordInput.specialCharacterRequirement',
|
|
defaultMessage: '{count} special character',
|
|
},
|
|
{ count: 1 }
|
|
)
|
|
case 'allowedCharacters':
|
|
return intl.formatMessage({
|
|
id: 'passwordInput.allowedCharactersRequirement',
|
|
defaultMessage: 'Only allowed characters',
|
|
})
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={styles.errors}
|
|
role="status"
|
|
aria-live="polite"
|
|
aria-atomic="false"
|
|
id={id}
|
|
>
|
|
{Object.entries(passwordValidators).map(([key, { message }]) => (
|
|
<Typography variant="Label/xsRegular" key={key}>
|
|
<span className={styles.helpText}>
|
|
<Icon errorMessage={message} errors={errors} />
|
|
{getErrorMessage(key as PasswordValidatorKey)}
|
|
</span>
|
|
</Typography>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
interface IconProps {
|
|
errorMessage: string
|
|
errors: string[]
|
|
}
|
|
|
|
function Icon({ errorMessage, errors }: IconProps) {
|
|
const intl = useIntl()
|
|
return errors.includes(errorMessage) ? (
|
|
<MaterialIcon
|
|
icon="close"
|
|
color="Icon/Feedback/Error"
|
|
size={20}
|
|
role="img"
|
|
aria-label={intl.formatMessage({
|
|
id: 'common.error',
|
|
defaultMessage: 'Error',
|
|
})}
|
|
/>
|
|
) : (
|
|
<MaterialIcon
|
|
icon="check"
|
|
color="Icon/Feedback/Success"
|
|
size={20}
|
|
role="img"
|
|
aria-label={intl.formatMessage({
|
|
id: 'common.success',
|
|
defaultMessage: 'Success',
|
|
})}
|
|
/>
|
|
)
|
|
}
|