feat: (SW-3655) new Input and FormInput components * First version new Input and FormInput components * Handle aria-describedby with react-aria instead of manually add it * Update breaking unit and stories tests * Merge branch 'master' into feat/SW-3655-input-component * Update example form * Merge branch 'master' into feat/SW-3655-input-component * New lock file Approved-by: Linus Flood
85 lines
2.4 KiB
TypeScript
85 lines
2.4 KiB
TypeScript
'use client'
|
|
|
|
import {
|
|
Label as AriaLabel,
|
|
Text,
|
|
TextArea as AriaTextArea,
|
|
TextField,
|
|
} from 'react-aria-components'
|
|
import { Controller, useFormContext } from 'react-hook-form'
|
|
|
|
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
|
import { InputLabel } from '../../InputLabel'
|
|
import { Typography } from '../../Typography'
|
|
|
|
import styles from './textarea.module.css'
|
|
|
|
import type { TextAreaProps } from './input'
|
|
|
|
export default function TextArea({
|
|
'aria-label': ariaLabel,
|
|
className = '',
|
|
disabled = false,
|
|
helpText = '',
|
|
label,
|
|
name,
|
|
placeholder = '',
|
|
readOnly = false,
|
|
registerOptions = {},
|
|
}: TextAreaProps) {
|
|
const { control } = useFormContext()
|
|
|
|
return (
|
|
<Controller
|
|
disabled={disabled}
|
|
control={control}
|
|
name={name}
|
|
rules={registerOptions}
|
|
render={({ field, fieldState }) => (
|
|
<TextField
|
|
aria-label={ariaLabel}
|
|
className={className}
|
|
isDisabled={field.disabled}
|
|
isRequired={!!registerOptions.required}
|
|
onBlur={field.onBlur}
|
|
onChange={field.onChange}
|
|
validationBehavior="aria"
|
|
value={field.value}
|
|
>
|
|
<AriaLabel className={styles.container}>
|
|
<Typography variant="Body/Paragraph/mdRegular">
|
|
<AriaTextArea
|
|
{...field}
|
|
aria-labelledby={field.name}
|
|
placeholder={placeholder}
|
|
readOnly={readOnly}
|
|
required={!!registerOptions.required}
|
|
className={styles.textarea}
|
|
/>
|
|
</Typography>
|
|
<InputLabel required={!!registerOptions.required}>
|
|
{label}
|
|
</InputLabel>
|
|
</AriaLabel>
|
|
{helpText && !fieldState.error ? (
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<Text className={styles.helpText} slot="description">
|
|
<MaterialIcon icon="check" size={30} />
|
|
{helpText}
|
|
</Text>
|
|
</Typography>
|
|
) : null}
|
|
{fieldState.error ? (
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<p className={styles.error}>
|
|
<MaterialIcon icon="info" color="Icon/Interactive/Accent" />
|
|
{fieldState.error.message}
|
|
</p>
|
|
</Typography>
|
|
) : null}
|
|
</TextField>
|
|
)}
|
|
/>
|
|
)
|
|
}
|