@getmicdrop/svelte-components 5.5.1 → 5.5.5
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/dist/calendar/AboutShow/AboutShow.spec.d.ts +2 -0
- package/dist/calendar/AboutShow/AboutShow.spec.d.ts.map +1 -0
- package/dist/calendar/AboutShow/AboutShow.spec.js +791 -0
- package/dist/calendar/AboutShow/AboutShow.svelte +172 -172
- package/dist/calendar/Calendar/MiniMonthCalendar.spec.d.ts +2 -0
- package/dist/calendar/Calendar/MiniMonthCalendar.spec.d.ts.map +1 -0
- package/dist/calendar/Calendar/MiniMonthCalendar.spec.js +1191 -0
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
- package/dist/calendar/FAQs/FAQs.spec.d.ts +2 -0
- package/dist/calendar/FAQs/FAQs.spec.d.ts.map +1 -0
- package/dist/calendar/FAQs/FAQs.spec.js +238 -0
- package/dist/calendar/FAQs/FAQs.svelte +75 -75
- package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.d.ts +2 -0
- package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.d.ts.map +1 -0
- package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.js +420 -0
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
- package/dist/calendar/OrderSummary/OrderSummary.spec.d.ts +2 -0
- package/dist/calendar/OrderSummary/OrderSummary.spec.d.ts.map +1 -0
- package/dist/calendar/OrderSummary/OrderSummary.spec.js +808 -0
- package/dist/calendar/OrderSummary/OrderSummary.svelte +367 -367
- package/dist/calendar/PublicCard/PublicCard.spec.d.ts +2 -0
- package/dist/calendar/PublicCard/PublicCard.spec.d.ts.map +1 -0
- package/dist/calendar/PublicCard/PublicCard.spec.js +301 -0
- package/dist/calendar/PublicCard/PublicCard.svelte +134 -134
- package/dist/calendar/ShowCard/ShowCard.spec.d.ts +2 -0
- package/dist/calendar/ShowCard/ShowCard.spec.d.ts.map +1 -0
- package/dist/calendar/ShowCard/ShowCard.spec.js +714 -0
- package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
- package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.d.ts +2 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.d.ts.map +1 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.js +241 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
- package/dist/components/Layout/Grid.svelte +4 -4
- package/dist/components/Layout/Section.spec.d.ts +2 -0
- package/dist/components/Layout/Section.spec.d.ts.map +1 -0
- package/dist/components/Layout/Section.spec.js +149 -0
- package/dist/components/Layout/Section.svelte +80 -80
- package/dist/components/Layout/Sidebar.spec.d.ts +2 -0
- package/dist/components/Layout/Sidebar.spec.d.ts.map +1 -0
- package/dist/components/Layout/Sidebar.spec.js +186 -0
- package/dist/components/Layout/Sidebar.svelte +108 -108
- package/dist/components/Layout/Stack.spec.js +3 -3
- package/dist/components/Layout/Stack.svelte +6 -6
- package/dist/constants/formOptions.spec.js +9 -5
- package/dist/constants/validation.js +91 -91
- package/dist/constants/validation.spec.js +64 -64
- package/dist/datetime/__tests__/format.test.js +1 -1
- package/dist/datetime/__tests__/parse.test.js +1 -1
- package/dist/datetime/__tests__/timezone.test.js +124 -2
- package/dist/datetime/parse.js +1 -1
- package/dist/forms/createFieldTracker.spec.d.ts +2 -0
- package/dist/forms/createFieldTracker.spec.d.ts.map +1 -0
- package/dist/forms/createFieldTracker.spec.js +343 -0
- package/dist/forms/createFormStore.spec.d.ts +2 -0
- package/dist/forms/createFormStore.spec.d.ts.map +1 -0
- package/dist/forms/createFormStore.spec.js +689 -0
- package/dist/forms/createFormStore.svelte.js +0 -1
- package/dist/index.d.ts +5 -112
- package/dist/index.js +40 -225
- package/dist/patterns/data/DataGrid.spec.d.ts +2 -0
- package/dist/patterns/data/DataGrid.spec.d.ts.map +1 -0
- package/dist/patterns/data/DataGrid.spec.js +159 -0
- package/dist/patterns/data/DataGrid.svelte +45 -45
- package/dist/patterns/data/DataList.spec.d.ts +2 -0
- package/dist/patterns/data/DataList.spec.d.ts.map +1 -0
- package/dist/patterns/data/DataList.spec.js +158 -0
- package/dist/patterns/data/DataList.svelte +24 -24
- package/dist/patterns/data/DataTable.spec.d.ts +2 -0
- package/dist/patterns/data/DataTable.spec.d.ts.map +1 -0
- package/dist/patterns/data/DataTable.spec.js +196 -0
- package/dist/patterns/data/DataTable.svelte +36 -36
- package/dist/patterns/forms/FormActions.spec.js +95 -88
- package/dist/patterns/forms/FormActions.stories.svelte +97 -97
- package/dist/patterns/forms/FormActions.svelte +46 -46
- package/dist/patterns/forms/FormGrid.spec.d.ts +2 -0
- package/dist/patterns/forms/FormGrid.spec.d.ts.map +1 -0
- package/dist/patterns/forms/FormGrid.spec.js +125 -0
- package/dist/patterns/forms/FormGrid.svelte +33 -33
- package/dist/patterns/forms/FormSection.spec.d.ts +2 -0
- package/dist/patterns/forms/FormSection.spec.d.ts.map +1 -0
- package/dist/patterns/forms/FormSection.spec.js +153 -0
- package/dist/patterns/forms/FormSection.svelte +32 -32
- package/dist/patterns/forms/FormValidationSummary.stories.svelte +83 -83
- package/dist/patterns/forms/FormValidationSummary.svelte +33 -33
- package/dist/patterns/layout/Sidebar.spec.d.ts +2 -0
- package/dist/patterns/layout/Sidebar.spec.d.ts.map +1 -0
- package/dist/patterns/layout/Sidebar.spec.js +159 -0
- package/dist/patterns/layout/Sidebar.svelte +39 -39
- package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
- package/dist/patterns/navigation/BottomNav.svelte +20 -20
- package/dist/patterns/navigation/Header.spec.js +33 -24
- package/dist/patterns/navigation/Header.stories.svelte +77 -77
- package/dist/patterns/navigation/Header.svelte +193 -193
- package/dist/patterns/page/PageHeader.spec.d.ts +2 -0
- package/dist/patterns/page/PageHeader.spec.d.ts.map +1 -0
- package/dist/patterns/page/PageHeader.spec.js +167 -0
- package/dist/patterns/page/PageHeader.svelte +18 -18
- package/dist/patterns/page/PageLayout.spec.d.ts +2 -0
- package/dist/patterns/page/PageLayout.spec.d.ts.map +1 -0
- package/dist/patterns/page/PageLayout.spec.js +145 -0
- package/dist/patterns/page/PageLayout.svelte +40 -40
- package/dist/patterns/page/PageLoader.spec.js +57 -54
- package/dist/patterns/page/PageLoader.stories.svelte +137 -137
- package/dist/patterns/page/PageLoader.svelte +24 -24
- package/dist/patterns/page/SectionHeader.spec.d.ts +2 -0
- package/dist/patterns/page/SectionHeader.spec.d.ts.map +1 -0
- package/dist/patterns/page/SectionHeader.spec.js +197 -0
- package/dist/patterns/page/SectionHeader.svelte +29 -29
- package/dist/presets/badges.js +112 -112
- package/dist/presets/badges.spec.d.ts +2 -0
- package/dist/presets/badges.spec.d.ts.map +1 -0
- package/dist/presets/badges.spec.js +172 -0
- package/dist/presets/buttons.js +76 -76
- package/dist/presets/buttons.spec.d.ts +2 -0
- package/dist/presets/buttons.spec.d.ts.map +1 -0
- package/dist/presets/buttons.spec.js +135 -0
- package/dist/presets/index.js +9 -9
- package/dist/primitives/Accordion/Accordion.spec.d.ts +2 -0
- package/dist/primitives/Accordion/Accordion.spec.d.ts.map +1 -0
- package/dist/primitives/Accordion/Accordion.spec.js +83 -0
- package/dist/primitives/Accordion/Accordion.stories.svelte +75 -75
- package/dist/primitives/Accordion/Accordion.svelte +42 -42
- package/dist/primitives/Accordion/AccordionItem.spec.d.ts +2 -0
- package/dist/primitives/Accordion/AccordionItem.spec.d.ts.map +1 -0
- package/dist/primitives/Accordion/AccordionItem.spec.js +661 -0
- package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte +107 -0
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte.d.ts +35 -0
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Alert/Alert.spec.js +173 -170
- package/dist/primitives/Alert/Alert.stories.svelte +88 -88
- package/dist/primitives/Alert/Alert.svelte +27 -27
- package/dist/primitives/Avatar/Avatar.spec.d.ts +2 -0
- package/dist/primitives/Avatar/Avatar.spec.d.ts.map +1 -0
- package/dist/primitives/Avatar/Avatar.spec.js +211 -0
- package/dist/primitives/Avatar/Avatar.stories.svelte +94 -94
- package/dist/primitives/Avatar/Avatar.svelte +66 -66
- package/dist/primitives/Badges/Badge.spec.js +144 -103
- package/dist/primitives/Badges/Badge.stories.svelte +86 -86
- package/dist/primitives/Badges/Badge.svelte +79 -79
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +136 -127
- package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
- package/dist/primitives/BottomSheet/BottomSheet.svelte +100 -100
- package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte +13 -0
- package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte.d.ts +7 -0
- package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +122 -120
- package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +89 -89
- package/dist/primitives/Button/Button.spec.js +223 -211
- package/dist/primitives/Button/Button.stories.svelte +76 -76
- package/dist/primitives/Button/Button.svelte +270 -270
- package/dist/primitives/Button/ButtonSaveDemo.spec.js +146 -48
- package/dist/primitives/Button/ButtonSaveDemo.svelte +25 -25
- package/dist/primitives/Button/ButtonVariantShowcase.spec.d.ts +2 -0
- package/dist/primitives/Button/ButtonVariantShowcase.spec.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonVariantShowcase.spec.js +202 -0
- package/dist/primitives/Button/ButtonVariantShowcase.svelte +129 -129
- package/dist/primitives/Card.spec.js +49 -49
- package/dist/primitives/Card.stories.svelte +22 -22
- package/dist/primitives/Card.svelte +28 -28
- package/dist/primitives/Checkbox/Checkbox.spec.d.ts +2 -0
- package/dist/primitives/Checkbox/Checkbox.spec.d.ts.map +1 -0
- package/dist/primitives/Checkbox/Checkbox.spec.js +252 -0
- package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -84
- package/dist/primitives/Checkbox/Checkbox.svelte +88 -88
- package/dist/primitives/DarkModeToggle.spec.js +390 -357
- package/dist/primitives/DarkModeToggle.stories.svelte +57 -57
- package/dist/primitives/DarkModeToggle.svelte +136 -136
- package/dist/primitives/Drawer/Drawer.spec.d.ts +2 -0
- package/dist/primitives/Drawer/Drawer.spec.d.ts.map +1 -0
- package/dist/primitives/Drawer/Drawer.spec.js +212 -0
- package/dist/primitives/Drawer/Drawer.stories.svelte +80 -80
- package/dist/primitives/Drawer/Drawer.svelte +120 -120
- package/dist/primitives/Dropdown/Dropdown.spec.d.ts +2 -0
- package/dist/primitives/Dropdown/Dropdown.spec.d.ts.map +1 -0
- package/dist/primitives/Dropdown/Dropdown.spec.js +366 -0
- package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
- package/dist/primitives/Dropdown/Dropdown.svelte +14 -14
- package/dist/primitives/Dropdown/DropdownItem.spec.d.ts +2 -0
- package/dist/primitives/Dropdown/DropdownItem.spec.d.ts.map +1 -0
- package/dist/primitives/Dropdown/DropdownItem.spec.js +182 -0
- package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
- package/dist/primitives/Icons/ArrowLeft.svelte +8 -8
- package/dist/primitives/Icons/ArrowRight.svelte +8 -8
- package/dist/primitives/Icons/Availability.svelte +14 -14
- package/dist/primitives/Icons/Back.svelte +14 -14
- package/dist/primitives/Icons/CheckCircle.svelte +6 -6
- package/dist/primitives/Icons/CheckCircleOutline.svelte +15 -15
- package/dist/primitives/Icons/ChevronLeft.svelte +4 -4
- package/dist/primitives/Icons/ChevronRight.svelte +4 -4
- package/dist/primitives/Icons/Copy.svelte +15 -15
- package/dist/primitives/Icons/Cross.svelte +5 -5
- package/dist/primitives/Icons/DownArrow.svelte +8 -8
- package/dist/primitives/Icons/ErrorCircle.svelte +6 -6
- package/dist/primitives/Icons/FacebookIcon.svelte +2 -2
- package/dist/primitives/Icons/Home.svelte +15 -15
- package/dist/primitives/Icons/Icon.spec.js +169 -169
- package/dist/primitives/Icons/Icon.stories.svelte +100 -100
- package/dist/primitives/Icons/Icon.svelte +52 -52
- package/dist/primitives/Icons/IconGallery.stories.svelte +235 -235
- package/dist/primitives/Icons/Info.svelte +7 -7
- package/dist/primitives/Icons/InstagramIcon.svelte +4 -4
- package/dist/primitives/Icons/LogoInstagram.svelte +2 -2
- package/dist/primitives/Icons/Message.svelte +15 -15
- package/dist/primitives/Icons/MoonIcon.svelte +5 -5
- package/dist/primitives/Icons/More.svelte +21 -21
- package/dist/primitives/Icons/MoreHori.spec.js +61 -61
- package/dist/primitives/Icons/MoreHori.svelte +22 -22
- package/dist/primitives/Icons/Notification.svelte +14 -14
- package/dist/primitives/Icons/Payment.svelte +14 -14
- package/dist/primitives/Icons/Profile.svelte +21 -21
- package/dist/primitives/Icons/Reload.svelte +29 -29
- package/dist/primitives/Icons/Shows.svelte +21 -21
- package/dist/primitives/Icons/Signout.svelte +21 -21
- package/dist/primitives/Icons/SunIcon.svelte +8 -8
- package/dist/primitives/Icons/TiktokIcon.svelte +2 -2
- package/dist/primitives/Icons/TwitterIcon.svelte +2 -2
- package/dist/primitives/Icons/WarningIcon.spec.js +18 -18
- package/dist/primitives/Icons/WarningIcon.svelte +5 -5
- package/dist/primitives/Icons/iconTestUtils.spec.d.ts +2 -0
- package/dist/primitives/Icons/iconTestUtils.spec.d.ts.map +1 -0
- package/dist/primitives/Icons/iconTestUtils.spec.js +235 -0
- package/dist/primitives/Input/Input.spec.js +573 -573
- package/dist/primitives/Input/Input.stories.svelte +139 -139
- package/dist/primitives/Input/Input.svelte +384 -397
- package/dist/primitives/Input/Input.svelte.d.ts.map +1 -1
- package/dist/primitives/Input/Select.spec.js +212 -218
- package/dist/primitives/Input/Select.stories.svelte +112 -112
- package/dist/primitives/Input/Select.svelte +128 -128
- package/dist/primitives/Input/Textarea.spec.d.ts +2 -0
- package/dist/primitives/Input/Textarea.spec.d.ts.map +1 -0
- package/dist/primitives/Input/Textarea.spec.js +255 -0
- package/dist/primitives/Input/Textarea.stories.svelte +137 -137
- package/dist/primitives/Input/Textarea.svelte +35 -35
- package/dist/primitives/Label/Label.spec.d.ts +2 -0
- package/dist/primitives/Label/Label.spec.d.ts.map +1 -0
- package/dist/primitives/Label/Label.spec.js +157 -0
- package/dist/primitives/Label/Label.svelte +37 -37
- package/dist/primitives/Modal/Modal.spec.js +99 -95
- package/dist/primitives/Modal/Modal.stories.svelte +86 -86
- package/dist/primitives/Modal/Modal.svelte +158 -158
- package/dist/primitives/Modal/ModalTestWrapper.svelte +65 -0
- package/dist/primitives/Modal/ModalTestWrapper.svelte.d.ts +23 -0
- package/dist/primitives/Modal/ModalTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/NumberInput/NumberInput.spec.d.ts +2 -0
- package/dist/primitives/NumberInput/NumberInput.spec.d.ts.map +1 -0
- package/dist/primitives/NumberInput/NumberInput.spec.js +235 -0
- package/dist/primitives/NumberInput/NumberInput.svelte +106 -106
- package/dist/primitives/Pagination/Pagination.spec.d.ts +2 -0
- package/dist/primitives/Pagination/Pagination.spec.d.ts.map +1 -0
- package/dist/primitives/Pagination/Pagination.spec.js +266 -0
- package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
- package/dist/primitives/Pagination/Pagination.svelte +261 -261
- package/dist/primitives/Radio/Radio.spec.d.ts +2 -0
- package/dist/primitives/Radio/Radio.spec.d.ts.map +1 -0
- package/dist/primitives/Radio/Radio.spec.js +206 -0
- package/dist/primitives/Radio/Radio.stories.svelte +80 -80
- package/dist/primitives/Radio/Radio.svelte +67 -67
- package/dist/primitives/Skeleton/CardPlaceholder.spec.d.ts +2 -0
- package/dist/primitives/Skeleton/CardPlaceholder.spec.d.ts.map +1 -0
- package/dist/primitives/Skeleton/CardPlaceholder.spec.js +156 -0
- package/dist/primitives/Skeleton/CardPlaceholder.svelte +87 -87
- package/dist/primitives/Skeleton/ImagePlaceholder.spec.d.ts +2 -0
- package/dist/primitives/Skeleton/ImagePlaceholder.spec.d.ts.map +1 -0
- package/dist/primitives/Skeleton/ImagePlaceholder.spec.js +120 -0
- package/dist/primitives/Skeleton/ImagePlaceholder.svelte +59 -59
- package/dist/primitives/Skeleton/ListPlaceholder.spec.d.ts +2 -0
- package/dist/primitives/Skeleton/ListPlaceholder.spec.d.ts.map +1 -0
- package/dist/primitives/Skeleton/ListPlaceholder.spec.js +220 -0
- package/dist/primitives/Skeleton/ListPlaceholder.svelte +76 -76
- package/dist/primitives/Skeleton/Skeleton.spec.d.ts +2 -0
- package/dist/primitives/Skeleton/Skeleton.spec.d.ts.map +1 -0
- package/dist/primitives/Skeleton/Skeleton.spec.js +173 -0
- package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
- package/dist/primitives/Skeleton/Skeleton.svelte +26 -26
- package/dist/primitives/Spinner/Spinner.spec.js +71 -75
- package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
- package/dist/primitives/Spinner/Spinner.svelte +20 -20
- package/dist/primitives/Tabs/TabItem.spec.d.ts +2 -0
- package/dist/primitives/Tabs/TabItem.spec.d.ts.map +1 -0
- package/dist/primitives/Tabs/TabItem.spec.js +130 -0
- package/dist/primitives/Tabs/TabItem.svelte +49 -49
- package/dist/primitives/Tabs/Tabs.spec.d.ts +2 -0
- package/dist/primitives/Tabs/Tabs.spec.d.ts.map +1 -0
- package/dist/primitives/Tabs/Tabs.spec.js +295 -0
- package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
- package/dist/primitives/Tabs/Tabs.svelte +123 -123
- package/dist/primitives/Tabs/TabsWithItems.test.svelte +18 -0
- package/dist/primitives/Tabs/TabsWithItems.test.svelte.d.ts +16 -0
- package/dist/primitives/Tabs/TabsWithItems.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Toggle.spec.js +143 -127
- package/dist/primitives/Toggle.stories.svelte +92 -92
- package/dist/primitives/Toggle.svelte +71 -71
- package/dist/primitives/Typography/Typography.spec.d.ts +2 -0
- package/dist/primitives/Typography/Typography.spec.d.ts.map +1 -0
- package/dist/primitives/Typography/Typography.spec.js +183 -0
- package/dist/primitives/Typography/Typography.svelte +53 -53
- package/dist/primitives/ValidationError.spec.js +103 -103
- package/dist/primitives/ValidationError.stories.svelte +69 -69
- package/dist/primitives/ValidationError.svelte +29 -29
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.js +3 -0
- package/dist/recipes/CropImage/CropImage.spec.js +208 -216
- package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
- package/dist/recipes/CropImage/CropImage.svelte +238 -238
- package/dist/recipes/ImageUploader/ImageUploader.spec.d.ts +2 -0
- package/dist/recipes/ImageUploader/ImageUploader.spec.d.ts.map +1 -0
- package/dist/recipes/ImageUploader/ImageUploader.spec.js +1351 -0
- package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
- package/dist/recipes/ImageUploader/ImageUploader.svelte +804 -804
- package/dist/recipes/SuperLogin/SuperLogin.spec.d.ts +2 -0
- package/dist/recipes/SuperLogin/SuperLogin.spec.d.ts.map +1 -0
- package/dist/recipes/SuperLogin/SuperLogin.spec.js +1436 -0
- package/dist/recipes/SuperLogin/SuperLogin.svelte +7 -6
- package/dist/recipes/SuperLogin/SuperLogin.svelte.d.ts.map +1 -1
- package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
- package/dist/recipes/feedback/EmptyState/EmptyState.spec.d.ts +2 -0
- package/dist/recipes/feedback/EmptyState/EmptyState.spec.d.ts.map +1 -0
- package/dist/recipes/feedback/EmptyState/EmptyState.spec.js +202 -0
- package/dist/recipes/feedback/EmptyState/EmptyState.svelte +1 -1
- package/dist/recipes/feedback/ErrorDisplay.spec.js +69 -69
- package/dist/recipes/feedback/ErrorDisplay.stories.svelte +101 -101
- package/dist/recipes/feedback/ErrorDisplay.svelte +1 -1
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +133 -129
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +157 -157
- package/dist/recipes/fields/CheckboxField.spec.d.ts +2 -0
- package/dist/recipes/fields/CheckboxField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/CheckboxField.spec.js +135 -0
- package/dist/recipes/fields/CheckboxField.svelte +85 -85
- package/dist/recipes/fields/FormField.spec.d.ts +2 -0
- package/dist/recipes/fields/FormField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/FormField.spec.js +159 -0
- package/dist/recipes/fields/FormField.svelte +58 -58
- package/dist/recipes/fields/RadioGroup.spec.d.ts +2 -0
- package/dist/recipes/fields/RadioGroup.spec.d.ts.map +1 -0
- package/dist/recipes/fields/RadioGroup.spec.js +199 -0
- package/dist/recipes/fields/RadioGroup.svelte +95 -95
- package/dist/recipes/fields/SelectField.spec.d.ts +2 -0
- package/dist/recipes/fields/SelectField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/SelectField.spec.js +188 -0
- package/dist/recipes/fields/SelectField.svelte +80 -80
- package/dist/recipes/fields/TextareaField.spec.d.ts +2 -0
- package/dist/recipes/fields/TextareaField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/TextareaField.spec.js +205 -0
- package/dist/recipes/fields/TextareaField.svelte +97 -97
- package/dist/recipes/fields/ToggleField.spec.d.ts +2 -0
- package/dist/recipes/fields/ToggleField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/ToggleField.spec.js +153 -0
- package/dist/recipes/fields/ToggleField.svelte +60 -60
- package/dist/recipes/fields/index.js +7 -7
- package/dist/recipes/inputs/MultiSelect.spec.js +258 -257
- package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
- package/dist/recipes/inputs/MultiSelect.svelte +256 -249
- package/dist/recipes/inputs/MultiSelect.svelte.d.ts +2 -0
- package/dist/recipes/inputs/MultiSelect.svelte.d.ts.map +1 -1
- package/dist/recipes/inputs/OTPInput.spec.js +251 -238
- package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
- package/dist/recipes/inputs/OTPInput.svelte +29 -29
- package/dist/recipes/inputs/PasswordInput.spec.d.ts +2 -0
- package/dist/recipes/inputs/PasswordInput.spec.d.ts.map +1 -0
- package/dist/recipes/inputs/PasswordInput.spec.js +410 -0
- package/dist/recipes/inputs/PasswordInput.svelte +22 -22
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.spec.js +245 -165
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +43 -43
- package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte +71 -0
- package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte.d.ts +9 -0
- package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte.d.ts.map +1 -0
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.spec.js +1139 -193
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +123 -123
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +326 -326
- package/dist/recipes/inputs/Search.spec.d.ts +2 -0
- package/dist/recipes/inputs/Search.spec.d.ts.map +1 -0
- package/dist/recipes/inputs/Search.spec.js +177 -0
- package/dist/recipes/inputs/Search.svelte +37 -37
- package/dist/recipes/inputs/SelectDropdown.spec.d.ts +2 -0
- package/dist/recipes/inputs/SelectDropdown.spec.d.ts.map +1 -0
- package/dist/recipes/inputs/SelectDropdown.spec.js +512 -0
- package/dist/recipes/inputs/SelectDropdown.svelte +57 -57
- package/dist/recipes/modals/AlertModal.spec.d.ts +2 -0
- package/dist/recipes/modals/AlertModal.spec.d.ts.map +1 -0
- package/dist/recipes/modals/AlertModal.spec.js +432 -0
- package/dist/recipes/modals/AlertModal.svelte +130 -130
- package/dist/recipes/modals/ConfirmationModal.spec.js +206 -191
- package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
- package/dist/recipes/modals/ConfirmationModal.svelte +152 -152
- package/dist/recipes/modals/InputModal.spec.d.ts +2 -0
- package/dist/recipes/modals/InputModal.spec.d.ts.map +1 -0
- package/dist/recipes/modals/InputModal.spec.js +872 -0
- package/dist/recipes/modals/InputModal.svelte +182 -182
- package/dist/recipes/modals/ModalStateManager.spec.js +100 -100
- package/dist/recipes/modals/ModalStateManager.svelte +77 -77
- package/dist/recipes/modals/ModalTestWrapper.spec.d.ts +2 -0
- package/dist/recipes/modals/ModalTestWrapper.spec.d.ts.map +1 -0
- package/dist/recipes/modals/ModalTestWrapper.spec.js +502 -0
- package/dist/recipes/modals/ModalTestWrapper.svelte +65 -65
- package/dist/recipes/modals/StatusModal.spec.d.ts +2 -0
- package/dist/recipes/modals/StatusModal.spec.d.ts.map +1 -0
- package/dist/recipes/modals/StatusModal.spec.js +599 -0
- package/dist/recipes/modals/StatusModal.svelte +206 -206
- package/dist/services/EventService.js +75 -75
- package/dist/services/EventService.spec.js +217 -217
- package/dist/services/ShowService.spec.js +345 -342
- package/dist/stores/auth.js +36 -36
- package/dist/stores/auth.spec.js +139 -139
- package/dist/stores/toaster.js +13 -13
- package/dist/stories/ButtonAuditDashboard.spec.d.ts +2 -0
- package/dist/stories/ButtonAuditDashboard.spec.d.ts.map +1 -0
- package/dist/stories/ButtonAuditDashboard.spec.js +913 -0
- package/dist/stories/ButtonAuditReview.spec.d.ts +2 -0
- package/dist/stories/ButtonAuditReview.spec.d.ts.map +1 -0
- package/dist/stories/ButtonAuditReview.spec.js +422 -0
- package/dist/stories/ButtonAuditReview.stories.svelte +14 -14
- package/dist/stories/ButtonAuditReview.svelte +427 -427
- package/dist/stories/ButtonGridView.spec.d.ts +2 -0
- package/dist/stories/ButtonGridView.spec.d.ts.map +1 -0
- package/dist/stories/ButtonGridView.spec.js +667 -0
- package/dist/stories/ButtonShowcase.spec.d.ts +2 -0
- package/dist/stories/ButtonShowcase.spec.d.ts.map +1 -0
- package/dist/stories/ButtonShowcase.spec.js +499 -0
- package/dist/stories/PatternsGallery.spec.d.ts +2 -0
- package/dist/stories/PatternsGallery.spec.d.ts.map +1 -0
- package/dist/stories/PatternsGallery.spec.js +514 -0
- package/dist/stories/PatternsGallery.stories.svelte +19 -19
- package/dist/stories/PatternsGallery.svelte +206 -206
- package/dist/stories/PrimitivesGallery.spec.d.ts +2 -0
- package/dist/stories/PrimitivesGallery.spec.d.ts.map +1 -0
- package/dist/stories/PrimitivesGallery.spec.js +813 -0
- package/dist/stories/PrimitivesGallery.stories.svelte +19 -19
- package/dist/stories/PrimitivesGallery.svelte +725 -725
- package/dist/stories/RecipesGallery.spec.d.ts +2 -0
- package/dist/stories/RecipesGallery.spec.d.ts.map +1 -0
- package/dist/stories/RecipesGallery.spec.js +299 -0
- package/dist/stories/RecipesGallery.stories.svelte +19 -19
- package/dist/stories/RecipesGallery.svelte +271 -271
- package/dist/stories/button-audit-manifest.json +11186 -11186
- package/dist/stripe/useStripeTheme.spec.d.ts +2 -0
- package/dist/stripe/useStripeTheme.spec.d.ts.map +1 -0
- package/dist/stripe/useStripeTheme.spec.js +793 -0
- package/dist/tailwind/preset.cjs +82 -82
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +6 -5
- package/dist/telemetry.spec.js +495 -12
- package/dist/tokens/__tests__/colors.test.d.ts +2 -0
- package/dist/tokens/__tests__/colors.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/colors.test.js +152 -0
- package/dist/tokens/__tests__/radius.test.d.ts +2 -0
- package/dist/tokens/__tests__/radius.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/radius.test.js +118 -0
- package/dist/tokens/__tests__/shadows.test.d.ts +2 -0
- package/dist/tokens/__tests__/shadows.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/shadows.test.js +105 -0
- package/dist/tokens/__tests__/spacing.test.js +11 -8
- package/dist/tokens/__tests__/typography.test.d.ts +2 -0
- package/dist/tokens/__tests__/typography.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/typography.test.js +156 -0
- package/dist/tokens/__tests__/z-index.test.d.ts +2 -0
- package/dist/tokens/__tests__/z-index.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/z-index.test.js +121 -0
- package/dist/tokens/tokens.css +87 -87
- package/dist/utils/apiConfig.spec.js +102 -1
- package/dist/utils/formatters.spec.d.ts +2 -0
- package/dist/utils/formatters.spec.d.ts.map +1 -0
- package/dist/utils/formatters.spec.js +82 -0
- package/dist/utils/transitions.d.ts +24 -0
- package/dist/utils/transitions.d.ts.map +1 -0
- package/dist/utils/transitions.js +62 -0
- package/dist/utils/transitions.spec.d.ts +2 -0
- package/dist/utils/transitions.spec.d.ts.map +1 -0
- package/dist/utils/transitions.spec.js +130 -0
- package/dist/utils/utils.js +354 -354
- package/package.json +288 -283
|
@@ -0,0 +1,872 @@
|
|
|
1
|
+
import { render, screen, waitFor } from "@testing-library/svelte";
|
|
2
|
+
import userEvent from "@testing-library/user-event";
|
|
3
|
+
import { expect, describe, test, vi, afterEach } from "vitest";
|
|
4
|
+
import InputModal from "./InputModal.svelte";
|
|
5
|
+
import { ExclamationTriangleOutline } from "../../primitives/Icons";
|
|
6
|
+
|
|
7
|
+
function setupTest(args = {}) {
|
|
8
|
+
const user = userEvent.setup();
|
|
9
|
+
const { component } = render(InputModal, {
|
|
10
|
+
props: {
|
|
11
|
+
show: true,
|
|
12
|
+
title: "Test Input Modal",
|
|
13
|
+
...args,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
return { user, component };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe("InputModal Component Tests", () => {
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
vi.restoreAllMocks();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Note: Modal renders both mobile sheet and desktop centered versions
|
|
25
|
+
// CSS hides one based on viewport, but in tests both are in DOM
|
|
26
|
+
// Use getAllByText/queryAllByText and check length or first element
|
|
27
|
+
|
|
28
|
+
// Basic rendering tests
|
|
29
|
+
test("Does not render when show is false", () => {
|
|
30
|
+
render(InputModal, { props: { show: false } });
|
|
31
|
+
expect(screen.queryByText("Test Input Modal")).not.toBeInTheDocument();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("Renders when show is true", () => {
|
|
35
|
+
setupTest();
|
|
36
|
+
expect(screen.getAllByText("Test Input Modal").length).toBeGreaterThan(0);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("Displays title", () => {
|
|
40
|
+
setupTest({ title: "Enter Your Name" });
|
|
41
|
+
expect(screen.getAllByText("Enter Your Name").length).toBeGreaterThan(0);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("Displays description", () => {
|
|
45
|
+
setupTest({ description: "Please provide your full name" });
|
|
46
|
+
expect(screen.getAllByText("Please provide your full name").length).toBeGreaterThan(0);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("Hides title when not provided", () => {
|
|
50
|
+
setupTest({ title: "" });
|
|
51
|
+
const headings = screen.queryAllByRole("heading", { level: 3 });
|
|
52
|
+
expect(headings.length).toBe(0);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("Hides description when not provided", () => {
|
|
56
|
+
setupTest({ description: "" });
|
|
57
|
+
const descriptions = screen.queryByText(/Please provide/);
|
|
58
|
+
expect(descriptions).not.toBeInTheDocument();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Input label tests
|
|
62
|
+
test("Displays input label", () => {
|
|
63
|
+
setupTest({ inputLabel: "Email Address" });
|
|
64
|
+
expect(screen.getAllByText("Email Address").length).toBeGreaterThan(0);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("Hides input label when not provided", () => {
|
|
68
|
+
setupTest({ inputLabel: "" });
|
|
69
|
+
const labels = document.querySelectorAll("label");
|
|
70
|
+
expect(labels.length).toBe(0);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Input placeholder tests
|
|
74
|
+
test("Displays input placeholder", () => {
|
|
75
|
+
setupTest({ inputPlaceholder: "Enter your email" });
|
|
76
|
+
expect(screen.getAllByPlaceholderText("Enter your email").length).toBeGreaterThan(0);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Input type tests
|
|
80
|
+
test("Renders text input by default", () => {
|
|
81
|
+
setupTest();
|
|
82
|
+
const inputs = document.querySelectorAll("input[type='text']");
|
|
83
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("Renders email input", () => {
|
|
87
|
+
setupTest({ inputType: "email" });
|
|
88
|
+
const inputs = document.querySelectorAll("input[type='email']");
|
|
89
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("Renders password input", () => {
|
|
93
|
+
setupTest({ inputType: "password" });
|
|
94
|
+
const inputs = document.querySelectorAll("input[type='password']");
|
|
95
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("Renders textarea", () => {
|
|
99
|
+
setupTest({ inputType: "textarea", inputRows: 4 });
|
|
100
|
+
const textareas = document.querySelectorAll("textarea");
|
|
101
|
+
expect(textareas.length).toBeGreaterThan(0);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("Textarea has correct rows", () => {
|
|
105
|
+
setupTest({ inputType: "textarea", inputRows: 6 });
|
|
106
|
+
const textarea = document.querySelector("textarea");
|
|
107
|
+
expect(textarea).toHaveAttribute("rows", "6");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Input value binding tests
|
|
111
|
+
test("Input binds to inputValue", async () => {
|
|
112
|
+
const { user } = setupTest({ inputValue: "initial value" });
|
|
113
|
+
const input = screen.getAllByDisplayValue("initial value")[0];
|
|
114
|
+
expect(input).toBeInTheDocument();
|
|
115
|
+
|
|
116
|
+
await user.clear(input);
|
|
117
|
+
await user.type(input, "new value");
|
|
118
|
+
expect(input).toHaveValue("new value");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("Textarea binds to inputValue", async () => {
|
|
122
|
+
const { user } = setupTest({
|
|
123
|
+
inputType: "textarea",
|
|
124
|
+
inputValue: "initial text"
|
|
125
|
+
});
|
|
126
|
+
const textarea = screen.getAllByDisplayValue("initial text")[0];
|
|
127
|
+
expect(textarea).toBeInTheDocument();
|
|
128
|
+
|
|
129
|
+
await user.clear(textarea);
|
|
130
|
+
await user.type(textarea, "new text");
|
|
131
|
+
expect(textarea).toHaveValue("new text");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Input icon tests
|
|
135
|
+
test("Renders with input icon", () => {
|
|
136
|
+
setupTest({ inputIcon: ExclamationTriangleOutline });
|
|
137
|
+
const iconContainer = document.querySelector(".absolute.inset-y-0.left-0");
|
|
138
|
+
expect(iconContainer).toBeInTheDocument();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("Input has left padding when icon is present", () => {
|
|
142
|
+
setupTest({ inputIcon: ExclamationTriangleOutline });
|
|
143
|
+
const input = document.querySelector("input");
|
|
144
|
+
expect(input).toHaveClass("pl-10");
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("Input has regular padding when no icon", () => {
|
|
148
|
+
setupTest();
|
|
149
|
+
const input = document.querySelector("input");
|
|
150
|
+
expect(input).toHaveClass("px-3");
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Help text tests
|
|
154
|
+
test("Displays help text", () => {
|
|
155
|
+
setupTest({ helpText: "This is a helpful hint" });
|
|
156
|
+
expect(screen.getAllByText("This is a helpful hint").length).toBeGreaterThan(0);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("Hides help text when error is shown", () => {
|
|
160
|
+
setupTest({
|
|
161
|
+
helpText: "This is a helpful hint",
|
|
162
|
+
showError: true,
|
|
163
|
+
errorMessage: "Error message"
|
|
164
|
+
});
|
|
165
|
+
expect(screen.queryByText("This is a helpful hint")).not.toBeInTheDocument();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Email validation tests
|
|
169
|
+
test("Shows email error for invalid email", async () => {
|
|
170
|
+
const { user } = setupTest({ validateEmail: true, inputValue: "" });
|
|
171
|
+
const input = document.querySelector("input");
|
|
172
|
+
|
|
173
|
+
await user.type(input, "invalid-email");
|
|
174
|
+
|
|
175
|
+
await waitFor(() => {
|
|
176
|
+
expect(screen.getAllByText("Please enter a valid email address").length).toBeGreaterThan(0);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("Does not show email error for valid email", async () => {
|
|
181
|
+
const { user } = setupTest({ validateEmail: true, inputValue: "" });
|
|
182
|
+
const input = document.querySelector("input");
|
|
183
|
+
|
|
184
|
+
await user.type(input, "valid@email.com");
|
|
185
|
+
|
|
186
|
+
await waitFor(() => {
|
|
187
|
+
expect(screen.queryByText("Please enter a valid email address")).not.toBeInTheDocument();
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test("Email validation does not run when validateEmail is false", async () => {
|
|
192
|
+
const { user } = setupTest({ validateEmail: false, inputValue: "" });
|
|
193
|
+
const input = document.querySelector("input");
|
|
194
|
+
|
|
195
|
+
await user.type(input, "invalid-email");
|
|
196
|
+
|
|
197
|
+
expect(screen.queryByText("Please enter a valid email address")).not.toBeInTheDocument();
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Error message tests
|
|
201
|
+
test("Shows error message when showError is true", () => {
|
|
202
|
+
setupTest({
|
|
203
|
+
showError: true,
|
|
204
|
+
errorMessage: "This field is required"
|
|
205
|
+
});
|
|
206
|
+
expect(screen.getAllByText("This field is required").length).toBeGreaterThan(0);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test("Error message has error icon", () => {
|
|
210
|
+
setupTest({
|
|
211
|
+
showError: true,
|
|
212
|
+
errorMessage: "This field is required"
|
|
213
|
+
});
|
|
214
|
+
const errorContainer = screen.getAllByText("This field is required")[0].parentElement;
|
|
215
|
+
const icon = errorContainer?.querySelector("svg");
|
|
216
|
+
expect(icon).toBeInTheDocument();
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test("Input has error border when error is shown", () => {
|
|
220
|
+
setupTest({
|
|
221
|
+
showError: true,
|
|
222
|
+
errorMessage: "Error"
|
|
223
|
+
});
|
|
224
|
+
const input = document.querySelector("input");
|
|
225
|
+
expect(input).toHaveClass("border-red-500");
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test("Textarea has error border when error is shown", () => {
|
|
229
|
+
setupTest({
|
|
230
|
+
inputType: "textarea",
|
|
231
|
+
showError: true,
|
|
232
|
+
errorMessage: "Error"
|
|
233
|
+
});
|
|
234
|
+
const textarea = document.querySelector("textarea");
|
|
235
|
+
expect(textarea).toHaveClass("border-red-500");
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test("Email error takes precedence over custom error message", async () => {
|
|
239
|
+
const { user } = setupTest({
|
|
240
|
+
validateEmail: true,
|
|
241
|
+
showError: true,
|
|
242
|
+
errorMessage: "Custom error",
|
|
243
|
+
inputValue: ""
|
|
244
|
+
});
|
|
245
|
+
const input = document.querySelector("input");
|
|
246
|
+
|
|
247
|
+
await user.type(input, "invalid-email");
|
|
248
|
+
|
|
249
|
+
await waitFor(() => {
|
|
250
|
+
expect(screen.getAllByText("Please enter a valid email address").length).toBeGreaterThan(0);
|
|
251
|
+
expect(screen.queryByText("Custom error")).not.toBeInTheDocument();
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Required field tests
|
|
256
|
+
test("Primary button is disabled when required field is empty", () => {
|
|
257
|
+
setupTest({ inputRequired: true, inputValue: "" });
|
|
258
|
+
const buttons = screen.getAllByText("Confirm");
|
|
259
|
+
const primaryButton = buttons[0].closest("button");
|
|
260
|
+
expect(primaryButton).toBeDisabled();
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
test("Primary button is enabled when required field has value", () => {
|
|
264
|
+
setupTest({ inputRequired: true, inputValue: "some value" });
|
|
265
|
+
const buttons = screen.getAllByText("Confirm");
|
|
266
|
+
const primaryButton = buttons[0].closest("button");
|
|
267
|
+
expect(primaryButton).not.toBeDisabled();
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test("Primary button is disabled when required field has only whitespace", () => {
|
|
271
|
+
setupTest({ inputRequired: true, inputValue: " " });
|
|
272
|
+
const buttons = screen.getAllByText("Confirm");
|
|
273
|
+
const primaryButton = buttons[0].closest("button");
|
|
274
|
+
expect(primaryButton).toBeDisabled();
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
test("Input has required attribute when inputRequired is true", () => {
|
|
278
|
+
setupTest({ inputRequired: true });
|
|
279
|
+
const input = document.querySelector("input");
|
|
280
|
+
expect(input).toHaveAttribute("required");
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
// Button text tests
|
|
284
|
+
test("Displays custom primary button text", () => {
|
|
285
|
+
setupTest({ primaryButtonText: "Submit" });
|
|
286
|
+
expect(screen.getAllByText("Submit").length).toBeGreaterThan(0);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
test("Displays default primary button text", () => {
|
|
290
|
+
setupTest();
|
|
291
|
+
expect(screen.getAllByText("Confirm").length).toBeGreaterThan(0);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
test("Displays custom secondary button text", () => {
|
|
295
|
+
setupTest({ secondaryButtonText: "Go Back" });
|
|
296
|
+
expect(screen.getAllByText("Go Back").length).toBeGreaterThan(0);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test("Displays default secondary button text", () => {
|
|
300
|
+
setupTest();
|
|
301
|
+
expect(screen.getAllByText("Cancel").length).toBeGreaterThan(0);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test("Hides secondary button when text is empty", () => {
|
|
305
|
+
setupTest({ secondaryButtonText: "" });
|
|
306
|
+
expect(screen.queryByText("Cancel")).not.toBeInTheDocument();
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
// Button variant tests
|
|
310
|
+
test("Primary button uses blue-solid variant by default", () => {
|
|
311
|
+
setupTest();
|
|
312
|
+
const buttons = screen.getAllByText("Confirm");
|
|
313
|
+
const primaryButton = buttons[0].closest("button");
|
|
314
|
+
expect(primaryButton).toHaveClass("bg-blue-700");
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
test("Primary button uses red-solid variant", () => {
|
|
318
|
+
setupTest({ primaryButtonVariant: "red-solid" });
|
|
319
|
+
const buttons = screen.getAllByText("Confirm");
|
|
320
|
+
const primaryButton = buttons[0].closest("button");
|
|
321
|
+
expect(primaryButton).toHaveClass("bg-red-700");
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
test("Secondary button uses alternative variant", () => {
|
|
325
|
+
setupTest();
|
|
326
|
+
const buttons = screen.getAllByText("Cancel");
|
|
327
|
+
const secondaryButton = buttons[0].closest("button");
|
|
328
|
+
expect(secondaryButton).toHaveClass("border-gray-200");
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Disabled state tests
|
|
332
|
+
test("Input is disabled when disabled prop is true", () => {
|
|
333
|
+
setupTest({ disabled: true });
|
|
334
|
+
const input = document.querySelector("input");
|
|
335
|
+
expect(input).toBeDisabled();
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
test("Textarea is disabled when disabled prop is true", () => {
|
|
339
|
+
setupTest({ inputType: "textarea", disabled: true });
|
|
340
|
+
const textarea = document.querySelector("textarea");
|
|
341
|
+
expect(textarea).toBeDisabled();
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
test("Input is disabled when loading is true", () => {
|
|
345
|
+
setupTest({ loading: true });
|
|
346
|
+
const input = document.querySelector("input");
|
|
347
|
+
expect(input).toBeDisabled();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
test("Primary button is disabled when disabled prop is true", () => {
|
|
351
|
+
setupTest({ disabled: true });
|
|
352
|
+
const buttons = screen.getAllByText("Confirm");
|
|
353
|
+
const primaryButton = buttons[0].closest("button");
|
|
354
|
+
expect(primaryButton).toBeDisabled();
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test("Primary button is disabled when loading is true", () => {
|
|
358
|
+
setupTest({ loading: true });
|
|
359
|
+
const buttons = screen.getAllByText("Confirm");
|
|
360
|
+
const primaryButton = buttons[0].closest("button");
|
|
361
|
+
expect(primaryButton).toBeDisabled();
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test("Primary button is disabled when email is invalid", async () => {
|
|
365
|
+
const { user } = setupTest({ validateEmail: true, inputValue: "" });
|
|
366
|
+
const input = document.querySelector("input");
|
|
367
|
+
|
|
368
|
+
await user.type(input, "invalid-email");
|
|
369
|
+
|
|
370
|
+
await waitFor(() => {
|
|
371
|
+
const buttons = screen.getAllByText("Confirm");
|
|
372
|
+
const primaryButton = buttons[0].closest("button");
|
|
373
|
+
expect(primaryButton).toBeDisabled();
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
test("Secondary button is disabled when disabled prop is true", () => {
|
|
378
|
+
setupTest({ disabled: true });
|
|
379
|
+
const buttons = screen.getAllByText("Cancel");
|
|
380
|
+
const secondaryButton = buttons[0].closest("button");
|
|
381
|
+
expect(secondaryButton).toBeDisabled();
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
test("Secondary button is disabled when loading is true", () => {
|
|
385
|
+
setupTest({ loading: true });
|
|
386
|
+
const buttons = screen.getAllByText("Cancel");
|
|
387
|
+
const secondaryButton = buttons[0].closest("button");
|
|
388
|
+
expect(secondaryButton).toBeDisabled();
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
test("Input has disabled styling", () => {
|
|
392
|
+
setupTest({ disabled: true });
|
|
393
|
+
const input = document.querySelector("input");
|
|
394
|
+
expect(input).toHaveClass("disabled:opacity-50");
|
|
395
|
+
expect(input).toHaveClass("disabled:cursor-not-allowed");
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
// Loading state tests
|
|
399
|
+
test("Primary button shows loading state", () => {
|
|
400
|
+
setupTest({ loading: true });
|
|
401
|
+
const buttons = screen.getAllByText("Confirm");
|
|
402
|
+
const primaryButton = buttons[0].closest("button");
|
|
403
|
+
// Button component handles loading spinner display
|
|
404
|
+
expect(primaryButton).toBeDisabled();
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// Callback tests
|
|
408
|
+
test("Calls onconfirm with input value when primary button clicked", async () => {
|
|
409
|
+
const onconfirm = vi.fn();
|
|
410
|
+
const { user } = setupTest({
|
|
411
|
+
onconfirm,
|
|
412
|
+
inputValue: "test value"
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
const button = screen.getAllByText("Confirm")[0];
|
|
416
|
+
await user.click(button);
|
|
417
|
+
|
|
418
|
+
await waitFor(() => {
|
|
419
|
+
expect(onconfirm).toHaveBeenCalledOnce();
|
|
420
|
+
expect(onconfirm).toHaveBeenCalledWith({ value: "test value" });
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
test("Does not call onconfirm when primary button is disabled", async () => {
|
|
425
|
+
const onconfirm = vi.fn();
|
|
426
|
+
const { user } = setupTest({
|
|
427
|
+
onconfirm,
|
|
428
|
+
disabled: true
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
const button = screen.getAllByText("Confirm")[0];
|
|
432
|
+
await user.click(button);
|
|
433
|
+
|
|
434
|
+
// Wait a bit to ensure no calls were made
|
|
435
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
436
|
+
expect(onconfirm).not.toHaveBeenCalled();
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
test("Calls oncancel when secondary button clicked", async () => {
|
|
440
|
+
const oncancel = vi.fn();
|
|
441
|
+
const { user } = setupTest({ oncancel });
|
|
442
|
+
|
|
443
|
+
const button = screen.getAllByText("Cancel")[0];
|
|
444
|
+
await user.click(button);
|
|
445
|
+
|
|
446
|
+
await waitFor(() => {
|
|
447
|
+
expect(oncancel).toHaveBeenCalledOnce();
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
test("Calls onclose when secondary button clicked", async () => {
|
|
452
|
+
const onclose = vi.fn();
|
|
453
|
+
const { user } = setupTest({ onclose });
|
|
454
|
+
|
|
455
|
+
const button = screen.getAllByText("Cancel")[0];
|
|
456
|
+
await user.click(button);
|
|
457
|
+
|
|
458
|
+
await waitFor(() => {
|
|
459
|
+
expect(onclose).toHaveBeenCalledOnce();
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
test("Does not call oncancel when secondary button is disabled", async () => {
|
|
464
|
+
const oncancel = vi.fn();
|
|
465
|
+
const { user } = setupTest({
|
|
466
|
+
oncancel,
|
|
467
|
+
disabled: true
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
const button = screen.getAllByText("Cancel")[0];
|
|
471
|
+
await user.click(button);
|
|
472
|
+
|
|
473
|
+
// Wait a bit to ensure no calls were made
|
|
474
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
475
|
+
expect(oncancel).not.toHaveBeenCalled();
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
// Close button tests
|
|
479
|
+
test("Shows close button when closeBtn is true", () => {
|
|
480
|
+
setupTest({ closeBtn: true });
|
|
481
|
+
const closeButton = document.querySelector("img[alt='Close']");
|
|
482
|
+
expect(closeButton).toBeInTheDocument();
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
test("Hides close button by default", () => {
|
|
486
|
+
setupTest();
|
|
487
|
+
const closeButton = document.querySelector("img[alt='Close']");
|
|
488
|
+
expect(closeButton).not.toBeInTheDocument();
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
test("Calls onclose when close button is clicked", async () => {
|
|
492
|
+
const onclose = vi.fn();
|
|
493
|
+
const { user } = setupTest({ closeBtn: true, onclose });
|
|
494
|
+
|
|
495
|
+
const closeButton = document.querySelector("img[alt='Close']")?.closest("button");
|
|
496
|
+
await user.click(closeButton);
|
|
497
|
+
|
|
498
|
+
await waitFor(() => {
|
|
499
|
+
expect(onclose).toHaveBeenCalledOnce();
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
test("Close button is disabled when disabled prop is true", () => {
|
|
504
|
+
setupTest({ closeBtn: true, disabled: true });
|
|
505
|
+
const closeButton = document.querySelector("img[alt='Close']")?.closest("button");
|
|
506
|
+
expect(closeButton).toBeDisabled();
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
test("Close button does not call onclose when loading is true", async () => {
|
|
510
|
+
const onclose = vi.fn();
|
|
511
|
+
const { user } = setupTest({ closeBtn: true, loading: true, onclose });
|
|
512
|
+
|
|
513
|
+
const closeButton = document.querySelector("img[alt='Close']")?.closest("button");
|
|
514
|
+
// Button is not visibly disabled but handleClose prevents action
|
|
515
|
+
await user.click(closeButton);
|
|
516
|
+
|
|
517
|
+
// Wait a bit to ensure no calls were made
|
|
518
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
519
|
+
expect(onclose).not.toHaveBeenCalled();
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
test("Does not call onclose when close button is disabled", async () => {
|
|
523
|
+
const onclose = vi.fn();
|
|
524
|
+
const { user } = setupTest({
|
|
525
|
+
closeBtn: true,
|
|
526
|
+
disabled: true,
|
|
527
|
+
onclose
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
const closeButton = document.querySelector("img[alt='Close']")?.closest("button");
|
|
531
|
+
await user.click(closeButton);
|
|
532
|
+
|
|
533
|
+
// Wait a bit to ensure no calls were made
|
|
534
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
535
|
+
expect(onclose).not.toHaveBeenCalled();
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// Size prop test
|
|
539
|
+
test("Passes size prop to Modal", () => {
|
|
540
|
+
setupTest({ size: "large" });
|
|
541
|
+
// Modal component receives the size prop
|
|
542
|
+
expect(screen.getAllByText("Test Input Modal").length).toBeGreaterThan(0);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
test("Uses default size", () => {
|
|
546
|
+
setupTest();
|
|
547
|
+
// Default size is "default"
|
|
548
|
+
expect(screen.getAllByText("Test Input Modal").length).toBeGreaterThan(0);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
test("Accepts small size", () => {
|
|
552
|
+
setupTest({ size: "small" });
|
|
553
|
+
expect(screen.getAllByText("Test Input Modal").length).toBeGreaterThan(0);
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
// Persistent modal tests
|
|
557
|
+
test("Modal is not persistent by default", () => {
|
|
558
|
+
setupTest();
|
|
559
|
+
// persistent prop is passed to Modal component
|
|
560
|
+
expect(screen.getAllByText("Test Input Modal").length).toBeGreaterThan(0);
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
test("Modal can be persistent", () => {
|
|
564
|
+
setupTest({ persistent: true });
|
|
565
|
+
// persistent prop is passed to Modal component
|
|
566
|
+
expect(screen.getAllByText("Test Input Modal").length).toBeGreaterThan(0);
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
// Layout and styling tests
|
|
570
|
+
test("Header has text-left alignment", () => {
|
|
571
|
+
setupTest({ title: "Test Title" });
|
|
572
|
+
const header = screen.getAllByText("Test Title")[0].closest(".text-left");
|
|
573
|
+
expect(header).toBeInTheDocument();
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
test("Body has text-left alignment", () => {
|
|
577
|
+
setupTest({ description: "Test Description" });
|
|
578
|
+
const body = screen.getAllByText("Test Description")[0].closest(".text-left");
|
|
579
|
+
expect(body).toBeInTheDocument();
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
test("Footer buttons have gap spacing", () => {
|
|
583
|
+
setupTest();
|
|
584
|
+
const footer = document.querySelector(".flex.gap-3");
|
|
585
|
+
expect(footer).toBeInTheDocument();
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
test("Input has proper focus styling classes", () => {
|
|
589
|
+
setupTest();
|
|
590
|
+
const input = document.querySelector("input");
|
|
591
|
+
expect(input).toHaveClass("focus:ring-2");
|
|
592
|
+
expect(input).toHaveClass("focus:ring-blue-500");
|
|
593
|
+
expect(input).toHaveClass("focus:border-transparent");
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
test("Textarea has proper focus styling classes", () => {
|
|
597
|
+
setupTest({ inputType: "textarea" });
|
|
598
|
+
const textarea = document.querySelector("textarea");
|
|
599
|
+
expect(textarea).toHaveClass("focus:ring-2");
|
|
600
|
+
expect(textarea).toHaveClass("focus:ring-blue-500");
|
|
601
|
+
expect(textarea).toHaveClass("focus:border-transparent");
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
test("Textarea has resize-none class", () => {
|
|
605
|
+
setupTest({ inputType: "textarea" });
|
|
606
|
+
const textarea = document.querySelector("textarea");
|
|
607
|
+
expect(textarea).toHaveClass("resize-none");
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
test("Input label has proper margin", () => {
|
|
611
|
+
setupTest({ inputLabel: "Test Label" });
|
|
612
|
+
const label = screen.getAllByText("Test Label")[0];
|
|
613
|
+
expect(label).toHaveClass("mb-2");
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
// Dark mode styling tests
|
|
617
|
+
test("Input has dark mode classes", () => {
|
|
618
|
+
setupTest();
|
|
619
|
+
const input = document.querySelector("input");
|
|
620
|
+
expect(input).toHaveClass("dark:bg-gray-700");
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test("Textarea has dark mode classes", () => {
|
|
624
|
+
setupTest({ inputType: "textarea" });
|
|
625
|
+
const textarea = document.querySelector("textarea");
|
|
626
|
+
expect(textarea).toHaveClass("dark:bg-gray-700");
|
|
627
|
+
expect(textarea).toHaveClass("dark:border-gray-600");
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
test("Input has dark mode border classes", () => {
|
|
631
|
+
setupTest();
|
|
632
|
+
const input = document.querySelector("input");
|
|
633
|
+
expect(input).toHaveClass("dark:bg-gray-700");
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
test("Error message has dark mode classes", () => {
|
|
637
|
+
setupTest({
|
|
638
|
+
showError: true,
|
|
639
|
+
errorMessage: "Test error"
|
|
640
|
+
});
|
|
641
|
+
const errorText = screen.getAllByText("Test error")[0];
|
|
642
|
+
expect(errorText).toHaveClass("dark:text-red-400");
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
// Integration tests
|
|
646
|
+
test("Full text input flow", async () => {
|
|
647
|
+
const onconfirm = vi.fn();
|
|
648
|
+
const onclose = vi.fn();
|
|
649
|
+
const { user } = setupTest({
|
|
650
|
+
title: "Enter Name",
|
|
651
|
+
description: "Please enter your full name",
|
|
652
|
+
inputLabel: "Full Name",
|
|
653
|
+
inputPlaceholder: "John Doe",
|
|
654
|
+
inputRequired: true,
|
|
655
|
+
primaryButtonText: "Submit",
|
|
656
|
+
onconfirm,
|
|
657
|
+
onclose,
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
// Verify content
|
|
661
|
+
expect(screen.getAllByText("Enter Name").length).toBeGreaterThan(0);
|
|
662
|
+
expect(screen.getAllByText("Please enter your full name").length).toBeGreaterThan(0);
|
|
663
|
+
expect(screen.getAllByText("Full Name").length).toBeGreaterThan(0);
|
|
664
|
+
|
|
665
|
+
// Primary button should be disabled (empty required field)
|
|
666
|
+
let button = screen.getAllByText("Submit")[0].closest("button");
|
|
667
|
+
expect(button).toBeDisabled();
|
|
668
|
+
|
|
669
|
+
// Type in input
|
|
670
|
+
const input = screen.getAllByPlaceholderText("John Doe")[0];
|
|
671
|
+
await user.type(input, "Jane Smith");
|
|
672
|
+
|
|
673
|
+
// Primary button should now be enabled
|
|
674
|
+
await waitFor(() => {
|
|
675
|
+
button = screen.getAllByText("Submit")[0].closest("button");
|
|
676
|
+
expect(button).not.toBeDisabled();
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
// Click submit
|
|
680
|
+
await user.click(button);
|
|
681
|
+
|
|
682
|
+
// Verify callback was called with input value
|
|
683
|
+
await waitFor(() => {
|
|
684
|
+
expect(onconfirm).toHaveBeenCalledOnce();
|
|
685
|
+
expect(onconfirm).toHaveBeenCalledWith({ value: "Jane Smith" });
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
test("Full email validation flow", async () => {
|
|
690
|
+
const onconfirm = vi.fn();
|
|
691
|
+
const { user } = setupTest({
|
|
692
|
+
title: "Enter Email",
|
|
693
|
+
inputLabel: "Email Address",
|
|
694
|
+
inputType: "email",
|
|
695
|
+
validateEmail: true,
|
|
696
|
+
inputRequired: true,
|
|
697
|
+
onconfirm,
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
const input = document.querySelector("input");
|
|
701
|
+
|
|
702
|
+
// Type invalid email
|
|
703
|
+
await user.type(input, "invalid-email");
|
|
704
|
+
|
|
705
|
+
await waitFor(() => {
|
|
706
|
+
// Should show error
|
|
707
|
+
expect(screen.getAllByText("Please enter a valid email address").length).toBeGreaterThan(0);
|
|
708
|
+
|
|
709
|
+
// Primary button should be disabled
|
|
710
|
+
const button = screen.getAllByText("Confirm")[0].closest("button");
|
|
711
|
+
expect(button).toBeDisabled();
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
// Clear and type valid email
|
|
715
|
+
await user.clear(input);
|
|
716
|
+
await user.type(input, "valid@email.com");
|
|
717
|
+
|
|
718
|
+
await waitFor(() => {
|
|
719
|
+
// Error should be gone
|
|
720
|
+
expect(screen.queryByText("Please enter a valid email address")).not.toBeInTheDocument();
|
|
721
|
+
|
|
722
|
+
// Primary button should be enabled
|
|
723
|
+
const button = screen.getAllByText("Confirm")[0].closest("button");
|
|
724
|
+
expect(button).not.toBeDisabled();
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
// Click confirm
|
|
728
|
+
const button = screen.getAllByText("Confirm")[0].closest("button");
|
|
729
|
+
await user.click(button);
|
|
730
|
+
|
|
731
|
+
// Verify callback
|
|
732
|
+
await waitFor(() => {
|
|
733
|
+
expect(onconfirm).toHaveBeenCalledOnce();
|
|
734
|
+
expect(onconfirm).toHaveBeenCalledWith({ value: "valid@email.com" });
|
|
735
|
+
});
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
test("Full textarea flow", async () => {
|
|
739
|
+
const onconfirm = vi.fn();
|
|
740
|
+
const oncancel = vi.fn();
|
|
741
|
+
const { user } = setupTest({
|
|
742
|
+
title: "Leave a Comment",
|
|
743
|
+
inputType: "textarea",
|
|
744
|
+
inputRows: 5,
|
|
745
|
+
inputLabel: "Your Comment",
|
|
746
|
+
inputPlaceholder: "Type your comment here...",
|
|
747
|
+
helpText: "Maximum 500 characters",
|
|
748
|
+
primaryButtonText: "Post Comment",
|
|
749
|
+
secondaryButtonText: "Discard",
|
|
750
|
+
onconfirm,
|
|
751
|
+
oncancel,
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
// Verify textarea is rendered
|
|
755
|
+
const textarea = screen.getAllByPlaceholderText("Type your comment here...")[0];
|
|
756
|
+
expect(textarea.tagName).toBe("TEXTAREA");
|
|
757
|
+
expect(textarea).toHaveAttribute("rows", "5");
|
|
758
|
+
|
|
759
|
+
// Verify help text
|
|
760
|
+
expect(screen.getAllByText("Maximum 500 characters").length).toBeGreaterThan(0);
|
|
761
|
+
|
|
762
|
+
// Type in textarea
|
|
763
|
+
await user.type(textarea, "This is my comment");
|
|
764
|
+
|
|
765
|
+
// Click post
|
|
766
|
+
const postButton = screen.getAllByText("Post Comment")[0];
|
|
767
|
+
await user.click(postButton);
|
|
768
|
+
|
|
769
|
+
await waitFor(() => {
|
|
770
|
+
expect(onconfirm).toHaveBeenCalledOnce();
|
|
771
|
+
expect(onconfirm).toHaveBeenCalledWith({ value: "This is my comment" });
|
|
772
|
+
});
|
|
773
|
+
});
|
|
774
|
+
|
|
775
|
+
test("Cancel flow", async () => {
|
|
776
|
+
const oncancel = vi.fn();
|
|
777
|
+
const onclose = vi.fn();
|
|
778
|
+
const { user } = setupTest({
|
|
779
|
+
oncancel,
|
|
780
|
+
onclose,
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
const cancelButton = screen.getAllByText("Cancel")[0];
|
|
784
|
+
await user.click(cancelButton);
|
|
785
|
+
|
|
786
|
+
await waitFor(() => {
|
|
787
|
+
expect(oncancel).toHaveBeenCalledOnce();
|
|
788
|
+
expect(onclose).toHaveBeenCalledOnce();
|
|
789
|
+
});
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
test("Disabled state prevents all interactions", async () => {
|
|
793
|
+
const onconfirm = vi.fn();
|
|
794
|
+
const oncancel = vi.fn();
|
|
795
|
+
const onclose = vi.fn();
|
|
796
|
+
const { user } = setupTest({
|
|
797
|
+
disabled: true,
|
|
798
|
+
closeBtn: true,
|
|
799
|
+
inputValue: "test",
|
|
800
|
+
onconfirm,
|
|
801
|
+
oncancel,
|
|
802
|
+
onclose,
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
// Input should be disabled
|
|
806
|
+
const input = document.querySelector("input");
|
|
807
|
+
expect(input).toBeDisabled();
|
|
808
|
+
|
|
809
|
+
// Primary button should be disabled
|
|
810
|
+
const primaryButton = screen.getAllByText("Confirm")[0].closest("button");
|
|
811
|
+
expect(primaryButton).toBeDisabled();
|
|
812
|
+
await user.click(primaryButton);
|
|
813
|
+
|
|
814
|
+
// Secondary button should be disabled
|
|
815
|
+
const secondaryButton = screen.getAllByText("Cancel")[0].closest("button");
|
|
816
|
+
expect(secondaryButton).toBeDisabled();
|
|
817
|
+
await user.click(secondaryButton);
|
|
818
|
+
|
|
819
|
+
// Close button should be disabled
|
|
820
|
+
const closeButton = document.querySelector("img[alt='Close']")?.closest("button");
|
|
821
|
+
expect(closeButton).toBeDisabled();
|
|
822
|
+
await user.click(closeButton);
|
|
823
|
+
|
|
824
|
+
// Wait a bit
|
|
825
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
826
|
+
|
|
827
|
+
// No callbacks should have been called
|
|
828
|
+
expect(onconfirm).not.toHaveBeenCalled();
|
|
829
|
+
expect(oncancel).not.toHaveBeenCalled();
|
|
830
|
+
expect(onclose).not.toHaveBeenCalled();
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
test("Loading state prevents all interactions", async () => {
|
|
834
|
+
const onconfirm = vi.fn();
|
|
835
|
+
const oncancel = vi.fn();
|
|
836
|
+
const onclose = vi.fn();
|
|
837
|
+
const { user } = setupTest({
|
|
838
|
+
loading: true,
|
|
839
|
+
closeBtn: true,
|
|
840
|
+
inputValue: "test",
|
|
841
|
+
onconfirm,
|
|
842
|
+
oncancel,
|
|
843
|
+
onclose,
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
// Input should be disabled
|
|
847
|
+
const input = document.querySelector("input");
|
|
848
|
+
expect(input).toBeDisabled();
|
|
849
|
+
|
|
850
|
+
// Primary button should be disabled
|
|
851
|
+
const primaryButton = screen.getAllByText("Confirm")[0].closest("button");
|
|
852
|
+
expect(primaryButton).toBeDisabled();
|
|
853
|
+
await user.click(primaryButton);
|
|
854
|
+
|
|
855
|
+
// Secondary button should be disabled
|
|
856
|
+
const secondaryButton = screen.getAllByText("Cancel")[0].closest("button");
|
|
857
|
+
expect(secondaryButton).toBeDisabled();
|
|
858
|
+
await user.click(secondaryButton);
|
|
859
|
+
|
|
860
|
+
// Close button is not visibly disabled but handleClose prevents action
|
|
861
|
+
const closeButton = document.querySelector("img[alt='Close']")?.closest("button");
|
|
862
|
+
await user.click(closeButton);
|
|
863
|
+
|
|
864
|
+
// Wait a bit
|
|
865
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
866
|
+
|
|
867
|
+
// No callbacks should have been called
|
|
868
|
+
expect(onconfirm).not.toHaveBeenCalled();
|
|
869
|
+
expect(oncancel).not.toHaveBeenCalled();
|
|
870
|
+
expect(onclose).not.toHaveBeenCalled();
|
|
871
|
+
});
|
|
872
|
+
});
|