@getmicdrop/svelte-components 5.17.0 → 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/datetime/timezone.d.ts.map +1 -1
- package/dist/datetime/timezone.js +1 -2
- package/dist/forms/createFormStore.svelte.d.ts +1 -1
- package/dist/forms/createFormStore.svelte.d.ts.map +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 +21 -21
- package/dist/recipes/SuperLogin/SuperLogin.svelte +4 -4
- 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.spec.js +19 -19
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +123 -123
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +336 -339
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte.d.ts.map +1 -1
- 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.d.ts +1 -1
- package/dist/services/EventService.d.ts.map +1 -1
- package/dist/services/EventService.js +79 -75
- package/dist/services/EventService.spec.js +217 -217
- package/dist/services/ShowService.js +144 -143
- 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.d.ts.map +1 -1
- package/dist/telemetry.js +402 -405
- package/dist/telemetry.server.js +212 -212
- package/dist/telemetry.server.spec.js +437 -438
- package/dist/telemetry.spec.js +1168 -1169
- 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 -120
- 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 -294
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
<script module>
|
|
2
|
-
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
-
|
|
4
|
-
import BottomNav from './BottomNav.svelte';
|
|
5
|
-
|
|
6
|
-
const { Story } = defineMeta({
|
|
7
|
-
title: 'Components/Layout/BottomNav',
|
|
8
|
-
component: BottomNav,
|
|
9
|
-
tags: ['autodocs'],
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
</script>
|
|
13
|
-
|
|
14
|
-
<script>
|
|
15
|
-
|
|
16
|
-
const defaultLinks = [
|
|
17
|
-
{ label: 'Home', href: '/', icon: 'Home' },
|
|
18
|
-
{ label: 'Shows', href: '/shows', icon: 'Shows' },
|
|
19
|
-
{ label: 'Availability', href: '/availability', icon: 'Availability' },
|
|
20
|
-
{ label: 'Profile', href: '/profile', icon: 'Profile' },
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
const extendedLinks = [
|
|
24
|
-
{ label: 'Home', href: '/', icon: 'Home' },
|
|
25
|
-
{ label: 'Shows', href: '/shows', icon: 'Shows' },
|
|
26
|
-
{ label: 'Availability', href: '/availability', icon: 'Availability' },
|
|
27
|
-
{ label: 'Messages', href: '/messages', icon: 'Message' },
|
|
28
|
-
{ label: 'Profile', href: '/profile', icon: 'Profile' },
|
|
29
|
-
];
|
|
30
|
-
</script>
|
|
31
|
-
|
|
32
|
-
<Story name="Default (4 Tabs)">
|
|
33
|
-
<div class="bg-gray-100 dark:bg-gray-700 p-4">
|
|
34
|
-
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Mobile Bottom Navigation (4 tabs)</p>
|
|
35
|
-
<div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
|
|
36
|
-
<div class="h-64 bg-gradient-to-br from-blue-50 to-blue-100 flex items-center justify-center">
|
|
37
|
-
<p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
|
|
38
|
-
</div>
|
|
39
|
-
<div class="flex border-t bg-white dark:bg-gray-900">
|
|
40
|
-
<BottomNav links={defaultLinks} />
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
44
|
-
</Story>
|
|
45
|
-
|
|
46
|
-
<Story name="With 5 Tabs">
|
|
47
|
-
<div class="bg-gray-100 dark:bg-gray-700 p-4">
|
|
48
|
-
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Extended Navigation (5 tabs)</p>
|
|
49
|
-
<div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
|
|
50
|
-
<div class="h-64 bg-gradient-to-br from-purple-50 to-purple-100 flex items-center justify-center">
|
|
51
|
-
<p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
|
|
52
|
-
</div>
|
|
53
|
-
<div class="flex border-t bg-white dark:bg-gray-900">
|
|
54
|
-
<BottomNav links={extendedLinks} />
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
</Story>
|
|
59
|
-
|
|
60
|
-
<Story name="Different Icon Set">
|
|
61
|
-
<div class="bg-gray-100 dark:bg-gray-700 p-4">
|
|
62
|
-
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Custom Icons</p>
|
|
63
|
-
<div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
|
|
64
|
-
<div class="h-64 bg-gradient-to-br from-green-50 to-green-100 flex items-center justify-center">
|
|
65
|
-
<p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
|
|
66
|
-
</div>
|
|
67
|
-
<div class="flex border-t bg-white dark:bg-gray-900">
|
|
68
|
-
<BottomNav
|
|
69
|
-
links={[
|
|
70
|
-
{ label: 'Dashboard', href: '/', icon: 'Home' },
|
|
71
|
-
{ label: 'Events', href: '/events', icon: 'Shows' },
|
|
72
|
-
{ label: 'Notifications', href: '/notifications', icon: 'Notification' },
|
|
73
|
-
{ label: 'Settings', href: '/settings', icon: 'Profile' },
|
|
74
|
-
]}
|
|
75
|
-
/>
|
|
76
|
-
</div>
|
|
77
|
-
</div>
|
|
78
|
-
</div>
|
|
79
|
-
</Story>
|
|
80
|
-
|
|
81
|
-
<Story name="Mobile Viewport">
|
|
82
|
-
<div class="max-w-[375px] mx-auto bg-white dark:bg-gray-900 shadow-2xl rounded-3xl overflow-hidden">
|
|
83
|
-
<!-- Mock iPhone screen -->
|
|
84
|
-
<div class="h-[667px] flex flex-col">
|
|
85
|
-
<!-- Status bar -->
|
|
86
|
-
<div class="h-6 bg-black flex items-center justify-between px-4">
|
|
87
|
-
<span class="text-white text-xs">9:41</span>
|
|
88
|
-
<span class="text-white text-xs">100%</span>
|
|
89
|
-
</div>
|
|
90
|
-
|
|
91
|
-
<!-- Content area -->
|
|
92
|
-
<div class="flex-1 bg-gradient-to-br from-blue-50 to-purple-50 p-4">
|
|
93
|
-
<h1 class="text-2xl font-bold mb-2">Home</h1>
|
|
94
|
-
<p class="text-gray-500 dark:text-gray-400">This is a mobile viewport simulation</p>
|
|
95
|
-
</div>
|
|
96
|
-
|
|
97
|
-
<!-- Bottom navigation -->
|
|
98
|
-
<div class="flex border-t bg-white dark:bg-gray-900 safe-bottom">
|
|
99
|
-
<BottomNav links={defaultLinks} />
|
|
100
|
-
</div>
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
</Story>
|
|
104
|
-
|
|
105
|
-
<Story name="Dark Mode">
|
|
106
|
-
<div class="dark bg-gray-900 p-4 min-h-screen">
|
|
107
|
-
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Dark Mode Bottom Navigation</p>
|
|
108
|
-
<div class="max-w-md mx-auto bg-gray-800 rounded-lg shadow-2xl overflow-hidden">
|
|
109
|
-
<div class="h-64 bg-gradient-to-br from-gray-900 to-gray-800 flex items-center justify-center">
|
|
110
|
-
<p class="text-gray-500 dark:text-gray-400">Dark Mode Content</p>
|
|
111
|
-
</div>
|
|
112
|
-
<div class="flex border-t border-gray-700 bg-gray-800">
|
|
113
|
-
<BottomNav links={defaultLinks} />
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
</Story>
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
|
|
4
|
+
import BottomNav from './BottomNav.svelte';
|
|
5
|
+
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: 'Components/Layout/BottomNav',
|
|
8
|
+
component: BottomNav,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
|
|
16
|
+
const defaultLinks = [
|
|
17
|
+
{ label: 'Home', href: '/', icon: 'Home' },
|
|
18
|
+
{ label: 'Shows', href: '/shows', icon: 'Shows' },
|
|
19
|
+
{ label: 'Availability', href: '/availability', icon: 'Availability' },
|
|
20
|
+
{ label: 'Profile', href: '/profile', icon: 'Profile' },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const extendedLinks = [
|
|
24
|
+
{ label: 'Home', href: '/', icon: 'Home' },
|
|
25
|
+
{ label: 'Shows', href: '/shows', icon: 'Shows' },
|
|
26
|
+
{ label: 'Availability', href: '/availability', icon: 'Availability' },
|
|
27
|
+
{ label: 'Messages', href: '/messages', icon: 'Message' },
|
|
28
|
+
{ label: 'Profile', href: '/profile', icon: 'Profile' },
|
|
29
|
+
];
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<Story name="Default (4 Tabs)">
|
|
33
|
+
<div class="bg-gray-100 dark:bg-gray-700 p-4">
|
|
34
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Mobile Bottom Navigation (4 tabs)</p>
|
|
35
|
+
<div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
|
|
36
|
+
<div class="h-64 bg-gradient-to-br from-blue-50 to-blue-100 flex items-center justify-center">
|
|
37
|
+
<p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="flex border-t bg-white dark:bg-gray-900">
|
|
40
|
+
<BottomNav links={defaultLinks} />
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</Story>
|
|
45
|
+
|
|
46
|
+
<Story name="With 5 Tabs">
|
|
47
|
+
<div class="bg-gray-100 dark:bg-gray-700 p-4">
|
|
48
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Extended Navigation (5 tabs)</p>
|
|
49
|
+
<div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
|
|
50
|
+
<div class="h-64 bg-gradient-to-br from-purple-50 to-purple-100 flex items-center justify-center">
|
|
51
|
+
<p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="flex border-t bg-white dark:bg-gray-900">
|
|
54
|
+
<BottomNav links={extendedLinks} />
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</Story>
|
|
59
|
+
|
|
60
|
+
<Story name="Different Icon Set">
|
|
61
|
+
<div class="bg-gray-100 dark:bg-gray-700 p-4">
|
|
62
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Custom Icons</p>
|
|
63
|
+
<div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
|
|
64
|
+
<div class="h-64 bg-gradient-to-br from-green-50 to-green-100 flex items-center justify-center">
|
|
65
|
+
<p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="flex border-t bg-white dark:bg-gray-900">
|
|
68
|
+
<BottomNav
|
|
69
|
+
links={[
|
|
70
|
+
{ label: 'Dashboard', href: '/', icon: 'Home' },
|
|
71
|
+
{ label: 'Events', href: '/events', icon: 'Shows' },
|
|
72
|
+
{ label: 'Notifications', href: '/notifications', icon: 'Notification' },
|
|
73
|
+
{ label: 'Settings', href: '/settings', icon: 'Profile' },
|
|
74
|
+
]}
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</Story>
|
|
80
|
+
|
|
81
|
+
<Story name="Mobile Viewport">
|
|
82
|
+
<div class="max-w-[375px] mx-auto bg-white dark:bg-gray-900 shadow-2xl rounded-3xl overflow-hidden">
|
|
83
|
+
<!-- Mock iPhone screen -->
|
|
84
|
+
<div class="h-[667px] flex flex-col">
|
|
85
|
+
<!-- Status bar -->
|
|
86
|
+
<div class="h-6 bg-black flex items-center justify-between px-4">
|
|
87
|
+
<span class="text-white text-xs">9:41</span>
|
|
88
|
+
<span class="text-white text-xs">100%</span>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<!-- Content area -->
|
|
92
|
+
<div class="flex-1 bg-gradient-to-br from-blue-50 to-purple-50 p-4">
|
|
93
|
+
<h1 class="text-2xl font-bold mb-2">Home</h1>
|
|
94
|
+
<p class="text-gray-500 dark:text-gray-400">This is a mobile viewport simulation</p>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<!-- Bottom navigation -->
|
|
98
|
+
<div class="flex border-t bg-white dark:bg-gray-900 safe-bottom">
|
|
99
|
+
<BottomNav links={defaultLinks} />
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</Story>
|
|
104
|
+
|
|
105
|
+
<Story name="Dark Mode">
|
|
106
|
+
<div class="dark bg-gray-900 p-4 min-h-screen">
|
|
107
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Dark Mode Bottom Navigation</p>
|
|
108
|
+
<div class="max-w-md mx-auto bg-gray-800 rounded-lg shadow-2xl overflow-hidden">
|
|
109
|
+
<div class="h-64 bg-gradient-to-br from-gray-900 to-gray-800 flex items-center justify-center">
|
|
110
|
+
<p class="text-gray-500 dark:text-gray-400">Dark Mode Content</p>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="flex border-t border-gray-700 bg-gray-800">
|
|
113
|
+
<BottomNav links={defaultLinks} />
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</Story>
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { page } from '../../__LIB_STORES__.js';
|
|
3
|
-
import { base } from '../../__LIB_PATHS__.js';
|
|
4
|
-
import { browser } from '../../__LIB_ENVIRONMENT__.js';
|
|
5
|
-
import { onMount } from "svelte";
|
|
6
|
-
import Icon from "../../primitives/Icons/Icon.svelte";
|
|
7
|
-
import { typography } from '../../tokens/typography';
|
|
8
|
-
|
|
9
|
-
interface NavLink {
|
|
10
|
-
label: string;
|
|
11
|
-
href: string;
|
|
12
|
-
icon: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface Props {
|
|
16
|
-
links?: NavLink[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let {
|
|
20
|
-
links = [],
|
|
21
|
-
}: Props = $props();
|
|
22
|
-
|
|
23
|
-
let invitationCount = $state(0);
|
|
24
|
-
|
|
25
|
-
let currentPath = $derived($page.url.pathname);
|
|
26
|
-
|
|
27
|
-
function isActive(href: string, path: string): boolean {
|
|
28
|
-
if (href === `${base}/` || href === '/') {
|
|
29
|
-
return path === href || path === `${base}/`;
|
|
30
|
-
}
|
|
31
|
-
return path.startsWith(href);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
onMount(() => {
|
|
35
|
-
async function fetchShows() {
|
|
36
|
-
try {
|
|
37
|
-
const res = await fetch(`/api/getEventsForVenue`);
|
|
38
|
-
if (!res.ok) {
|
|
39
|
-
// Silently ignore auth errors - user may not be logged in yet
|
|
40
|
-
if (res.status === 401) return;
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
const events = await res.json();
|
|
44
|
-
invitationCount = events.filter((event: { acceptedState: number }) => event.acceptedState === 0).length;
|
|
45
|
-
} catch (_err) {
|
|
46
|
-
// Silently fail - this is non-critical UI enhancement
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (browser) {
|
|
51
|
-
fetchShows();
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
</script>
|
|
55
|
-
|
|
56
|
-
{#each links as { label, href, icon }}
|
|
57
|
-
<a
|
|
58
|
-
{href}
|
|
59
|
-
class={`bottom-nav-item flex-1 flex items-center justify-center py-3 px-2 no-underline bg-transparent border-none cursor-pointer min-w-0
|
|
60
|
-
${typography.textMuted} transition-colors duration-150
|
|
61
|
-
hover:text-gray-900 hover:no-underline dark:hover:text-white
|
|
62
|
-
select-none touch-manipulation
|
|
63
|
-
${isActive(href, currentPath) ? 'active text-blue-700 dark:text-blue-500' : ''}`}
|
|
64
|
-
aria-label={label}
|
|
65
|
-
style="-webkit-tap-highlight-color: transparent; -webkit-touch-callout: none;"
|
|
66
|
-
>
|
|
67
|
-
<span class="bottom-nav-icon relative flex items-center justify-center transition-transform duration-150 active:scale-[0.8]">
|
|
68
|
-
<Icon name={icon} size="24" />
|
|
69
|
-
{#if label === "Shows" && invitationCount > 0}
|
|
70
|
-
<span class="notification-dot absolute -top-1 -right-1 w-2 h-2 bg-red-500 rounded-full"></span>
|
|
71
|
-
{/if}
|
|
72
|
-
</span>
|
|
73
|
-
</a>
|
|
74
|
-
{/each}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { page } from '../../__LIB_STORES__.js';
|
|
3
|
+
import { base } from '../../__LIB_PATHS__.js';
|
|
4
|
+
import { browser } from '../../__LIB_ENVIRONMENT__.js';
|
|
5
|
+
import { onMount } from "svelte";
|
|
6
|
+
import Icon from "../../primitives/Icons/Icon.svelte";
|
|
7
|
+
import { typography } from '../../tokens/typography';
|
|
8
|
+
|
|
9
|
+
interface NavLink {
|
|
10
|
+
label: string;
|
|
11
|
+
href: string;
|
|
12
|
+
icon: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
links?: NavLink[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
links = [],
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
|
|
23
|
+
let invitationCount = $state(0);
|
|
24
|
+
|
|
25
|
+
let currentPath = $derived($page.url.pathname);
|
|
26
|
+
|
|
27
|
+
function isActive(href: string, path: string): boolean {
|
|
28
|
+
if (href === `${base}/` || href === '/') {
|
|
29
|
+
return path === href || path === `${base}/`;
|
|
30
|
+
}
|
|
31
|
+
return path.startsWith(href);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
onMount(() => {
|
|
35
|
+
async function fetchShows() {
|
|
36
|
+
try {
|
|
37
|
+
const res = await fetch(`/api/getEventsForVenue`);
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
// Silently ignore auth errors - user may not be logged in yet
|
|
40
|
+
if (res.status === 401) return;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const events = await res.json();
|
|
44
|
+
invitationCount = events.filter((event: { acceptedState: number }) => event.acceptedState === 0).length;
|
|
45
|
+
} catch (_err) {
|
|
46
|
+
// Silently fail - this is non-critical UI enhancement
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (browser) {
|
|
51
|
+
fetchShows();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
{#each links as { label, href, icon }}
|
|
57
|
+
<a
|
|
58
|
+
{href}
|
|
59
|
+
class={`bottom-nav-item flex-1 flex items-center justify-center py-3 px-2 no-underline bg-transparent border-none cursor-pointer min-w-0
|
|
60
|
+
${typography.textMuted} transition-colors duration-150
|
|
61
|
+
hover:text-gray-900 hover:no-underline dark:hover:text-white
|
|
62
|
+
select-none touch-manipulation
|
|
63
|
+
${isActive(href, currentPath) ? 'active text-blue-700 dark:text-blue-500' : ''}`}
|
|
64
|
+
aria-label={label}
|
|
65
|
+
style="-webkit-tap-highlight-color: transparent; -webkit-touch-callout: none;"
|
|
66
|
+
>
|
|
67
|
+
<span class="bottom-nav-icon relative flex items-center justify-center transition-transform duration-150 active:scale-[0.8]">
|
|
68
|
+
<Icon name={icon} size="24" />
|
|
69
|
+
{#if label === "Shows" && invitationCount > 0}
|
|
70
|
+
<span class="notification-dot absolute -top-1 -right-1 w-2 h-2 bg-red-500 rounded-full"></span>
|
|
71
|
+
{/if}
|
|
72
|
+
</span>
|
|
73
|
+
</a>
|
|
74
|
+
{/each}
|
|
@@ -136,6 +136,18 @@ describe('Header', () => {
|
|
|
136
136
|
await fireEvent.click(desktopButton);
|
|
137
137
|
expect(container.querySelector('div.absolute.top-\\[calc\\(100\\%\\+0\\.5rem\\)\\]')).toBeFalsy();
|
|
138
138
|
});
|
|
139
|
+
it('navigates and closes dropdown when a dropdown link is clicked', async () => {
|
|
140
|
+
const { goto } = await import('$app/navigation');
|
|
141
|
+
const { container } = render(Header, defaultProps);
|
|
142
|
+
const desktopButton = container.querySelector('button.hidden.md\\:block');
|
|
143
|
+
await fireEvent.click(desktopButton);
|
|
144
|
+
// Click the "Account Settings" menu item in the dropdown
|
|
145
|
+
const accountSettings = screen.getByText('Account Settings');
|
|
146
|
+
await fireEvent.click(accountSettings);
|
|
147
|
+
expect(goto).toHaveBeenCalledWith('/account-settings');
|
|
148
|
+
// Dropdown should be closed after clicking
|
|
149
|
+
expect(container.querySelector('div.absolute.top-\\[calc\\(100\\%\\+0\\.5rem\\)\\]')).toBeFalsy();
|
|
150
|
+
});
|
|
139
151
|
});
|
|
140
152
|
describe('mobile sheet', () => {
|
|
141
153
|
it('triggers mobile sheet state when mobile avatar is clicked', async () => {
|
|
@@ -150,6 +162,69 @@ describe('Header', () => {
|
|
|
150
162
|
const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
|
|
151
163
|
expect(mobileSheet).toBeTruthy();
|
|
152
164
|
});
|
|
165
|
+
it('navigates when a mobile sheet dropdown link is clicked', async () => {
|
|
166
|
+
const { goto } = await import('$app/navigation');
|
|
167
|
+
const { container } = render(Header, defaultProps);
|
|
168
|
+
const mobileButton = container.querySelector('button.block.md\\:hidden');
|
|
169
|
+
await fireEvent.click(mobileButton);
|
|
170
|
+
// Mobile sheet renders via portal in document.body
|
|
171
|
+
const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
|
|
172
|
+
expect(mobileSheet).toBeTruthy();
|
|
173
|
+
// Click the first dropdown link in the mobile sheet
|
|
174
|
+
const menuItems = mobileSheet.querySelectorAll('button');
|
|
175
|
+
// Find the menu item with "Account Settings" text
|
|
176
|
+
const accountBtn = Array.from(menuItems).find(btn => btn.textContent?.includes('Account Settings'));
|
|
177
|
+
expect(accountBtn).toBeTruthy();
|
|
178
|
+
await fireEvent.click(accountBtn);
|
|
179
|
+
expect(goto).toHaveBeenCalledWith('/account-settings');
|
|
180
|
+
});
|
|
181
|
+
it('calls signoutHandler and closes sheet when mobile sign out is clicked', async () => {
|
|
182
|
+
const signoutHandler = vi.fn();
|
|
183
|
+
const { container } = render(Header, { ...defaultProps, signoutHandler });
|
|
184
|
+
const mobileButton = container.querySelector('button.block.md\\:hidden');
|
|
185
|
+
await fireEvent.click(mobileButton);
|
|
186
|
+
const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
|
|
187
|
+
expect(mobileSheet).toBeTruthy();
|
|
188
|
+
// Find the Sign Out button in the mobile sheet
|
|
189
|
+
const menuItems = mobileSheet.querySelectorAll('button');
|
|
190
|
+
const signOutBtn = Array.from(menuItems).find(btn => btn.textContent?.includes('Sign Out'));
|
|
191
|
+
expect(signOutBtn).toBeTruthy();
|
|
192
|
+
await fireEvent.click(signOutBtn);
|
|
193
|
+
expect(signoutHandler).toHaveBeenCalled();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
describe('back button mode desktop dropdown', () => {
|
|
197
|
+
it('shows dropdown with dropdown links and sign out when avatar clicked in back-button mode', async () => {
|
|
198
|
+
const { goto } = await import('$app/navigation');
|
|
199
|
+
const signoutHandler = vi.fn();
|
|
200
|
+
const { container } = render(Header, { ...defaultProps, showBackButton: true, signoutHandler });
|
|
201
|
+
// In back-button mode, the desktop section is within "hidden md:flex"
|
|
202
|
+
// The avatar button is the only AvatarButton in that section
|
|
203
|
+
const avatarButtons = container.querySelectorAll('button');
|
|
204
|
+
// Find the avatar button that opens the dropdown (not the Back button)
|
|
205
|
+
const desktopAvatarBtn = Array.from(avatarButtons).find(btn => !btn.textContent?.includes('Back') && btn.querySelector('img'));
|
|
206
|
+
expect(desktopAvatarBtn).toBeTruthy();
|
|
207
|
+
await fireEvent.click(desktopAvatarBtn);
|
|
208
|
+
// Dropdown should be visible
|
|
209
|
+
const dropdown = container.querySelector('div.absolute.top-\\[calc\\(100\\%\\+0\\.5rem\\)\\]');
|
|
210
|
+
expect(dropdown).toBeTruthy();
|
|
211
|
+
// Click a dropdown link
|
|
212
|
+
const accountSettings = screen.getByText('Account Settings');
|
|
213
|
+
await fireEvent.click(accountSettings);
|
|
214
|
+
expect(goto).toHaveBeenCalledWith('/account-settings');
|
|
215
|
+
});
|
|
216
|
+
it('calls signoutHandler when sign out clicked in back-button mode dropdown', async () => {
|
|
217
|
+
const signoutHandler = vi.fn();
|
|
218
|
+
const { container } = render(Header, { ...defaultProps, showBackButton: true, signoutHandler });
|
|
219
|
+
// Find the avatar button (not the Back button)
|
|
220
|
+
const avatarButtons = container.querySelectorAll('button');
|
|
221
|
+
const desktopAvatarBtn = Array.from(avatarButtons).find(btn => !btn.textContent?.includes('Back') && btn.querySelector('img'));
|
|
222
|
+
await fireEvent.click(desktopAvatarBtn);
|
|
223
|
+
// Click sign out
|
|
224
|
+
const signOutBtn = screen.getByText('Sign out');
|
|
225
|
+
await fireEvent.click(signOutBtn);
|
|
226
|
+
expect(signoutHandler).toHaveBeenCalled();
|
|
227
|
+
});
|
|
153
228
|
});
|
|
154
229
|
describe('navigation active state', () => {
|
|
155
230
|
it('marks current path as active', () => {
|
|
@@ -166,5 +241,53 @@ describe('Header', () => {
|
|
|
166
241
|
await fireEvent.click(desktopButton);
|
|
167
242
|
expect(screen.getByText('Performer')).toBeTruthy();
|
|
168
243
|
});
|
|
244
|
+
it('shows name in mobile sheet when provided', async () => {
|
|
245
|
+
const { container } = render(Header, { ...defaultProps, name: 'Jane Doe' });
|
|
246
|
+
const mobileButton = container.querySelector('button.block.md\\:hidden');
|
|
247
|
+
await fireEvent.click(mobileButton);
|
|
248
|
+
const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
|
|
249
|
+
expect(mobileSheet).toBeTruthy();
|
|
250
|
+
expect(mobileSheet.textContent).toContain('Jane Doe');
|
|
251
|
+
});
|
|
252
|
+
it('shows "Performer" in mobile sheet when name is empty', async () => {
|
|
253
|
+
const { container } = render(Header, { ...defaultProps, name: '' });
|
|
254
|
+
const mobileButton = container.querySelector('button.block.md\\:hidden');
|
|
255
|
+
await fireEvent.click(mobileButton);
|
|
256
|
+
const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
|
|
257
|
+
expect(mobileSheet).toBeTruthy();
|
|
258
|
+
expect(mobileSheet.textContent).toContain('Performer');
|
|
259
|
+
});
|
|
260
|
+
it('shows "Performer" in back-button mode dropdown when name is empty', async () => {
|
|
261
|
+
const { container } = render(Header, { ...defaultProps, name: '', showBackButton: true });
|
|
262
|
+
const avatarButtons = container.querySelectorAll('button');
|
|
263
|
+
const desktopAvatarBtn = Array.from(avatarButtons).find(btn => !btn.textContent?.includes('Back') && btn.querySelector('img'));
|
|
264
|
+
await fireEvent.click(desktopAvatarBtn);
|
|
265
|
+
const dropdown = container.querySelector('div.absolute.top-\\[calc\\(100\\%\\+0\\.5rem\\)\\]');
|
|
266
|
+
expect(dropdown).toBeTruthy();
|
|
267
|
+
expect(dropdown.textContent).toContain('Performer');
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
describe('isActive edge cases', () => {
|
|
271
|
+
it('marks root nav link as active when path matches base', () => {
|
|
272
|
+
// The mock sets page pathname to '/shows' and base to '/performers'
|
|
273
|
+
// Add a root link and verify it is NOT active (since path is /shows)
|
|
274
|
+
const propsWithRoot = {
|
|
275
|
+
...defaultProps,
|
|
276
|
+
navLinks: [
|
|
277
|
+
{ label: 'Home', href: '/performers/' },
|
|
278
|
+
...defaultProps.navLinks
|
|
279
|
+
]
|
|
280
|
+
};
|
|
281
|
+
const { container } = render(Header, propsWithRoot);
|
|
282
|
+
const homeLink = container.querySelector('a[href="/performers/"]');
|
|
283
|
+
// /shows does not match /performers/, so it should NOT be active
|
|
284
|
+
expect(homeLink.classList.contains('text-blue-700')).toBe(false);
|
|
285
|
+
});
|
|
286
|
+
it('marks link as active using startsWith for non-root paths', () => {
|
|
287
|
+
const { container } = render(Header, defaultProps);
|
|
288
|
+
// '/shows' starts with '/shows' so it should be active
|
|
289
|
+
const showsLink = container.querySelector('a[href="/shows"]');
|
|
290
|
+
expect(showsLink.classList.contains('text-blue-700')).toBe(true);
|
|
291
|
+
});
|
|
169
292
|
});
|
|
170
293
|
});
|