@hyphen/hyphen-components 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +70 -0
- package/package.json +138 -0
- package/src/components/Alert/Alert.constants.ts +19 -0
- package/src/components/Alert/Alert.mdx +29 -0
- package/src/components/Alert/Alert.module.scss +74 -0
- package/src/components/Alert/Alert.stories.tsx +102 -0
- package/src/components/Alert/Alert.test.tsx +187 -0
- package/src/components/Alert/Alert.tsx +157 -0
- package/src/components/Alert/Alert.types.ts +14 -0
- package/src/components/Badge/Badge.mdx +28 -0
- package/src/components/Badge/Badge.module.scss +155 -0
- package/src/components/Badge/Badge.stories.tsx +52 -0
- package/src/components/Badge/Badge.test.tsx +74 -0
- package/src/components/Badge/Badge.tsx +70 -0
- package/src/components/Box/Box.mdx +259 -0
- package/src/components/Box/Box.module.scss +16 -0
- package/src/components/Box/Box.stories.tsx +1679 -0
- package/src/components/Box/Box.test.tsx +478 -0
- package/src/components/Box/Box.tsx +636 -0
- package/src/components/Button/Button.constants.ts +10 -0
- package/src/components/Button/Button.mdx +71 -0
- package/src/components/Button/Button.module.scss +312 -0
- package/src/components/Button/Button.stories.tsx +117 -0
- package/src/components/Button/Button.test.tsx +460 -0
- package/src/components/Button/Button.tsx +241 -0
- package/src/components/Card/Card.mdx +46 -0
- package/src/components/Card/Card.module.scss +6 -0
- package/src/components/Card/Card.stories.tsx +101 -0
- package/src/components/Card/Card.test.tsx +11 -0
- package/src/components/Card/Card.tsx +61 -0
- package/src/components/Card/components/CardFooter/CardFooter.test.tsx +11 -0
- package/src/components/Card/components/CardFooter/CardFooter.tsx +35 -0
- package/src/components/Card/components/CardHeader/CardHeader.test.tsx +23 -0
- package/src/components/Card/components/CardHeader/CardHeader.tsx +54 -0
- package/src/components/Card/components/CardSection/CardSection.test.tsx +28 -0
- package/src/components/Card/components/CardSection/CardSection.tsx +102 -0
- package/src/components/Card/components/index.ts +3 -0
- package/src/components/CheckboxInput/CheckboxInput.mdx +98 -0
- package/src/components/CheckboxInput/CheckboxInput.stories.tsx +254 -0
- package/src/components/CheckboxInput/CheckboxInput.test.tsx +436 -0
- package/src/components/CheckboxInput/CheckboxInput.tsx +171 -0
- package/src/components/CheckboxInput/components/Checkbox.module.scss +174 -0
- package/src/components/CheckboxInput/components/Checkbox.test.tsx +201 -0
- package/src/components/CheckboxInput/components/Checkbox.tsx +176 -0
- package/src/components/CheckboxInput/components/CheckboxIcon.tsx +71 -0
- package/src/components/DateInput/DateInput.mdx +61 -0
- package/src/components/DateInput/DateInput.stories.tsx +168 -0
- package/src/components/DateInput/DateInput.test.tsx +258 -0
- package/src/components/DateInput/DateInput.tsx +189 -0
- package/src/components/DatePicker/DatePicker.mdx +52 -0
- package/src/components/DatePicker/DatePicker.module.scss +603 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +199 -0
- package/src/components/DatePicker/DatePicker.test.tsx +26 -0
- package/src/components/DatePicker/DatePicker.tsx +138 -0
- package/src/components/Details/Details.mdx +30 -0
- package/src/components/Details/Details.module.scss +32 -0
- package/src/components/Details/Details.stories.tsx +38 -0
- package/src/components/Details/Details.test.tsx +189 -0
- package/src/components/Details/Details.tsx +51 -0
- package/src/components/Details/DetailsSummary.tsx +65 -0
- package/src/components/Drawer/Drawer.mdx +117 -0
- package/src/components/Drawer/Drawer.module.scss +96 -0
- package/src/components/Drawer/Drawer.stories.tsx +380 -0
- package/src/components/Drawer/Drawer.test.tsx +90 -0
- package/src/components/Drawer/Drawer.tsx +249 -0
- package/src/components/FormControl/FormControl.tsx +78 -0
- package/src/components/FormLabel/FormLabel.mdx +24 -0
- package/src/components/FormLabel/FormLabel.module.scss +19 -0
- package/src/components/FormLabel/FormLabel.stories.tsx +20 -0
- package/src/components/FormLabel/FormLabel.test.tsx +35 -0
- package/src/components/FormLabel/FormLabel.tsx +96 -0
- package/src/components/Formik/Formik.mdx +10 -0
- package/src/components/Formik/Formik.stories.tsx +307 -0
- package/src/components/Formik/FormikCheckboxInput/FormikCheckboxInput.test.tsx +172 -0
- package/src/components/Formik/FormikCheckboxInput/FormikCheckboxInput.tsx +41 -0
- package/src/components/Formik/FormikRadioGroup/FormikRadioGroup.test.tsx +205 -0
- package/src/components/Formik/FormikRadioGroup/FormikRadioGroup.tsx +37 -0
- package/src/components/Formik/FormikSelectInput/FormikSelectInput.test.tsx +210 -0
- package/src/components/Formik/FormikSelectInput/FormikSelectInput.tsx +41 -0
- package/src/components/Formik/FormikSelectInputInset/FormikSelectInputInset.test.tsx +153 -0
- package/src/components/Formik/FormikSelectInputInset/FormikSelectInputInset.tsx +44 -0
- package/src/components/Formik/FormikSelectInputNative/FormikSelectInputNative.test.tsx +161 -0
- package/src/components/Formik/FormikSelectInputNative/FormikSelectInputNative.tsx +46 -0
- package/src/components/Formik/FormikTextInput/FormikTextInput.test.tsx +176 -0
- package/src/components/Formik/FormikTextInput/FormikTextInput.tsx +38 -0
- package/src/components/Formik/FormikTextInputInset/FormikTextInputInset.test.tsx +170 -0
- package/src/components/Formik/FormikTextInputInset/FormikTextInputInset.tsx +42 -0
- package/src/components/Formik/FormikTextareaInput/FormikTextareaInput.test.tsx +186 -0
- package/src/components/Formik/FormikTextareaInput/FormikTextareaInput.tsx +42 -0
- package/src/components/Formik/FormikTextareaInputInset/FormikTextareaInputInset.test.tsx +179 -0
- package/src/components/Formik/FormikTextareaInputInset/FormikTextareaInputInset.tsx +42 -0
- package/src/components/Formik/FormikTimePicker/FormikTimePicker.test.tsx +224 -0
- package/src/components/Formik/FormikTimePicker/FormikTimePicker.tsx +37 -0
- package/src/components/Formik/FormikTimePickerNative/FormikTimePickerNative.test.tsx +175 -0
- package/src/components/Formik/FormikTimePickerNative/FormikTimePickerNative.tsx +38 -0
- package/src/components/Formik/FormikToggle/FormikToggle.test.tsx +172 -0
- package/src/components/Formik/FormikToggle/FormikToggle.tsx +38 -0
- package/src/components/Heading/Heading.constants.ts +19 -0
- package/src/components/Heading/Heading.mdx +35 -0
- package/src/components/Heading/Heading.module.scss +5 -0
- package/src/components/Heading/Heading.stories.tsx +90 -0
- package/src/components/Heading/Heading.test.tsx +67 -0
- package/src/components/Heading/Heading.tsx +67 -0
- package/src/components/HelpText/HelpText.module.scss +14 -0
- package/src/components/HelpText/HelpText.tsx +33 -0
- package/src/components/Icon/Icon.mdx +40 -0
- package/src/components/Icon/Icon.stories.tsx +72 -0
- package/src/components/Icon/Icon.test.tsx +30 -0
- package/src/components/Icon/Icon.tsx +61 -0
- package/src/components/InputValidationMessage/InputValidationMessage.module.scss +3 -0
- package/src/components/InputValidationMessage/InputValidationMessage.tsx +27 -0
- package/src/components/Modal/Modal.mdx +60 -0
- package/src/components/Modal/Modal.module.scss +135 -0
- package/src/components/Modal/Modal.stories.tsx +194 -0
- package/src/components/Modal/Modal.test.tsx +81 -0
- package/src/components/Modal/Modal.tsx +174 -0
- package/src/components/Modal/components/ModalBody/ModalBody.test.tsx +20 -0
- package/src/components/Modal/components/ModalBody/ModalBody.tsx +24 -0
- package/src/components/Modal/components/ModalFooter/ModalFooter.test.tsx +32 -0
- package/src/components/Modal/components/ModalFooter/ModalFooter.tsx +37 -0
- package/src/components/Modal/components/ModalHeader/ModalHeader.test.tsx +29 -0
- package/src/components/Modal/components/ModalHeader/ModalHeader.tsx +58 -0
- package/src/components/Modal/components/index.ts +5 -0
- package/src/components/Pagination/Pagination.mdx +26 -0
- package/src/components/Pagination/Pagination.stories.tsx +55 -0
- package/src/components/Pagination/Pagination.test.tsx +225 -0
- package/src/components/Pagination/Pagination.tsx +162 -0
- package/src/components/Pagination/Pagination.utilities.test.ts +133 -0
- package/src/components/Pagination/Pagination.utilities.ts +101 -0
- package/src/components/Popover/Popover.mdx +104 -0
- package/src/components/Popover/Popover.module.scss +74 -0
- package/src/components/Popover/Popover.stories.tsx +471 -0
- package/src/components/Popover/Popover.test.tsx +128 -0
- package/src/components/Popover/Popover.tsx +277 -0
- package/src/components/RadioGroup/RadioGroup.mdx +81 -0
- package/src/components/RadioGroup/RadioGroup.module.scss +23 -0
- package/src/components/RadioGroup/RadioGroup.stories.tsx +375 -0
- package/src/components/RadioGroup/RadioGroup.test.tsx +282 -0
- package/src/components/RadioGroup/RadioGroup.tsx +145 -0
- package/src/components/RadioGroup/RadioInput/RadioInput.module.scss +114 -0
- package/src/components/RadioGroup/RadioInput/RadioInput.test.tsx +156 -0
- package/src/components/RadioGroup/RadioInput/RadioInput.tsx +148 -0
- package/src/components/RadioGroup/RadioInput/RadioInputIcon.tsx +59 -0
- package/src/components/ResponsiveProvider/ResponsiveProvider.mdx +36 -0
- package/src/components/ResponsiveProvider/ResponsiveProvider.stories.tsx +54 -0
- package/src/components/ResponsiveProvider/ResponsiveProvider.test.tsx +70 -0
- package/src/components/ResponsiveProvider/ResponsiveProvider.tsx +73 -0
- package/src/components/SelectInput/SelectInput.mdx +115 -0
- package/src/components/SelectInput/SelectInput.module.scss +357 -0
- package/src/components/SelectInput/SelectInput.stories.tsx +373 -0
- package/src/components/SelectInput/SelectInput.test.tsx +403 -0
- package/src/components/SelectInput/SelectInput.tsx +245 -0
- package/src/components/SelectInputInset/SelectInputInset.mdx +56 -0
- package/src/components/SelectInputInset/SelectInputInset.module.scss +397 -0
- package/src/components/SelectInputInset/SelectInputInset.stories.tsx +189 -0
- package/src/components/SelectInputInset/SelectInputInset.test.tsx +305 -0
- package/src/components/SelectInputInset/SelectInputInset.tsx +235 -0
- package/src/components/SelectInputNative/SelectInputNative.mdx +87 -0
- package/src/components/SelectInputNative/SelectInputNative.module.scss +356 -0
- package/src/components/SelectInputNative/SelectInputNative.stories.tsx +282 -0
- package/src/components/SelectInputNative/SelectInputNative.test.tsx +341 -0
- package/src/components/SelectInputNative/SelectInputNative.tsx +121 -0
- package/src/components/Spinner/Spinner.mdx +29 -0
- package/src/components/Spinner/Spinner.module.scss +16 -0
- package/src/components/Spinner/Spinner.stories.tsx +48 -0
- package/src/components/Spinner/Spinner.test.tsx +47 -0
- package/src/components/Spinner/Spinner.tsx +116 -0
- package/src/components/Table/Table.mdx +216 -0
- package/src/components/Table/Table.module.scss +61 -0
- package/src/components/Table/Table.stories.tsx +884 -0
- package/src/components/Table/Table.test.tsx +437 -0
- package/src/components/Table/Table.tsx +171 -0
- package/src/components/Table/TableBody/TableBody.module.scss +19 -0
- package/src/components/Table/TableBody/TableBody.test.tsx +38 -0
- package/src/components/Table/TableBody/TableBody.tsx +96 -0
- package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.module.scss +47 -0
- package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.test.tsx +81 -0
- package/src/components/Table/TableBody/TableBodyCell/TableBodyCell.tsx +94 -0
- package/src/components/Table/TableHead/TableHead.test.tsx +20 -0
- package/src/components/Table/TableHead/TableHead.tsx +78 -0
- package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.module.scss +72 -0
- package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.test.tsx +187 -0
- package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.tsx +192 -0
- package/src/components/Table/common/TableRow/TableRow.module.scss +5 -0
- package/src/components/Table/common/TableRow/TableRow.test.tsx +52 -0
- package/src/components/Table/common/TableRow/TableRow.tsx +155 -0
- package/src/components/TextInput/TextInput.mdx +96 -0
- package/src/components/TextInput/TextInput.module.scss +405 -0
- package/src/components/TextInput/TextInput.stories.tsx +268 -0
- package/src/components/TextInput/TextInput.test.tsx +231 -0
- package/src/components/TextInput/TextInput.tsx +263 -0
- package/src/components/TextInputInset/TextInputInset.mdx +62 -0
- package/src/components/TextInputInset/TextInputInset.module.scss +418 -0
- package/src/components/TextInputInset/TextInputInset.stories.tsx +213 -0
- package/src/components/TextInputInset/TextInputInset.test.tsx +222 -0
- package/src/components/TextInputInset/TextInputInset.tsx +261 -0
- package/src/components/TextareaInput/TextareaInput.mdx +117 -0
- package/src/components/TextareaInput/TextareaInput.module.scss +275 -0
- package/src/components/TextareaInput/TextareaInput.stories.tsx +293 -0
- package/src/components/TextareaInput/TextareaInput.test.tsx +195 -0
- package/src/components/TextareaInput/TextareaInput.tsx +182 -0
- package/src/components/TextareaInputInset/TextareaInputInset.mdx +55 -0
- package/src/components/TextareaInputInset/TextareaInputInset.module.scss +337 -0
- package/src/components/TextareaInputInset/TextareaInputInset.stories.tsx +160 -0
- package/src/components/TextareaInputInset/TextareaInputInset.test.tsx +199 -0
- package/src/components/TextareaInputInset/TextareaInputInset.tsx +213 -0
- package/src/components/ThemeProvider/ThemeProvider.mdx +11 -0
- package/src/components/ThemeProvider/ThemeProvider.stories.tsx +56 -0
- package/src/components/ThemeProvider/ThemeProvider.tsx +75 -0
- package/src/components/TimePicker/TimePicker.mdx +75 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +149 -0
- package/src/components/TimePicker/TimePicker.test.tsx +97 -0
- package/src/components/TimePicker/TimePicker.tsx +83 -0
- package/src/components/TimePickerNative/TimePickerNative.mdx +67 -0
- package/src/components/TimePickerNative/TimePickerNative.stories.tsx +151 -0
- package/src/components/TimePickerNative/TimePickerNative.test.tsx +117 -0
- package/src/components/TimePickerNative/TimePickerNative.tsx +93 -0
- package/src/components/Toast/Toast.mdx +134 -0
- package/src/components/Toast/Toast.store.ts +280 -0
- package/src/components/Toast/Toast.stories.tsx +283 -0
- package/src/components/Toast/Toast.test.tsx +784 -0
- package/src/components/Toast/Toast.types.ts +98 -0
- package/src/components/Toast/ToastContainer.tsx +170 -0
- package/src/components/Toast/ToastNotification.module.scss +63 -0
- package/src/components/Toast/ToastNotification.tsx +176 -0
- package/src/components/Toast/index.ts +4 -0
- package/src/components/Toast/toast.ts +102 -0
- package/src/components/Toast/useToasts.ts +102 -0
- package/src/components/Toggle/Toggle.mdx +51 -0
- package/src/components/Toggle/Toggle.module.scss +294 -0
- package/src/components/Toggle/Toggle.stories.tsx +128 -0
- package/src/components/Toggle/Toggle.test.tsx +308 -0
- package/src/components/Toggle/Toggle.tsx +184 -0
- package/src/constants/keyCodes.ts +2 -0
- package/src/docs/Brands.mdx +153 -0
- package/src/docs/Colors.mdx +158 -0
- package/src/docs/DesignTokens.mdx +415 -0
- package/src/docs/GetStarted.mdx +47 -0
- package/src/docs/intro.mdx +12 -0
- package/src/fonts/AvenirBold.otf +0 -0
- package/src/fonts/AvenirBold.woff +0 -0
- package/src/fonts/AvenirBold.woff2 +0 -0
- package/src/fonts/AvenirLight.otf +0 -0
- package/src/fonts/AvenirLight.woff +0 -0
- package/src/fonts/AvenirLight.woff2 +0 -0
- package/src/fonts/AvenirRegular.otf +0 -0
- package/src/fonts/AvenirRegular.woff +0 -0
- package/src/fonts/AvenirRegular.woff2 +0 -0
- package/src/fonts/Geist-Bold.otf +0 -0
- package/src/fonts/Geist-Bold.woff +0 -0
- package/src/fonts/Geist-Bold.woff2 +0 -0
- package/src/fonts/Geist-Medium.otf +0 -0
- package/src/fonts/Geist-Medium.woff +0 -0
- package/src/fonts/Geist-Medium.woff2 +0 -0
- package/src/fonts/Geist-Regular.otf +0 -0
- package/src/fonts/Geist-Regular.woff +0 -0
- package/src/fonts/Geist-Regular.woff2 +0 -0
- package/src/fonts/Geist-SemiBold.otf +0 -0
- package/src/fonts/Geist-SemiBold.woff +0 -0
- package/src/fonts/Geist-SemiBold.woff2 +0 -0
- package/src/fonts/GeistMono-Regular.otf +0 -0
- package/src/fonts/GeistMono-Regular.woff +0 -0
- package/src/fonts/GeistMono-Regular.woff2 +0 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useBreakpoint/useBreakpoint.mdx +26 -0
- package/src/hooks/useBreakpoint/useBreakpoint.stories.tsx +30 -0
- package/src/hooks/useBreakpoint/useBreakpoint.test.tsx +19 -0
- package/src/hooks/useBreakpoint/useBreakpoint.ts +50 -0
- package/src/hooks/useIsomorphicLayoutEffect/useIsomorphicLayouEffect.ts +5 -0
- package/src/hooks/useOpenClose/useOpenClose.mdx +15 -0
- package/src/hooks/useOpenClose/useOpenClose.stories.tsx +41 -0
- package/src/hooks/useOpenClose/useOpenClose.test.tsx +119 -0
- package/src/hooks/useOpenClose/useOpenClose.tsx +95 -0
- package/src/hooks/useWindowSize/useWindowSize.mdx +25 -0
- package/src/hooks/useWindowSize/useWindowSize.stories.tsx +35 -0
- package/src/hooks/useWindowSize/useWindowSize.ts +24 -0
- package/src/index.ts +48 -0
- package/src/lib/cssShorthandToClasses.test.ts +149 -0
- package/src/lib/cssShorthandToClasses.ts +133 -0
- package/src/lib/doesStringIncludeCssUnit.ts +6 -0
- package/src/lib/generateResponsiveClasses.test.ts +24 -0
- package/src/lib/generateResponsiveClasses.ts +30 -0
- package/src/lib/getAutoCompleteValue.test.ts +27 -0
- package/src/lib/getAutoCompleteValue.ts +12 -0
- package/src/lib/getColumnKeys.ts +27 -0
- package/src/lib/getDimensionCss.test.ts +148 -0
- package/src/lib/getDimensionCss.ts +73 -0
- package/src/lib/getElementType.test.tsx +42 -0
- package/src/lib/getElementType.ts +42 -0
- package/src/lib/getFlexCss.test.ts +122 -0
- package/src/lib/getFlexCss.ts +67 -0
- package/src/lib/index.ts +15 -0
- package/src/lib/isFunction.ts +6 -0
- package/src/lib/mergeRefs.ts +15 -0
- package/src/lib/prefersReducedMotion.ts +12 -0
- package/src/lib/react-children-utilities/filter.ts +12 -0
- package/src/lib/react-children-utilities/index.ts +1 -0
- package/src/lib/reactRouterClickHandler.ts +37 -0
- package/src/lib/resolveValue.ts +7 -0
- package/src/lib/tokens.ts +139 -0
- package/src/modes.ts +8 -0
- package/src/styles/animation.scss +152 -0
- package/src/styles/cursor.scss +43 -0
- package/src/styles/display.scss +119 -0
- package/src/styles/flex.scss +453 -0
- package/src/styles/fonts.scss +44 -0
- package/src/styles/globals/utilities.scss +4 -0
- package/src/styles/mixins.scss +14 -0
- package/src/styles/overflow.scss +41 -0
- package/src/styles/position.scss +45 -0
- package/src/styles/reset.scss +108 -0
- package/src/styles/text-align.scss +21 -0
- package/src/styles/utilities.scss +9 -0
- package/src/styles/variables/forms.scss +71 -0
- package/src/styles/variables/index.scss +3 -0
- package/src/styles/white-space.scss +21 -0
- package/src/types/index.ts +201 -0
- package/src/types/lib.types.ts +3 -0
|
@@ -0,0 +1,784 @@
|
|
|
1
|
+
import {
|
|
2
|
+
act,
|
|
3
|
+
cleanup,
|
|
4
|
+
fireEvent,
|
|
5
|
+
render,
|
|
6
|
+
screen,
|
|
7
|
+
waitFor,
|
|
8
|
+
} from '@testing-library/react';
|
|
9
|
+
import React, { ReactNode } from 'react';
|
|
10
|
+
import { ToastPosition } from '.';
|
|
11
|
+
import { toast } from './toast';
|
|
12
|
+
import { ToastContainer } from './ToastContainer';
|
|
13
|
+
|
|
14
|
+
Object.defineProperty(window, 'matchMedia', {
|
|
15
|
+
writable: true,
|
|
16
|
+
value: jest.fn().mockImplementation((query) => ({
|
|
17
|
+
matches: false,
|
|
18
|
+
media: query,
|
|
19
|
+
onchange: null,
|
|
20
|
+
addListener: jest.fn(), // Deprecated
|
|
21
|
+
removeListener: jest.fn(), // Deprecated
|
|
22
|
+
addEventListener: jest.fn(),
|
|
23
|
+
removeEventListener: jest.fn(),
|
|
24
|
+
dispatchEvent: jest.fn(),
|
|
25
|
+
})),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function wait(t: number) {
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
window.setTimeout(resolve, t);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe('Toast', () => {
|
|
35
|
+
const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect;
|
|
36
|
+
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
jest.useFakeTimers();
|
|
39
|
+
Element.prototype.getBoundingClientRect = jest.fn(() => ({
|
|
40
|
+
width: 300,
|
|
41
|
+
height: 50,
|
|
42
|
+
top: 0,
|
|
43
|
+
left: 0,
|
|
44
|
+
bottom: 0,
|
|
45
|
+
right: 0,
|
|
46
|
+
x: 0,
|
|
47
|
+
y: 0,
|
|
48
|
+
toJSON: () => {}, // eslint-disable-line
|
|
49
|
+
}));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
afterEach(() => {
|
|
53
|
+
jest.useRealTimers();
|
|
54
|
+
cleanup();
|
|
55
|
+
Element.prototype.getBoundingClientRect = originalGetBoundingClientRect;
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('Default', () => {
|
|
59
|
+
render(<ToastContainer data-testid="toast-container-default" />);
|
|
60
|
+
|
|
61
|
+
expect(screen.getByTestId('toast-container-default')).toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('With Children', () => {
|
|
65
|
+
render(
|
|
66
|
+
<ToastContainer
|
|
67
|
+
data-testid="toast-container-children"
|
|
68
|
+
// eslint-disable-next-line
|
|
69
|
+
children={(t) => (
|
|
70
|
+
<button type="button">{t.message as ReactNode}</button>
|
|
71
|
+
)}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
act(() => {
|
|
76
|
+
toast('test with children function');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
expect(
|
|
80
|
+
screen.getByText('test with children function').closest('button')
|
|
81
|
+
).toBeInTheDocument();
|
|
82
|
+
|
|
83
|
+
act(() => {
|
|
84
|
+
toast.dismiss();
|
|
85
|
+
jest.advanceTimersByTime(1000);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
expect(screen.queryByText('test with children function')).toBe(null);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('With Toasts', () => {
|
|
92
|
+
render(<ToastContainer data-testid="toast-container" />);
|
|
93
|
+
act(() => {
|
|
94
|
+
toast('test blank toast');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(screen.getByText('test blank toast')).toBeInTheDocument();
|
|
98
|
+
|
|
99
|
+
act(() => {
|
|
100
|
+
toast.dismiss();
|
|
101
|
+
jest.advanceTimersByTime(1000);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
expect(screen.queryByText('test blank toast')).toBe(null);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('Positions', () => {
|
|
108
|
+
const positions: ToastPosition[] = [
|
|
109
|
+
'top-left',
|
|
110
|
+
'top-right',
|
|
111
|
+
'top-center',
|
|
112
|
+
'bottom-left',
|
|
113
|
+
'bottom-center',
|
|
114
|
+
'bottom-right',
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
positions.forEach((position) => {
|
|
118
|
+
test(`${position}`, () => {
|
|
119
|
+
render(
|
|
120
|
+
<ToastContainer
|
|
121
|
+
data-testid={`toast-container-${position}`}
|
|
122
|
+
position={position}
|
|
123
|
+
/>
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
act(() => {
|
|
127
|
+
toast(`test position toast ${position}`);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(
|
|
131
|
+
screen.getByTestId(`toast-container-${position}`)
|
|
132
|
+
).toBeInTheDocument();
|
|
133
|
+
|
|
134
|
+
expect(
|
|
135
|
+
screen.getByText(`test position toast ${position}`)
|
|
136
|
+
).toBeInTheDocument();
|
|
137
|
+
|
|
138
|
+
const verticalStyle: React.CSSProperties = position.includes('top')
|
|
139
|
+
? { top: 0 }
|
|
140
|
+
: { bottom: 0 };
|
|
141
|
+
const horizontalStyle = {
|
|
142
|
+
...(position.includes('center') && { justifyContent: 'center' }),
|
|
143
|
+
...(!position.includes('center') &&
|
|
144
|
+
position.includes('right') && { justifyContent: 'flex-end' }),
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
expect(
|
|
148
|
+
screen.getByTestId(`toast-container-${position}`).children[0]
|
|
149
|
+
).toHaveStyle({
|
|
150
|
+
...verticalStyle,
|
|
151
|
+
...horizontalStyle,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
act(() => {
|
|
155
|
+
toast.dismiss();
|
|
156
|
+
jest.advanceTimersByTime(1000);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
expect(screen.queryByText(`test position toast ${position}`)).toBe(
|
|
160
|
+
null
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
positions.forEach((position) => {
|
|
166
|
+
test(`Custom toast positions ${position}`, () => {
|
|
167
|
+
render(<ToastContainer />);
|
|
168
|
+
|
|
169
|
+
act(() => {
|
|
170
|
+
toast(`test custom position toast ${position}`, { position });
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
expect(
|
|
174
|
+
screen.getByText(`test custom position toast ${position}`)
|
|
175
|
+
).toBeInTheDocument();
|
|
176
|
+
|
|
177
|
+
act(() => {
|
|
178
|
+
toast.dismiss();
|
|
179
|
+
jest.advanceTimersByTime(1000);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
expect(
|
|
183
|
+
screen.queryByText(`test custom position toast ${position}`)
|
|
184
|
+
).toBe(null);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
describe('Toast Types', () => {
|
|
190
|
+
test('Success', () => {
|
|
191
|
+
render(<ToastContainer />);
|
|
192
|
+
|
|
193
|
+
act(() => {
|
|
194
|
+
toast.success('test success toast');
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
expect(screen.getByText('test success toast')).toBeInTheDocument();
|
|
198
|
+
|
|
199
|
+
act(() => {
|
|
200
|
+
toast.dismiss();
|
|
201
|
+
jest.advanceTimersByTime(1000);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
expect(screen.queryByText('test success toast')).toBe(null);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test('error', () => {
|
|
208
|
+
render(<ToastContainer />);
|
|
209
|
+
|
|
210
|
+
act(() => {
|
|
211
|
+
toast.error('test error toast');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
expect(screen.getByText('test error toast')).toBeInTheDocument();
|
|
215
|
+
|
|
216
|
+
act(() => {
|
|
217
|
+
toast.dismiss();
|
|
218
|
+
jest.advanceTimersByTime(1000);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
expect(screen.queryByText('test error toast')).toBe(null);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test('Loading', () => {
|
|
225
|
+
render(<ToastContainer />);
|
|
226
|
+
|
|
227
|
+
act(() => {
|
|
228
|
+
toast.loading('test loading toast');
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
expect(screen.getByText('test loading toast')).toBeInTheDocument();
|
|
232
|
+
|
|
233
|
+
act(() => {
|
|
234
|
+
toast.dismiss();
|
|
235
|
+
jest.advanceTimersByTime(1000);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
expect(screen.queryByText('test loading toast')).toBe(null);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test('Custom', () => {
|
|
242
|
+
render(<ToastContainer />);
|
|
243
|
+
|
|
244
|
+
act(() => {
|
|
245
|
+
toast.custom(<p>test custom toast</p>);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
expect(screen.getByText('test custom toast')).toBeInTheDocument();
|
|
249
|
+
|
|
250
|
+
act(() => {
|
|
251
|
+
toast.dismiss();
|
|
252
|
+
jest.advanceTimersByTime(1000);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
expect(screen.queryByText('test custom toast')).toBe(null);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test('Async Success', async () => {
|
|
259
|
+
render(<ToastContainer />);
|
|
260
|
+
|
|
261
|
+
const myPromise = new Promise(async (resolve) => {
|
|
262
|
+
// eslint-disable-line no-async-promise-executor
|
|
263
|
+
await wait(1000);
|
|
264
|
+
resolve('yay');
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
act(() => {
|
|
268
|
+
toast.async(myPromise, {
|
|
269
|
+
loading: 'loading...',
|
|
270
|
+
success: (data) => `success ${data}`,
|
|
271
|
+
error: (err) => `error ${err}`,
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
expect(screen.getByText('loading...')).toBeInTheDocument();
|
|
276
|
+
|
|
277
|
+
act(() => {
|
|
278
|
+
jest.advanceTimersByTime(1000);
|
|
279
|
+
jest.useRealTimers();
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
await waitFor(() => {
|
|
283
|
+
expect(screen.getByText('success yay')).toBeInTheDocument();
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test('Async Error', async () => {
|
|
288
|
+
render(<ToastContainer />);
|
|
289
|
+
|
|
290
|
+
const myPromise = new Promise(async (_resolve, reject) => {
|
|
291
|
+
// eslint-disable-line no-async-promise-executor
|
|
292
|
+
await wait(1000);
|
|
293
|
+
reject('boo'); // eslint-disable-line prefer-promise-reject-errors
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
act(() => {
|
|
297
|
+
toast.async(myPromise, {
|
|
298
|
+
loading: 'loading...',
|
|
299
|
+
success: (data) => `success ${data}`,
|
|
300
|
+
error: (err) => `error ${err}`,
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
expect(screen.getByText('loading...')).toBeInTheDocument();
|
|
305
|
+
|
|
306
|
+
act(() => {
|
|
307
|
+
jest.advanceTimersByTime(1000);
|
|
308
|
+
jest.useRealTimers();
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
await waitFor(() => {
|
|
312
|
+
expect(screen.getByText('error boo')).toBeInTheDocument();
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
test('With children function', async () => {
|
|
317
|
+
render(<ToastContainer />);
|
|
318
|
+
|
|
319
|
+
act(() => {
|
|
320
|
+
toast((t) => (
|
|
321
|
+
<span>
|
|
322
|
+
Custom and
|
|
323
|
+
<b>bold</b>
|
|
324
|
+
<button type="button" onClick={() => toast.dismiss(t.id)}>
|
|
325
|
+
Dismiss
|
|
326
|
+
</button>
|
|
327
|
+
</span>
|
|
328
|
+
));
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
expect(screen.getByText('Custom and')).toBeInTheDocument();
|
|
332
|
+
|
|
333
|
+
act(() => {
|
|
334
|
+
toast.dismiss();
|
|
335
|
+
jest.advanceTimersByTime(1000);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
expect(screen.queryByText('Custom and')).toBe(null);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
test('Compact', async () => {
|
|
343
|
+
render(<ToastContainer data-testid="toast-container" />);
|
|
344
|
+
|
|
345
|
+
act(() => {
|
|
346
|
+
toast('test compact toast', { isCompact: true });
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
expect(screen.getByText('test compact toast')).toBeInTheDocument();
|
|
350
|
+
expect(screen.getByText('test compact toast').parentElement).toHaveClass(
|
|
351
|
+
'p-sm'
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
act(() => {
|
|
355
|
+
toast.dismiss();
|
|
356
|
+
jest.advanceTimersByTime(1000);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
expect(screen.queryByText('test compact toast')).toBe(null);
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
test('Dismissing Toast', async () => {
|
|
363
|
+
render(<ToastContainer data-testid="toast-container" />);
|
|
364
|
+
|
|
365
|
+
act(() => {
|
|
366
|
+
toast('dismissing toast');
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
const closeIcon = await screen.getByTestId('icon-testid--remove');
|
|
370
|
+
const closeButton = closeIcon.closest('button');
|
|
371
|
+
expect(closeButton).toBeInTheDocument();
|
|
372
|
+
|
|
373
|
+
if (closeButton) {
|
|
374
|
+
await act(async () => {
|
|
375
|
+
await fireEvent.click(closeButton);
|
|
376
|
+
jest.advanceTimersByTime(1000);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
expect(screen.queryByText('dismissing toast')).toBe(null);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
test('Non-dismissable toast', async () => {
|
|
384
|
+
render(<ToastContainer data-testid="toast-container" />);
|
|
385
|
+
|
|
386
|
+
act(() => {
|
|
387
|
+
toast('cannot dismiss', { canDismiss: false });
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
await waitFor(() => {
|
|
391
|
+
expect(screen.getByText('cannot dismiss')).toBeInTheDocument();
|
|
392
|
+
expect(screen.queryByTestId('icon-testid--remove-light')).toBe(null);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
act(() => {
|
|
396
|
+
toast.dismiss();
|
|
397
|
+
jest.advanceTimersByTime(1000);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
expect(screen.queryByText('cannot dismiss')).toBe(null);
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
test('Dismiss a single toast', () => {
|
|
404
|
+
render(<ToastContainer data-testid="toast-container" />);
|
|
405
|
+
|
|
406
|
+
let toastId: string;
|
|
407
|
+
|
|
408
|
+
act(() => {
|
|
409
|
+
toast('multiple toasts 1');
|
|
410
|
+
jest.advanceTimersByTime(1500);
|
|
411
|
+
toastId = toast('multiple toasts 2');
|
|
412
|
+
jest.advanceTimersByTime(1000);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
expect(screen.getByText('multiple toasts 1')).toBeInTheDocument();
|
|
416
|
+
expect(screen.getByText('multiple toasts 2')).toBeInTheDocument();
|
|
417
|
+
|
|
418
|
+
act(() => {
|
|
419
|
+
toast.dismiss(toastId);
|
|
420
|
+
jest.advanceTimersByTime(1000);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
expect(screen.getByText('multiple toasts 1')).toBeInTheDocument();
|
|
424
|
+
expect(screen.queryByText('multiple toasts 2')).toBe(null);
|
|
425
|
+
|
|
426
|
+
// cleanup -- dismiss remaining toast.
|
|
427
|
+
act(() => {
|
|
428
|
+
toast.dismiss();
|
|
429
|
+
jest.advanceTimersByTime(1000);
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
describe('Duration', () => {
|
|
434
|
+
/**
|
|
435
|
+
* Based on a default duration time for each toast,
|
|
436
|
+
* we track the state of the toast at various points in time.
|
|
437
|
+
*/
|
|
438
|
+
test('Default duration -- blank toast', async () => {
|
|
439
|
+
render(<ToastContainer />);
|
|
440
|
+
|
|
441
|
+
act(() => {
|
|
442
|
+
toast('default timeout blank toast');
|
|
443
|
+
});
|
|
444
|
+
expect(
|
|
445
|
+
screen.getByText('default timeout blank toast')
|
|
446
|
+
).toBeInTheDocument();
|
|
447
|
+
|
|
448
|
+
// After 3000ms nothing should have changed.
|
|
449
|
+
act(() => {
|
|
450
|
+
jest.advanceTimersByTime(3000);
|
|
451
|
+
});
|
|
452
|
+
expect(
|
|
453
|
+
screen.getByText('default timeout blank toast')
|
|
454
|
+
).toBeInTheDocument();
|
|
455
|
+
|
|
456
|
+
// After 4000ms (3000 + 1000) the toast should still be in the DOM,
|
|
457
|
+
// but not visible. We confirm this with the `not-visible` class.
|
|
458
|
+
act(() => {
|
|
459
|
+
jest.advanceTimersByTime(1000);
|
|
460
|
+
});
|
|
461
|
+
expect(
|
|
462
|
+
screen.getByText('default timeout blank toast')?.parentElement
|
|
463
|
+
).toHaveClass('toast-notification--not-visible');
|
|
464
|
+
|
|
465
|
+
// After another 1000ms the toast is cleared from the DOM completely (after animation is done).
|
|
466
|
+
act(() => {
|
|
467
|
+
jest.advanceTimersByTime(1000);
|
|
468
|
+
});
|
|
469
|
+
expect(screen.queryByText('default timeout blank toast')).toBe(null);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
test('Default duration -- error toast', async () => {
|
|
473
|
+
render(<ToastContainer />);
|
|
474
|
+
|
|
475
|
+
act(() => {
|
|
476
|
+
toast.error('default timeout error toast');
|
|
477
|
+
});
|
|
478
|
+
expect(
|
|
479
|
+
screen.getByText('default timeout error toast')
|
|
480
|
+
).toBeInTheDocument();
|
|
481
|
+
|
|
482
|
+
// After 3000ms nothing should have changed.
|
|
483
|
+
act(() => {
|
|
484
|
+
jest.advanceTimersByTime(3000);
|
|
485
|
+
});
|
|
486
|
+
expect(
|
|
487
|
+
screen.getByText('default timeout error toast')
|
|
488
|
+
).toBeInTheDocument();
|
|
489
|
+
|
|
490
|
+
// After 4000ms (3000 + 1000) the toast should still be in the DOM,
|
|
491
|
+
// but not visible. We confirm this with the `not-visible` class.
|
|
492
|
+
act(() => {
|
|
493
|
+
jest.advanceTimersByTime(1000);
|
|
494
|
+
});
|
|
495
|
+
expect(
|
|
496
|
+
screen.getByText('default timeout error toast')?.parentElement
|
|
497
|
+
).toHaveClass('toast-notification--not-visible');
|
|
498
|
+
|
|
499
|
+
// After another 1000ms the toast is cleared from the DOM completely (after animation is done).
|
|
500
|
+
act(() => {
|
|
501
|
+
jest.advanceTimersByTime(1000);
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
expect(screen.queryByText('default timeout error toast')).toBe(null);
|
|
505
|
+
});
|
|
506
|
+
test('Default duration -- success toast', async () => {
|
|
507
|
+
render(<ToastContainer />);
|
|
508
|
+
|
|
509
|
+
act(() => {
|
|
510
|
+
toast.success('default timeout success toast');
|
|
511
|
+
});
|
|
512
|
+
expect(
|
|
513
|
+
screen.getByText('default timeout success toast')
|
|
514
|
+
).toBeInTheDocument();
|
|
515
|
+
|
|
516
|
+
// After 1000ms nothing should have changed.
|
|
517
|
+
act(() => {
|
|
518
|
+
jest.advanceTimersByTime(1000);
|
|
519
|
+
});
|
|
520
|
+
expect(
|
|
521
|
+
screen.getByText('default timeout success toast')
|
|
522
|
+
).toBeInTheDocument();
|
|
523
|
+
|
|
524
|
+
// After 2000ms (1000 + 1000) the toast should still be in the DOM,
|
|
525
|
+
// but not visible. We confirm this with the `not-visible` class.
|
|
526
|
+
act(() => {
|
|
527
|
+
jest.advanceTimersByTime(1000);
|
|
528
|
+
});
|
|
529
|
+
expect(
|
|
530
|
+
screen.getByText('default timeout success toast')?.parentElement
|
|
531
|
+
).toHaveClass('toast-notification--not-visible');
|
|
532
|
+
|
|
533
|
+
// After another 1000ms the toast is cleared from the DOM completely (after animation is done).
|
|
534
|
+
act(() => {
|
|
535
|
+
jest.advanceTimersByTime(1000);
|
|
536
|
+
});
|
|
537
|
+
expect(screen.queryByText('default timeout success toast')).toBe(null);
|
|
538
|
+
});
|
|
539
|
+
test('Default duration -- loading toast', async () => {
|
|
540
|
+
render(<ToastContainer />);
|
|
541
|
+
|
|
542
|
+
act(() => {
|
|
543
|
+
toast.loading('default timeout loading toast');
|
|
544
|
+
});
|
|
545
|
+
expect(
|
|
546
|
+
screen.getByText('default timeout loading toast')
|
|
547
|
+
).toBeInTheDocument();
|
|
548
|
+
|
|
549
|
+
// After any amount of time nothing should have changed.
|
|
550
|
+
act(() => {
|
|
551
|
+
jest.advanceTimersByTime(999999);
|
|
552
|
+
});
|
|
553
|
+
expect(
|
|
554
|
+
screen.getByText('default timeout loading toast')
|
|
555
|
+
).toBeInTheDocument();
|
|
556
|
+
|
|
557
|
+
// Toast can be dismissed programmatically, however.
|
|
558
|
+
act(() => {
|
|
559
|
+
toast.dismiss();
|
|
560
|
+
jest.advanceTimersByTime(1000);
|
|
561
|
+
});
|
|
562
|
+
expect(screen.queryByText('default timeout loading toast')).toBe(null);
|
|
563
|
+
});
|
|
564
|
+
test('With a custom duration on the container', async () => {
|
|
565
|
+
render(<ToastContainer toastOptions={{ duration: 10000 }} />);
|
|
566
|
+
|
|
567
|
+
act(() => {
|
|
568
|
+
toast('custom timeout on container toast');
|
|
569
|
+
});
|
|
570
|
+
expect(
|
|
571
|
+
screen.getByText('custom timeout on container toast')
|
|
572
|
+
).toBeInTheDocument();
|
|
573
|
+
|
|
574
|
+
// After 8000ms nothing should have changed.
|
|
575
|
+
act(() => {
|
|
576
|
+
jest.advanceTimersByTime(8000);
|
|
577
|
+
});
|
|
578
|
+
expect(
|
|
579
|
+
screen.getByText('custom timeout on container toast')
|
|
580
|
+
).toBeInTheDocument();
|
|
581
|
+
|
|
582
|
+
// after 10000ms toast should be in DOM but not visible.
|
|
583
|
+
act(() => {
|
|
584
|
+
jest.advanceTimersByTime(2000);
|
|
585
|
+
});
|
|
586
|
+
expect(
|
|
587
|
+
screen.getByText('custom timeout on container toast')?.parentElement
|
|
588
|
+
).toHaveClass('toast-notification--not-visible');
|
|
589
|
+
|
|
590
|
+
// after another 1000ms the toast should be removed from the DOM.
|
|
591
|
+
act(() => {
|
|
592
|
+
jest.advanceTimersByTime(1000);
|
|
593
|
+
});
|
|
594
|
+
expect(screen.queryByText('custom timeout on container toast')).toBe(
|
|
595
|
+
null
|
|
596
|
+
);
|
|
597
|
+
});
|
|
598
|
+
test('Overriding container duration in single toast', async () => {
|
|
599
|
+
render(<ToastContainer />);
|
|
600
|
+
|
|
601
|
+
act(() => {
|
|
602
|
+
toast('custom timeout on individual toast', { duration: 10000 });
|
|
603
|
+
});
|
|
604
|
+
expect(
|
|
605
|
+
screen.getByText('custom timeout on individual toast')
|
|
606
|
+
).toBeInTheDocument();
|
|
607
|
+
|
|
608
|
+
// After 8000ms nothing should have changed.
|
|
609
|
+
act(() => {
|
|
610
|
+
jest.advanceTimersByTime(8000);
|
|
611
|
+
});
|
|
612
|
+
expect(
|
|
613
|
+
screen.getByText('custom timeout on individual toast')
|
|
614
|
+
).toBeInTheDocument();
|
|
615
|
+
|
|
616
|
+
// after 10000ms toast should be in DOM but not visible.
|
|
617
|
+
act(() => {
|
|
618
|
+
jest.advanceTimersByTime(2000);
|
|
619
|
+
});
|
|
620
|
+
expect(
|
|
621
|
+
screen.getByText('custom timeout on individual toast')?.parentElement
|
|
622
|
+
).toHaveClass('toast-notification--not-visible');
|
|
623
|
+
|
|
624
|
+
// after another 1000ms the toast should be removed from the DOM.
|
|
625
|
+
act(() => {
|
|
626
|
+
jest.advanceTimersByTime(1000);
|
|
627
|
+
});
|
|
628
|
+
expect(screen.queryByText('custom timeout on individual toast')).toBe(
|
|
629
|
+
null
|
|
630
|
+
);
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
test('Removing Toast', () => {
|
|
635
|
+
render(<ToastContainer data-testid="toast-container" />);
|
|
636
|
+
let toastId: string;
|
|
637
|
+
|
|
638
|
+
act(() => {
|
|
639
|
+
toastId = toast('test remove toast');
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
expect(screen.getByText('test remove toast')).toBeInTheDocument();
|
|
643
|
+
|
|
644
|
+
act(() => {
|
|
645
|
+
toast.remove(toastId);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
expect(screen.queryByText('test remove toast')).toBe(null);
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
test('Pause duration on mouseover', async () => {
|
|
652
|
+
render(<ToastContainer />);
|
|
653
|
+
|
|
654
|
+
act(() => {
|
|
655
|
+
toast('default timeout blank toast');
|
|
656
|
+
});
|
|
657
|
+
expect(screen.getByText('default timeout blank toast')).toBeInTheDocument();
|
|
658
|
+
|
|
659
|
+
// Mousing over the element should delay the duration until toast is dismissed
|
|
660
|
+
await fireEvent.mouseOver(screen.getByText('default timeout blank toast'));
|
|
661
|
+
|
|
662
|
+
// Toast should still be present since user has moused over it.
|
|
663
|
+
act(() => {
|
|
664
|
+
jest.advanceTimersByTime(99999);
|
|
665
|
+
});
|
|
666
|
+
expect(screen.getByText('default timeout blank toast')).toBeInTheDocument();
|
|
667
|
+
|
|
668
|
+
// Mouse out should re-start timer.
|
|
669
|
+
await fireEvent.mouseOut(screen.getByText('default timeout blank toast'));
|
|
670
|
+
|
|
671
|
+
// After 3000ms nothing should have changed.
|
|
672
|
+
act(() => {
|
|
673
|
+
jest.advanceTimersByTime(3000);
|
|
674
|
+
});
|
|
675
|
+
expect(screen.getByText('default timeout blank toast')).toBeInTheDocument();
|
|
676
|
+
|
|
677
|
+
// After 4000ms (3000 + 1000) the toast should still be in the DOM,
|
|
678
|
+
// but not visible. We confirm this with the `not-visible` class.
|
|
679
|
+
act(() => {
|
|
680
|
+
jest.advanceTimersByTime(1000);
|
|
681
|
+
});
|
|
682
|
+
expect(
|
|
683
|
+
screen.getByText('default timeout blank toast')?.parentElement
|
|
684
|
+
).toHaveClass('toast-notification--not-visible');
|
|
685
|
+
|
|
686
|
+
// After another 1000ms the toast is cleared from the DOM completely (after animation is done).
|
|
687
|
+
act(() => {
|
|
688
|
+
jest.advanceTimersByTime(1000);
|
|
689
|
+
});
|
|
690
|
+
expect(screen.queryByText('default timeout blank toast')).toBe(null);
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
test('Toasts in reverse order', () => {
|
|
694
|
+
render(<ToastContainer data-testid="toast-container" reverseOrder />);
|
|
695
|
+
act(() => {
|
|
696
|
+
toast('test reverse order');
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
expect(screen.getByText('test reverse order')).toBeInTheDocument();
|
|
700
|
+
|
|
701
|
+
act(() => {
|
|
702
|
+
toast.dismiss();
|
|
703
|
+
jest.advanceTimersByTime(1000);
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
expect(screen.queryByText('test reverse order')).toBe(null);
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
test('Update Existing Toast', () => {
|
|
710
|
+
render(<ToastContainer />);
|
|
711
|
+
let toastId: string;
|
|
712
|
+
|
|
713
|
+
act(() => {
|
|
714
|
+
toastId = toast('test update toast');
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
expect(screen.getByText('test update toast')).toBeInTheDocument();
|
|
718
|
+
|
|
719
|
+
act(() => {
|
|
720
|
+
toast.success('updated to success', { id: toastId });
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
expect(screen.queryByText('test update toast')).toBe(null);
|
|
724
|
+
expect(screen.getByText('updated to success')).toBeInTheDocument();
|
|
725
|
+
|
|
726
|
+
act(() => {
|
|
727
|
+
toast.remove();
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
expect(screen.queryByText('updated to success')).toBe(null);
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
test('Update after dismiss', () => {
|
|
734
|
+
render(<ToastContainer />);
|
|
735
|
+
let toastId: string;
|
|
736
|
+
|
|
737
|
+
act(() => {
|
|
738
|
+
toastId = toast('update after dismiss');
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
expect(screen.getByText('update after dismiss')).toBeInTheDocument();
|
|
742
|
+
|
|
743
|
+
act(() => {
|
|
744
|
+
toast.dismiss(toastId);
|
|
745
|
+
jest.advanceTimersByTime(100);
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
act(() => {
|
|
749
|
+
toast.success('updated after dismiss to success', { id: toastId });
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
expect(screen.queryByText('update after dismiss')).toBe(null);
|
|
753
|
+
expect(
|
|
754
|
+
screen.getByText('updated after dismiss to success')
|
|
755
|
+
).toBeInTheDocument();
|
|
756
|
+
|
|
757
|
+
act(() => {
|
|
758
|
+
toast.remove();
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
expect(screen.queryByText('updated after dismiss to success')).toBe(null);
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
test('Dismiss toast that is already in dismiss queue', () => {
|
|
765
|
+
render(<ToastContainer data-testid="toast-container" />);
|
|
766
|
+
act(() => {
|
|
767
|
+
toast('dismiss twice');
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
expect(screen.getByText('dismiss twice')).toBeInTheDocument();
|
|
771
|
+
|
|
772
|
+
act(() => {
|
|
773
|
+
toast.dismiss();
|
|
774
|
+
jest.advanceTimersByTime(100);
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
act(() => {
|
|
778
|
+
toast.dismiss();
|
|
779
|
+
jest.advanceTimersByTime(900);
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
expect(screen.queryByText('dismiss twice')).toBe(null);
|
|
783
|
+
});
|
|
784
|
+
});
|