Merged in feat/use-new-input-component (pull request #3324)

feat(SW-3659): Use new input component

* Use new input component

* Update error formatter

* Merged master into feat/use-new-input-component

* Merged master into feat/use-new-input-component

* Merge branch 'master' into feat/use-new-input-component

* Merged master into feat/use-new-input-component

* Update Input stories

* Merge branch 'feat/use-new-input-component' of bitbucket.org:scandic-swap/web into feat/use-new-input-component

* Update Storybook logo

* Add some new demo icon input story

* Fix the clear content button position

* Fix broken password input icon

* Merged master into feat/use-new-input-component

* Merged master into feat/use-new-input-component

* Add aria-hidden to required asterisk

* Merge branch 'feat/use-new-input-component' of bitbucket.org:scandic-swap/web into feat/use-new-input-component

* Merge branch 'master' into feat/use-new-input-component


Approved-by: Bianca Widstam
Approved-by: Matilda Landström
This commit is contained in:
Rasmus Langvad
2025-12-18 15:42:09 +00:00
parent 40e1efa81f
commit b9a62b5280
34 changed files with 520 additions and 1113 deletions

View File

@@ -1,27 +1,14 @@
"use client"
// This is almost a copy of the Input in TempDesignSystem, but since it's tightly coupled
// to the error messages we need to duplicate it for now. In the future we should
// rewrite it to be more reusable.
import { forwardRef, useMemo } from "react"
import { forwardRef } from "react"
import { Text, TextField } from "react-aria-components"
import {
Controller,
type RegisterOptions,
useFormContext,
} from "react-hook-form"
import { useIntl } from "react-intl"
import Caption from "@scandic-hotels/design-system/Caption"
import { ErrorMessage } from "@scandic-hotels/design-system/Form/ErrorMessage"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Input as InputWithLabel } from "@scandic-hotels/design-system/Input"
import { FormInput } from "@scandic-hotels/design-system/Form/FormInput"
import { useBookingFlowConfig } from "../../bookingFlowConfig/bookingFlowConfigContext"
import { getErrorMessage } from "./errors"
import styles from "./input.module.css"
import type { RegisterOptions } from "react-hook-form"
import type { IntlShape } from "react-intl"
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
helpText?: string
@@ -34,7 +21,6 @@ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
const BookingFlowInput = forwardRef<HTMLInputElement, InputProps>(
function Input(
{
"aria-label": ariaLabel,
autoComplete,
className = "",
disabled = false,
@@ -48,67 +34,38 @@ const BookingFlowInput = forwardRef<HTMLInputElement, InputProps>(
type = "text",
hideError,
inputMode,
...props
},
ref
) {
const intl = useIntl()
const { control, formState } = useFormContext()
const config = useBookingFlowConfig()
// Create error formatter wrapper that uses getErrorMessage with the variant
const errorFormatter = useMemo(
() => (intl: IntlShape, errorMessage?: string) =>
getErrorMessage(intl, config.variant, errorMessage) ?? "",
[config.variant]
)
return (
<Controller
<FormInput
{...props}
ref={ref}
autoComplete={autoComplete}
className={className}
description={helpText}
descriptionIcon="check"
disabled={disabled}
control={control}
errorFormatter={errorFormatter}
hideError={hideError}
inputMode={inputMode}
label={label}
maxLength={maxLength}
name={name}
rules={registerOptions}
render={({ field, fieldState }) => (
<TextField
aria-label={ariaLabel}
className={className}
isDisabled={field.disabled}
isInvalid={fieldState.invalid}
isRequired={!!registerOptions.required}
name={field.name}
onBlur={field.onBlur}
onChange={field.onChange}
validationBehavior="aria"
value={field.value}
>
<InputWithLabel
{...field}
ref={ref}
aria-labelledby={field.name}
autoComplete={autoComplete}
id={field.name}
label={label}
maxLength={maxLength}
placeholder={placeholder}
readOnly={readOnly}
required={!!registerOptions.required}
type={type}
inputMode={inputMode}
/>
{helpText && !fieldState.error ? (
<Caption asChild color="black">
<Text className={styles.helpText} slot="description">
<MaterialIcon icon="check" size={20} />
{helpText}
</Text>
</Caption>
) : null}
{fieldState.error && !hideError ? (
<ErrorMessage
errors={formState.errors}
name={name}
messageLabel={getErrorMessage(
intl,
config.variant,
fieldState.error.message
)}
/>
) : null}
</TextField>
)}
placeholder={placeholder}
readOnly={readOnly}
registerOptions={registerOptions}
type={type}
/>
)
}