Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lambdacurry/forms",
"version": "0.19.1",
"version": "0.19.2",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
16 changes: 11 additions & 5 deletions packages/components/src/ui/text-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,17 @@ export const FieldSuffix = ({
export interface TextInputProps extends Omit<InputProps, 'prefix' | 'suffix'> {
control?: Control<FieldValues>;
name: FieldPath<FieldValues>;
label?: string | React.ReactNode;
label?: string;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Avoid breaking change: keep label as ReactNode-compatible.

Narrowing label to string breaks valid use cases (icons, formatted labels, i18n components). Recommend restoring React.ReactNode.

Apply:

-  label?: string;
+  label?: React.ReactNode;

If you intend to keep it string-only, please confirm there are no callsites passing JSX. Use the script in package.json review to verify.


🏁 Script executed:

#!/bin/bash
set -e

echo "1) Finding TextField usages with non-string label props (JSX expressions):"
rg -n --type tsx '<TextField[^>]*label\s*=\s*\{' .

echo
echo "2) Finding any label prop passed as an expression anywhere in the repo:"
rg -n --type tsx 'label\s*=\s*\{' .

Length of output: 248


🏁 Script executed:

#!/bin/bash
set -e

echo "Searching for TextField usages with label prop passed as an expression (non-string) in TSX/JSX files:"
rg -n "<TextField[^>]*label\s*=\s*\{" --glob "*.{tsx,jsx}" .

Length of output: 284


Restore ReactNode for the label prop

Our search across all .tsx/.jsx files did not find any instances of non-string labels being passed to <TextField>, so reverting this change is non-breaking today and preserves future flexibility (icons, formatted labels, i18n components).

• File: packages/components/src/ui/text-field.tsx line 57
• Apply:

-  label?: string;
+  label?: React.ReactNode;
🤖 Prompt for AI Agents
In packages/components/src/ui/text-field.tsx around line 57, the label prop was
narrowed to string; restore it to allow ReactNode to preserve flexibility
(icons, formatted labels, i18n). Update the prop type from label?: string to
label?: React.ReactNode (or import ReactNode and use label?: ReactNode), ensure
React is imported or ReactNode is imported from 'react', and keep the prop
optional so existing usage remains valid.

description?: string;
components?: Partial<FieldComponents> & {
Input?: React.ComponentType<InputProps & React.RefAttributes<HTMLInputElement>>;
};
prefix?: React.ReactNode;
suffix?: React.ReactNode;
className?: string;
groupClassName?: string;
prefixClassName?: string;
suffixClassName?: string;
}

export const TextField = function TextField({
Expand All @@ -74,6 +77,9 @@ export const TextField = function TextField({
prefix,
suffix,
ref,
groupClassName,
prefixClassName,
suffixClassName,
...props
Comment on lines +80 to 83
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider forwarding refs properly instead of accepting a ref prop.

Function components don’t receive ref via props; won’t populate the ref variable unless you use React.forwardRef. This is orthogonal to this PR but worth addressing.

Example refactor (outside this hunk):

export const TextField = React.forwardRef<HTMLInputElement, TextInputProps>(function TextField(
  {
    control,
    name,
    label,
    description,
    className,
    components,
    prefix,
    suffix,
    groupClassName,
    prefixClassName,
    suffixClassName,
    ...props
  },
  ref
) {
  // ... use `ref` here
});

Then remove ref from TextInputProps entirely (it will be provided by forwardRef).

🤖 Prompt for AI Agents
In packages/components/src/ui/text-field.tsx around lines 80 to 83, the
component currently expects a ref prop via props which won’t be populated when
consumers use <TextField ref={...}>; change the component to use
React.forwardRef and accept (props, ref) so refs are forwarded correctly, remove
ref from the TextInputProps type, and update internal usage to call the
forwarded ref (or pass it to the underlying input element) instead of reading a
ref from props.

}: TextInputProps & { ref?: React.Ref<HTMLInputElement> }) {
// Use the custom Input component if provided, otherwise use the default TextInput
Expand All @@ -91,10 +97,10 @@ export const TextField = function TextField({
className={cn('flex group transition-all duration-200 rounded-md', {
'field__input--with-prefix': prefix,
'field__input--with-suffix': suffix,
'focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background': true,
})}
'focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background': true
}, groupClassName)}
>
{prefix && <FieldPrefix>{prefix}</FieldPrefix>}
{prefix && <FieldPrefix className={prefixClassName}>{prefix}</FieldPrefix>}
<FormControl Component={components?.FormControl}>
<InputComponent
{...field}
Expand All @@ -106,7 +112,7 @@ export const TextField = function TextField({
})}
/>
</FormControl>
{suffix && <FieldSuffix>{suffix}</FieldSuffix>}
{suffix && <FieldSuffix className={suffixClassName}>{suffix}</FieldSuffix>}
</div>
{description && <FormDescription Component={components?.FormDescription}>{description}</FormDescription>}
{fieldState.error && (
Expand Down