React Accordion Component with TypeScript
This challenge asks you to build a reusable accordion component in React using TypeScript. Accordions are a common UI element used to display a list of items where only one item is visible at a time, and clicking on an item expands or collapses it. This component will be useful for organizing large amounts of information into a more manageable and user-friendly format.
Problem Description
You need to create a React component called Accordion that renders a list of accordion items. Each item should have a title and a content section. Initially, all content sections should be collapsed. Clicking on a title should toggle the visibility of the corresponding content section. The component should be flexible enough to handle different content types within each accordion item.
Key Requirements:
- TypeScript: The component must be written in TypeScript.
- Props: The component should accept an array of objects as a prop. Each object in the array should have a
title(string) andcontent(React.ReactNode) property. - State: The component should manage the state of which items are expanded.
- Click Handling: Clicking on an accordion title should toggle the expanded state of that item.
- CSS Styling: Basic styling is required to visually represent the accordion (e.g., borders, padding, transitions). You can use inline styles, CSS modules, or a CSS-in-JS library. The focus should be on functionality, but the component should be reasonably presentable.
- Accessibility: Ensure the component is accessible by using appropriate HTML elements and ARIA attributes where necessary (e.g.,
aria-expanded,aria-controls).
Expected Behavior:
- Initially, all accordion items should be collapsed.
- Clicking on an item's title should expand that item and collapse any previously expanded items.
- Clicking on an already expanded item's title should collapse it.
- The content of each item should be rendered correctly when expanded.
- The component should handle different types of content within the
contentprop (e.g., text, images, lists, other components).
Edge Cases to Consider:
- Empty input array: The component should render gracefully if the input array is empty (e.g., display a message like "No items to display").
- Invalid input: Consider how the component should behave if the input array contains objects that don't have
titleorcontentproperties. (You can choose to ignore them or throw an error). - Large number of items: Consider performance implications if the accordion contains a very large number of items. (While not a primary focus, be mindful of potential optimization opportunities).
Examples
Example 1:
Input: [{ title: "Section 1", content: "Content for Section 1" }, { title: "Section 2", content: "Content for Section 2" }]
Output: An accordion with two sections. Initially, both sections are collapsed. Clicking "Section 1" expands it and collapses "Section 2" (if expanded). Clicking "Section 1" again collapses it.
Explanation: The component renders two accordion items, each with a title and content. The state manages the expanded/collapsed state of each item.
Example 2:
Input: [{ title: "Section A", content: <p>This is some <strong>bold</strong> content.</p> }, { title: "Section B", content: <ul><li>Item 1</li><li>Item 2</li></ul> }]
Output: An accordion with two sections. Section A contains a paragraph with bold text, and Section B contains an unordered list. Clicking on the titles toggles the visibility of the content.
Explanation: The component correctly renders React nodes as content within the accordion items.
Example 3: (Edge Case)
Input: []
Output: A message "No items to display" or an empty container.
Explanation: The component handles the case where the input array is empty.
Constraints
- Component Size: The component should be reasonably concise and easy to understand.
- Performance: While not a primary focus, avoid unnecessary re-renders.
- Input Array Size: The input array can contain up to 20 items.
- Content Size: The
contentof each item should not exceed 500 characters. (This is to prevent excessively large content from impacting rendering performance).
Notes
- Consider using the
useStatehook to manage the expanded state of each accordion item. - You can use CSS classes or inline styles to style the accordion.
- Think about how to make the component reusable and configurable.
- Pay attention to accessibility best practices.
- Focus on creating a functional and well-structured component. Don't over-engineer it.