@vertisanpro/flowbite-react
Version:
Non-Official React components built for Flowbite and Tailwind CSS
124 lines (123 loc) • 6.62 kB
JavaScript
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { HiEye, HiHeart, HiInformationCircle } from '@vertisanpro/react-icons/hi';
import React, { useState } from 'react';
import { describe, expect, it, vi } from 'vitest';
import { Flowbite } from '../Flowbite';
import { Alert } from './Alert';
describe.concurrent('Components / Alert', () => {
describe.concurrent('A11y', () => {
it('should have `role="alert"`', () => {
render(React.createElement(TestAlert, null));
expect(alert()).toBeInTheDocument();
});
describe('Theme', () => {
it('should use custom `base` classes', () => {
const theme = {
alert: {
color: {
info: 'text-purple-100',
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(TestAlert, null)));
expect(alert()).toHaveClass('text-purple-100');
});
it('should use custom `borderAccent` classes', () => {
const theme = {
alert: {
borderAccent: 'border-t-4 border-purple-500',
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(TestAlert, { withBorderAccent: true })));
expect(alert()).toHaveClass('border-t-4 border-purple-500');
});
it('should use custom `wrapper` classes', () => {
const theme = {
alert: {
wrapper: 'flex items-center',
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(TestAlert, null)));
expect(wrapper()).toHaveClass('flex items-center');
});
it('should use custom `color` classes', () => {
const theme = {
alert: {
closeButton: {
color: {
info: 'text-purple-500 hover:bg-purple-200 dark:text-purple-600 dark:hover:text-purple-300',
},
},
color: {
info: 'text-purple-700 bg-purple-100 border-purple-500 dark:bg-purple-200 dark:text-purple-800',
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(TestAlert, null)));
expect(alert()).toHaveClass('text-purple-700 bg-purple-100 border-purple-500 dark:bg-purple-200 dark:text-purple-800');
expect(dismiss()).toHaveClass('text-purple-500 hover:bg-purple-200 dark:text-purple-600 dark:hover:text-purple-300');
});
it('should use custom `icon`', () => {
const theme = {
alert: {
icon: 'alert-custom-icon',
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(TestAlert, { icon: HiHeart })));
expect(icon()).toHaveClass('alert-custom-icon');
});
it('should show custom `rounded` class', () => {
const theme = {
alert: {
rounded: 'rounded',
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(TestAlert, null)));
expect(alert()).toHaveClass('rounded');
});
});
});
describe.concurrent('Keyboard interactions', () => {
it('should dismiss when `Tab` is pressed to navigate to Dismiss button and `Space` is pressed', async () => {
const onDismiss = vi.fn();
const user = userEvent.setup();
render(React.createElement(Alert, { onDismiss: onDismiss }));
await waitFor(async () => {
await user.tab();
expect(dismiss()).toHaveFocus();
});
await user.keyboard('[Space]');
expect(onDismiss).toHaveBeenCalled();
});
});
describe.concurrent('Props', () => {
it('should call `onDismiss` when clicked', async () => {
const onDismiss = vi.fn();
const user = userEvent.setup();
render(React.createElement(Alert, { onDismiss: onDismiss }));
await user.click(dismiss());
expect(onDismiss).toHaveBeenCalled();
});
});
});
const TestAlert = (props) => {
const [isDismissed, setDismissed] = useState(false);
return (React.createElement(Alert, { ...props, additionalContent: React.createElement(React.Fragment, null,
React.createElement("div", { className: "mb-4 mt-2 text-sm text-cyan-700 dark:text-cyan-800" }, "More info about this info alert goes here. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content."),
React.createElement("div", { className: "flex" },
React.createElement("button", { type: "button", className: "mr-2 inline-flex items-center rounded-lg bg-cyan-700 px-3 py-1.5 text-center text-xs font-medium text-white hover:bg-cyan-800 focus:ring-4 focus:ring-cyan-300 dark:bg-cyan-800 dark:hover:bg-cyan-900" },
React.createElement(HiEye, { className: "-ml-0.5 mr-2 h-4 w-4" }),
"View more"),
React.createElement("button", { type: "button", className: "rounded-lg border border-cyan-700 bg-transparent px-3 py-1.5 text-center text-xs font-medium text-cyan-700 hover:bg-cyan-800 hover:text-white focus:ring-4 focus:ring-cyan-300 dark:border-cyan-800 dark:text-cyan-800 dark:hover:text-white" }, "Dismiss"))), color: "info", icon: HiInformationCircle, onDismiss: () => setDismissed(!isDismissed), rounded: true, withBorderAccent: true }, isDismissed ? 'dismissed' : 'waiting'));
};
const alert = () => screen.getByRole('alert');
const wrapper = () => screen.getByTestId('flowbite-alert-wrapper');
const icon = () => screen.getByTestId('flowbite-alert-icon');
const dismiss = () => screen.getByLabelText('Dismiss');