-
Notifications
You must be signed in to change notification settings - Fork 0
Enhance TextField component with ref support and update stories #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,14 +57,14 @@ export interface TextInputProps extends Omit<InputProps, 'prefix' | 'suffix'> { | |
| label?: string; | ||
| description?: string; | ||
| components?: Partial<FieldComponents> & { | ||
| Input?: React.ComponentType<InputProps>; | ||
| Input?: React.ComponentType<InputProps & React.RefAttributes<HTMLInputElement>>; | ||
| }; | ||
| prefix?: React.ReactNode; | ||
| suffix?: React.ReactNode; | ||
| className?: string; | ||
| } | ||
|
|
||
| export const TextField = ({ | ||
| export const TextField = function TextField({ | ||
| control, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly! Let's apply the React 19 ref-as-prop pattern here as well. This will be much cleaner: export interface TextInputProps extends Omit<InputProps, 'prefix' | 'suffix'> {
control: Control<any>;
name: string;
label?: string;
description?: string;
components?: Partial<FieldComponents> & {
Input?: React.ComponentType<InputProps & { ref?: React.Ref<HTMLInputElement> }>;
};
prefix?: React.ReactNode;
suffix?: React.ReactNode;
className?: string;
ref?: React.Ref<HTMLInputElement>;
}
export const TextField = function TextField({
control,
name,
label,
description,
className,
components,
prefix,
suffix,
ref,
...props
}: TextInputProps) {
// ... rest of implementation
return (
<Controller
control={control}
name={name}
render={({ field, fieldState }) => (
// ... existing JSX with ref passed to InputComponent
<InputComponent
{...field}
{...props}
ref={ref}
// ... rest of props
/>
)}
/>
);
};This eliminates the need for |
||
| name, | ||
| label, | ||
|
|
@@ -73,8 +73,9 @@ export const TextField = ({ | |
| components, | ||
| prefix, | ||
| suffix, | ||
| ref, | ||
| ...props | ||
| }: TextInputProps) => { | ||
| }: TextInputProps & { ref?: React.Ref<HTMLInputElement> }) { | ||
| // Use the custom Input component if provided, otherwise use the default TextInput | ||
| const InputComponent = components?.Input || TextInput; | ||
|
|
||
|
|
@@ -98,6 +99,7 @@ export const TextField = ({ | |
| <InputComponent | ||
| {...field} | ||
| {...props} | ||
| ref={ref} | ||
| className={cn('focus-visible:ring-0 focus-visible:ring-offset-0 border-input', { | ||
| 'rounded-l-none border-l-0': prefix, | ||
| 'rounded-r-none border-r-0': suffix, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,14 @@ | ||
| import type * as React from 'react'; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're absolutely right! This should remain as a import type * as React from 'react'; |
||
| import { cn } from './utils'; | ||
|
|
||
| export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {} | ||
| export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> { | ||
| ref?: React.Ref<HTMLInputElement>; | ||
| } | ||
|
|
||
| function TextInput({ className, type, ...props }: InputProps) { | ||
| function TextInput({ className, type, ref, ...props }: InputProps) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perfect suggestion! With React 19, we can eliminate export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
ref?: React.Ref<HTMLInputElement>;
}
function TextInput({ className, type, ref, ...props }: InputProps) {
return (
<input
ref={ref}
type={type}
className={cn(
'flex h-10 w-full text-base sm:text-sm rounded-md border border-input bg-background px-3 py-2 ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...props}
/>
);
}This is much cleaner and leverages React 19's native ref prop support! |
||
| return ( | ||
| <input | ||
| ref={ref} | ||
| type={type} | ||
| className={cn( | ||
| 'flex h-10 w-full text-base sm:text-sm rounded-md border border-input bg-background px-3 py-2 ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', | ||
|
|
@@ -17,4 +20,6 @@ function TextInput({ className, type, ...props }: InputProps) { | |
| ); | ||
| } | ||
|
|
||
| TextInput.displayName = 'TextInput'; | ||
|
|
||
| export { TextInput }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect suggestion! Let's apply the React 19 pattern here too. The remix-hook-form TextField should also use the ref-as-prop pattern:
This maintains consistency with the React 19 pattern across all TextField components!