Hone logo
Hone
Problems

React Lightbox Component Challenge

Create an accessible and reusable React component that implements a lightbox (also known as a modal or image viewer). This component will allow users to click on an image or a thumbnail and have it display in a larger, overlaying view. This is a common UI pattern for showcasing images in a clean and interactive way.

Problem Description

Your task is to build a Lightbox React component in TypeScript. This component should be able to display an image provided as a prop. When a trigger element (e.g., a thumbnail image) is clicked, the Lightbox should appear, overlaying the current content and displaying the larger image. The lightbox should also provide controls for closing it.

Key Requirements:

  1. Component Structure: Create a Lightbox component that accepts an imageUrl prop (string) for the image to display and a children prop which will act as the trigger to open the lightbox.
  2. Opening the Lightbox: The Lightbox should be initially hidden. It should become visible when the children prop (the trigger) is clicked.
  3. Displaying the Image: When visible, the Lightbox should display the image specified by the imageUrl prop in a larger format.
  4. Closing the Lightbox: The lightbox must have a clear way to be closed. This could be a close button within the lightbox or clicking outside the image area.
  5. Styling: The component should have basic styling to appear as a modal overlay. The background should be semi-transparent, and the image should be centered.
  6. Accessibility: Ensure the component is keyboard accessible. Users should be able to open and close the lightbox using the keyboard (e.g., Tab to focus the trigger, Enter or Space to open, Escape to close). The focused element when the lightbox opens should be managed appropriately.
  7. Reusability: The component should be designed to be easily integrated into different parts of an application.

Expected Behavior:

  • A clickable element (provided as children) is rendered.
  • Clicking this element opens the Lightbox.
  • The Lightbox displays a semi-transparent overlay covering the viewport.
  • The larger image is displayed within the overlay, typically centered.
  • A close button or clicking the overlay closes the Lightbox.
  • Pressing the Escape key closes the Lightbox.

Edge Cases:

  • What happens if imageUrl is not provided? (The component should gracefully handle this, perhaps by not rendering or showing a placeholder).
  • What if the children prop is not a single clickable element? (Focus on the most common use case where children is a single image or link).

Examples

Example 1: Basic Usage

// Parent Component
function App() {
  const imageUrl = "https://via.placeholder.com/800x600.png?text=Large+Image";

  return (
    <div>
      <h1>My Gallery</h1>
      <Lightbox imageUrl={imageUrl}>
        <img
          src="https://via.placeholder.com/150x100.png?text=Thumbnail+1"
          alt="Thumbnail 1"
          style={{ cursor: 'pointer' }}
        />
      </Lightbox>
      <Lightbox imageUrl={imageUrl}>
        <button>Open Image</button>
      </Lightbox>
    </div>
  );
}

Expected Output (Visual):

Initially, you see "My Gallery" followed by a thumbnail image and a button. Clicking either the thumbnail or the button will open the lightbox.

Lightbox Open State Visual:

The entire screen is covered by a semi-transparent dark overlay. In the center, a large image (800x600 placeholder) is displayed. A small "X" icon in the corner of the overlay allows closing.

Explanation:

The Lightbox component wraps a trigger element (img or button). When the trigger is clicked, the Lightbox component manages its own visibility state, rendering the overlay and the larger image.

Example 2: Handling No Image URL

// Parent Component
function App() {
  return (
    <div>
      <h1>My Gallery</h1>
      <Lightbox imageUrl="">
        <img
          src="https://via.placeholder.com/150x100.png?text=Broken+Link+Thumbnail"
          alt="Broken Link Thumbnail"
          style={{ cursor: 'pointer' }}
        />
      </Lightbox>
    </div>
  );
}

Expected Behavior:

Clicking the thumbnail should not open the lightbox, or it should open but display a placeholder or an error message within the lightbox, as no valid imageUrl is provided.

Explanation:

The Lightbox component should detect that imageUrl is an empty string and prevent itself from fully rendering the image display, or render a fallback.

Constraints

  • The solution must be implemented in React using TypeScript.
  • State management for the lightbox's open/closed status should be handled within the Lightbox component itself.
  • The overlay styling should be a fixed position with a high z-index to ensure it's on top of other content.
  • The close button should be visually distinct and easily clickable.
  • Keyboard navigation (focus management, Escape key) is a critical requirement.

Notes

  • Consider using React's useState hook for managing the open/closed state of the lightbox.
  • You will likely need CSS (or a CSS-in-JS solution) to style the overlay and the image.
  • For accessibility, ensure that focus is trapped within the lightbox when it's open and returned to the trigger element when closed.
  • Think about how to prevent scrolling of the background content when the lightbox is open.
  • You might want to add an alt attribute to the displayed image within the lightbox for better accessibility.
Loading editor...
typescript