-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
docs(input): form validation examples #4368
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThis pull request introduces comprehensive documentation and example components for form input validation in NextUI. The changes include four new React components demonstrating different validation strategies: built-in, custom, real-time, and server-side validation. The documentation in Changes
Sequence DiagramsequenceDiagram
participant User
participant Form
participant Validation
participant Server
User->>Form: Enter Input
Form->>Validation: Validate Input
alt Input Valid
Validation-->>Form: Validation Passed
Form->>Server: Submit Data
Server-->>Form: Response
else Input Invalid
Validation-->>Form: Show Error Messages
end
Possibly related PRs
Suggested labels
Suggested reviewers
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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
Documentation and Community
|
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: 4
🧹 Nitpick comments (10)
apps/docs/content/components/input/custom-validation.raw.jsx (3)
22-29
: Consider enhancing validation logic.The current validation could be improved by:
- Adding maximum length validation
- Including character type validation (e.g., alphanumeric only)
- Moving validation logic to a separate function for better maintainability
+const validateUsername = (value) => { + if (!value) return "Username is required"; + if (value.length < 3) return "Username must be at least 3 characters long"; + if (value.length > 20) return "Username must be less than 20 characters"; + if (!/^[a-zA-Z0-9_]+$/.test(value)) return "Username must be alphanumeric"; + if (value === "admin") return "Nice try!"; + return null; +}; <Input isRequired label="Username" labelPlacement="outside" name="username" placeholder="Enter your username" type="text" - validate={(value) => { - if (value.length < 3) { - return "Username must be at least 3 characters long"; - } - - return value === "admin" ? "Nice try!" : null; - }} + validate={validateUsername} />
6-11
: Improve error handling in form submission.Consider adding error handling for the form submission process and providing feedback to users when errors occur.
const onSubmit = (e) => { e.preventDefault(); - const data = Object.fromEntries(new FormData(e.currentTarget)); - - setSubmitted(data); + try { + const data = Object.fromEntries(new FormData(e.currentTarget)); + setSubmitted(data); + } catch (error) { + console.error('Form submission error:', error); + // Consider adding user feedback for submission errors + } };
33-37
: Consider enhancing the submission feedback.The current JSON display might not be the most user-friendly way to show submission results. Consider formatting the output for better readability.
{submitted && ( <div className="text-small text-default-500"> - You submitted: <code>{JSON.stringify(submitted)}</code> + <p>Submission successful!</p> + <div className="mt-2"> + <strong>Username:</strong> {submitted.username} + </div> </div> )}apps/docs/content/components/input/built-in-validation.raw.jsx (2)
6-11
: Consider adding type safety to form data handlingSince this is a documentation example, it would be beneficial to show type-safe form handling.
- const onSubmit = (e) => { + const onSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - const data = Object.fromEntries(new FormData(e.currentTarget)); + const formData = new FormData(e.currentTarget); + const data = { + email: formData.get('email') as string + }; setSubmitted(data); };
13-39
: Enhance the example with more validation featuresAs a documentation example, it would be valuable to demonstrate more built-in validation features.
isRequired + minLength={5} + maxLength={50} + pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$" errorMessage={({validationDetails, validationErrors}) => { if (validationDetails.typeMismatch) { return "Please enter a valid email address"; } + if (validationDetails.tooShort) { + return "Email must be at least 5 characters"; + } + if (validationDetails.tooLong) { + return "Email cannot exceed 50 characters"; + } + if (validationDetails.patternMismatch) { + return "Please enter a valid email format"; + }apps/docs/content/components/input/server-validation.raw.jsx (1)
40-49
: Enhance mock server exampleThe mock server could demonstrate more realistic validation scenarios.
// Fake server used in this example. -async function callServer(_) { +async function callServer(data: { username: string }) { await new Promise((resolve) => setTimeout(resolve, 500)); + // Simulate different validation scenarios + if (data.username.length < 3) { + return { + errors: { + username: "Username must be at least 3 characters long.", + }, + }; + } + + if (data.username === "admin") { return { errors: { username: "Sorry, this username is taken.", }, }; + } + + // Simulate success case + return { errors: {} }; }apps/docs/content/components/input/real-time-validation.raw.jsx (3)
4-23
: Consider refactoring validation logic for better maintainabilityThe password validation logic could be improved by extracting it into a separate function and using constants for magic numbers.
+const PASSWORD_MIN_LENGTH = 4; +const validatePassword = (password) => { + const errors = []; + if (password.length < PASSWORD_MIN_LENGTH) { + errors.push(`Password must be ${PASSWORD_MIN_LENGTH} characters or more.`); + } + if ((password.match(/[A-Z]/g) || []).length < 1) { + errors.push("Password must include at least 1 upper case letter"); + } + if ((password.match(/[^a-z0-9]/gi) || []).length < 1) { + errors.push("Password must include at least 1 symbol."); + } + return errors; +}; export default function App() { const [submitted, setSubmitted] = React.useState(null); const [password, setPassword] = React.useState(""); - const errors = []; - - if (password.length < 4) { - errors.push("Password must be 4 characters or more."); - } - if ((password.match(/[A-Z]/g) || []).length < 1) { - errors.push("Password must include at least 1 upper case letter"); - } - if ((password.match(/[^a-z0-9]/gi) || []).length < 1) { - errors.push("Password must include at least 1 symbol."); - } + const errors = validatePassword(password);
8-13
: Add TypeScript type annotations for better type safetyConsider adding type annotations to the event parameter and form data.
- const onSubmit = (e) => { + const onSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - const data = Object.fromEntries(new FormData(e.currentTarget)); + const data = Object.fromEntries(new FormData(e.currentTarget)) as { + password: string; + }; setSubmitted(data); };
30-33
: Avoid using array indices as React keysUsing array indices as keys can lead to issues with React's reconciliation when the list items change. Consider using a more stable identifier or the error message itself as the key.
<ul> - {errors.map((error, i) => ( - <li key={i}>{error}</li> + {errors.map((error) => ( + <li key={error}>{error}</li> ))} </ul>apps/docs/content/docs/components/input.mdx (1)
130-130
: Fix grammatical structure in the sentenceThe sentence lacks a proper subject. Consider rephrasing for better clarity.
-`Input` can be used with a `Form` component to leverage form state management. +The `Input` component can be used with a `Form` component to leverage form state management.🧰 Tools
🪛 LanguageTool
[style] ~130-~130: To form a complete sentence, be sure to include a subject.
Context: ...ook-form.com/). ### With FormInput
can be used with aForm
component to leve...(MISSING_IT_THERE)
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
apps/docs/content/components/input/built-in-validation.raw.jsx
(1 hunks)apps/docs/content/components/input/built-in-validation.ts
(1 hunks)apps/docs/content/components/input/custom-validation.raw.jsx
(1 hunks)apps/docs/content/components/input/custom-validation.ts
(1 hunks)apps/docs/content/components/input/index.ts
(2 hunks)apps/docs/content/components/input/real-time-validation.raw.jsx
(1 hunks)apps/docs/content/components/input/real-time-validation.ts
(1 hunks)apps/docs/content/components/input/server-validation.raw.jsx
(1 hunks)apps/docs/content/components/input/server-validation.ts
(1 hunks)apps/docs/content/docs/components/input.mdx
(2 hunks)apps/docs/content/docs/guide/forms.mdx
(3 hunks)
✅ Files skipped from review due to trivial changes (2)
- apps/docs/content/components/input/built-in-validation.ts
- apps/docs/content/components/input/custom-validation.ts
🧰 Additional context used
🪛 LanguageTool
apps/docs/content/docs/components/input.mdx
[style] ~130-~130: To form a complete sentence, be sure to include a subject.
Context: ...ook-form.com/). ### With Form Input
can be used with a Form
component to leve...
(MISSING_IT_THERE)
🔇 Additional comments (5)
apps/docs/content/components/input/server-validation.ts (1)
1-9
: LGTM! Clean and consistent implementation.
The file follows the established pattern for documentation examples, properly importing and exporting the raw JSX component.
apps/docs/content/components/input/real-time-validation.ts (1)
1-9
: LGTM! Maintains consistent structure.
The implementation follows the same clean pattern used across validation example files.
apps/docs/content/components/input/index.ts (1)
17-20
: LGTM! Well-organized validation examples
The new validation examples are properly imported and exported, maintaining consistent code organization.
Also applies to: 41-44
apps/docs/content/docs/components/input.mdx (1)
314-337
: LGTM! API documentation is clear and comprehensive
The new validation props are well-documented with clear descriptions and types.
apps/docs/content/docs/guide/forms.mdx (1)
Line range hint 199-238
: LGTM! Validation documentation is thorough and well-explained
The documentation clearly explains different validation approaches and their use cases, with appropriate examples.
import {Button, Form, Input} from "@nextui-org/react"; | ||
|
||
export default function App() { | ||
const [submitted, setSubmitted] = React.useState(null); | ||
|
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.
Add missing React import.
The component uses React.useState but React is not imported.
+import React from "react";
import {Button, Form, Input} from "@nextui-org/react";
📝 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.
import {Button, Form, Input} from "@nextui-org/react"; | |
export default function App() { | |
const [submitted, setSubmitted] = React.useState(null); | |
import React from "react"; | |
import {Button, Form, Input} from "@nextui-org/react"; | |
export default function App() { | |
const [submitted, setSubmitted] = React.useState(null); |
@@ -0,0 +1,40 @@ | |||
import {Button, Form, Input} from "@nextui-org/react"; |
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.
Add missing React import
The component uses React.useState
but doesn't import React.
+import * as React from "react";
import {Button, Form, Input} from "@nextui-org/react";
📝 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.
import {Button, Form, Input} from "@nextui-org/react"; | |
import * as React from "react"; | |
import {Button, Form, Input} from "@nextui-org/react"; |
@@ -0,0 +1,49 @@ | |||
import {Button, Form, Input} from "@nextui-org/react"; |
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.
Add missing React import
The component uses React.useState
but doesn't import React.
+import * as React from "react";
import {Button, Form, Input} from "@nextui-org/react";
📝 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.
import {Button, Form, Input} from "@nextui-org/react"; | |
import * as React from "react"; | |
import {Button, Form, Input} from "@nextui-org/react"; |
const onSubmit = async (e) => { | ||
e.preventDefault(); | ||
setIsLoading(true); | ||
|
||
const data = Object.fromEntries(new FormData(e.currentTarget)); | ||
const result = await callServer(data); | ||
|
||
setErrors(result.errors); | ||
setIsLoading(false); | ||
}; |
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
Add error handling and type safety
As a documentation example, it should demonstrate proper error handling and type safety.
- const onSubmit = async (e) => {
+ type FormData = {
+ username: string;
+ };
+
+ const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setIsLoading(true);
+ try {
+ const formData = new FormData(e.currentTarget);
+ const data: FormData = {
+ username: formData.get('username') as string
+ };
+ const result = await callServer(data);
- const data = Object.fromEntries(new FormData(e.currentTarget));
- const result = await callServer(data);
-
- setErrors(result.errors);
+ setErrors(result.errors);
+ } catch (error) {
+ setErrors({ username: "An error occurred. Please try again." });
+ }
setIsLoading(false);
};
📝 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.
const onSubmit = async (e) => { | |
e.preventDefault(); | |
setIsLoading(true); | |
const data = Object.fromEntries(new FormData(e.currentTarget)); | |
const result = await callServer(data); | |
setErrors(result.errors); | |
setIsLoading(false); | |
}; | |
type FormData = { | |
username: string; | |
}; | |
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => { | |
e.preventDefault(); | |
setIsLoading(true); | |
try { | |
const formData = new FormData(e.currentTarget); | |
const data: FormData = { | |
username: formData.get('username') as string | |
}; | |
const result = await callServer(data); | |
setErrors(result.errors); | |
} catch (error) { | |
setErrors({ username: "An error occurred. Please try again." }); | |
} | |
setIsLoading(false); | |
}; |
Part of eng-1690
📝 Description
⛳️ Current behavior (updates)
🚀 New behavior
💣 Is this a breaking change (Yes/No):
📝 Additional Information
Summary by CodeRabbit
New Features
Documentation
Input
component, detailing validation features and usage scenarios.Chores