@getmicdrop/svelte-components 5.17.1 → 5.17.3
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.svelte +187 -187
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
- package/dist/calendar/FAQs/FAQs.svelte +77 -77
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
- package/dist/calendar/OrderSummary/OrderSummary.svelte +457 -457
- package/dist/calendar/PublicCard/PublicCard.svelte +146 -146
- package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
- package/dist/components/Heading.spec.d.ts +2 -0
- package/dist/components/Heading.spec.d.ts.map +1 -0
- package/dist/components/Heading.spec.js +89 -0
- package/dist/components/Heading.svelte +60 -60
- package/dist/components/Layout/AppShell.svelte +104 -104
- package/dist/components/Layout/ContentSection.svelte +80 -80
- package/dist/components/Layout/Grid.svelte +4 -4
- package/dist/components/Layout/Heading.svelte +81 -81
- package/dist/components/Layout/PageContainer.svelte +69 -69
- package/dist/components/Layout/Responsive.svelte +75 -75
- package/dist/components/Layout/Section.svelte +80 -80
- package/dist/components/Layout/ShowOnDesktop.svelte +37 -37
- package/dist/components/Layout/ShowOnMobile.svelte +37 -37
- package/dist/components/Layout/Sidebar.svelte +108 -108
- package/dist/components/Layout/Stack.spec.js +1 -1
- package/dist/components/Layout/Stack.svelte +6 -6
- package/dist/components/Layout/Text.svelte +87 -87
- package/dist/components/Layout/TwoColumn.svelte +108 -108
- package/dist/components/Layout/__tests__/AppShell.test.js +140 -0
- package/dist/components/Text.spec.d.ts +2 -0
- package/dist/components/Text.spec.d.ts.map +1 -0
- package/dist/components/Text.spec.js +89 -0
- package/dist/components/Text.svelte +53 -53
- 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 +1 -1
- package/dist/datetime/parse.js +1 -1
- package/dist/forms/createFormStore.svelte.js +1 -0
- package/dist/forms/createFormStore.svelte.spec.d.ts +2 -0
- package/dist/forms/createFormStore.svelte.spec.d.ts.map +1 -0
- package/dist/forms/createFormStore.svelte.spec.js +388 -0
- package/dist/index.js +57 -57
- package/dist/index.spec.js +369 -369
- package/dist/patterns/chat/ChatActivityNotice.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.js +59 -0
- package/dist/patterns/chat/ChatActivityNotice.svelte +41 -41
- package/dist/patterns/chat/ChatBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatBubble.spec.js +91 -0
- package/dist/patterns/chat/ChatBubble.svelte +95 -95
- package/dist/patterns/chat/ChatContainer.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatContainer.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatContainer.spec.js +30 -0
- package/dist/patterns/chat/ChatContainer.svelte +46 -46
- package/dist/patterns/chat/ChatDateDivider.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatDateDivider.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatDateDivider.spec.js +30 -0
- package/dist/patterns/chat/ChatDateDivider.svelte +27 -27
- package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.js +46 -0
- package/dist/patterns/chat/ChatInvitationBubble.svelte +37 -37
- package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.js +32 -0
- package/dist/patterns/chat/ChatInvitationNotice.svelte +27 -27
- package/dist/patterns/chat/ChatMessageGroup.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.js +58 -0
- package/dist/patterns/chat/ChatMessageGroup.svelte +57 -57
- package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.js +65 -0
- package/dist/patterns/chat/ChatSlotUpdate.svelte +46 -46
- package/dist/patterns/chat/ChatStatusBadge.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.js +79 -0
- package/dist/patterns/chat/ChatStatusBadge.svelte +91 -91
- package/dist/patterns/chat/ChatStatusTransition.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.js +81 -0
- package/dist/patterns/chat/ChatStatusTransition.svelte +64 -64
- package/dist/patterns/chat/ChatTextBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatTextBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatTextBubble.spec.js +35 -0
- package/dist/patterns/chat/ChatTextBubble.svelte +41 -41
- package/dist/patterns/chat/index.js +22 -22
- package/dist/patterns/data/DataGrid.svelte +45 -45
- package/dist/patterns/data/DataList.svelte +24 -24
- package/dist/patterns/data/DataTable.spec.js +61 -0
- package/dist/patterns/data/DataTable.svelte +36 -36
- package/dist/patterns/forms/FormActions.spec.js +95 -95
- package/dist/patterns/forms/FormActions.stories.svelte +97 -97
- package/dist/patterns/forms/FormActions.svelte +46 -46
- package/dist/patterns/forms/FormGrid.spec.js +34 -0
- package/dist/patterns/forms/FormGrid.svelte +33 -33
- package/dist/patterns/forms/FormSection.svelte +32 -32
- package/dist/patterns/forms/FormValidationSummary.stories.svelte +83 -83
- package/dist/patterns/forms/FormValidationSummary.svelte +74 -74
- package/dist/patterns/index.js +21 -21
- package/dist/patterns/layout/Sidebar.spec.js +240 -1
- package/dist/patterns/layout/Sidebar.svelte +39 -39
- package/dist/patterns/layout/SidebarTestWrapper.svelte +34 -0
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts +23 -0
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts.map +1 -0
- package/dist/patterns/layout/index.js +29 -29
- package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
- package/dist/patterns/navigation/BottomNav.svelte +74 -74
- package/dist/patterns/navigation/Header.spec.js +123 -0
- package/dist/patterns/navigation/Header.stories.svelte +77 -77
- package/dist/patterns/navigation/Header.svelte +251 -251
- package/dist/patterns/page/PageHeader.svelte +18 -18
- package/dist/patterns/page/PageLayout.svelte +40 -40
- package/dist/patterns/page/PageLoader.spec.js +57 -57
- package/dist/patterns/page/PageLoader.stories.svelte +137 -137
- package/dist/patterns/page/PageLoader.svelte +24 -24
- package/dist/patterns/page/SectionHeader.svelte +29 -29
- package/dist/presets/badges.js +112 -112
- package/dist/presets/buttons.js +76 -76
- package/dist/presets/index.js +9 -9
- package/dist/primitives/Accordion/Accordion.spec.js +112 -2
- package/dist/primitives/Accordion/Accordion.stories.svelte +75 -75
- package/dist/primitives/Accordion/Accordion.svelte +42 -42
- package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte +28 -0
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts +7 -0
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Alert/Alert.spec.js +173 -173
- package/dist/primitives/Alert/Alert.stories.svelte +88 -88
- package/dist/primitives/Alert/Alert.svelte +27 -27
- package/dist/primitives/Avatar/Avatar.spec.js +23 -0
- package/dist/primitives/Avatar/Avatar.stories.svelte +94 -94
- package/dist/primitives/Avatar/Avatar.svelte +66 -66
- package/dist/primitives/AvatarButton/AvatarButton.svelte +57 -57
- package/dist/primitives/Badges/Badge.spec.js +144 -144
- package/dist/primitives/Badges/Badge.stories.svelte +86 -86
- package/dist/primitives/Badges/Badge.svelte +99 -99
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +238 -136
- package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
- package/dist/primitives/BottomSheet/BottomSheet.svelte +115 -115
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte +20 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts +10 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +123 -123
- package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +99 -99
- package/dist/primitives/Button/Button.spec.js +225 -225
- package/dist/primitives/Button/Button.stories.svelte +76 -76
- package/dist/primitives/Button/Button.svelte +278 -278
- package/dist/primitives/Button/ButtonGroup.spec.d.ts +2 -0
- package/dist/primitives/Button/ButtonGroup.spec.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonGroup.spec.js +44 -0
- package/dist/primitives/Button/ButtonGroup.svelte +50 -50
- package/dist/primitives/Button/ButtonSaveDemo.spec.js +146 -146
- package/dist/primitives/Button/ButtonSaveDemo.svelte +25 -25
- 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/CardAction/CardAction.svelte +68 -68
- package/dist/primitives/Checkbox/Checkbox.spec.js +32 -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 -390
- package/dist/primitives/DarkModeToggle.stories.svelte +57 -57
- package/dist/primitives/DarkModeToggle.svelte +136 -136
- package/dist/primitives/Drawer/Drawer.spec.js +437 -0
- package/dist/primitives/Drawer/Drawer.stories.svelte +80 -80
- package/dist/primitives/Drawer/Drawer.svelte +224 -224
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte +86 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts +26 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Dropdown/Dropdown.spec.js +116 -0
- package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
- package/dist/primitives/Dropdown/Dropdown.svelte +170 -170
- package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts +2 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts.map +1 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.js +30 -0
- package/dist/primitives/Dropdown/DropdownDivider.svelte +9 -9
- package/dist/primitives/Dropdown/DropdownItem.spec.js +155 -1
- package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte +43 -0
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts +17 -0
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Helper/Helper.spec.d.ts +2 -0
- package/dist/primitives/Helper/Helper.spec.d.ts.map +1 -0
- package/dist/primitives/Helper/Helper.spec.js +57 -0
- package/dist/primitives/Helper/Helper.svelte +33 -33
- 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/Input/Input.spec.js +1235 -573
- package/dist/primitives/Input/Input.stories.svelte +139 -139
- package/dist/primitives/Input/Input.svelte +423 -423
- package/dist/primitives/Input/Select.spec.js +632 -218
- package/dist/primitives/Input/Select.stories.svelte +112 -112
- package/dist/primitives/Input/Select.svelte +252 -252
- package/dist/primitives/Input/Textarea.stories.svelte +137 -137
- package/dist/primitives/Input/Textarea.svelte +105 -105
- package/dist/primitives/Label/Label.spec.js +9 -0
- package/dist/primitives/Label/Label.svelte +37 -37
- package/dist/primitives/LandingButton/LandingButton.spec.d.ts +2 -0
- package/dist/primitives/LandingButton/LandingButton.spec.d.ts.map +1 -0
- package/dist/primitives/LandingButton/LandingButton.spec.js +61 -0
- package/dist/primitives/LandingButton/LandingButton.svelte +92 -92
- package/dist/primitives/MenuItem/MenuItem.spec.d.ts +2 -0
- package/dist/primitives/MenuItem/MenuItem.spec.d.ts.map +1 -0
- package/dist/primitives/MenuItem/MenuItem.spec.js +130 -0
- package/dist/primitives/MenuItem/MenuItem.svelte +85 -85
- package/dist/primitives/Modal/Modal.spec.js +314 -99
- package/dist/primitives/Modal/Modal.stories.svelte +86 -86
- package/dist/primitives/Modal/Modal.svelte +181 -181
- package/dist/primitives/NavItem/NavItem.spec.d.ts +2 -0
- package/dist/primitives/NavItem/NavItem.spec.d.ts.map +1 -0
- package/dist/primitives/NavItem/NavItem.spec.js +97 -0
- package/dist/primitives/NavItem/NavItem.svelte +75 -75
- package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
- package/dist/primitives/Pagination/Pagination.svelte +261 -261
- package/dist/primitives/Radio/Radio.stories.svelte +80 -80
- package/dist/primitives/Radio/Radio.svelte +67 -67
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts +2 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts.map +1 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.js +78 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.svelte +109 -109
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts +2 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts.map +1 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.js +61 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.svelte +55 -55
- package/dist/primitives/Skeleton/CardPlaceholder.svelte +87 -87
- package/dist/primitives/Skeleton/ImagePlaceholder.svelte +59 -59
- package/dist/primitives/Skeleton/ListPlaceholder.svelte +76 -76
- package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
- package/dist/primitives/Skeleton/Skeleton.svelte +26 -26
- package/dist/primitives/Spinner/Spinner.spec.js +84 -71
- package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
- package/dist/primitives/Spinner/Spinner.svelte +20 -20
- package/dist/primitives/Tabs/TabItem.svelte +49 -49
- package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
- package/dist/primitives/Tabs/Tabs.svelte +137 -137
- package/dist/primitives/Toggle.spec.js +221 -146
- package/dist/primitives/Toggle.stories.svelte +92 -92
- package/dist/primitives/Toggle.svelte +141 -141
- package/dist/primitives/ToggleTestWrapper.svelte +30 -0
- package/dist/primitives/ToggleTestWrapper.svelte.d.ts +29 -0
- package/dist/primitives/ToggleTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.spec.d.ts +2 -0
- package/dist/primitives/Tooltip/Tooltip.spec.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.spec.js +126 -0
- package/dist/primitives/Tooltip/Tooltip.svelte +83 -83
- 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.js +113 -113
- package/dist/recipes/CropImage/CropImage.spec.js +208 -208
- package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
- package/dist/recipes/CropImage/CropImage.svelte +241 -241
- package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
- package/dist/recipes/ImageUploader/ImageUploader.svelte +992 -992
- package/dist/recipes/SuperLogin/SuperLogin.spec.js +2 -2
- package/dist/recipes/SuperLogin/SuperLogin.svelte +1 -1
- package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
- 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 -133
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +157 -157
- package/dist/recipes/fields/CheckboxField.svelte +85 -85
- package/dist/recipes/fields/FormField.svelte +58 -58
- package/dist/recipes/fields/RadioGroup.svelte +95 -95
- package/dist/recipes/fields/SelectField.svelte +82 -82
- package/dist/recipes/fields/TextareaField.svelte +97 -97
- package/dist/recipes/fields/ToggleField.svelte +60 -60
- package/dist/recipes/fields/index.js +7 -7
- package/dist/recipes/inputs/MultiSelect.spec.js +263 -263
- package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
- package/dist/recipes/inputs/MultiSelect.svelte +283 -283
- package/dist/recipes/inputs/OTPInput.spec.js +251 -251
- package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
- package/dist/recipes/inputs/OTPInput.svelte +117 -117
- package/dist/recipes/inputs/PasswordInput.svelte +22 -22
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +131 -131
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +123 -123
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +336 -336
- package/dist/recipes/inputs/Search.spec.js +66 -2
- package/dist/recipes/inputs/Search.svelte +102 -102
- package/dist/recipes/inputs/index.js +7 -7
- package/dist/recipes/modals/AlertModal.svelte +130 -130
- package/dist/recipes/modals/ConfirmationModal.spec.js +396 -206
- package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
- package/dist/recipes/modals/ConfirmationModal.svelte +162 -162
- 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.svelte +65 -65
- package/dist/recipes/modals/StatusModal.svelte +206 -206
- package/dist/services/EventService.js +79 -79
- package/dist/services/EventService.spec.js +217 -217
- package/dist/services/ShowService.js +144 -144
- package/dist/services/ShowService.spec.js +345 -345
- package/dist/stores/auth.svelte.spec.d.ts +2 -0
- package/dist/stores/auth.svelte.spec.d.ts.map +1 -0
- package/dist/stores/auth.svelte.spec.js +112 -0
- package/dist/stores/formDataStore.svelte.spec.d.ts +2 -0
- package/dist/stores/formDataStore.svelte.spec.d.ts.map +1 -0
- package/dist/stores/formDataStore.svelte.spec.js +150 -0
- package/dist/stores/formSave.svelte.spec.d.ts +2 -0
- package/dist/stores/formSave.svelte.spec.d.ts.map +1 -0
- package/dist/stores/formSave.svelte.spec.js +196 -0
- package/dist/stores/navigation.spec.d.ts +2 -0
- package/dist/stores/navigation.spec.d.ts.map +1 -0
- package/dist/stores/navigation.spec.js +53 -0
- package/dist/stores/toaster.js +13 -13
- package/dist/stories/ButtonAuditReview.stories.svelte +14 -14
- package/dist/stories/ButtonAuditReview.svelte +427 -427
- package/dist/stories/PatternsGallery.stories.svelte +19 -19
- package/dist/stories/PatternsGallery.svelte +206 -206
- package/dist/stories/PrimitivesGallery.stories.svelte +19 -19
- package/dist/stories/PrimitivesGallery.svelte +756 -756
- package/dist/stories/RecipesGallery.stories.svelte +19 -19
- package/dist/stories/RecipesGallery.svelte +454 -454
- package/dist/stories/button-audit-manifest.json +11186 -11186
- package/dist/tailwind/preset.cjs +82 -82
- package/dist/telemetry.js +402 -402
- package/dist/telemetry.server.js +212 -212
- package/dist/telemetry.server.spec.js +437 -437
- package/dist/telemetry.spec.js +1168 -1168
- package/dist/tokens/tokens.css +87 -87
- package/dist/tokens/typography-base.css +163 -163
- package/dist/tokens/utilities.css +353 -353
- package/dist/utils/apiConfig.js +117 -117
- package/dist/utils/apiConfig.spec.js +219 -219
- package/dist/utils/greetings.js +187 -187
- package/dist/utils/haptic.spec.d.ts +2 -0
- package/dist/utils/haptic.spec.d.ts.map +1 -0
- package/dist/utils/haptic.spec.js +153 -0
- package/dist/utils/imageOptimizer.spec.d.ts +2 -0
- package/dist/utils/imageOptimizer.spec.d.ts.map +1 -0
- package/dist/utils/imageOptimizer.spec.js +201 -0
- package/dist/utils/imageValidation.js +121 -121
- package/dist/utils/logger.spec.d.ts +2 -0
- package/dist/utils/logger.spec.d.ts.map +1 -0
- package/dist/utils/logger.spec.js +95 -0
- package/dist/utils/transitions.js +4 -4
- package/dist/utils/utils.js +693 -693
- package/package.json +292 -293
|
@@ -1,181 +1,181 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
/**
|
|
3
|
-
* Modal Component - Flowbite Native
|
|
4
|
-
* Migrated to Svelte 5 runes
|
|
5
|
-
*
|
|
6
|
-
* Haptic Feedback:
|
|
7
|
-
* - Light haptic on modal open (subtle attention cue)
|
|
8
|
-
*/
|
|
9
|
-
import { onDestroy } from "svelte";
|
|
10
|
-
import { fade, fly } from "svelte/transition";
|
|
11
|
-
import { cubicOut } from "svelte/easing";
|
|
12
|
-
import { portal } from "../../utils/portal.js";
|
|
13
|
-
import { triggerHaptic } from "../../utils/haptic.js";
|
|
14
|
-
|
|
15
|
-
/** @type {{
|
|
16
|
-
open?: boolean,
|
|
17
|
-
isProcessing?: boolean,
|
|
18
|
-
isSuccess?: boolean,
|
|
19
|
-
size?: 'sm' | 'md' | 'lg' | 'xl',
|
|
20
|
-
persistent?: boolean,
|
|
21
|
-
haptic?: boolean,
|
|
22
|
-
oncancel?: () => void,
|
|
23
|
-
header?: import('svelte').Snippet,
|
|
24
|
-
body?: import('svelte').Snippet,
|
|
25
|
-
footer?: import('svelte').Snippet,
|
|
26
|
-
class?: string,
|
|
27
|
-
}} */
|
|
28
|
-
let {
|
|
29
|
-
open = $bindable(false),
|
|
30
|
-
isProcessing: _isProcessing = false,
|
|
31
|
-
isSuccess: _isSuccess = false,
|
|
32
|
-
size = "md",
|
|
33
|
-
persistent = false,
|
|
34
|
-
haptic = true,
|
|
35
|
-
oncancel,
|
|
36
|
-
header,
|
|
37
|
-
body,
|
|
38
|
-
footer,
|
|
39
|
-
class: _className,
|
|
40
|
-
...restProps
|
|
41
|
-
} = $props();
|
|
42
|
-
|
|
43
|
-
// Store scroll position for iOS scroll lock
|
|
44
|
-
let scrollY = $state(0);
|
|
45
|
-
|
|
46
|
-
// Track previous open state to detect open transitions
|
|
47
|
-
let prevOpen = $state(false);
|
|
48
|
-
|
|
49
|
-
// Trigger haptic on modal open (QOL Bible)
|
|
50
|
-
$effect(() => {
|
|
51
|
-
if (open && !prevOpen && haptic) {
|
|
52
|
-
triggerHaptic('light');
|
|
53
|
-
}
|
|
54
|
-
prevOpen = open;
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// Handle escape key
|
|
58
|
-
function handleKeydown(event) {
|
|
59
|
-
if (event.key === "Escape" && open && !persistent) {
|
|
60
|
-
resetModal();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const resetModal = () => {
|
|
65
|
-
oncancel?.();
|
|
66
|
-
open = false;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
// Size classes for desktop modal (xs/sm/md/lg/xl scale)
|
|
70
|
-
const sizeClasses = {
|
|
71
|
-
sm: "max-w-sm",
|
|
72
|
-
md: "max-w-md",
|
|
73
|
-
lg: "max-w-xl",
|
|
74
|
-
xl: "max-w-2xl"
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
let modalSizeClass = $derived(sizeClasses[size] || sizeClasses.md);
|
|
78
|
-
|
|
79
|
-
// iOS-compatible scroll lock using position:fixed approach
|
|
80
|
-
// Also compensates for scrollbar width to prevent layout shift
|
|
81
|
-
$effect(() => {
|
|
82
|
-
if (typeof document !== "undefined") {
|
|
83
|
-
if (open) {
|
|
84
|
-
scrollY = window.scrollY;
|
|
85
|
-
// Calculate scrollbar width before hiding it
|
|
86
|
-
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
87
|
-
document.body.style.position = "fixed";
|
|
88
|
-
document.body.style.top = `-${scrollY}px`;
|
|
89
|
-
document.body.style.left = "0";
|
|
90
|
-
document.body.style.right = "0";
|
|
91
|
-
document.body.style.overflow = "hidden";
|
|
92
|
-
// Add padding to compensate for scrollbar disappearing
|
|
93
|
-
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
94
|
-
} else {
|
|
95
|
-
document.body.style.position = "";
|
|
96
|
-
document.body.style.top = "";
|
|
97
|
-
document.body.style.left = "";
|
|
98
|
-
document.body.style.right = "";
|
|
99
|
-
document.body.style.overflow = "";
|
|
100
|
-
document.body.style.paddingRight = "";
|
|
101
|
-
window.scrollTo(0, scrollY);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
onDestroy(() => {
|
|
107
|
-
if (typeof document !== "undefined") {
|
|
108
|
-
document.body.style.position = "";
|
|
109
|
-
document.body.style.top = "";
|
|
110
|
-
document.body.style.left = "";
|
|
111
|
-
document.body.style.right = "";
|
|
112
|
-
document.body.style.overflow = "";
|
|
113
|
-
document.body.style.paddingRight = "";
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
</script>
|
|
117
|
-
|
|
118
|
-
<svelte:window onkeydown={handleKeydown} />
|
|
119
|
-
|
|
120
|
-
{#if open}
|
|
121
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
122
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
123
|
-
<div
|
|
124
|
-
class="fixed inset-0 flex bg-black/50 z-50 items-end justify-center md:items-center md:p-4 touch-none overscroll-none"
|
|
125
|
-
onmousedown={(e) => {
|
|
126
|
-
// Only track direct clicks on backdrop, not drags that end on backdrop
|
|
127
|
-
if (e.target === e.currentTarget && !persistent) {
|
|
128
|
-
e.currentTarget.dataset.clickStartedOnBackdrop = 'true';
|
|
129
|
-
}
|
|
130
|
-
}}
|
|
131
|
-
onmouseup={(e) => {
|
|
132
|
-
// Only close if both mousedown and mouseup were on the backdrop
|
|
133
|
-
if (e.target === e.currentTarget && e.currentTarget.dataset.clickStartedOnBackdrop === 'true' && !persistent) {
|
|
134
|
-
resetModal();
|
|
135
|
-
}
|
|
136
|
-
delete e.currentTarget.dataset.clickStartedOnBackdrop;
|
|
137
|
-
}}
|
|
138
|
-
transition:fade={{ duration: 300 }}
|
|
139
|
-
role="dialog"
|
|
140
|
-
aria-modal="true"
|
|
141
|
-
use:portal
|
|
142
|
-
{...restProps}
|
|
143
|
-
>
|
|
144
|
-
<!-- Mobile: Bottom sheet -->
|
|
145
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
146
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
147
|
-
<div
|
|
148
|
-
class="md:hidden bg-white dark:bg-gray-800 rounded-t-3xl w-full max-h-[90vh] max-h-[90dvh] overflow-hidden flex flex-col shadow-[0_-10px_40px_rgba(0,0,0,0.15)] touch-pan-y overscroll-contain"
|
|
149
|
-
onclick={(e) => e.stopPropagation()}
|
|
150
|
-
transition:fly={{ y: 300, duration: 300, easing: cubicOut }}
|
|
151
|
-
>
|
|
152
|
-
<!-- Handle bar -->
|
|
153
|
-
<div class="flex justify-center pt-3 pb-1 shrink-0">
|
|
154
|
-
<div class="w-10 h-1 bg-gray-300 dark:bg-gray-600 rounded-xs"></div>
|
|
155
|
-
</div>
|
|
156
|
-
|
|
157
|
-
<div class="p-6 pb-[calc(5rem+env(safe-area-inset-bottom,0px))] overflow-y-auto flex-1">
|
|
158
|
-
{#if header}{@render header()}{/if}
|
|
159
|
-
{#if body}{@render body()}{/if}
|
|
160
|
-
<div class="w-full flex flex-col gap-3 mt-6 empty:hidden empty:mt-0">
|
|
161
|
-
{#if footer}{@render footer()}{/if}
|
|
162
|
-
</div>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
|
|
166
|
-
<!-- Desktop: Centered modal -->
|
|
167
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
168
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
169
|
-
<div
|
|
170
|
-
class="hidden md:block bg-white dark:bg-gray-800 p-6 rounded-lg {modalSizeClass} w-full max-h-[calc(100vh-4rem)] overflow-y-auto shadow-2xl"
|
|
171
|
-
onclick={(e) => e.stopPropagation()}
|
|
172
|
-
transition:fly={{ y: 20, duration: 200 }}
|
|
173
|
-
>
|
|
174
|
-
{#if header}{@render header()}{/if}
|
|
175
|
-
{#if body}{@render body()}{/if}
|
|
176
|
-
<div class="w-full flex flex-col md:flex-row md:justify-end gap-3 mt-6 empty:hidden empty:mt-0">
|
|
177
|
-
{#if footer}{@render footer()}{/if}
|
|
178
|
-
</div>
|
|
179
|
-
</div>
|
|
180
|
-
</div>
|
|
181
|
-
{/if}
|
|
1
|
+
<script>
|
|
2
|
+
/**
|
|
3
|
+
* Modal Component - Flowbite Native
|
|
4
|
+
* Migrated to Svelte 5 runes
|
|
5
|
+
*
|
|
6
|
+
* Haptic Feedback:
|
|
7
|
+
* - Light haptic on modal open (subtle attention cue)
|
|
8
|
+
*/
|
|
9
|
+
import { onDestroy } from "svelte";
|
|
10
|
+
import { fade, fly } from "svelte/transition";
|
|
11
|
+
import { cubicOut } from "svelte/easing";
|
|
12
|
+
import { portal } from "../../utils/portal.js";
|
|
13
|
+
import { triggerHaptic } from "../../utils/haptic.js";
|
|
14
|
+
|
|
15
|
+
/** @type {{
|
|
16
|
+
open?: boolean,
|
|
17
|
+
isProcessing?: boolean,
|
|
18
|
+
isSuccess?: boolean,
|
|
19
|
+
size?: 'sm' | 'md' | 'lg' | 'xl',
|
|
20
|
+
persistent?: boolean,
|
|
21
|
+
haptic?: boolean,
|
|
22
|
+
oncancel?: () => void,
|
|
23
|
+
header?: import('svelte').Snippet,
|
|
24
|
+
body?: import('svelte').Snippet,
|
|
25
|
+
footer?: import('svelte').Snippet,
|
|
26
|
+
class?: string,
|
|
27
|
+
}} */
|
|
28
|
+
let {
|
|
29
|
+
open = $bindable(false),
|
|
30
|
+
isProcessing: _isProcessing = false,
|
|
31
|
+
isSuccess: _isSuccess = false,
|
|
32
|
+
size = "md",
|
|
33
|
+
persistent = false,
|
|
34
|
+
haptic = true,
|
|
35
|
+
oncancel,
|
|
36
|
+
header,
|
|
37
|
+
body,
|
|
38
|
+
footer,
|
|
39
|
+
class: _className,
|
|
40
|
+
...restProps
|
|
41
|
+
} = $props();
|
|
42
|
+
|
|
43
|
+
// Store scroll position for iOS scroll lock
|
|
44
|
+
let scrollY = $state(0);
|
|
45
|
+
|
|
46
|
+
// Track previous open state to detect open transitions
|
|
47
|
+
let prevOpen = $state(false);
|
|
48
|
+
|
|
49
|
+
// Trigger haptic on modal open (QOL Bible)
|
|
50
|
+
$effect(() => {
|
|
51
|
+
if (open && !prevOpen && haptic) {
|
|
52
|
+
triggerHaptic('light');
|
|
53
|
+
}
|
|
54
|
+
prevOpen = open;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Handle escape key
|
|
58
|
+
function handleKeydown(event) {
|
|
59
|
+
if (event.key === "Escape" && open && !persistent) {
|
|
60
|
+
resetModal();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const resetModal = () => {
|
|
65
|
+
oncancel?.();
|
|
66
|
+
open = false;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Size classes for desktop modal (xs/sm/md/lg/xl scale)
|
|
70
|
+
const sizeClasses = {
|
|
71
|
+
sm: "max-w-sm",
|
|
72
|
+
md: "max-w-md",
|
|
73
|
+
lg: "max-w-xl",
|
|
74
|
+
xl: "max-w-2xl"
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
let modalSizeClass = $derived(sizeClasses[size] || sizeClasses.md);
|
|
78
|
+
|
|
79
|
+
// iOS-compatible scroll lock using position:fixed approach
|
|
80
|
+
// Also compensates for scrollbar width to prevent layout shift
|
|
81
|
+
$effect(() => {
|
|
82
|
+
if (typeof document !== "undefined") {
|
|
83
|
+
if (open) {
|
|
84
|
+
scrollY = window.scrollY;
|
|
85
|
+
// Calculate scrollbar width before hiding it
|
|
86
|
+
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
87
|
+
document.body.style.position = "fixed";
|
|
88
|
+
document.body.style.top = `-${scrollY}px`;
|
|
89
|
+
document.body.style.left = "0";
|
|
90
|
+
document.body.style.right = "0";
|
|
91
|
+
document.body.style.overflow = "hidden";
|
|
92
|
+
// Add padding to compensate for scrollbar disappearing
|
|
93
|
+
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
94
|
+
} else {
|
|
95
|
+
document.body.style.position = "";
|
|
96
|
+
document.body.style.top = "";
|
|
97
|
+
document.body.style.left = "";
|
|
98
|
+
document.body.style.right = "";
|
|
99
|
+
document.body.style.overflow = "";
|
|
100
|
+
document.body.style.paddingRight = "";
|
|
101
|
+
window.scrollTo(0, scrollY);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
onDestroy(() => {
|
|
107
|
+
if (typeof document !== "undefined") {
|
|
108
|
+
document.body.style.position = "";
|
|
109
|
+
document.body.style.top = "";
|
|
110
|
+
document.body.style.left = "";
|
|
111
|
+
document.body.style.right = "";
|
|
112
|
+
document.body.style.overflow = "";
|
|
113
|
+
document.body.style.paddingRight = "";
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<svelte:window onkeydown={handleKeydown} />
|
|
119
|
+
|
|
120
|
+
{#if open}
|
|
121
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
122
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
123
|
+
<div
|
|
124
|
+
class="fixed inset-0 flex bg-black/50 z-50 items-end justify-center md:items-center md:p-4 touch-none overscroll-none"
|
|
125
|
+
onmousedown={(e) => {
|
|
126
|
+
// Only track direct clicks on backdrop, not drags that end on backdrop
|
|
127
|
+
if (e.target === e.currentTarget && !persistent) {
|
|
128
|
+
e.currentTarget.dataset.clickStartedOnBackdrop = 'true';
|
|
129
|
+
}
|
|
130
|
+
}}
|
|
131
|
+
onmouseup={(e) => {
|
|
132
|
+
// Only close if both mousedown and mouseup were on the backdrop
|
|
133
|
+
if (e.target === e.currentTarget && e.currentTarget.dataset.clickStartedOnBackdrop === 'true' && !persistent) {
|
|
134
|
+
resetModal();
|
|
135
|
+
}
|
|
136
|
+
delete e.currentTarget.dataset.clickStartedOnBackdrop;
|
|
137
|
+
}}
|
|
138
|
+
transition:fade={{ duration: 300 }}
|
|
139
|
+
role="dialog"
|
|
140
|
+
aria-modal="true"
|
|
141
|
+
use:portal
|
|
142
|
+
{...restProps}
|
|
143
|
+
>
|
|
144
|
+
<!-- Mobile: Bottom sheet -->
|
|
145
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
146
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
147
|
+
<div
|
|
148
|
+
class="md:hidden bg-white dark:bg-gray-800 rounded-t-3xl w-full max-h-[90vh] max-h-[90dvh] overflow-hidden flex flex-col shadow-[0_-10px_40px_rgba(0,0,0,0.15)] touch-pan-y overscroll-contain"
|
|
149
|
+
onclick={(e) => e.stopPropagation()}
|
|
150
|
+
transition:fly={{ y: 300, duration: 300, easing: cubicOut }}
|
|
151
|
+
>
|
|
152
|
+
<!-- Handle bar -->
|
|
153
|
+
<div class="flex justify-center pt-3 pb-1 shrink-0">
|
|
154
|
+
<div class="w-10 h-1 bg-gray-300 dark:bg-gray-600 rounded-xs"></div>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div class="p-6 pb-[calc(5rem+env(safe-area-inset-bottom,0px))] overflow-y-auto flex-1">
|
|
158
|
+
{#if header}{@render header()}{/if}
|
|
159
|
+
{#if body}{@render body()}{/if}
|
|
160
|
+
<div class="w-full flex flex-col gap-3 mt-6 empty:hidden empty:mt-0">
|
|
161
|
+
{#if footer}{@render footer()}{/if}
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<!-- Desktop: Centered modal -->
|
|
167
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
168
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
169
|
+
<div
|
|
170
|
+
class="hidden md:block bg-white dark:bg-gray-800 p-6 rounded-lg {modalSizeClass} w-full max-h-[calc(100vh-4rem)] overflow-y-auto shadow-2xl"
|
|
171
|
+
onclick={(e) => e.stopPropagation()}
|
|
172
|
+
transition:fly={{ y: 20, duration: 200 }}
|
|
173
|
+
>
|
|
174
|
+
{#if header}{@render header()}{/if}
|
|
175
|
+
{#if body}{@render body()}{/if}
|
|
176
|
+
<div class="w-full flex flex-col md:flex-row md:justify-end gap-3 mt-6 empty:hidden empty:mt-0">
|
|
177
|
+
{#if footer}{@render footer()}{/if}
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
{/if}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavItem.spec.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/NavItem/NavItem.spec.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { render, fireEvent } from '@testing-library/svelte';
|
|
2
|
+
import { createRawSnippet } from 'svelte';
|
|
3
|
+
import { expect, describe, test, vi } from 'vitest';
|
|
4
|
+
import NavItem from './NavItem.svelte';
|
|
5
|
+
|
|
6
|
+
function textSnippet(text) {
|
|
7
|
+
return createRawSnippet(() => ({
|
|
8
|
+
render: () => `<span>${text}</span>`
|
|
9
|
+
}));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('NavItem', () => {
|
|
13
|
+
test('renders a button by default', () => {
|
|
14
|
+
const { container } = render(NavItem);
|
|
15
|
+
expect(container.querySelector('button')).toBeInTheDocument();
|
|
16
|
+
expect(container.querySelector('a')).not.toBeInTheDocument();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('renders an anchor when href is provided', () => {
|
|
20
|
+
const { container } = render(NavItem, { props: { href: '/home' } });
|
|
21
|
+
expect(container.querySelector('a')).toBeInTheDocument();
|
|
22
|
+
expect(container.querySelector('a')).toHaveAttribute('href', '/home');
|
|
23
|
+
expect(container.querySelector('button')).not.toBeInTheDocument();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('button has type="button"', () => {
|
|
27
|
+
const { container } = render(NavItem);
|
|
28
|
+
expect(container.querySelector('button')).toHaveAttribute('type', 'button');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('applies default (inactive) styling', () => {
|
|
32
|
+
const { container } = render(NavItem);
|
|
33
|
+
const button = container.querySelector('button');
|
|
34
|
+
expect(button.className).toContain('text-gray-500');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('applies active styling', () => {
|
|
38
|
+
const { container } = render(NavItem, { props: { active: true } });
|
|
39
|
+
const button = container.querySelector('button');
|
|
40
|
+
expect(button.className).toContain('text-blue-600');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('applies disabled styling', () => {
|
|
44
|
+
const { container } = render(NavItem, { props: { disabled: true } });
|
|
45
|
+
const button = container.querySelector('button');
|
|
46
|
+
expect(button).toBeDisabled();
|
|
47
|
+
expect(button.className).toContain('cursor-not-allowed');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('onclick handler on button', async () => {
|
|
51
|
+
const onclick = vi.fn();
|
|
52
|
+
const { container } = render(NavItem, { props: { onclick } });
|
|
53
|
+
await fireEvent.click(container.querySelector('button'));
|
|
54
|
+
expect(onclick).toHaveBeenCalled();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('onclick handler on anchor', async () => {
|
|
58
|
+
const onclick = vi.fn();
|
|
59
|
+
const { container } = render(NavItem, { props: { href: '/page', onclick } });
|
|
60
|
+
await fireEvent.click(container.querySelector('a'));
|
|
61
|
+
expect(onclick).toHaveBeenCalled();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('applies custom className', () => {
|
|
65
|
+
const { container } = render(NavItem, { props: { class: 'my-nav' } });
|
|
66
|
+
expect(container.querySelector('.my-nav')).toBeInTheDocument();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('renders children content in button mode', () => {
|
|
70
|
+
const { container } = render(NavItem, {
|
|
71
|
+
props: { children: textSnippet('Nav label') }
|
|
72
|
+
});
|
|
73
|
+
expect(container.querySelector('button').textContent).toBe('Nav label');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('renders children content in anchor mode', () => {
|
|
77
|
+
const { container } = render(NavItem, {
|
|
78
|
+
props: { href: '/page', children: textSnippet('Link label') }
|
|
79
|
+
});
|
|
80
|
+
expect(container.querySelector('a').textContent).toBe('Link label');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('renders empty button when no children provided', () => {
|
|
84
|
+
const { container } = render(NavItem);
|
|
85
|
+
expect(container.querySelector('button').textContent).toBe('');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('renders empty anchor when no children provided', () => {
|
|
89
|
+
const { container } = render(NavItem, { props: { href: '/page' } });
|
|
90
|
+
expect(container.querySelector('a').textContent).toBe('');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('passes through additional props', () => {
|
|
94
|
+
const { container } = render(NavItem, { props: { 'data-testid': 'my-nav-item' } });
|
|
95
|
+
expect(container.querySelector('[data-testid="my-nav-item"]')).toBeInTheDocument();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* NavItem Component
|
|
4
|
-
* Bottom navigation item with vertical layout.
|
|
5
|
-
*
|
|
6
|
-
* Replaces: Button variant="nav"
|
|
7
|
-
*/
|
|
8
|
-
import { twMerge } from 'tailwind-merge';
|
|
9
|
-
import type { Snippet } from 'svelte';
|
|
10
|
-
|
|
11
|
-
interface Props {
|
|
12
|
-
/** Active/selected state */
|
|
13
|
-
active?: boolean;
|
|
14
|
-
/** Disabled state */
|
|
15
|
-
disabled?: boolean;
|
|
16
|
-
/** Link href (renders as <a> if provided) */
|
|
17
|
-
href?: string | null;
|
|
18
|
-
/** Content (icon + label) */
|
|
19
|
-
children?: Snippet;
|
|
20
|
-
/** Additional classes */
|
|
21
|
-
class?: string;
|
|
22
|
-
/** Click handler */
|
|
23
|
-
onclick?: (e: MouseEvent) => void;
|
|
24
|
-
[key: string]: unknown;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let {
|
|
28
|
-
active = false,
|
|
29
|
-
disabled = false,
|
|
30
|
-
href = null,
|
|
31
|
-
children,
|
|
32
|
-
class: className = '',
|
|
33
|
-
onclick,
|
|
34
|
-
...restProps
|
|
35
|
-
}: Props = $props();
|
|
36
|
-
|
|
37
|
-
const baseClasses = 'flex flex-col items-center justify-center h-full py-2 bg-transparent border-transparent rounded-lg font-medium leading-none focus:outline-hidden transition-all duration-150 ease-out select-none';
|
|
38
|
-
const defaultClasses = 'text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-500';
|
|
39
|
-
const activeClasses = 'text-blue-600 dark:text-blue-500';
|
|
40
|
-
const disabledClasses = 'text-gray-400 cursor-not-allowed dark:text-gray-500';
|
|
41
|
-
|
|
42
|
-
let variantClass = $derived(() => {
|
|
43
|
-
if (disabled) return disabledClasses;
|
|
44
|
-
if (active) return activeClasses;
|
|
45
|
-
return defaultClasses;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
let classes = $derived(twMerge(
|
|
49
|
-
baseClasses,
|
|
50
|
-
variantClass(),
|
|
51
|
-
disabled ? 'cursor-not-allowed' : 'cursor-pointer',
|
|
52
|
-
className
|
|
53
|
-
));
|
|
54
|
-
</script>
|
|
55
|
-
|
|
56
|
-
{#if href}
|
|
57
|
-
<a
|
|
58
|
-
{href}
|
|
59
|
-
class={classes}
|
|
60
|
-
{onclick}
|
|
61
|
-
{...restProps}
|
|
62
|
-
>
|
|
63
|
-
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
64
|
-
</a>
|
|
65
|
-
{:else}
|
|
66
|
-
<button
|
|
67
|
-
type="button"
|
|
68
|
-
class={classes}
|
|
69
|
-
{disabled}
|
|
70
|
-
{onclick}
|
|
71
|
-
{...restProps}
|
|
72
|
-
>
|
|
73
|
-
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
74
|
-
</button>
|
|
75
|
-
{/if}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* NavItem Component
|
|
4
|
+
* Bottom navigation item with vertical layout.
|
|
5
|
+
*
|
|
6
|
+
* Replaces: Button variant="nav"
|
|
7
|
+
*/
|
|
8
|
+
import { twMerge } from 'tailwind-merge';
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
/** Active/selected state */
|
|
13
|
+
active?: boolean;
|
|
14
|
+
/** Disabled state */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
/** Link href (renders as <a> if provided) */
|
|
17
|
+
href?: string | null;
|
|
18
|
+
/** Content (icon + label) */
|
|
19
|
+
children?: Snippet;
|
|
20
|
+
/** Additional classes */
|
|
21
|
+
class?: string;
|
|
22
|
+
/** Click handler */
|
|
23
|
+
onclick?: (e: MouseEvent) => void;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let {
|
|
28
|
+
active = false,
|
|
29
|
+
disabled = false,
|
|
30
|
+
href = null,
|
|
31
|
+
children,
|
|
32
|
+
class: className = '',
|
|
33
|
+
onclick,
|
|
34
|
+
...restProps
|
|
35
|
+
}: Props = $props();
|
|
36
|
+
|
|
37
|
+
const baseClasses = 'flex flex-col items-center justify-center h-full py-2 bg-transparent border-transparent rounded-lg font-medium leading-none focus:outline-hidden transition-all duration-150 ease-out select-none';
|
|
38
|
+
const defaultClasses = 'text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-500';
|
|
39
|
+
const activeClasses = 'text-blue-600 dark:text-blue-500';
|
|
40
|
+
const disabledClasses = 'text-gray-400 cursor-not-allowed dark:text-gray-500';
|
|
41
|
+
|
|
42
|
+
let variantClass = $derived(() => {
|
|
43
|
+
if (disabled) return disabledClasses;
|
|
44
|
+
if (active) return activeClasses;
|
|
45
|
+
return defaultClasses;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
let classes = $derived(twMerge(
|
|
49
|
+
baseClasses,
|
|
50
|
+
variantClass(),
|
|
51
|
+
disabled ? 'cursor-not-allowed' : 'cursor-pointer',
|
|
52
|
+
className
|
|
53
|
+
));
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
{#if href}
|
|
57
|
+
<a
|
|
58
|
+
{href}
|
|
59
|
+
class={classes}
|
|
60
|
+
{onclick}
|
|
61
|
+
{...restProps}
|
|
62
|
+
>
|
|
63
|
+
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
64
|
+
</a>
|
|
65
|
+
{:else}
|
|
66
|
+
<button
|
|
67
|
+
type="button"
|
|
68
|
+
class={classes}
|
|
69
|
+
{disabled}
|
|
70
|
+
{onclick}
|
|
71
|
+
{...restProps}
|
|
72
|
+
>
|
|
73
|
+
{#if typeof children === 'function'}{@render children()}{:else if children}{children}{/if}
|
|
74
|
+
</button>
|
|
75
|
+
{/if}
|