← All tasksReact · Middle
Accordion
Write an Accordion component that receives an array items of { title, content } objects. Each item gets a button with the title text, and content below it when the item is open.
All items start closed. Only one can be open at a time: opening an item closes the other, and clicking the open one again closes it. The button has aria-expanded reflecting the item state.
Ctrl+Enter runs the tests. Tab indents; to leave the editor with the keyboard, press Esc and then Tab. Your code is saved in this browser.
Tests (4)
const items = [{ title: 'Q1', content: 'A1' }, { title: 'Q2', content: 'A2' }]; render(<Accordion items={items} />); expect(screen.queryByText('A1')).toBe(null); expect(screen.queryByText('A2')).toBe(null); expect(screen.getByRole('button', { name: 'Q1' }).getAttribute('aria-expanded')).toBe('false');
const items = [{ title: 'Q1', content: 'A1' }, { title: 'Q2', content: 'A2' }]; render(<Accordion items={items} />); fireEvent.click(screen.getByRole('button', { name: 'Q1' })); expect(screen.getByText('A1')).toBeTruthy(); expect(screen.getByRole('button', { name: 'Q1' }).getAttribute('aria-expanded')).toBe('true');
const items = [{ title: 'Q1', content: 'A1' }, { title: 'Q2', content: 'A2' }]; render(<Accordion items={items} />); fireEvent.click(screen.getByRole('button', { name: 'Q1' })); fireEvent.click(screen.getByRole('button', { name: 'Q2' })); expect(screen.getByText('A2')).toBeTruthy(); expect(screen.queryByText('A1')).toBe(null);
const items = [{ title: 'Q1', content: 'A1' }]; render(<Accordion items={items} />); fireEvent.click(screen.getByRole('button', { name: 'Q1' })); fireEvent.click(screen.getByRole('button', { name: 'Q1' })); expect(screen.queryByText('A1')).toBe(null);