96 lines
2.7 KiB
TypeScript
96 lines
2.7 KiB
TypeScript
"use client"
|
|
|
|
import { forwardRef, type HTMLAttributes, type WheelEvent } from "react"
|
|
import { Text, TextField } from "react-aria-components"
|
|
import { Controller, useFormContext } from "react-hook-form"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
|
|
import AriaInputWithLabel from "@/components/TempDesignSystem/Form/Input/AriaInputWithLabel"
|
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
|
|
import { getErrorMessage } from "./errors"
|
|
|
|
import styles from "./input.module.css"
|
|
|
|
import type { InputProps } from "./input"
|
|
|
|
const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
|
{
|
|
"aria-label": ariaLabel,
|
|
className = "",
|
|
disabled = false,
|
|
helpText = "",
|
|
label,
|
|
maxLength,
|
|
name,
|
|
placeholder = "",
|
|
readOnly = false,
|
|
registerOptions = {},
|
|
type = "text",
|
|
hideError,
|
|
},
|
|
ref
|
|
) {
|
|
const intl = useIntl()
|
|
const { control } = useFormContext()
|
|
let numberAttributes: HTMLAttributes<HTMLInputElement> = {}
|
|
if (type === "number") {
|
|
numberAttributes.onWheel = function (evt: WheelEvent<HTMLInputElement>) {
|
|
evt.currentTarget.blur()
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Controller
|
|
disabled={disabled}
|
|
control={control}
|
|
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}
|
|
>
|
|
<AriaInputWithLabel
|
|
{...field}
|
|
ref={ref}
|
|
aria-labelledby={field.name}
|
|
id={field.name}
|
|
label={label}
|
|
maxLength={maxLength}
|
|
placeholder={placeholder}
|
|
readOnly={readOnly}
|
|
required={!!registerOptions.required}
|
|
type={type}
|
|
/>
|
|
{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 ? (
|
|
<Caption className={styles.error} fontOnly>
|
|
<MaterialIcon icon="info" color="Icon/Interactive/Accent" />
|
|
{getErrorMessage(intl, fieldState.error.message)}
|
|
</Caption>
|
|
) : null}
|
|
</TextField>
|
|
)}
|
|
/>
|
|
)
|
|
})
|
|
export default Input
|