Files
web/packages/design-system/lib/components/PasswordInput/NewPasswordValidation.tsx
Rasmus Langvad d0546926a9 Merged in fix/3697-prettier-configs (pull request #3396)
fix(SW-3691): Setup one prettier config for whole repo

* Setup prettierrc in root and remove other configs


Approved-by: Joakim Jäderberg
Approved-by: Linus Flood
2026-01-07 12:45:50 +00:00

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",
})}
/>
)
}