Skip to content
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(autocomplete): validate prop not working after hovering #4452

Merged
merged 4 commits into from
Jan 2, 2025

Conversation

Peterl561
Copy link
Contributor

@Peterl561 Peterl561 commented Dec 27, 2024

Closes eng-1790

📝 Description

  • autocomplete has an <input> that has 2 useFormValidation hooks attached to it due to autocomplete's implementation using NextUI's own input
    • the 2 useFormValidation hooks are attached by autocomplete's useComboBox and input's useTextField
    • this works fine for most cases as the input's useFormValidation is controlled externally by autocomplete through isInvalid and errorMessage
  • when using the validate prop's function for validation and validationBehavior=native, after initial render, autocomplete will be invalid but the errors do not show yet since nothing has been committed
  • however, if the input is hovered, the input's useFormValidation will execute due to the useHover hook, which will cause it to overwrite the validation result of the useFormValidation hook from useCombobox
    • this overwrite happens because both useFormValidation hooks reference the same <input>
    • at this moment, the input has isInvalid=false and no validation errors yet
    • under these conditions, useFormValidation will run and set the <input> 's validity to true since its errors externally controlled but there are no errors yet
  • if the form is submitted now, the submission will succeed before autocomplete's useFormValidation has a chance to update the <input> to the correct validation state
  • the fix in this PR is a hack that works by setting input's isInvalid to undefined when there is uncommitted validation so input's useFormValidation does not overwrite that of autocomplete

sandbox: https://codesandbox.io/p/github/Peterl561/autocomplete-validate/main

  1. have autocomplete in a validationBehavior=native form with a validate function
  2. hover over autocomplete after initial render (not clicking)
  3. click form submit
  4. observe that failed validate on autocomplete does not prevent submission
  5. repeat steps 2-4 infinitely
    a. clicking submit without hovering autocomplete works
    b. clicking autocomplete (instead of only hovering) before submitting works

⛳️ Current behavior (updates)

when autocomplete first renders, repeatedly hovering the input prevent validate from working as expected

before.mp4

🚀 New behavior

hovering autocomplete before submit does not interfere with validate

after.mp4

💣 Is this a breaking change (Yes/No):

No

📝 Additional Information

Summary by CodeRabbit

  • Bug Fixes

    • Resolved an issue with the validation behavior of the autocomplete component after user interaction.
  • Tests

    • Added a new test case to verify the validation behavior of the autocomplete component when hovered over and submitted without a valid selection.

Copy link

linear bot commented Dec 27, 2024

Copy link

vercel bot commented Dec 27, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
nextui-docs-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 27, 2024 7:44am
nextui-storybook-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 27, 2024 7:44am

Copy link

changeset-bot bot commented Dec 27, 2024

🦋 Changeset detected

Latest commit: 0abd1a0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@nextui-org/autocomplete Patch
@nextui-org/react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

coderabbitai bot commented Dec 27, 2024

Walkthrough

A patch has been introduced for the @nextui-org/autocomplete package to address an issue with the validate property. The changes focus on improving the validation behavior when a user hovers over the autocomplete component. A new test case was added to verify the validation mechanism, and modifications were made to the useAutocomplete hook to handle uncommitted validation errors more accurately.

Changes

File Change Summary
.changeset/ninety-lobsters-deliver.md Patch introduction for @nextui-org/autocomplete package
packages/components/autocomplete/__tests__/autocomplete.test.tsx Added new test case to verify validation behavior after hovering
packages/components/autocomplete/src/use-autocomplete.ts Introduced hasUncommittedValidation variable to improve validation logic

Possibly related PRs

Suggested reviewers

  • jrgarciadev
  • wingkwong

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


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?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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/autocomplete/src/use-autocomplete.ts (1)

447-447: Clarify why isInvalid is conditionally set to undefined.

A quick inline comment explaining that setting isInvalid to undefined defers to the parent or custom validation logic would help future maintainers understand this workaround. This also ensures that the default isInvalid is not inadvertently persisted in scenarios with uncommitted validation.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ab9ad9b and 6ce1e34.

📒 Files selected for processing (3)
  • .changeset/ninety-lobsters-deliver.md (1 hunks)
  • packages/components/autocomplete/__tests__/autocomplete.test.tsx (1 hunks)
  • packages/components/autocomplete/src/use-autocomplete.ts (1 hunks)
🔇 Additional comments (3)
packages/components/autocomplete/src/use-autocomplete.ts (1)

436-441: Validate the existence of displayValidation and realtimeValidation objects.

Although this logic effectively prevents the use-input hook from overwriting the validation state, consider adding a safety check to ensure state.displayValidation and state.realtimeValidation are always defined. If they are ever undefined, this could throw an error.

packages/components/autocomplete/__tests__/autocomplete.test.tsx (1)

742-795: Comprehensive test scenario for hovering-related validation behavior.

This new test method thoroughly validates the fix by simulating user actions that caused the bug. It effectively ensures that form submission is blocked when hovering disrupts the validation state, and that the validation message is only dismissed upon a correct selection. Great job covering a realistic user flow!

.changeset/ninety-lobsters-deliver.md (1)

1-5: Clear and concise change log.

The patch statement and description of the fix are clear, making it straightforward for users to understand the nature of this release.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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/autocomplete/src/use-autocomplete.ts (1)

436-441: LGTM! Consider enhancing the comment for better clarity.

The logic for detecting uncommitted validation errors is well-implemented. However, the comment could be more descriptive.

Consider updating the comment to better explain the validation state conflict:

-  // prevent use-input's useFormValidation hook from overwriting use-autocomplete's useFormValidation hook when there are uncommitted validation errors
-  // see https://github.com/nextui-org/nextui/pull/4452
+  // Prevents validation state conflicts between useFormValidation hooks
+  // When there are uncommitted validation errors:
+  // - use-input's useFormValidation hook attempts to overwrite the state
+  // - use-autocomplete's useFormValidation hook needs to maintain control
+  // See: https://github.com/nextui-org/nextui/pull/4452
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ce1e34 and 0abd1a0.

📒 Files selected for processing (1)
  • packages/components/autocomplete/src/use-autocomplete.ts (1 hunks)
🔇 Additional comments (1)
packages/components/autocomplete/src/use-autocomplete.ts (1)

448-448: LGTM! Let's verify the validation behavior.

The conditional setting of isInvalid to undefined effectively prevents validation state conflicts. This change aligns perfectly with the PR's objective.

Let's verify that this change doesn't affect other validation scenarios:

✅ Verification successful

Let me try a different approach to verify the validation behavior.


Let me check the test file to understand the validation scenarios.


Based on the test file and implementation details, I can now provide a conclusive response about the validation behavior change.

✓ The validation behavior change is correct and well-tested

The modification to isInvalid prop is a deliberate fix that prevents validation state conflicts between use-input and use-autocomplete hooks. The test file includes a specific test case "should work with validate after hovering" that verifies this exact scenario:

  • The test confirms that hovering over the combobox no longer causes validation from use-input to overwrite the validation from use-autocomplete
  • It verifies that form submission correctly handles validation errors after hovering
  • The implementation ensures that validation state remains consistent when there are uncommitted validation errors

Key test evidence:

it("should work with validate after hovering", async () => {
  // ... test setup ...
  await user.hover(combobox);
  await user.click(submit);
  expect(onSubmit).toHaveBeenCalledTimes(0);
  expect(combobox).toHaveAttribute("aria-describedby");
  // ... validation continues correctly after hover ...
});
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other validation-related code that might be affected
# Look for validation behavior patterns in tests and related components

# Search for validation-related test cases
echo "Checking validation-related test cases:"
rg -l "validation|isInvalid|validate" --type ts --type tsx packages/components/autocomplete/__tests__/

# Search for other components using useFormValidation
echo "Checking other components using useFormValidation:"
rg -l "useFormValidation" --type ts --type tsx packages/components/

# Look for similar validation patterns
echo "Checking for similar validation patterns:"
ast-grep --pattern 'isInvalid = $value ? undefined : $expr'

Length of output: 583


Script:

#!/bin/bash
# Search for validation-related test cases with correct file type
echo "Checking validation-related test cases:"
rg -l "validation|isInvalid|validate" packages/components/autocomplete/__tests__/

# Search for other components using useFormValidation
echo "Checking other components using useFormValidation:"
rg -l "useFormValidation" packages/components/

# Look for isInvalid usage in autocomplete tests
echo "Checking isInvalid usage in tests:"
rg "isInvalid" -C 3 packages/components/autocomplete/__tests__/

# Check the implementation of useFormValidation
echo "Checking useFormValidation implementation:"
fd "use-form-validation.ts" packages/components/ --exec cat {}

Length of output: 855


Script:

#!/bin/bash
# Check the autocomplete test file content
echo "Checking autocomplete test content:"
cat packages/components/autocomplete/__tests__/autocomplete.test.tsx

# Look for validation-related hooks in the component
echo "Checking validation-related hooks:"
rg "useFormValidation|useValidation" -C 5 packages/components/autocomplete/src/use-autocomplete.ts

# Check how isInvalid is used in other components
echo "Checking isInvalid usage in select and input-otp:"
rg "isInvalid" -C 3 packages/components/select/src/hidden-select.tsx
rg "isInvalid" -C 3 packages/components/input-otp/src/use-input-otp.ts

Length of output: 33351

@jrgarciadev jrgarciadev merged commit 0401f25 into canary Jan 2, 2025
8 checks passed
@jrgarciadev jrgarciadev deleted the fix/autocomplete-hover-native-form-validate branch January 2, 2025 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants