@@ -10,42 +10,96 @@ import {
1010 FormMessage ,
1111} from './form' ;
1212import { TextInput } from './text-input' ;
13+ import { cn } from './utils' ;
1314
14- export interface TextFieldComponents extends FieldComponents {
15- Input ?: React . ComponentType < React . InputHTMLAttributes < HTMLInputElement > > ;
16- }
15+ export const FieldPrefix = ( {
16+ children,
17+ className,
18+ } : {
19+ children : React . ReactNode ;
20+ className ?: string ;
21+ } ) => {
22+ return (
23+ < div
24+ className = { cn (
25+ 'flex h-full text-base items-center pl-3 pr-0 text-gray-500 group-focus-within:text-gray-700 transition-colors duration-200 border-y border-l border-input rounded-l-md bg-background' ,
26+ className ,
27+ ) }
28+ >
29+ < span className = "whitespace-nowrap" > { children } </ span >
30+ </ div >
31+ ) ;
32+ } ;
1733
18- export interface TextFieldProps <
19- TFieldValues extends FieldValues = FieldValues ,
20- TName extends FieldPath < TFieldValues > = FieldPath < TFieldValues > ,
21- > extends Omit < React . InputHTMLAttributes < HTMLInputElement > , 'name' > {
22- control ?: Control < TFieldValues > ;
23- name : TName ;
34+ export const FieldSuffix = ( {
35+ children,
36+ className,
37+ } : {
38+ children : React . ReactNode ;
39+ className ?: string ;
40+ } ) => {
41+ return (
42+ < div
43+ className = { cn (
44+ 'flex h-full text-base items-center pr-3 pl-0 text-gray-500 group-focus-within:text-gray-700 transition-colors duration-200 border-y border-r border-input rounded-r-md bg-background' ,
45+ className ,
46+ ) }
47+ >
48+ < span className = "whitespace-nowrap" > { children } </ span >
49+ </ div >
50+ ) ;
51+ } ;
52+
53+ // Create a specific interface for the input props that includes className explicitly
54+ type TextInputProps = React . ComponentPropsWithRef < typeof TextInput > & {
55+ control ?: Control < FieldValues > ;
56+ name : FieldPath < FieldValues > ;
2457 label ?: string ;
2558 description ?: string ;
26- components ?: Partial < TextFieldComponents > ;
27- }
28-
29- export const TextField = React . forwardRef < HTMLDivElement , TextFieldProps > (
30- ( { control, name, label, description, className, components, ...props } , ref ) => {
31- const InputComponent = components ?. Input || TextInput ;
59+ components ?: Partial < FieldComponents > ;
60+ prefix ?: React . ReactNode ;
61+ suffix ?: React . ReactNode ;
62+ className ?: string ;
63+ } ;
3264
65+ export const TextField = React . forwardRef < HTMLDivElement , TextInputProps > (
66+ ( { control, name, label, description, className, components, prefix, suffix, ...props } , ref ) => {
3367 return (
3468 < FormField
3569 control = { control }
3670 name = { name }
37- render = { ( { field, fieldState } ) => (
38- < FormItem className = { className } ref = { ref } >
39- { label && < FormLabel Component = { components ?. FormLabel } > { label } </ FormLabel > }
40- < FormControl Component = { components ?. FormControl } >
41- < InputComponent { ...field } { ...props } ref = { field . ref } />
42- </ FormControl >
43- { description && < FormDescription Component = { components ?. FormDescription } > { description } </ FormDescription > }
44- { fieldState . error && (
45- < FormMessage Component = { components ?. FormMessage } > { fieldState . error . message } </ FormMessage >
46- ) }
47- </ FormItem >
48- ) }
71+ render = { ( { field, fieldState } ) => {
72+ return (
73+ < FormItem className = { className } ref = { ref } >
74+ { label && < FormLabel Component = { components ?. FormLabel } > { label } </ FormLabel > }
75+ < FormControl Component = { components ?. FormControl } >
76+ < div
77+ className = { cn ( 'flex group transition-all duration-200 rounded-md' , {
78+ 'field__input--with-prefix' : prefix ,
79+ 'field__input--with-suffix' : suffix ,
80+ 'focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background' : true ,
81+ } ) }
82+ >
83+ { prefix && < FieldPrefix > { prefix } </ FieldPrefix > }
84+ < TextInput
85+ { ...field }
86+ { ...props }
87+ ref = { field . ref }
88+ className = { cn ( 'focus-visible:ring-0 focus-visible:ring-offset-0' , {
89+ 'rounded-l-none border-l-0' : prefix ,
90+ 'rounded-r-none border-r-0' : suffix ,
91+ } ) }
92+ />
93+ { suffix && < FieldSuffix > { suffix } </ FieldSuffix > }
94+ </ div >
95+ </ FormControl >
96+ { description && < FormDescription Component = { components ?. FormDescription } > { description } </ FormDescription > }
97+ { fieldState . error && (
98+ < FormMessage Component = { components ?. FormMessage } > { fieldState . error . message } </ FormMessage >
99+ ) }
100+ </ FormItem >
101+ ) ;
102+ } }
49103 />
50104 ) ;
51105 } ,
0 commit comments