diff --git a/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/NewPasswordValidation.tsx b/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/NewPasswordValidation.tsx
new file mode 100644
index 000000000..781cd59cf
--- /dev/null
+++ b/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/NewPasswordValidation.tsx
@@ -0,0 +1,119 @@
+import { useIntl } from "react-intl"
+
+import { passwordValidators } from "@scandic-hotels/common/utils/zod/passwordValidator"
+import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
+import { Typography } from "@scandic-hotels/design-system/Typography"
+
+import styles from "./passwordInput.module.css"
+
+import type { PasswordValidatorKey } from "@/types/components/form/newPassword"
+
+export function NewPasswordValidation({
+ value,
+ errors,
+}: {
+ value: string
+ errors: 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 (
+
+ {Object.entries(passwordValidators).map(([key, { message }]) => (
+
+
+
+ {getErrorMessage(key as PasswordValidatorKey)}
+
+
+ ))}
+
+ )
+}
+
+interface IconProps {
+ errorMessage: string
+ errors: string[]
+}
+
+function Icon({ errorMessage, errors }: IconProps) {
+ const intl = useIntl()
+ return errors.includes(errorMessage) ? (
+
+ ) : (
+
+ )
+}
diff --git a/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/index.tsx b/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/index.tsx
index 5c8453d1c..9e442e910 100644
--- a/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/index.tsx
+++ b/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/index.tsx
@@ -1,22 +1,32 @@
"use client"
import { useState } from "react"
-import { Text, TextField } from "react-aria-components"
-import { Controller, useFormContext } from "react-hook-form"
+import { TextField } from "react-aria-components"
+import {
+ Controller,
+ type RegisterOptions,
+ useFormContext,
+} from "react-hook-form"
import { useIntl } from "react-intl"
-import { passwordValidators } from "@scandic-hotels/common/utils/zod/passwordValidator"
-import Caption from "@scandic-hotels/design-system/Caption"
+import { IconButton } from "@scandic-hotels/design-system/IconButton"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Input } from "@scandic-hotels/design-system/Input"
-import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
+import { Typography } from "@scandic-hotels/design-system/Typography"
import { getErrorMessage } from "@/utils/getErrorMessage"
+import { NewPasswordValidation } from "./NewPasswordValidation"
+
import styles from "./passwordInput.module.css"
-import type { PasswordValidatorKey } from "@/types/components/form/newPassword"
-import type { IconProps, PasswordInputProps } from "./passwordInput"
+interface PasswordInputProps
+ extends React.InputHTMLAttributes {
+ label?: string
+ registerOptions?: RegisterOptions
+ visibilityToggleable?: boolean
+ isNewPassword?: boolean
+}
export default function PasswordInput({
name = "password",
@@ -48,6 +58,8 @@ export default function PasswordInput({
{visibilityToggleable ? (
-
+
+
) : null}
@@ -120,16 +128,10 @@ export default function PasswordInput({
{isNewPassword ? (
!field.value && fieldState.error ? (
-
-
- {getErrorMessage(intl, fieldState.error.message)}
-
+
) : null
) : fieldState.error ? (
-
-
- {getErrorMessage(intl, fieldState.error.message)}
-
+
) : null}
)
@@ -138,88 +140,24 @@ export default function PasswordInput({
)
}
-function Icon({ errorMessage, errors }: IconProps) {
- return errors.includes(errorMessage) ? (
-
- ) : (
-
- )
-}
-
-function NewPasswordValidation({
- value,
- errors,
-}: {
- value: string
- errors: string[]
-}) {
+function ErrorMessage({ errorMessage }: { errorMessage?: 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 (
-
- {Object.entries(passwordValidators).map(([key, { message }]) => (
-
-
-
- {getErrorMessage(key as PasswordValidatorKey)}
-
-
- ))}
-
+
+
+
+ {getErrorMessage(intl, errorMessage)}
+
+
)
}
diff --git a/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/passwordInput.ts b/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/passwordInput.ts
deleted file mode 100644
index 21c08a51e..000000000
--- a/apps/scandic-web/components/TempDesignSystem/Form/PasswordInput/passwordInput.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import type { RegisterOptions } from "react-hook-form"
-
-export interface PasswordInputProps
- extends React.InputHTMLAttributes {
- label?: string
- registerOptions?: RegisterOptions
- visibilityToggleable?: boolean
- isNewPassword?: boolean
-}
-
-export interface IconProps {
- errorMessage: string
- errors: string[]
-}
diff --git a/packages/design-system/lib/components/Icons/MaterialIcon/MaterialIcon.tsx b/packages/design-system/lib/components/Icons/MaterialIcon/MaterialIcon.tsx
index e9ad0465c..c4570f263 100644
--- a/packages/design-system/lib/components/Icons/MaterialIcon/MaterialIcon.tsx
+++ b/packages/design-system/lib/components/Icons/MaterialIcon/MaterialIcon.tsx
@@ -3,9 +3,11 @@ import { MaterialSymbol, type MaterialSymbolProps } from './MaterialSymbol'
import { iconVariants } from '../variants'
import type { VariantProps } from 'class-variance-authority'
+import { HTMLAttributes } from 'react'
export interface MaterialIconProps
extends Pick,
+ Omit, 'color' | 'id'>,
VariantProps {
isFilled?: boolean
}
@@ -18,6 +20,12 @@ export function MaterialIcon({
...props
}: MaterialIconProps) {
const classNames = iconVariants({ className, color })
+ const { role, 'aria-label': ariaLabel, 'aria-hidden': ariaHidden } = props
+
+ // Automatically decide whether to hide from assistive tech
+ const computedAriaHidden =
+ ariaHidden !== undefined ? ariaHidden : ariaLabel || role ? false : true
+
return (
// The span is used to prevent the MaterialSymbol from being underlined when used inside a link or button
@@ -25,8 +33,9 @@ export function MaterialIcon({
className={classNames}
data-testid="MaterialIcon"
size={size}
- {...props}
fill={isFilled}
+ aria-hidden={computedAriaHidden}
+ {...props}
/>
)