Hone logo
Hone
Problems

React Modal Component with TypeScript

This challenge asks you to build a reusable modal component in React using TypeScript. Modals are essential for displaying important information, confirmations, or forms in a non-intrusive way, and a well-designed, reusable component can significantly improve the user experience and code maintainability of your applications.

Problem Description

You need to create a Modal component that can be opened and closed programmatically. The component should overlay the main content of the page, dimming the background and displaying the modal content in a centered position. The modal should accept a title, a children prop (containing the content to be displayed within the modal), and a function to be called when the modal is closed. The component should also handle keyboard presses (Escape key) to close the modal.

Key Requirements:

  • Overlay: A semi-transparent overlay should cover the background when the modal is open.
  • Centering: The modal content should be centered both horizontally and vertically.
  • Close Function: The component must accept a onClose prop, which is a function that will be called when the modal is closed (either by clicking the close button or pressing Escape).
  • Open/Closed State: The component should manage its own open/closed state.
  • Keyboard Accessibility: Pressing the Escape key should close the modal.
  • TypeScript: The component must be written in TypeScript, with appropriate type definitions for props and state.

Expected Behavior:

  • When the isOpen prop is true, the overlay and modal content should be visible and centered.
  • When the isOpen prop is false, the overlay and modal content should be hidden.
  • Clicking outside the modal content (on the overlay) should trigger the onClose function.
  • Pressing the Escape key should trigger the onClose function.
  • The modal content should be rendered within the modal container.

Edge Cases to Consider:

  • What happens if children is null or undefined? The modal should still render correctly (without content).
  • How should the component handle different screen sizes? (Consider responsiveness, though a full responsive design is not required for this challenge).
  • What happens if onClose is not provided? (The component should still function, perhaps by logging a warning).

Examples

Example 1:

Input:
<Modal isOpen={true} onClose={() => console.log("Modal closed")}>
  <h2>Confirmation</h2>
  <p>Are you sure you want to proceed?</p>
  <button>Confirm</button>
  <button>Cancel</button>
</Modal>
Output:
A modal window appears with the title "Confirmation", the message "Are you sure you want to proceed?", and two buttons labeled "Confirm" and "Cancel". The background is dimmed.
Explanation: The modal is opened and displays the provided content.  Clicking "Cancel" or pressing Escape will call the `onClose` function.

Example 2:

Input:
<Modal isOpen={false} onClose={() => console.log("Modal closed")}>
  <h2>Information</h2>
  <p>This is some important information.</p>
</Modal>
Output:
The modal is not visible. The overlay is not present.
Explanation: The modal is closed because `isOpen` is false.

Example 3: (Edge Case)

Input:
<Modal isOpen={true} onClose={() => console.log("Modal closed")}>
</Modal>
Output:
A modal window appears with a title (empty) and no content. The background is dimmed.
Explanation: The modal renders correctly even when no children are provided.

Constraints

  • The component should be implemented as a functional component using React Hooks.
  • The overlay should have an opacity of 0.5.
  • The modal content should have a maximum width of 500px.
  • The component should be reusable and easily configurable.
  • The solution must be written in TypeScript.

Notes

  • Consider using CSS modules or styled-components for styling. Plain CSS is also acceptable.
  • Think about how to handle focus management when the modal opens and closes (though perfect focus management is not required for this challenge).
  • Focus on creating a clean, well-structured, and maintainable component.
  • The isOpen prop is the primary control for showing/hiding the modal. You don't need to implement a separate "open" button within the component itself.
Loading editor...
typescript