← Усі задачіReact · Middle

Акордеон

Напишіть компонент Accordion, який отримує масив items з об'єктів { title, content }. Для кожного пункту - кнопка з текстом title, а під нею content, якщо пункт відкритий.

Спочатку всі пункти закриті. Водночас відкритий лише один: відкриття пункту закриває інший, а повторне натискання закриває поточний. У кнопки - aria-expanded зі станом пункту.

Тести (4)

  1. 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');
  2. 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');
  3. 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);
  4. 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);