Conversation
There was a problem hiding this comment.
Walkthrough
This PR introduces an isOneOf validation rule across the codebase, enabling form fields to restrict input to a predefined set of acceptable values. The new validation type is added to the ErrorType union and FormFieldConfig interface, implemented in the validations logic, and demonstrated with a new tShirtSize field in the demo page.
Changes
| File(s) | Summary |
|---|---|
src/interfaces.ts |
Added isOneOf to the ErrorType union and an optional isOneOf?: Value[] property to FormFieldConfig. |
src/validations.ts |
Added isOneOf validation rule that returns true if the field is empty or if the value exists within the allowed values array. |
demo/pages/index.tsx |
Added tShirtSize to UserFormFields, introduced an isOneOf validation config entry with error text, and rendered the field as a FormInput component. |
🔗 Cross-Repository Impact Analysis
Enable automatic detection of breaking changes across your dependent repositories. → Set up now
Learn more about Cross-Repository Analysis
What It Does
- Automatically identifies repositories that depend on this code
- Analyzes potential breaking changes across your entire codebase
- Provides risk assessment before merging to prevent cross-repo issues
How to Enable
- Visit Settings → Code Management
- Configure repository dependencies
- Future PRs will automatically include cross-repo impact analysis!
Benefits
- 🛡️ Prevent breaking changes across repositories
- 🔍 Catch integration issues before they reach production
- 📊 Better visibility into your multi-repo architecture
| <FormInput key={email.name} formField={email} /> | ||
|
|
||
| <FormInput | ||
| key={tshirtSize.name} | ||
| formField={tshirtSize} | ||
| autoComplete="off" | ||
| placeholder="small, medium, or large" |
There was a problem hiding this comment.
Correctness: The destructured field is tshirtSize but the UserFormFields interface and formFieldConfigs define it as tShirtSize (camelCase with capital S). This will be undefined at runtime, causing a crash when accessing tshirtSize.name.
Affected Locations:
- demo/pages/index.tsx:72-78
- demo/pages/index.tsx:11-11
- demo/pages/index.tsx:48-48
🤖 AI Agent Prompt for Cursor/Windsurf
📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue
In demo/pages/index.tsx, lines 72-78, the variable `tshirtSize` is used but the UserFormFields interface and formFieldConfigs define it as `tShirtSize` (capital S). Fix the destructuring in the render method from `tshirtSize` to `tShirtSize` and update all usages of `tshirtSize` in this block to `tShirtSize` to match the interface definition and avoid a runtime crash.
| isOneOf(formField: FormField, formFields: FormFields, submitting: boolean, allowedValues: Value[]) { | ||
| return !isExisty(formField.value) || isEmpty(formField.value) || allowedValues.includes(formField.value); | ||
| }, |
There was a problem hiding this comment.
Correctness: The new isOneOf validation is never invoked in FormsProvider.tsx's isValid function, so even if a formFieldConfig.isOneOf is configured, it will silently be ignored and no validation error will be pushed.
🤖 AI Agent Prompt for Cursor/Windsurf
📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue
In src/FormsProvider.tsx, inside the `isValid` function, add a call to `validations.isOneOf` similar to the other validations. After the `minLength` block (around line 434), add:
```typescript
if (formFieldConfig.isOneOf && !validations.isOneOf(formField, formFields, submitting, formFieldConfig.isOneOf)) {
errors.push('isOneOf');
}
Also ensure FormFieldConfig interface includes an isOneOf?: Value[] property.
</details>
<!-- ai_prompt_end -->
There was a problem hiding this comment.
Walkthrough
This PR introduces an isOneOf validation type across the codebase, enabling form fields to restrict input to a predefined set of allowed values. Changes span the validation logic, type interfaces, and a demo form that adds a tShirtSize field using this new validation. A minor naming inconsistency exists in the demo between the destructured variable (tshirtSize) and the interface field (tShirtSize).
Changes
| File(s) | Summary |
|---|---|
src/interfaces.ts |
Adds isOneOf to the ErrorType union and adds an optional isOneOf property (accepting Value[]) to FormFieldConfig. |
src/validations.ts |
Adds an isOneOf validation function that returns true if the field is empty or its value exists in the provided allowedValues array. |
demo/pages/index.tsx |
Adds tShirtSize field to UserFormFields interface and form config with isOneOf validation restricted to 'small', 'medium', 'large'; renders a corresponding FormInput with autocomplete-off and placeholder text; includes a minor naming bug (tshirtSize vs tShirtSize). |
Sequence Diagram
This diagram shows the interactions between components:
sequenceDiagram
participant User as User
participant Home as Home Component
participant CF as ClassyForm
participant FCC as FormsContextContext
participant FI as FormInput
participant GE as getErrorText
Note over Home: formFieldConfigs now includes tShirtSize field
Home->>CF: render with formFieldConfigs
Note over CF: configs: firstName, lastName,<br/>email, tShirtSize (isOneOf: small/medium/large)
CF->>FCC: provide formFields context
FCC-->>Home: { firstName, lastName, email, tShirtSize, onSubmit }
Home->>FI: render <FormInput formField={firstName} />
Home->>FI: render <FormInput formField={lastName} />
Home->>FI: render <FormInput formField={email} />
Home->>FI: render <FormInput formField={tShirtSize} autoComplete="off" placeholder="small, medium, or large" />
User->>FI: enters value in tShirtSize field
alt valid value (small, medium, or large)
FI->>GE: getHelperText(tShirtSize, formFields)
GE-->>FI: no error
else invalid value
FI->>GE: getHelperText(tShirtSize, formFields)
Note over GE: case 'isOneOf'
GE-->>FI: "Must be small, medium, or large"
FI-->>User: display helper text error
end
User->>FI: submit form
FI->>FCC: onSubmit(formData)
🔗 Cross-Repository Impact Analysis
Enable automatic detection of breaking changes across your dependent repositories. → Set up now
Learn more about Cross-Repository Analysis
What It Does
- Automatically identifies repositories that depend on this code
- Analyzes potential breaking changes across your entire codebase
- Provides risk assessment before merging to prevent cross-repo issues
How to Enable
- Visit Settings → Code Management
- Configure repository dependencies
- Future PRs will automatically include cross-repo impact analysis!
Benefits
- 🛡️ Prevent breaking changes across repositories
- 🔍 Catch integration issues before they reach production
- 📊 Better visibility into your multi-repo architecture
|
|
||
| <FormInput key={email.name} formField={email} /> | ||
|
|
||
| <FormInput | ||
| key={tshirtSize.name} | ||
| formField={tshirtSize} | ||
| autoComplete="off" |
There was a problem hiding this comment.
Correctness: The destructured field is tshirtSize (camelCase, no capital S) but the UserFormFields interface defines it as tShirtSize (capital S), and the formFieldConfigs array also uses tShirtSize. This means tshirtSize will be undefined at runtime, causing a crash when accessing tshirtSize.name.
🤖 AI Agent Prompt for Cursor/Windsurf
📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue
In demo/pages/index.tsx, lines 71-77, the variable `tshirtSize` is used but the interface `UserFormFields` defines the field as `tShirtSize` (capital S). The destructuring on the render method also uses `tshirtSize` (lowercase s) which won't match the actual field key. Fix the destructuring from `tshirtSize` to `tShirtSize` and update all references in these lines to `tShirtSize`.
|
|
||
| <FormInput key={email.name} formField={email} /> | ||
|
|
||
| <FormInput | ||
| key={tshirtSize.name} | ||
| formField={tshirtSize} | ||
| autoComplete="off" |
There was a problem hiding this comment.
Correctness: The destructured field is tshirtSize (camelCase, no capital S) but the UserFormFields interface defines it as tShirtSize (capital S), and the formFieldConfigs array also uses tShirtSize. This means tshirtSize will be undefined at runtime, causing a crash when accessing tshirtSize.name.
Affected Locations:
- demo/pages/index.tsx:71-77
- demo/pages/index.tsx:11-14
- demo/pages/index.tsx:46-46
🤖 AI Agent Prompt for Cursor/Windsurf
📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue
In demo/pages/index.tsx, lines 71-77, the variable `tshirtSize` is used but the interface `UserFormFields` defines the field as `tShirtSize` (capital S). The destructuring on the render method also uses `tshirtSize` (lowercase s) which won't match the actual field key. Fix the destructuring from `tshirtSize` to `tShirtSize` and update all references in these lines to `tShirtSize`.
| isOneOf(formField: FormField, formFields: FormFields, submitting: boolean, allowedValues: Value[]) { | ||
| return !isExisty(formField.value) || isEmpty(formField.value) || allowedValues.includes(formField.value); | ||
| }, |
There was a problem hiding this comment.
Correctness: The new isOneOf validation is never invoked in FormsProvider.tsx's isValid function, unlike every other validation rule — meaning formFieldConfig.isOneOf will never be evaluated and validation will silently pass.
🤖 AI Agent Prompt for Cursor/Windsurf
📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue
In `src/FormsProvider.tsx`, inside the `isValid` function, add a call to `validations.isOneOf` after the `minLength` block (around line 434), following the same pattern as the other validations:
```ts
if (formFieldConfig.isOneOf && !validations.isOneOf(formField, formFields, submitting, formFieldConfig.isOneOf)) {
errors.push('isOneOf');
}
Also ensure FormFieldConfig includes an isOneOf property typed as Value[] | undefined.
</details>
<!-- ai_prompt_end -->
There was a problem hiding this comment.
Walkthrough
This PR introduces an isOneOf validation type across the form validation system. It adds the new error type and config property to the interfaces, implements the validation logic to check if a field's value belongs to a predefined set of allowed values, and demonstrates the feature in the demo app with a t-shirt size field restricted to 'small', 'medium', or 'large'.
Changes
| File(s) | Summary |
|---|---|
src/interfaces.ts |
Added isOneOf to the ErrorType union and an optional isOneOf?: Value[] property to FormFieldConfig. |
src/validations.ts |
Implemented isOneOf validation method that returns true if the field is empty or its value is in the allowed list. |
demo/pages/index.tsx |
Added tShirtSize field to UserFormFields, a new isOneOf validation case with error text, a FormFieldConfig entry, and rendered a corresponding FormInput in the demo form. |
Sequence Diagram
This diagram shows the interactions between components:
sequenceDiagram
participant User as User
participant Home as Home Component
participant CF as ClassyForm
participant FI as FormInput
participant GE as getErrorText
Note over Home: formFieldConfigs includes<br/>firstName, lastName, email,<br/>+ tShirtSize (isOneOf validation)
Home->>CF: render with formFieldConfigs
activate CF
CF-->>Home: FormsContextContext<br/>{ formFields: { firstName, lastName,<br/>email, tshirtSize }, onSubmit }
Home->>FI: render FormInput(firstName)
Home->>FI: render FormInput(lastName)
Home->>FI: render FormInput(email)
Home->>FI: render FormInput(tshirtSize)<br/>placeholder="small, medium, or large"<br/>autoComplete="off"
User->>FI: enters value in tShirtSize field
activate FI
FI->>GE: getHelperText(tShirtSize, formFields)
activate GE
alt value not provided
GE-->>FI: 'Required'
else value not in [small, medium, large]
GE-->>FI: 'Must be small, medium, or large'
else valid value
GE-->>FI: (no error)
end
deactivate GE
deactivate FI
User->>CF: submit form (onSubmit)
CF-->>User: registration with tShirtSize submitted
deactivate CF
🔗 Cross-Repository Impact Analysis
Enable automatic detection of breaking changes across your dependent repositories. → Set up now
Learn more about Cross-Repository Analysis
What It Does
- Automatically identifies repositories that depend on this code
- Analyzes potential breaking changes across your entire codebase
- Provides risk assessment before merging to prevent cross-repo issues
How to Enable
- Visit Settings → Code Management
- Configure repository dependencies
- Future PRs will automatically include cross-repo impact analysis!
Benefits
- 🛡️ Prevent breaking changes across repositories
- 🔍 Catch integration issues before they reach production
- 📊 Better visibility into your multi-repo architecture
| <FormInput key={email.name} formField={email} /> | ||
|
|
||
| <FormInput | ||
| key={tshirtSize.name} | ||
| formField={tshirtSize} | ||
| autoComplete="off" | ||
| placeholder="small, medium, or large" |
There was a problem hiding this comment.
Correctness: The destructured field is tshirtSize but the UserFormFields interface and formFieldConfigs use tShirtSize (camelCase with capital S) — this will resolve to undefined at runtime, causing a crash when accessing tshirtSize.name.
🤖 AI Agent Prompt for Cursor/Windsurf
📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue
In demo/pages/index.tsx, lines 72-78, the FormInput for t-shirt size uses `tshirtSize` but the UserFormFields interface declares `tShirtSize` (capital S). Fix the destructuring in the ClassyForm render prop from `tshirtSize` to `tShirtSize` and update the key and formField props accordingly to avoid a runtime crash.
| <FormInput key={email.name} formField={email} /> | ||
|
|
||
| <FormInput | ||
| key={tshirtSize.name} | ||
| formField={tshirtSize} | ||
| autoComplete="off" | ||
| placeholder="small, medium, or large" |
There was a problem hiding this comment.
Correctness: The destructured field is tshirtSize but the UserFormFields interface and formFieldConfigs use tShirtSize (camelCase with capital S) — this will resolve to undefined at runtime, causing a crash when accessing tshirtSize.name.
Affected Locations:
- demo/pages/index.tsx:72-78
- demo/pages/index.tsx:46-46
🤖 AI Agent Prompt for Cursor/Windsurf
📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue
In demo/pages/index.tsx, lines 72-78, the FormInput for t-shirt size uses `tshirtSize` but the UserFormFields interface declares `tShirtSize` (capital S). Fix the destructuring in the ClassyForm render prop from `tshirtSize` to `tShirtSize` and update the key and formField props accordingly to avoid a runtime crash.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Comment Tip CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present. |
There was a problem hiding this comment.
♻️ Duplicate comments (2)
demo/pages/index.tsx (1)
62-79:⚠️ Potential issue | 🔴 CriticalCase mismatch:
tshirtSizevstShirtSizewill cause runtime crash.The destructured variable
tshirtSize(lowercase 's') doesn't match the interface definitiontShirtSize(capital 'S') on line 14 or the config name on line 49. This will beundefinedat runtime, causing aTypeErrorwhen accessingtshirtSize.name.🐛 Proposed fix
- {({ - formFields: { email, firstName, lastName, tshirtSize }, - onSubmit, - }: FormsContextContext<UserFormFields>) => { + {({ + formFields: { email, firstName, lastName, tShirtSize }, + onSubmit, + }: FormsContextContext<UserFormFields>) => {<FormInput - key={tshirtSize.name} - formField={tshirtSize} + key={tShirtSize.name} + formField={tShirtSize} autoComplete="off" placeholder="small, medium, or large" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@demo/pages/index.tsx` around lines 62 - 79, The destructured form field name uses "tshirtSize" but the interface/config defines "tShirtSize", causing undefined at runtime; update the destructuring in the FormsContext callback to use the exact identifier "tShirtSize" (i.e., change formFields: { email, firstName, lastName, tshirtSize } to use tShirtSize) so FormInput receives a valid formField, and ensure any other references (keys, placeholder assignment) use tShirtSize to match the UserFormFields definition and the config name.src/validations.ts (1)
98-100:⚠️ Potential issue | 🔴 CriticalValidation function is defined but never invoked.
The
isOneOfvalidation implementation looks correct, but it is not integrated intoFormsProvider.tsx'sisValidfunction. This means even whenformFieldConfig.isOneOfis configured, the validation will silently be skipped and always pass.Add the corresponding check in
FormsProvider.tsx:if (formFieldConfig.isOneOf && !validations.isOneOf(formField, formFields, submitting, formFieldConfig.isOneOf)) { errors.push('isOneOf'); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/validations.ts` around lines 98 - 100, The isOneOf validator in validations.ts (isOneOf(formField, formFields, submitting, allowedValues)) is implemented but never called from FormsProvider.tsx; update the isValid function in FormsProvider.tsx to check for formFieldConfig.isOneOf and call validations.isOneOf with the formField, formFields, submitting flag, and formFieldConfig.isOneOf array, and if it returns false push 'isOneOf' into the errors array (i.e., add the conditional: if (formFieldConfig.isOneOf && !validations.isOneOf(...)) { errors.push('isOneOf'); } so configured isOneOf rules are enforced).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@demo/pages/index.tsx`:
- Around line 62-79: The destructured form field name uses "tshirtSize" but the
interface/config defines "tShirtSize", causing undefined at runtime; update the
destructuring in the FormsContext callback to use the exact identifier
"tShirtSize" (i.e., change formFields: { email, firstName, lastName, tshirtSize
} to use tShirtSize) so FormInput receives a valid formField, and ensure any
other references (keys, placeholder assignment) use tShirtSize to match the
UserFormFields definition and the config name.
In `@src/validations.ts`:
- Around line 98-100: The isOneOf validator in validations.ts
(isOneOf(formField, formFields, submitting, allowedValues)) is implemented but
never called from FormsProvider.tsx; update the isValid function in
FormsProvider.tsx to check for formFieldConfig.isOneOf and call
validations.isOneOf with the formField, formFields, submitting flag, and
formFieldConfig.isOneOf array, and if it returns false push 'isOneOf' into the
errors array (i.e., add the conditional: if (formFieldConfig.isOneOf &&
!validations.isOneOf(...)) { errors.push('isOneOf'); } so configured isOneOf
rules are enforced).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c17f2ec3-d0e8-42a7-9656-8007568b1cfd
📒 Files selected for processing (3)
demo/pages/index.tsxsrc/interfaces.tssrc/validations.ts
Greptile SummaryThis PR adds an
Both of these bugs were raised in prior review cycles and have not been addressed in this revision. Confidence Score: 1/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Form Submit / onBlur / onChange] --> B[validateFormFields]
B --> C[isValid per field]
C --> D{formFieldConfig.required?}
D -- Yes --> E[validations.isDefaultRequiredValue]
E --> F[push 'required' error]
C --> G{formFieldConfig.isEmail?}
G -- Yes --> H[validations.isEmail]
H --> I[push 'isEmail' error]
C --> J{formFieldConfig.isOneOf?}
J -- Yes --> K["❌ NO DISPATCH BLOCK EXISTS\n(missing from FormsProvider.tsx)"]
K --> L[isOneOf error NEVER pushed]
C --> M[... other validators ...]
style K fill:#ff4444,color:#fff
style L fill:#ff4444,color:#fff
Last reviewed commit: "Add |
| isOneOf(formField: FormField, formFields: FormFields, submitting: boolean, allowedValues: Value[]) { | ||
| return !isExisty(formField.value) || isEmpty(formField.value) || allowedValues.includes(formField.value); | ||
| }, |
There was a problem hiding this comment.
isOneOf validator is never invoked — validation is completely non-functional
validations.isOneOf is defined here, but the isValid() function in src/FormsProvider.tsx (lines 344–443) contains an explicit if block for every other validation rule and has no corresponding check for isOneOf. Because FormsProvider.tsx is the only place validations are dispatched, any field configured with isOneOf will silently pass validation regardless of its value.
The following block must be added to isValid() in src/FormsProvider.tsx, alongside the other validator checks:
if (
formFieldConfig.isOneOf &&
!validations.isOneOf(formField, formFields, submitting, formFieldConfig.isOneOf)
) {
errors.push('isOneOf');
}Without this change, the entire feature introduced by this PR has no effect at runtime.
| formFields: { email, firstName, lastName, tshirtSize }, | ||
| onSubmit, |
There was a problem hiding this comment.
tshirtSize casing mismatch causes runtime crash
The field is configured in formFieldConfigs with name: 'tShirtSize' (capital S) and declared in UserFormFields as tShirtSize, but it is destructured here as tshirtSize (lowercase s). Because the key does not exist in formFields, tshirtSize will be undefined at runtime. Accessing tshirtSize.name on line 75 will then throw a TypeError.
Fix the destructured name to match the registered field name:
| formFields: { email, firstName, lastName, tshirtSize }, | |
| onSubmit, | |
| formFields: { email, firstName, lastName, tShirtSize }, |
Also update lines 75–79 to reference tShirtSize instead of tshirtSize.
EntelligenceAI PR Summary
Adds an
isOneOfvalidation feature that restricts a form field's value to a predefined set of allowed options.src/interfaces.ts: ExtendedErrorTypeunion with'isOneOf'and addedisOneOf?: Value[]toFormFieldConfigsrc/validations.ts: AddedisOneOfvalidator that passes for empty fields or values matching any entry in the allowed listdemo/pages/index.tsx: IntegratedtShirtSizefield usingisOneOf: ['small', 'medium', 'large']with corresponding error message andFormInputrenderingConfidence Score: 1/5 - Blocking Issues
tshirtSizevstShirtSizecase mismatch will cause the field value to always beundefined, breaking form submission silentlyisOneOfvalidation invalidations.tsis never called fromFormsProvider.tsx, meaning an entire validation rule is completely non-functional — a logic bug that will cause silent validation failuresFiles requiring special attention
demo/pages/index.tsxsrc/validations.tsSummary by CodeRabbit