import React from 'react';
import {
Input as AriaInput,
Label as AriaLabel,
Text as AriaText,
TextField as AriaTextField,
type TextFieldProps as AriaTextFieldProps
} from 'react-aria-components';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from 'stride-ds';
// Define variants with CVA
const inputVariants = cva(
'w-full px-3 border rounded-full',
{
variants: {
size: {
sm: 'h-8 text-xs px-3',
md: 'h-10 text-sm px-3',
lg: 'h-12 text-md px-4'
},
variant: {
default: 'border-gray-300',
error: 'border-red-500',
success: 'border-green-500'
}
},
defaultVariants: {
size: 'md',
variant: 'default'
}
}
);
// Define component props
export interface InputProps
extends Omit<AriaTextFieldProps, 'children'>,
VariantProps<typeof inputVariants> {
label?: string;
placeholder?: string;
helperText?: string;
errorMessage?: string;
className?: string;
inputClassName?: string;
leftIcon?: React.ReactNode;
rightIcon?: React.ReactNode;
}
// Component with forwardRef
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
(
{
className,
inputClassName,
size,
variant,
label,
placeholder,
helperText,
errorMessage,
leftIcon,
rightIcon,
isRequired,
isDisabled,
...props
},
ref
) => {
const computedVariant = errorMessage ? 'error' : variant;
const displayHelperText = errorMessage || helperText;
return (
<AriaTextField
className={cn('w-full', className)}
isRequired={isRequired}
isDisabled={isDisabled}
{...props}
>
{label && (
<AriaLabel>
{label}
{isRequired && <span className="text-red-500 ml-1">*</span>}
</AriaLabel>
)}
<div className="relative">
{leftIcon && (
<div className="absolute left-3 top-1/2 -translate-y-1/2">
{leftIcon}
</div>
)}
<AriaInput
ref={ref}
className={cn(
inputVariants({ size, variant: computedVariant }),
leftIcon && 'pl-10',
rightIcon && 'pr-10',
inputClassName
)}
placeholder={placeholder}
/>
{rightIcon && (
<div className="absolute right-3 top-1/2 -translate-y-1/2">
{rightIcon}
</div>
)}
</div>
{displayHelperText && (
<AriaText slot={errorMessage ? 'errorMessage' : 'description'}>
{displayHelperText}
</AriaText>
)}
</AriaTextField>
);
}
);
Input.displayName = 'Input';