-
Notifications
You must be signed in to change notification settings - Fork 0
Fix textarea validation tests and success state display #105
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
Fix textarea validation tests and success state display #105
Conversation
- Add missing success message display in textarea story (fetcher.data?.message) - Add comprehensive validation tests similar to text field story - Include testInvalidSubmission to verify validation errors show correctly - Include testValidSubmission to verify success state works properly - Add missing StoryContext import for test functions This ensures textarea component has the same validation behavior and test coverage as other form components.
|
|
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the WalkthroughThe story file for a controlled textarea component in Storybook was updated. The changes include refactoring the play function to use two new exported asynchronous test helpers for simulating valid and invalid form submissions, updating the component to conditionally display a success message, and expanding Storybook type imports. Separately, the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
📝 Storybook Preview: View Storybook This preview will be updated automatically when you push new changes to this PR.
|
|
🔍 Check Suite Status for PR #105
Results & Findingstest: ✅ I've successfully fixed the TypeScript compilation errors that were causing the check suite to ... |
The textarea component was missing React.forwardRef which is required for React Hook Form to properly register and control the component. This was causing form submission to fail. Key changes: - Import React fully instead of just types - Wrap component in React.forwardRef - Add proper ref handling in both CustomTextarea and native textarea cases - Maintain existing functionality while adding ref support This matches the pattern used in other working form components like TextInput.
- Add React import and forwardRef to Button component to support ref prop - Fix debounce function type issues with proper type assertions - Fix use-debounce-callback hook type definitions - Fix debounced-input component to work with updated debounce function signature These changes resolve the TypeScript compilation errors that were causing the test suite to fail.
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.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/components/src/ui/button.tsx(2 hunks)packages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx(1 hunks)packages/components/src/ui/data-table-filter/lib/debounce.ts(1 hunks)packages/components/src/ui/debounced-input.tsx(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/components/src/ui/data-table-filter/lib/debounce.ts
🧰 Additional context used
📓 Path-based instructions (10)
packages/components/src/ui/**/*.tsx
📄 CodeRabbit Inference Engine (.cursor/rules/form-component-patterns.mdc)
packages/components/src/ui/**/*.tsx: Build on @radix-ui components as the foundation for base UI components
Follow the component composition pattern for UI components that accept form integration
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsxpackages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
packages/components/src/ui/*.{tsx,ts}
📄 CodeRabbit Inference Engine (.cursor/rules/form-component-patterns.mdc)
Base UI components should be named as ComponentName in ui/ directory
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsx
**/*.{tsx,ts}
📄 CodeRabbit Inference Engine (.cursor/rules/form-component-patterns.mdc)
**/*.{tsx,ts}: Props interfaces should be named as ComponentNameProps
Form schemas should be named formSchema or componentNameSchema
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsxpackages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
packages/components/src/{remix-hook-form,ui}/*.{tsx,ts}
📄 CodeRabbit Inference Engine (.cursor/rules/form-component-patterns.mdc)
Always export both the component and its props type
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsx
{apps,packages}/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
{apps,packages}/**/*.{ts,tsx}: Use package name imports for published packages (e.g., import { TextField } from '@lambdacurry/forms/remix-hook-form')
Import from specific entry points (e.g., import { TextField } from '@lambdacurry/forms/remix-hook-form/text-field')
Do not use relative imports across packages (e.g., avoid import { TextField } from '../../packages/components/src/remix-hook-form/text-field')
Order imports: 1) external libraries, 2) internal package imports, 3) cross-package imports, 4) type-only imports (grouped separately)
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsxpackages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
{apps,packages}/**/src/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
{apps,packages}/**/src/**/*.{ts,tsx}: Use relative imports within the same package (e.g., import { FormControl } from './form')
Use relative imports for sibling directories (e.g., import { Button } from '../ui/button')
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsxpackages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
packages/components/src/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
packages/components/src/**/*.{ts,tsx}: Always export both component and props type (e.g., export { ComponentName }; export type { ComponentNameProps };)
Use named exports for components for better tree-shaking (e.g., export const ComponentName = ...; avoid default exports)
Avoid default exports for components
Use tree-shaking friendly exports
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsxpackages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
{apps,packages}/**/src/**/*.{tsx,ts}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
{apps,packages}/**/src/**/*.{tsx,ts}: Use kebab-case for component file names (e.g., text-field.tsx, data-table.tsx)
Match component name in PascalCase to the exported component from the file (e.g., text-field.tsx exports TextField)
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsxpackages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
packages/components/src/ui/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
Don't import from remix-hook-form package in ui components
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsxpackages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
Avoid circular dependencies
Files:
packages/components/src/ui/button.tsxpackages/components/src/ui/debounced-input.tsxpackages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: jaruesink
PR: lambda-curry/forms#14
File: packages/components/src/ui/textarea.tsx:17-24
Timestamp: 2024-11-26T05:28:58.779Z
Learning: In `packages/components/src/ui/textarea.tsx`, the `Textarea` component forwards its ref to `FormItem`, and the textarea element receives `field.ref`, so the ref forwarding works correctly.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Ensure proper accessibility and validation integration in form components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.test.tsx : Test both valid and invalid form states in form component tests
Learnt from: jaruesink
PR: lambda-curry/forms#14
File: packages/components/src/ui/textarea.tsx:32-34
Timestamp: 2024-11-26T05:29:39.395Z
Learning: In the `Textarea` component (`packages/components/src/ui/textarea.tsx`), it's acceptable to assign `field.ref` directly to the `ref` of the textarea element without merging it with external refs.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to apps/docs/src/remix-hook-form/*.stories.tsx : Test both client-side and server-side validation in form stories.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.test.tsx : Verify server-side validation integration in form component tests
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.stories.tsx : Form components should work with the existing Storybook testing patterns
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Clear errors appropriately when fields are corrected
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Use remix-hook-form for form state management and validation
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.test.tsx : Test component composition and customization in form component tests
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Always use semantic queries (e.g., getByRole, getByLabelText) instead of CSS selectors or getByTestId in Storybook play functions.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Always use play functions to simulate user interactions and assert results in stories.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Use the three-phase testing pattern in play functions: default state, invalid submission, valid submission.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Use accessibility-first queries and test keyboard navigation in stories.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Always include required imports for Storybook interaction testing: `Meta`, `StoryObj`, `expect`, `userEvent`, and `withReactRouterStubDecorator`.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Stories should serve as both documentation and automated tests.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to apps/docs/src/remix-hook-form/*.stories.tsx : Story files must be named in kebab-case and have the `.stories.tsx` extension, located in `apps/docs/src/remix-hook-form/`.
packages/components/src/ui/button.tsx (19)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use direct ref props in React 19 components instead of forwardRef
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Embrace React 19 ref handling patterns and avoid legacy patterns like forwardRef
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{hooks,components}/**/*.{ts,tsx} : Use modern useRef patterns with useCallback for imperative actions in React 19
Learnt from: jaruesink
PR: #14
File: packages/components/src/ui/textarea.tsx:17-24
Timestamp: 2024-11-26T05:28:58.779Z
Learning: In packages/components/src/ui/textarea.tsx, the Textarea component forwards its ref to FormItem, and the textarea element receives field.ref, so the ref forwarding works correctly.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/ui-component-patterns.mdc:0-0
Timestamp: 2025-07-06T02:47:43.432Z
Learning: Applies to src/components/**/*.{tsx} : Use consistent component structure: import React, Slot, cva, cn utility, and define variants using CVA
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use ref cleanup functions in React 19 when assigning refs
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use functional components with TypeScript interfaces
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/ui/**/*.tsx : Follow the component composition pattern for UI components that accept form integration
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to {apps,packages}//src//*.{ts,tsx} : Use relative imports for sibling directories (e.g., import { Button } from '../ui/button')
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/ui-component-patterns.mdc:0-0
Timestamp: 2025-07-06T02:47:43.432Z
Learning: Applies to src/components/**/*.{tsx} : Follow the Slot pattern for polymorphic components using @radix-ui/react-slot
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/ui-component-patterns.mdc:0-0
Timestamp: 2025-07-06T02:47:43.432Z
Learning: Applies to src/components/**/*.{ts,tsx} : Implement variant patterns using class-variance-authority (CVA) for all components that require variants
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/ui-component-patterns.mdc:0-0
Timestamp: 2025-07-06T02:47:43.432Z
Learning: Applies to src/components/**/*.{ts,tsx} : Use only Radix UI primitives from the following list: @radix-ui/react-alert-dialog, @radix-ui/react-avatar, @radix-ui/react-checkbox, @radix-ui/react-dialog, @radix-ui/react-dropdown-menu, @radix-ui/react-label, @radix-ui/react-popover, @radix-ui/react-radio-group, @radix-ui/react-scroll-area, @radix-ui/react-separator, @radix-ui/react-slot, @radix-ui/react-switch, @radix-ui/react-tooltip
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use union types for controlled options in component props
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/ui/**/*.tsx : Build on @radix-ui components as the foundation for base UI components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Organize React components with the structure: external imports, internal imports, type definitions, variants, implementation, displayName
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Extend HTML attributes in props interfaces when appropriate
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/ui-component-patterns.mdc:0-0
Timestamp: 2025-07-06T02:47:43.432Z
Learning: Build accessible-first components using Radix UI primitives
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/ui-component-patterns.mdc:0-0
Timestamp: 2025-07-06T02:47:43.432Z
Learning: Applies to src/components/dropdown-menu.tsx : Implement Dropdown Menu components following the established dropdown-menu.tsx pattern, using Radix UI and Tailwind 4 optimizations
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Implement polymorphic components using asChild and as props in React 19 style
packages/components/src/ui/debounced-input.tsx (10)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{hooks,components}/**/*.{ts,tsx} : Use modern useRef patterns with useCallback for imperative actions in React 19
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Ensure keyboard navigation works correctly in form components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Maintain FormField consistency for all form inputs
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use descriptive event handler names in component props (e.g., onValueChange, onSelectionChange, onSubmit, onError)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Ensure proper accessibility and validation integration in form components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Validate on blur and submit, not on every keystroke
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use the React 19 use() hook for async operations in components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/hooks/use-*.ts : Name hooks in camelCase starting with 'use' (e.g., useFormValidation)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{components,hooks}/**/*.{ts,tsx} : Create strongly typed React context values and custom hooks for context consumption
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Embrace React 19 ref handling patterns and avoid legacy patterns like forwardRef
packages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx (10)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{hooks,components}/**/*.{ts,tsx} : Use modern useRef patterns with useCallback for imperative actions in React 19
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{components,hooks}/**/*.{ts,tsx} : Use generic type patterns for form components and components that accept custom renderers
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use specific types instead of any in component props
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use union types for controlled options in component props
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use the React 19 use() hook for async operations in components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/src/**/*index.{ts,tsx} : Re-export with explicit names and types; avoid mixing default and named exports
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Use functional components with TypeScript interfaces
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Prefer interfaces over types for component props in TypeScript
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{components,hooks}/**/*.{ts,tsx} : Use named exports for components and types
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Ensure proper accessibility and validation integration in form components
🔇 Additional comments (3)
packages/components/src/ui/button.tsx (1)
3-3: LGTM! React import properly updated for forwardRef usage.The import statement correctly includes the React namespace to access
React.forwardRef.packages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx (2)
27-27: Good addition of explicit null handling.Making the ref type explicitly nullable (
| null) improves type safety by being explicit about the initial state and potential cleanup scenarios.
17-20: Type safety regression: Consider maintaining stronger return type constraints.Changing the return type constraint from
ReturnType<T>toanyremoves compile-time type safety guarantees. This makes the hook more permissive but potentially less safe.If broader compatibility is needed, consider using a union type or conditional type instead of
any:-export type DebouncedState<T extends (...args: any) => any> = (( +export type DebouncedState<T extends (...args: any[]) => any> = (( ...args: Parameters<T> -) => ReturnType<T> | undefined) & +) => ReturnType<T> | undefined) & ControlFunctions;This maintains type safety while allowing the intended flexibility.
⛔ Skipped due to learnings
Learnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/react-typescript-patterns.mdc:0-0 Timestamp: 2025-07-23T12:47:43.342Z Learning: Applies to src/{hooks,components}/**/*.{ts,tsx} : Use modern useRef patterns with useCallback for imperative actions in React 19Learnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/form-component-patterns.mdc:0-0 Timestamp: 2025-07-23T12:46:51.780Z Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Ensure proper accessibility and validation integration in form componentsLearnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/form-component-patterns.mdc:0-0 Timestamp: 2025-07-23T12:46:51.780Z Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Consider field-level subscriptions for large formsLearnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/react-typescript-patterns.mdc:0-0 Timestamp: 2025-07-23T12:47:43.342Z Learning: Applies to src/{components,hooks}/**/*.{ts,tsx} : Create strongly typed React context values and custom hooks for context consumptionLearnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/form-component-patterns.mdc:0-0 Timestamp: 2025-07-23T12:46:51.780Z Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Avoid unnecessary re-renders by properly structuring form stateLearnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/form-component-patterns.mdc:0-0 Timestamp: 2025-07-23T12:46:51.780Z Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Maintain FormField consistency for all form inputsLearnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/form-component-patterns.mdc:0-0 Timestamp: 2025-07-23T12:46:51.780Z Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Validate on blur and submit, not on every keystrokeLearnt from: jaruesink PR: lambda-curry/forms#14 File: packages/components/src/remix/remix-textarea.tsx:10-15 Timestamp: 2024-11-26T05:28:16.321Z Learning: When reviewing components like `RemixTextarea` in `packages/components/src/remix/`, avoid suggesting to memoize the `components` object with `useMemo` if the performance benefit is minimal.Learnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/react-typescript-patterns.mdc:0-0 Timestamp: 2025-07-23T12:47:43.342Z Learning: Applies to src/components/**/*.tsx : Use specific types instead of any in component propsLearnt from: CR PR: lambda-curry/forms#0 File: .cursor/rules/react-typescript-patterns.mdc:0-0 Timestamp: 2025-07-23T12:47:43.342Z Learning: Applies to src/components/**/*.tsx : Use union types for controlled options in component props
packages/components/src/ui/data-table-filter/hooks/use-debounce-callback.tsx
Outdated
Show resolved
Hide resolved
| debounce((...args: unknown[]) => { | ||
| const newValue = args[0] as string | number; | ||
| onChange(newValue); |
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.
🛠️ Refactor suggestion
Consider a more type-safe approach to maintain flexibility without losing compile-time safety.
The change from a typed parameter to rest parameters with casting reduces type safety. While this makes the debounce utility more generic, the runtime cast args[0] as string | number could fail if unexpected argument types are passed.
Consider maintaining type safety while preserving flexibility:
- debounce((...args: unknown[]) => {
- const newValue = args[0] as string | number;
+ debounce((newValue: string | number) => {
onChange(newValue);
}, debounceMs),If generic flexibility is required, consider using a proper generic constraint in the debounce utility instead of runtime casting.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| debounce((...args: unknown[]) => { | |
| const newValue = args[0] as string | number; | |
| onChange(newValue); | |
| debounce((newValue: string | number) => { | |
| onChange(newValue); | |
| }, debounceMs), |
🤖 Prompt for AI Agents
In packages/components/src/ui/debounced-input.tsx around lines 25 to 27, the
current use of rest parameters with a runtime cast to string | number reduces
type safety and risks runtime errors. To fix this, update the debounce function
to use a generic type parameter that enforces the expected argument type at
compile time. Replace the rest parameter and casting with a properly typed
single parameter matching the generic constraint, ensuring onChange receives a
correctly typed value without unsafe casting.
|
@codegen-sh Address these please 🔍 CodeRabbit PR Review Analysis - PR #105Discovery Results ✅Successfully found CodeRabbit comments using GitHub API, CLI, and direct search. CodeRabbit is active and properly integrated. Impact Analysis🔴 High-Impact (1 comment)Button.tsx:43 - React 19 compatibility issue
:large_yellow_circle: Medium-Impact (2 comments)1. use-debounce-callback.tsx:26 - Type safety regression
🟢 Low-Impact (1 comment)Walkthrough summary - Informational overview of changes Summary
Key Recommendations
|
1. Fix Button component for React 19 compatibility: - Add React.forwardRef to Button component - Import React fully to access forwardRef - Add proper ref handling for both asChild and regular button cases 2. Improve type safety in debounce utilities: - Update generic constraints from 'any' to 'any[]' for better type inference - Fix type casting in debounce function with explicit ReturnType<T> cast - Improve ref typing in use-debounce-callback hook 3. Standardize ref-handling patterns: - All form components now consistently use React.forwardRef - Proper ref forwarding for React Hook Form integration - Consistent patterns across Button, Textarea, and other components These changes address the high-impact React 19 compatibility issue and medium-impact type safety concerns identified in the CodeRabbit review.
|
✅ CodeRabbit review comments addressed! I've successfully fixed all the issues identified in the PR review: 🔧 High-Impact Fix: React 19 Compatibility
🛡️ Medium-Impact Fixes: Type Safety
📊 Results
🔄 View Updated PR #105 - All changes have been pushed to the existing PR branch. The original textarea validation issue is fixed AND the codebase now has improved type safety and React 19 compatibility! 🚀 💻 View my work • 🛑 Stop • React 👍 or 👎 |
- Remove React.forwardRef wrapper as per React 19 guidelines - Add optional ref prop to ButtonProps interface with type React.Ref<HTMLButtonElement> - Convert Button to normal function component that extracts ref from props - Pass ref directly to rendered component (Comp) - Maintain all existing functionality while aligning with modern React patterns This change follows React 19's simplified ref handling where refs are treated as regular props instead of requiring forwardRef.
Co-authored-by: jaruesink <4207065+jaruesink@users.noreply.github.com>
…points - Simplified the exports structure in package.json by removing unnecessary nested import objects. - Updated Vite config to streamline entry points for remix-hook-form and ui components. - Enhanced index.ts to explicitly export Textarea from both remix-hook-form and ui to resolve naming conflicts. These changes improve clarity and maintainability of the component library's structure.
Co-authored-by: jaruesink <4207065+jaruesink@users.noreply.github.com>
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.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/components/src/index.ts (1)
1-11: Well-structured solution for naming conflict resolution.The export strategy effectively resolves the Textarea naming conflict by using explicit aliases. The approach of exporting
RemixTextareafor the form-aware wrapper andTextareafor the base UI component provides clear distinction for consumers.However, consider the long-term maintainability implications:
Naming Convention: The
RemixTextareavsTextareanaming might be confusing - consider whetherFormTextareaorTextareaFieldwould be more intuitive.Scalability: If other components develop similar conflicts, this pattern would need consistent application across the codebase.
Documentation: Ensure this naming strategy is clearly documented for library consumers.
Consider standardizing the naming pattern for form-aware components:
-// The remix-hook-form Textarea is a form-aware wrapper -export { Textarea as RemixTextarea } from './remix-hook-form/textarea'; +// The remix-hook-form Textarea is a form-aware wrapper +export { Textarea as TextareaField } from './remix-hook-form/textarea';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/components/package.json(1 hunks)packages/components/src/index.ts(1 hunks)packages/components/vite.config.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/components/package.json
🧰 Additional context used
📓 Path-based instructions (9)
**/*.ts
📄 CodeRabbit Inference Engine (.cursor/rules/form-component-patterns.mdc)
Handle server-side validation using getValidatedFormData with zodResolver and return errors as needed
Files:
packages/components/src/index.tspackages/components/vite.config.ts
**/*.{tsx,ts}
📄 CodeRabbit Inference Engine (.cursor/rules/form-component-patterns.mdc)
**/*.{tsx,ts}: Props interfaces should be named as ComponentNameProps
Form schemas should be named formSchema or componentNameSchema
Files:
packages/components/src/index.tspackages/components/vite.config.ts
{apps,packages}/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
{apps,packages}/**/*.{ts,tsx}: Use package name imports for published packages (e.g., import { TextField } from '@lambdacurry/forms/remix-hook-form')
Import from specific entry points (e.g., import { TextField } from '@lambdacurry/forms/remix-hook-form/text-field')
Do not use relative imports across packages (e.g., avoid import { TextField } from '../../packages/components/src/remix-hook-form/text-field')
Order imports: 1) external libraries, 2) internal package imports, 3) cross-package imports, 4) type-only imports (grouped separately)
Files:
packages/components/src/index.tspackages/components/vite.config.ts
{apps,packages}/**/src/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
{apps,packages}/**/src/**/*.{ts,tsx}: Use relative imports within the same package (e.g., import { FormControl } from './form')
Use relative imports for sibling directories (e.g., import { Button } from '../ui/button')
Files:
packages/components/src/index.ts
packages/components/src/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
packages/components/src/**/*.{ts,tsx}: Always export both component and props type (e.g., export { ComponentName }; export type { ComponentNameProps };)
Use named exports for components for better tree-shaking (e.g., export const ComponentName = ...; avoid default exports)
Avoid default exports for components
Use tree-shaking friendly exports
Files:
packages/components/src/index.ts
{apps,packages}/**/src/**/*.{tsx,ts}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
{apps,packages}/**/src/**/*.{tsx,ts}: Use kebab-case for component file names (e.g., text-field.tsx, data-table.tsx)
Match component name in PascalCase to the exported component from the file (e.g., text-field.tsx exports TextField)
Files:
packages/components/src/index.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
Avoid circular dependencies
Files:
packages/components/src/index.tspackages/components/vite.config.ts
packages/components/src/**/*index.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
Re-export with explicit names and types; avoid mixing default and named exports
Files:
packages/components/src/index.ts
packages/components/vite.config.ts
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo-organization.mdc)
packages/components/vite.config.ts: Keep bundle sizes minimal with proper externals
Use vite-plugin-dts and configure multiple entry points in vite.config.ts for packages/components
Files:
packages/components/vite.config.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: jaruesink
PR: lambda-curry/forms#14
File: packages/components/src/ui/textarea.tsx:17-24
Timestamp: 2024-11-26T05:28:58.779Z
Learning: In `packages/components/src/ui/textarea.tsx`, the `Textarea` component forwards its ref to `FormItem`, and the textarea element receives `field.ref`, so the ref forwarding works correctly.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Ensure proper accessibility and validation integration in form components
Learnt from: jaruesink
PR: lambda-curry/forms#14
File: packages/components/src/ui/textarea.tsx:32-34
Timestamp: 2024-11-26T05:29:39.395Z
Learning: In the `Textarea` component (`packages/components/src/ui/textarea.tsx`), it's acceptable to assign `field.ref` directly to the `ref` of the textarea element without merging it with external refs.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/components/**/*.tsx : Embrace React 19 ref handling patterns and avoid legacy patterns like forwardRef
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{hooks,components}/**/*.{ts,tsx} : Use modern useRef patterns with useCallback for imperative actions in React 19
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.test.tsx : Test both valid and invalid form states in form component tests
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.stories.tsx : Form components should work with the existing Storybook testing patterns
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to apps/docs/src/remix-hook-form/*.stories.tsx : Test both client-side and server-side validation in form stories.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.test.tsx : Verify server-side validation integration in form component tests
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Use remix-hook-form for form state management and validation
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Always use semantic queries (e.g., getByRole, getByLabelText) instead of CSS selectors or getByTestId in Storybook play functions.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Always use play functions to simulate user interactions and assert results in stories.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Use the three-phase testing pattern in play functions: default state, invalid submission, valid submission.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Use accessibility-first queries and test keyboard navigation in stories.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Always include required imports for Storybook interaction testing: `Meta`, `StoryObj`, `expect`, `userEvent`, and `withReactRouterStubDecorator`.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to **/*.stories.tsx : Stories should serve as both documentation and automated tests.
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/storybook-testing.mdc:0-0
Timestamp: 2025-07-23T12:48:03.192Z
Learning: Applies to apps/docs/src/remix-hook-form/*.stories.tsx : Story files must be named in kebab-case and have the `.stories.tsx` extension, located in `apps/docs/src/remix-hook-form/`.
packages/components/src/index.ts (14)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/{remix-hook-form,ui}/*.{tsx,ts} : Always export both the component and its props type
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/src/ui/**/*.{ts,tsx} : Don't import from remix-hook-form package in ui components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Use the required imports for Remix Hook Form integration, Zod, and base UI components in form-aware components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/src/**/*index.{ts,tsx} : Re-export with explicit names and types; avoid mixing default and named exports
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{components,hooks}/**/*.{ts,tsx} : Use named exports for components and types
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Use remix-hook-form for form state management and validation
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/*.{tsx,ts} : Form-aware components should be named as ComponentName (e.g., TextField, Checkbox)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/src/**/*.{ts,tsx} : Use named exports for components for better tree-shaking (e.g., export const ComponentName = ...; avoid default exports)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Use the form setup pattern for form initialization in Remix
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{components,hooks}/**/index.ts : Re-export from index files
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to {apps,packages}/**/*.{ts,tsx} : Import from specific entry points (e.g., import { TextField } from '@lambdacurry/forms/remix-hook-form/text-field')
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Follow the remix-hook-form/ and ui/ directory separation pattern
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Organize files in the structure: src/components/ui, src/components/remix-hook-form, src/hooks, src/utils
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Follow the wrapper component pattern for all form-aware components
packages/components/vite.config.ts (17)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/vite.config.ts : Use vite-plugin-dts and configure multiple entry points in vite.config.ts for packages/components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/vite.config.ts : Keep bundle sizes minimal with proper externals
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to {apps,packages}/**/*.{ts,tsx} : Import from specific entry points (e.g., import { TextField } from '@lambdacurry/forms/remix-hook-form/text-field')
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{components,hooks}/**/index.ts : Re-export from index files
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/src/**/*index.{ts,tsx} : Re-export with explicit names and types; avoid mixing default and named exports
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/src/ui/**/*.{ts,tsx} : Don't import from remix-hook-form package in ui components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{components,hooks}/**/*.{ts,tsx} : Use named exports for components and types
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/src/**/*.{ts,tsx} : Use tree-shaking friendly exports
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Applies to src/{components,hooks,utils}/**/*.{ts,tsx} : Name files in kebab-case (e.g., text-field.tsx, data-table.tsx)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to packages/components/src/**/*.{ts,tsx} : Use named exports for components for better tree-shaking (e.g., export const ComponentName = ...; avoid default exports)
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Use the required imports for Remix Hook Form integration, Zod, and base UI components in form-aware components
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/react-typescript-patterns.mdc:0-0
Timestamp: 2025-07-23T12:47:43.342Z
Learning: Organize files in the structure: src/components/ui, src/components/remix-hook-form, src/hooks, src/utils
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/{remix-hook-form,ui}/*.{tsx,ts} : Always export both the component and its props type
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Use remix-hook-form for form state management and validation
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Follow the remix-hook-form/ and ui/ directory separation pattern
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/form-component-patterns.mdc:0-0
Timestamp: 2025-07-23T12:46:51.780Z
Learning: Applies to packages/components/src/remix-hook-form/**/*.tsx : Use the form setup pattern for form initialization in Remix
Learnt from: CR
PR: lambda-curry/forms#0
File: .cursor/rules/monorepo-organization.mdc:0-0
Timestamp: 2025-07-23T12:47:17.244Z
Learning: Applies to {apps,packages}/**/*.{ts,tsx} : Use package name imports for published packages (e.g., import { TextField } from '@lambdacurry/forms/remix-hook-form')
🔇 Additional comments (1)
packages/components/vite.config.ts (1)
20-21: Entry point simplification verified – no internal breakageNo occurrences of the old
/indeximport patterns were found in the codebase. The new Vite entries ('remix-hook-form'and'ui') align with thepackage.jsonexport map and existing Rollup configuration.• Internal imports now correctly reference
@lambdacurry/forms/remix-hook-formand@lambdacurry/forms/ui.
• No further code changes required.Please update any external documentation and notify consumers to adopt the new import paths.
…ddc-8718-113aeb6081cf
- Changed export of Textarea from remix-hook-form to TextareaField to resolve naming conflicts. - Updated display name of TextField component from RemixTextField to TextField for consistency. These changes enhance clarity in component naming and improve the overall structure of exports.
…f github.com:lambda-curry/forms into codegen-bot/fix-textarea-validation-tests-1753586526
- Added multiple new packages and updated existing ones to their latest versions. - Enhanced dependency management by resolving version conflicts and ensuring compatibility across the project. These changes improve the overall stability and performance of the application.
Problem
The textarea component was showing "Required" validation errors even when it had content, as reported in the user's screenshot. After investigation, I discovered the root cause: the textarea component was missing
React.forwardRef, which is essential for React Hook Form to properly register and control form components.Root Cause Analysis
Comparing the textarea component with working components like
TextInput, I found:❌ Textarea (broken):
✅ TextInput (working):
Solution
This PR fixes the textarea validation issue by:
1. Fixed the Core Issue - Added React.forwardRef
React.forwardRef<HTMLTextAreaElement, TextareaProps>import type * as Reacttoimport * as Reactto accessforwardRef2. Enhanced Test Coverage
textarea.stories.tsx:testInvalidSubmission: Tests validation errors appear correctlytestValidSubmission: Tests success messages display properly{fetcher.data?.message && <p className="mt-2 text-green-600">{fetcher.data.message}</p>}StoryContextimport for proper test typing3. Consistent Behavior
text-field.stories.tsxFiles Changed
packages/components/src/ui/textarea.tsx: Fixed missing React.forwardRefapps/docs/src/remix-hook-form/textarea.stories.tsx: Enhanced with proper validation tests and success state displayTesting
✅ Component builds successfully - verified with
npm run build✅ TypeScript compilation passes - no new type errors introduced
✅ Ref forwarding works - textarea can now be properly controlled by React Hook Form
✅ Validation tests added - comprehensive test coverage matching other components
Why This Fixes the Issue
React Hook Form requires components to forward refs so it can:
Without
forwardRef, React Hook Form couldn't properly register the textarea, causing validation to fail even with valid content.This resolves the reported "Required" validation error by ensuring the textarea integrates correctly with the form validation system.
💻 View my work • About Codegen
Summary by CodeRabbit
New Features
Refactor
Bug Fixes