Skip to content

Conversation

@ebbbang
Copy link

@ebbbang ebbbang commented Dec 12, 2025

Summary

Fixes the modal close button to only render when the modal is dismissible. Previously, the X button in the modal header would always display, even when dismissible={false}, which created a confusing UX where the button appeared but had no effect.

Changes

  • Added dismissible prop to ModalContext interface
  • Updated Modal component to pass dismissible through context
  • Modified ModalHeader to conditionally render the close button based on dismissible prop
  • Added 2 new tests to verify the close button visibility behavior
  • Updated existing test to pass dismissible prop where needed

Behavior

  • Before: Close button always visible in modal header
  • After: Close button only visible when dismissible={true}

Test Plan

  • All existing tests pass (11/11 Modal tests)
  • Added test: close button should not render when modal is not dismissible
  • Added test: close button should render when modal is dismissible
  • Manually verified: modal without dismissible prop shows no close button
  • Manually verified: modal with dismissible={true} shows close button

Screenshots

N/A - behavioral change only

These follow the project's conventions from the contributing guide, including the commitizen-style prefix and the Claude Code attribution footer.

Summary by CodeRabbit

Release Notes

  • New Features

    • Modal component now supports a dismissible property to control close button visibility. Developers can configure modals to hide the close button when not needed.
  • Tests

    • Added tests verifying close button behavior based on modal dismissibility configuration.

✏️ Tip: You can customize this high-level summary in your review settings.

The close button in the modal header now only renders when the modal
is dismissible. This prevents confusion where users see a close button
but the modal cannot be dismissed by clicking outside or pressing Escape.

Changes:
- Add dismissible prop to ModalContext
- Conditionally render close button in ModalHeader based on dismissible
- Add tests to verify close button visibility behavior
@changeset-bot
Copy link

changeset-bot bot commented Dec 12, 2025

⚠️ No Changeset found

Latest commit: b49ab1a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@vercel
Copy link

vercel bot commented Dec 12, 2025

@ebbbang is attempting to deploy a commit to the Themesberg Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

Walkthrough

The changes add a dismissible property to the Modal component. This prop is threaded through ModalContext and used in ModalHeader to conditionally render the close button. Tests verify the close button visibility based on the dismissible flag.

Changes

Cohort / File(s) Summary
Dismissible Modal Support
packages/ui/src/components/Modal/ModalContext.tsx, packages/ui/src/components/Modal/Modal.tsx, packages/ui/src/components/Modal/ModalHeader.tsx
Adds optional dismissible property to ModalContextValue interface; Modal now passes dismissible prop to context provider; ModalHeader conditionally renders close button based on dismissible flag from context
Tests
packages/ui/src/components/Modal/Modal.test.tsx
Adds tests verifying close button is not rendered when modal is not dismissible and is rendered when dismissible; updates existing test to include dismissible prop

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

  • Straightforward prop threading through context without complex logic
  • Conditional rendering based on single boolean flag
  • Consistent pattern applied across files with no edge cases
  • Test coverage validates expected behavior

Poem

🐰 A modal now decides its fate,
Dismissible or locked at the gate,
The close button knows when to appear,
Through context it whispers, crystal clear! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly summarizes the main change: hiding the modal close button when the modal is not dismissible, which is the primary focus of all file modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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/ui/src/components/Modal/Modal.tsx (1)

85-85: Consider the breaking change implications of the false default.

With dismissible defaulting to false, existing code that doesn't explicitly pass this prop will no longer show the close button (previously it always showed). While this fixes the inconsistency described in the PR and creates more logical behavior, it could surprise users upgrading the library.

Consider:

  • Adding a migration note in the changelog
  • Documenting the dismissible prop clearly in component documentation
  • Potentially adding a console warning in development mode if the prop is undefined (though this might be too noisy)

Would you like me to help draft migration guidance or documentation for this change?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 850fbd2 and b49ab1a.

📒 Files selected for processing (4)
  • packages/ui/src/components/Modal/Modal.test.tsx (2 hunks)
  • packages/ui/src/components/Modal/Modal.tsx (1 hunks)
  • packages/ui/src/components/Modal/ModalContext.tsx (1 hunks)
  • packages/ui/src/components/Modal/ModalHeader.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/ui/src/components/Modal/ModalHeader.tsx (1)
apps/web/examples/modal/modal.dismissible.tsx (1)
  • dismissible (78-88)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: 🧰 Build
🔇 Additional comments (7)
packages/ui/src/components/Modal/ModalContext.tsx (1)

9-9: LGTM! Clean context extension.

The addition of the optional dismissible property to the context interface is straightforward and follows the existing pattern (similar to the popup property).

packages/ui/src/components/Modal/ModalHeader.tsx (2)

34-34: LGTM! Correct context consumption.

Properly extracts the dismissible flag from the modal context for use in conditional rendering.


68-72: LGTM! Correct conditional rendering.

The close button now only renders when the modal is dismissible, which ensures consistent behavior—non-dismissible modals won't show a close button that wouldn't work anyway. The existing aria-label="Close" maintains accessibility when the button is rendered.

packages/ui/src/components/Modal/Modal.test.tsx (3)

29-41: LGTM! Good test coverage for non-dismissible case.

This test correctly verifies that the close button is not rendered when dismissible is not set (defaults to false). Using queryByLabelText is the right choice since it returns null when the element is not found.


43-55: LGTM! Good test coverage for dismissible case.

This test correctly verifies that the close button is rendered when dismissible={true} is explicitly set.


113-113: LGTM! Correct test update.

This test needs dismissible={true} to ensure the close button is rendered so it can be clicked. Good catch updating this existing test.

packages/ui/src/components/Modal/Modal.tsx (1)

120-120: LGTM! Correctly threads prop through context.

The dismissible prop is now properly passed through the context provider, making it available to ModalHeader for conditional rendering of the close button. This creates consistent behavior where dismissible controls both outside-click dismissal (line 104) and close button visibility.

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.

1 participant