Hone logo
Hone
Problems

React Carousel Component Implementation

Develop a reusable and accessible carousel component in React using TypeScript. This component will allow users to cycle through a collection of items, such as images or content blocks, with intuitive navigation controls. Carousels are a common UI pattern for displaying multiple pieces of content in a limited space, enhancing user experience and engagement.

Problem Description

Your task is to build a React functional component named Carousel that accepts an array of items and renders them in a horizontally scrollable view. The component should provide navigation buttons (previous and next) to allow users to manually cycle through the items.

Key Requirements:

  1. Component Structure: The Carousel component should accept a items prop, which is an array of React nodes (e.g., JSX.Element[]).
  2. Displaying Items: Only one item should be visible at a time. The items should transition horizontally.
  3. Navigation Controls:
    • A "Previous" button that, when clicked, displays the preceding item.
    • A "Next" button that, when clicked, displays the succeeding item.
  4. Looping Behavior: When the user reaches the first item and clicks "Previous", it should wrap around to the last item. Similarly, when the user reaches the last item and clicks "Next", it should wrap around to the first item.
  5. TypeScript: The component and its props must be defined using TypeScript.
  6. Accessibility: Ensure basic accessibility for navigation buttons (e.g., ARIA labels).
  7. Styling: Basic styling should be applied to make the carousel functional and visually presentable. You can use inline styles, CSS modules, or a CSS-in-JS solution of your choice.
  8. No External Libraries: Do not use third-party carousel libraries. Implement the core logic from scratch.

Expected Behavior:

  • When the component mounts, the first item in the items array should be displayed.
  • Clicking "Next" advances the displayed item by one.
  • Clicking "Previous" reverts the displayed item by one.
  • The navigation buttons should be disabled or hidden appropriately when there's only one item or if other edge cases arise. (For this challenge, assume at least one item will be present).

Edge Cases:

  • Empty items array: The component should gracefully handle an empty items array (e.g., render nothing or a placeholder).
  • Single item in items array: The "Previous" and "Next" buttons should be disabled or hidden.

Examples

Example 1: Basic Carousel with Multiple Items

// Input Data
const myItems: JSX.Element[] = [
  <div key={1} style={{ height: '200px', backgroundColor: 'lightblue', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Item 1</div>,
  <div key={2} style={{ height: '200px', backgroundColor: 'lightgreen', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Item 2</div>,
  <div key={3} style={{ height: '200px', backgroundColor: 'lightcoral', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Item 3</div>,
];

// Rendered Component (Initial State)
// The Carousel component will render the first item:
// <div style={{ height: '200px', backgroundColor: 'lightblue', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Item 1</div>
// With "Previous" and "Next" buttons visible.

// After clicking "Next" once:
// <div style={{ height: '200px', backgroundColor: 'lightgreen', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Item 2</div>
// With "Previous" and "Next" buttons visible.

// After clicking "Next" twice more (reaching the end and wrapping around):
// <div style={{ height: '200px', backgroundColor: 'lightblue', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Item 1</div>
// With "Previous" and "Next" buttons visible.

// After clicking "Previous" twice (from the initial state):
// <div style={{ height: '200px', backgroundColor: 'lightcoral', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Item 3</div>
// With "Previous" and "Next" buttons visible.

Explanation: The Carousel component takes an array of div elements. It displays one div at a time and uses "Previous" and "Next" buttons to navigate through them. The navigation wraps around.

Example 2: Carousel with a Single Item

// Input Data
const singleItem: JSX.Element[] = [
  <div key={1} style={{ height: '200px', backgroundColor: 'gold', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Only Item</div>,
];

// Rendered Component
// <div style={{ height: '200px', backgroundColor: 'gold', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>Only Item</div>
// The "Previous" and "Next" buttons should be disabled or hidden.

Explanation: When only one item is provided, the navigation controls are not needed and should be visually disabled or removed.

Example 3: Empty Carousel

// Input Data
const emptyItems: JSX.Element[] = [];

// Rendered Component
// Nothing is rendered, or a placeholder message like "No items to display."

Explanation: The component should handle the case where no items are provided gracefully.

Constraints

  • The items prop will be an array of JSX.Element.
  • The items array can contain zero or more elements.
  • The component should render efficiently, avoiding unnecessary re-renders.
  • The solution must be written in TypeScript.

Notes

  • Consider how you will manage the activeIndex state.
  • Think about the styling of the carousel container and the items to ensure they display correctly.
  • For accessibility, add aria-label attributes to your navigation buttons.
  • The transition between items can be a simple visual change without complex animations for this challenge. Focus on the core functionality.
  • The key prop is crucial when rendering arrays of elements in React. Ensure each item has a unique key.
Loading editor...
typescript