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(modal): onOpenChange triggering when modal opens #3902

Open
wants to merge 4 commits into
base: canary
Choose a base branch
from

Conversation

sanuj21
Copy link
Contributor

@sanuj21 sanuj21 commented Oct 16, 2024

Closes #3887

📝 Description

The changes in this PR makes the onOpenChange fire when modal opens, making it consistent.

⛳️ Current behavior (updates)

  • onOpenChange fires only when modal closes and not when it opens.
  • onOpenChange in useDisclosure decides which action to fire on isOpen state.

🚀 New behavior

  • onOpenChange fires on both states consistently.
  • Added useEffect, so when isOpen changes to true, onOpenChange is called.
  • onOpenChange in useDisclosure decides which action to fire on basis of isOpen argument, used to do isOpen state earlier.

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

No

📝 Additional Information

  • onClose function in modal is basically coming from useOuterlayTriggerState, but onOpen is just a normal function. Thats why we need that useEffect to fire onOpenChange explicitly.
  • Make sure to pass the isOpen variable when you are wrapping onOpenChange inside a function. Like this onOpenChange(isOpen).

Summary by CodeRabbit

  • New Features

    • Improved modal functionality with enhanced responsiveness to state changes.
    • Updated disclosure logic to better handle open and close actions based on boolean parameters.
  • Bug Fixes

    • Fixed issues related to side effects not triggering correctly when the modal opens.
  • Tests

    • Added a new test case to verify the onOpenChange callback is triggered when the "Open" button is clicked.

Copy link

changeset-bot bot commented Oct 16, 2024

🦋 Changeset detected

Latest commit: d20d2f2

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

This PR includes changesets to release 3 packages
Name Type
@nextui-org/modal Patch
@nextui-org/use-disclosure 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

vercel bot commented Oct 16, 2024

@sanuj21 is attempting to deploy a commit to the NextUI Inc Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented Oct 16, 2024

Walkthrough

The changes in this pull request involve modifications to the useModal and useDisclosure hooks. A useEffect hook has been added in useModal to trigger the onOpenChange callback when the modal's isOpen state changes to true. Additionally, the onOpenChange function in useDisclosure has been updated to accept a boolean parameter, enhancing its responsiveness to state changes.

Changes

File Path Change Summary
.changeset/early-ghosts-fix.md Added a useEffect in useModal to trigger onOpenChange on modal open; updated onOpenChange in useDisclosure to accept a boolean.
packages/hooks/use-disclosure/src/index.ts Updated onOpenChange function signature to accept a boolean parameter.
packages/components/modal/tests/modal.test.tsx Added a test case to verify that onOpenChange is triggered when the "Open" button is clicked.

Assessment against linked issues

Objective Addressed Explanation
onOpenChange should fire when the modal opens (#3887)
Ensure side effects are executed when modal opens (#3887)

Possibly related PRs

Suggested reviewers

  • wingkwong
  • jrgarciadev

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 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

🧹 Outside diff range and nitpick comments (3)
.changeset/early-ghosts-fix.md (1)

6-7: Consider adding more details to the change description.

While the current description provides a good overview, it could be enhanced to provide more context and details about the changes. This would help users and maintainers better understand the impact and reasoning behind the modifications.

Consider expanding the description to include:

  1. The reason for the change (addressing the issue of onOpenChange not firing when the modal opens).
  2. The expected impact on users (improved consistency in onOpenChange behavior).
  3. Any potential considerations for users updating to this version.

Here's a suggested expanded description:

Added useEffect in useModal to fire onOpenChange when onOpen changes to true.
This ensures that onOpenChange is triggered consistently for both opening and closing of the modal.
In useDisclosure, onOpenChange now depends on arg onOpen, rather than state(onOpen),
improving responsiveness to external state changes.

These changes address the issue where onOpenChange was only firing when the modal closed.
Users can now rely on onOpenChange for actions related to both opening and closing the modal.
This update maintains backwards compatibility while providing more consistent behavior.
packages/hooks/use-disclosure/src/index.ts (1)

47-54: Approve changes with suggestions for improvement

The modifications to onOpenChange align well with the PR objectives, allowing the callback to fire consistently for both opening and closing actions. This change enhances the flexibility and usability of the useDisclosure hook.

However, to ensure a smooth transition for existing users and maintain type safety, consider the following suggestions:

  1. Update the TypeScript interface UseDisclosureProps to reflect the new onOpenChange signature:
export interface UseDisclosureProps {
  // ... existing props
  onOpenChange?(isOpen: boolean): void;
}
  1. Add a comment explaining the new behavior of onOpenChange for clarity:
/**
 * Callback fired when the disclosure state changes.
 * @param isOpen - The new state of the disclosure.
 */
const onOpenChange = useCallback(
  (isOpen: boolean) => {
    // ... existing implementation
  },
  [isOpen, onOpen, onClose]
);
  1. Consider adding a warning or deprecation notice for the old usage pattern to help users transition to the new API.
packages/components/modal/src/use-modal.ts (1)

132-136: LGTM: useEffect hook addresses the issue effectively.

The added useEffect hook successfully addresses the issue by triggering onOpenChange when the modal opens. This implementation is non-breaking and aligns with the PR objectives.

Consider a minor optimization:

 useEffect(() => {
   if (isOpen) {
     onOpenChange?.(isOpen);
   }
-}, [isOpen]);
+}, [isOpen, onOpenChange]);

Adding onOpenChange to the dependency array ensures the effect uses the latest callback if it changes between renders.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8a33eab and 4741a84.

📒 Files selected for processing (3)
  • .changeset/early-ghosts-fix.md (1 hunks)
  • packages/components/modal/src/use-modal.ts (2 hunks)
  • packages/hooks/use-disclosure/src/index.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (3)
.changeset/early-ghosts-fix.md (1)

1-4: LGTM: Version bumps are appropriate.

The minor version bumps for "@nextui-org/modal" and "@nextui-org/use-disclosure" are appropriate for the described changes. This ensures that users of these packages will receive the new functionality while maintaining backwards compatibility.

packages/components/modal/src/use-modal.ts (2)

6-6: LGTM: Import statement updated correctly.

The addition of useEffect to the import statement is necessary and correctly placed with other React imports. This change supports the new functionality added later in the file.


Line range hint 1-236: Summary: Changes effectively address the issue with minimal risk.

The modifications successfully ensure that onOpenChange fires when the modal opens, addressing the reported issue without introducing breaking changes. The implementation is clean and integrates well with the existing code structure.

To further improve confidence in this change:

Consider adding a test case to verify the new behavior:

it('should call onOpenChange when modal opens', async () => {
  const onOpenChange = jest.fn();
  const { result } = renderHook(() => useModal({ onOpenChange }));
  
  act(() => {
    result.current.onClose(); // Ensure modal is closed
  });
  
  act(() => {
    result.current.isOpen = true; // Simulate opening the modal
  });
  
  await waitFor(() => {
    expect(onOpenChange).toHaveBeenCalledWith(true);
  });
});

This test would ensure that the onOpenChange callback is called with the correct value when the modal opens.

Copy link
Member

@wingkwong wingkwong left a comment

Choose a reason for hiding this comment

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

please add a test case to cover the logic.

.changeset/early-ghosts-fix.md Outdated Show resolved Hide resolved
.changeset/early-ghosts-fix.md Outdated Show resolved Hide resolved
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: 1

🧹 Outside diff range and nitpick comments (2)
.changeset/early-ghosts-fix.md (1)

6-6: LGTM with a minor suggestion: Add missing article.

The change description accurately summarizes the modifications and includes the relevant issue reference. However, there's a small grammatical improvement to be made.

Consider this minor change:

-Added useEffect in useModal to fire onOpenChange and in useDisclosure, onOpenChange now accepts onOpen as parameter(#3887)
+Added useEffect in useModal to fire onOpenChange and in useDisclosure, onOpenChange now accepts onOpen as a parameter (#3887)
🧰 Tools
🪛 LanguageTool

[uncategorized] ~6-~6: You might be missing the article “a” here.
Context: ...ure, onOpenChange now accepts onOpen as parameter(#3887)

(AI_EN_LECTOR_MISSING_DETERMINER_A)

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

Line range hint 1-143: Overall assessment of changes

The addition of a new test case for the Modal component's opening behavior is a positive step. It demonstrates an effort to improve test coverage and ensure the component behaves correctly when opened.

However, as noted in the previous comment, there are opportunities to enhance this test further:

  1. Ensure the modal starts in a closed state and verify it opens.
  2. Use consistent naming for the callback function.
  3. Verify the correct boolean value is passed to the callback.

These improvements will make the test more robust and better reflect real-world usage of the Modal component.

Consider adding more comprehensive tests that cover different scenarios of modal usage, such as:

  • Testing the modal with different content
  • Verifying accessibility attributes change correctly when the modal opens and closes
  • Testing keyboard navigation within the modal

This will help ensure the Modal component remains reliable and accessible as the codebase evolves.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 4741a84 and dbf2c49.

📒 Files selected for processing (2)
  • .changeset/early-ghosts-fix.md (1 hunks)
  • packages/components/modal/tests/modal.test.tsx (2 hunks)
🧰 Additional context used
🪛 LanguageTool
.changeset/early-ghosts-fix.md

[uncategorized] ~6-~6: You might be missing the article “a” here.
Context: ...ure, onOpenChange now accepts onOpen as parameter(#3887)

(AI_EN_LECTOR_MISSING_DETERMINER_A)

🔇 Additional comments (3)
.changeset/early-ghosts-fix.md (2)

1-3: LGTM: Appropriate version bumps for the changes.

The "patch" updates for both "@nextui-org/modal" and "@nextui-org/use-disclosure" are correct, as they reflect minor bug fixes without introducing breaking changes. This aligns well with the PR objectives.


1-6: Great job addressing previous review comments!

The changes suggested in the past review comments have been successfully implemented:

  1. Both package updates are now set to 'patch'.
  2. The description is summarized in one line and includes the issue reference ([BUG] - Modal onOpenChange only fires on close #3887) at the end.

These improvements enhance the clarity and consistency of the changeset.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~6-~6: You might be missing the article “a” here.
Context: ...ure, onOpenChange now accepts onOpen as parameter(#3887)

(AI_EN_LECTOR_MISSING_DETERMINER_A)

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

6-6: LGTM: New import statement for Button component.

The import of the Button component is correctly added and is necessary for the new test case.

Comment on lines 95 to 120
test("should fire 'onOpenChange' callback when open button is clicked", async () => {
const onOpen = jest.fn();

const {getByLabelText} = render(
<>
<Button aria-label="Open" onClick={onOpen}>
Open Modal
</Button>
<Modal isOpen>
<ModalContent>
<ModalHeader>Modal header</ModalHeader>
<ModalBody>Modal body</ModalBody>
<ModalFooter>Modal footer</ModalFooter>
</ModalContent>
</Modal>
</>,
);

const openButton = getByLabelText("Open");

const user = userEvent.setup();

await user.click(openButton);

expect(onOpen).toHaveBeenCalled();
});
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

ModalProps interface missing onOpenChange prop

The ModalProps interface does not include the onOpenChange prop, which is used in various Modal components and tests. This inconsistency can lead to type errors and unreliable test behavior.

🔗 Analysis chain

Improve test case for modal opening behavior

While the new test case is a good addition, there are a few areas that could be improved:

  1. The test doesn't actually open the modal or check its state. Consider updating the Modal to start closed and verify it opens.
  2. The Modal is rendered as always open (isOpen={true}), which doesn't reflect a real-world scenario. It should start closed.
  3. The test name mentions 'onOpenChange', but the mock function is called 'onOpen'. This should be consistent.

Here's a suggested improvement:

test("should fire 'onOpenChange' callback when modal is opened", async () => {
  const onOpenChange = jest.fn();

  const { getByLabelText } = render(
    <>
      <Button aria-label="Open">Open Modal</Button>
      <Modal isOpen={false} onOpenChange={onOpenChange}>
        <ModalContent>
          <ModalHeader>Modal header</ModalHeader>
          <ModalBody>Modal body</ModalBody>
          <ModalFooter>Modal footer</ModalFooter>
        </ModalContent>
      </Modal>
    </>
  );

  const openButton = getByLabelText("Open");
  const user = userEvent.setup();

  await user.click(openButton);

  expect(onOpenChange).toHaveBeenCalledWith(true);
});

This version:

  • Uses a consistent name for the callback (onOpenChange)
  • Starts with the modal closed
  • Verifies that onOpenChange is called with true when the modal is opened

To ensure the Modal component behaves as expected with these changes, we can run the following verification:

This will confirm that the Modal component accepts an onOpenChange prop of the correct type.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the Modal component's onOpenChange prop
ast-grep --lang typescript --pattern 'interface ModalProps {
  $$$
  onOpenChange?: (isOpen: boolean) => void;
  $$$
}'

Length of output: 121


Script:

#!/bin/bash
# Search for occurrences of 'onOpenChange' in the codebase
rg 'onOpenChange' --type=typescript

Length of output: 70


Script:

#!/bin/bash
# Search for similar prop names related to opening the modal
rg 'onOpen[^A-Z]' --type=typescript

Length of output: 72


Script:

#!/bin/bash
# Verify the Modal component's onOpenChange prop with a flexible pattern
ast-grep --lang typescript --pattern 'interface ModalProps {
  $$$
  onOpenChange?($_): void;
  $$$
}'

Length of output: 104


Script:

#!/bin/bash
# Search for occurrences of 'onOpenChange' in .ts and .tsx files
rg 'onOpenChange' --glob '*.ts' --glob '*.tsx'

Length of output: 9539


Script:

#!/bin/bash
# Search for similar prop names related to opening the modal in .ts and .tsx files
rg 'onOpen[^A-Z]' --glob '*.ts' --glob '*.tsx'

Length of output: 4430

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

🧹 Outside diff range and nitpick comments (1)
packages/components/modal/__tests__/modal.test.tsx (1)

114-125: LGTM with suggestion: New test case for onOpenChange

The new test case is well-implemented and correctly verifies that the onOpenChange callback is fired when the modal opens. Good job on using userEvent for simulating the button click.

Suggestion for improvement:
Consider verifying the argument passed to onOpenChange. You can update the expectation to:

expect(onOpenChange).toHaveBeenCalledWith(true);

This ensures that onOpenChange is not only called but also receives the correct argument indicating that the modal is opening.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between dbf2c49 and d20d2f2.

📒 Files selected for processing (1)
  • packages/components/modal/tests/modal.test.tsx (2 hunks)
🧰 Additional context used
🔇 Additional comments (2)
packages/components/modal/__tests__/modal.test.tsx (2)

4-6: LGTM: New imports are correctly added

The new imports for Button and useDisclosure are necessary for the newly added test case. They are correctly placed and sourced from the appropriate packages.


95-112: LGTM: ModalWrapper component is well-implemented

The ModalWrapper component is correctly implemented:

  • It uses the useDisclosure hook to manage the Modal's open state.
  • The Button is properly set up to open the Modal.
  • The Modal correctly receives the isOpen and onOpenChange props.

This component provides a good setup for testing the Modal's opening behavior.

@wingkwong wingkwong requested review from ryo-manba and removed request for jrgarciadev October 16, 2024 16:15
@wingkwong wingkwong changed the title fix: onOpenChange triggering when modal opens fix(modal): onOpenChange triggering when modal opens Oct 16, 2024
Comment on lines +132 to +137
useEffect(() => {
if (isOpen) {
onOpenChange?.(isOpen);
}
}, [isOpen]);

Copy link

Choose a reason for hiding this comment

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

I came across this interesting resource on the React docs (https://react.dev/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes) that suggests alternative approaches to useEffect in some scenarios. It might be worth considering if it applies to this particular use case.

In the example provided, they achieve a similar outcome by storing information from previous renders. I took a stab at adapting it here (untested):

const [prevIsOpen, setPrevIsOpen] = useState(isOpen);
if (isOpen !== prevIsOpen) {
  setPrevIsOpen(isOpen);
  if (isOpen) {
    onOpenChange?.(isOpen);
  }
}

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, It seems a very nice idea to avoid useEffect. I'll test and see if it works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tested, actually the onOpenChange is eventually changing the isOpen state. And we shouldn't directly update parent state inside child without useEffect.

I tried though and got the warning : "Cannot update a component (App) while rendering a different component (NextUI.Modal)".

Let me know if I am missing something.

@sanuj21 sanuj21 requested a review from weeix October 17, 2024 10:38
packages/components/modal/src/use-modal.ts Show resolved Hide resolved
Comment on lines +47 to +49
const onOpenChange = useCallback(
(isOpen: boolean) => {
const action = isOpen ? onOpen : onClose;
Copy link
Member

Choose a reason for hiding this comment

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

Since isOpen is managed within useDisclosure whether it is controlled or uncontrolled, is it necessary to pass it as an argument?

Copy link
Contributor Author

@sanuj21 sanuj21 Oct 19, 2024

Choose a reason for hiding this comment

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

Yes, in this case its needed. Because when the onClose is called its modifiying the internal state as I said earlier ( isOpen becomes false), but at this point the isOpen which is in useDisclosure is still true.
Initially the definition of onOpenChange was like this isOpen ? onClose : onOpen, thats why it was working when onClose used to get called.
But now that will cause infinite render due to useEffect, thats why I reversed it and and added and argument.

Copy link
Member

Choose a reason for hiding this comment

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

Isn't that the expected behavior?

  1. You press the close button → state.close (internal state becomes false).
  2. onOpenChange is called (at this point, useDisclosure state is still true).
  3. Since isOpen is true, onClose gets called.
  4. The useDisclosure state becomes false (syncing the internal state with useDisclosure).

Accepting an argument would be a breaking change, so it might be better to leave it as is for backward compatibility.

Copy link
Member

Choose a reason for hiding this comment

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

Could you clarify in what cases the useEffect bug occurs?

Copy link
Contributor Author

@sanuj21 sanuj21 Oct 24, 2024

Choose a reason for hiding this comment

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

Isn't that the expected behavior?

  1. You press the close button → state.close (internal state becomes false).
  2. onOpenChange is called (at this point, useDisclosure state is still true).
  3. Since isOpen is true, onClose gets called.
  4. The useDisclosure state becomes false (syncing the internal state with useDisclosure).

Accepting an argument would be a breaking change, so it might be better to leave it as is for backward compatibility.

  1. You press the open button → external state becomes true. That will remount modal Component.

  2. useOverlayTriggerState will re-run with isOpen true. After this, useEffect will be called and it will call the outer onOpenChange(which was received as prop to modal), without passing argument(( useDisclosure state is true here).

  3. Since isOpen is true, onClose gets called(at this point, useDisclosure state becomes false, but internal state is still true). (Not sync)

  4. Now, you press the close button → state.close (internal state becomes false).

  5. onOpenChange is called (at this point, useDisclosure state is false), which means onOpen gets called but here onClose needs to get called.

Ya, i thought that it might be a breaking change, but we are also passing state while calling onOpenChange from useOverlayTriggerState

onOpenChange: (isOpen) => {

Copy link
Member

Choose a reason for hiding this comment

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

Oh, so the useEffect added in useModal is the issue. Hmm, with the current implementation, it might introduce new bugs. Could you consider exploring alternative implementation methods?

Copy link
Member

Choose a reason for hiding this comment

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

What do you think? @jrgarciadev

@chirokas
Copy link
Contributor

  • The current commit causes onOpenChange to trigger twice when in an uncontrolled state.
  • Should we treat this as incorrect usage rather than a bug? 🤔 See here.

@ryo-manba
Copy link
Member

@chirokas
Thanks for the comment! In basic use cases, it seems that the approach in your example would work well. However, I think this behavior of the Modal is also a bug. I'll be sure to pay attention to onChange in useDisclosure when making fixes. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] - Modal onOpenChange only fires on close
5 participants