Hone logo
Hone
Problems

Build an Interactive Accordion Component in React (TypeScript)

Create a reusable and accessible accordion component in React using TypeScript. This component will allow users to toggle the visibility of content sections, enhancing user experience by organizing information and saving screen real estate.

Problem Description

Your task is to build a React functional component named Accordion that renders a list of collapsible content panels. Each panel should have a clickable header, and when the header is clicked, its associated content should expand or collapse.

Key Requirements:

  1. Component Structure: The Accordion component should accept an array of objects as a prop, where each object represents a single accordion item. Each item object should have at least a title (string) and content (ReactNode).
  2. State Management: The component must manage which panel is currently open. Only one panel should be open at a time.
  3. Click Behavior: Clicking on an accordion header should toggle its corresponding content. If the clicked header belongs to the currently open panel, it should close it. If it belongs to a closed panel, it should open that panel and close any previously open panel.
  4. Accessibility: Implement basic ARIA attributes to ensure the accordion is accessible to users with assistive technologies. Specifically, consider aria-expanded and aria-controls.
  5. Styling: Provide basic CSS classes for the accordion container, individual items, headers, and content areas, allowing for external styling. The content should be hidden when collapsed.

Expected Behavior:

  • Initially, all panels are collapsed.
  • Clicking a header expands its content.
  • Clicking an already expanded header collapses its content.
  • Clicking a different header expands its content and collapses the previously expanded one.

Edge Cases:

  • An empty array of items should render an empty accordion.
  • Consider how the component should behave if the content prop is empty or null.

Examples

Example 1:

Input data for Accordion component:
[
  { title: "Section 1", content: <p>Content for section 1.</p> },
  { title: "Section 2", content: <p>Content for section 2.</p> }
]

Initial Render Output: A list of two accordion items. Both "Section 1" and "Section 2" headers are visible, and their respective content areas are hidden.

After clicking "Section 1" header: "Section 1" header is visible, its content is visible. "Section 2" header is visible, its content is hidden.

After clicking "Section 2" header (while Section 1 is open): "Section 1" header is visible, its content is hidden. "Section 2" header is visible, its content is visible.

Explanation: The Accordion component receives an array of item objects. It renders each item with a clickable title and a collapsible content section. The component tracks the index of the currently open item to manage expansion and collapse behavior.

Example 2:

Input data for Accordion component:
[]

Render Output: An empty container or a message indicating no items are available.

Explanation: The component gracefully handles an empty array of items, rendering a placeholder or simply nothing.

Constraints

  • The Accordion component must be a functional component.
  • Use TypeScript for type safety.
  • The component should be reasonably performant for up to 50 accordion items.
  • The content prop can be any valid React Node.
  • External CSS should be able to target the provided class names.

Notes

  • Consider using React's useState hook for managing the open panel's index.
  • For accessibility, use appropriate semantic HTML elements and ARIA attributes. Think about role="button", aria-expanded, aria-controls, and id attributes.
  • The transition for expanding/collapsing content can be achieved using CSS. A simple way is to set max-height: 0 and overflow: hidden when collapsed, and max-height: "some large value" or auto when expanded.
  • You will need to define the types for the Accordion component's props.
Loading editor...
typescript