@vertisanpro/flowbite-react
Version:
Non-Official React components built for Flowbite and Tailwind CSS
96 lines (95 loc) • 4.49 kB
JavaScript
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { HiCloudDownload } from '@vertisanpro/react-icons/hi';
import React, { useState } from 'react';
import { describe, expect, it } from 'vitest';
import { Flowbite } from '../Flowbite';
import { ListGroup } from './ListGroup';
describe('Components / List group', () => {
describe('Keyboard interactions', () => {
it('should trigger `onClick` when `Enter` is pressed on a `ListGroup.Item`', async () => {
const user = userEvent.setup();
render(React.createElement(TestListGroup, null));
await user.tab();
await user.keyboard('[Enter]');
const firstItem = items()[0];
expect(firstItem).toHaveAccessibleName('Clicked');
});
it('should trigger `onClick` when `Space` is pressed on a `ListGroup.Item`', async () => {
const user = userEvent.setup();
render(React.createElement(TestListGroup, null));
await user.tab();
await user.keyboard('[Space]');
const firstItem = items()[0];
expect(firstItem).toHaveAccessibleName('Clicked');
});
});
it('should be possible to `Tab` out', async () => {
const user = userEvent.setup();
render(React.createElement(React.Fragment, null,
React.createElement(TestListGroup, null),
React.createElement("button", { "aria-label": "Outside" }, "Outside")));
const outsideButton = screen.getByLabelText('Outside');
await user.tab();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const _ of items()) {
await user.tab();
}
expect(outsideButton).toHaveFocus();
});
describe('Theme', () => {
it('should use custom classes', () => {
const theme = {
listGroup: {
root: {
base: 'text-gray-100',
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(TestListGroup, null))),
expect(listGroup()).toHaveClass('text-gray-100');
});
it('should use custom classes on `ListGroup.Item`', () => {
const theme = {
listGroup: {
item: {
base: 'text-gray-100',
link: {
active: {
off: 'text-gray-400',
on: 'text-gray-200',
},
href: {
off: 'font-bold',
on: 'font-normal',
},
icon: 'text-gray-300',
},
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(TestListGroup, null)));
icons().forEach((icon) => expect(icon).toHaveClass('text-gray-300'));
items().forEach((item) => expect(item.parentNode).toHaveClass('text-gray-100'));
const activeItem = items()[0];
const itemWithHref = items()[1];
[...items().filter((item) => item !== activeItem)].forEach((item) => expect(item).toHaveClass('text-gray-400'));
[...items().filter((item) => item !== itemWithHref)].forEach((item) => expect(item).toHaveClass('font-bold'));
expect(activeItem).toHaveClass('text-gray-200');
expect(itemWithHref).toHaveClass('font-normal');
});
});
});
const TestListGroup = () => {
const [isClicked, setClicked] = useState(false);
return (React.createElement(ListGroup, null,
React.createElement(ListGroup.Item, { active: true, onClick: () => setClicked(!isClicked) }, isClicked ? 'Clicked' : 'Waiting'),
React.createElement(ListGroup.Item, { href: "#" }, "Settings"),
React.createElement(ListGroup.Item, null, "Messages"),
React.createElement(ListGroup.Item, { icon: HiCloudDownload }, "Download")));
};
const listGroup = () => screen.getByRole('list');
const icons = () => screen.getAllByTestId('flowbite-list-group-item-icon');
const items = () => screen.getAllByRole('listitem').map((li) => li.firstElementChild);