1- // biome-ignore lint/style/noNamespaceImport: prevents React undefined errors when exporting as a component library
21import * as React from 'react' ;
32import type { Control , FieldPath , FieldValues } from 'react-hook-form' ;
43import {
@@ -13,69 +12,94 @@ import {
1312import { TextInput } from './text-input' ;
1413import { cn } from './utils' ;
1514
16- export const FieldPrefix = ( { children, className } : { children : React . ReactNode ; className ?: string } ) => {
15+ export const FieldPrefix = ( {
16+ children,
17+ className,
18+ } : {
19+ children : React . ReactNode ;
20+ className ?: string ;
21+ } ) => {
1722 return (
18- < span className = { cn ( "whitespace-nowrap shadow-sm font-bold rounded-md text-base flex items-center px-2.5 pr-5 -mr-2.5 bg-gray-50 text-gray-500" , className ) } >
19- { children }
20- </ span >
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 >
2131 ) ;
2232} ;
2333
24- export const FieldSuffix = ( { children, className } : { children : React . ReactNode ; className ?: string } ) => {
34+ export const FieldSuffix = ( {
35+ children,
36+ className,
37+ } : {
38+ children : React . ReactNode ;
39+ className ?: string ;
40+ } ) => {
2541 return (
26- < span className = { cn ( "whitespace-nowrap shadow-sm font-bold rounded-md text-base flex items-center px-2.5 pl-5 -ml-2.5 bg-gray-50 text-gray-500" , className ) } >
27- { children }
28- </ span >
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 >
2950 ) ;
3051} ;
3152
32- export interface TextFieldProps <
33- TFieldValues extends FieldValues = FieldValues ,
34- TName extends FieldPath < TFieldValues > = FieldPath < TFieldValues > ,
35- > extends Omit < React . InputHTMLAttributes < HTMLInputElement > , 'name' > {
36- control ?: Control < TFieldValues > ;
37- name : TName ;
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 > ;
3857 label ?: string ;
3958 description ?: string ;
4059 components ?: Partial < FieldComponents > ;
4160 prefix ?: React . ReactNode ;
4261 suffix ?: React . ReactNode ;
43- }
62+ className ?: string ;
63+ } ;
4464
45- export const TextField = React . forwardRef < HTMLDivElement , TextFieldProps > (
65+ export const TextField = React . forwardRef < HTMLDivElement , TextInputProps > (
4666 ( { control, name, label, description, className, components, prefix, suffix, ...props } , ref ) => {
4767 return (
4868 < FormField
4969 control = { control }
5070 name = { name }
51- render = { ( { field, fieldState } ) => (
52- < FormItem className = { className } ref = { ref } >
53- { label && < FormLabel Component = { components ?. FormLabel } > { label } </ FormLabel > }
54- < FormControl Component = { components ?. FormControl } >
55- < div className = { cn ( "flex items-stretch relative" , {
56- "field__input--with-prefix" : prefix ,
57- "field__input--with-suffix" : suffix ,
58- } ) } >
59- { prefix && < FieldPrefix > { prefix } </ FieldPrefix > }
60- < TextInput
61- { ...field }
62- { ...props }
63- ref = { field . ref }
64- className = { cn ( props . className , {
65- "z-10" : prefix || suffix ,
66- "rounded-l-none" : prefix ,
67- "rounded-r-none" : suffix ,
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 ,
6881 } ) }
69- />
70- { suffix && < FieldSuffix > { suffix } </ FieldSuffix > }
71- </ div >
72- </ FormControl >
73- { description && < FormDescription Component = { components ?. FormDescription } > { description } </ FormDescription > }
74- { fieldState . error && (
75- < FormMessage Component = { components ?. FormMessage } > { fieldState . error . message } </ FormMessage >
76- ) }
77- </ FormItem >
78- ) }
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+ } }
79103 />
80104 ) ;
81105 } ,
0 commit comments