@getmicdrop/svelte-components 5.19.0 → 5.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base.css +18 -0
- package/dist/calendar/AboutShow/AboutShow.svelte +191 -191
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte +803 -801
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte.d.ts.map +1 -1
- package/dist/calendar/FAQs/FAQs.svelte +88 -88
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +140 -140
- package/dist/calendar/OrderSummary/OrderSummary.svelte +461 -461
- package/dist/calendar/PublicCard/PublicCard.svelte +164 -164
- package/dist/calendar/ShowCard/ShowCard.svelte +180 -180
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +80 -80
- package/dist/calendar/index.js +15 -15
- package/dist/components/Heading.spec.js +89 -89
- package/dist/components/Heading.svelte +66 -60
- package/dist/components/Heading.svelte.d.ts +1 -0
- package/dist/components/Heading.svelte.d.ts.map +1 -1
- package/dist/components/Layout/AppShell.svelte +104 -104
- package/dist/components/Layout/ContentSection.svelte +80 -80
- package/dist/components/Layout/Grid.svelte +101 -101
- 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 +52 -52
- package/dist/components/Layout/Text.svelte +87 -87
- package/dist/components/Layout/TwoColumn.svelte +108 -108
- package/dist/components/Text.spec.js +89 -89
- package/dist/components/Text.svelte +64 -53
- package/dist/components/Text.svelte.d.ts +2 -1
- package/dist/components/Text.svelte.d.ts.map +1 -1
- package/dist/config.js +151 -151
- package/dist/config.spec.js +29 -29
- package/dist/constants/formOptions.d.ts +2 -5
- package/dist/constants/formOptions.d.ts.map +1 -1
- package/dist/constants/formOptions.js +48 -48
- package/dist/constants/formOptions.spec.js +2 -7
- package/dist/constants/validation.js +91 -91
- package/dist/constants/validation.spec.js +64 -64
- package/dist/datetime/README.md +323 -323
- 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 +0 -1
- package/dist/forms/createFormStore.svelte.spec.js +0 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +85 -66
- package/dist/index.spec.js +369 -369
- package/dist/patterns/chat/ChatActivityNotice.spec.js +59 -59
- package/dist/patterns/chat/ChatActivityNotice.svelte +41 -41
- package/dist/patterns/chat/ChatBubble.spec.js +91 -91
- package/dist/patterns/chat/ChatBubble.svelte +103 -103
- package/dist/patterns/chat/ChatContainer.spec.js +30 -30
- package/dist/patterns/chat/ChatContainer.svelte +46 -46
- package/dist/patterns/chat/ChatDateDivider.spec.js +30 -30
- package/dist/patterns/chat/ChatDateDivider.svelte +27 -27
- package/dist/patterns/chat/ChatInvitationBubble.spec.js +46 -46
- package/dist/patterns/chat/ChatInvitationBubble.svelte +46 -46
- package/dist/patterns/chat/ChatInvitationNotice.spec.js +32 -32
- package/dist/patterns/chat/ChatInvitationNotice.svelte +36 -36
- package/dist/patterns/chat/ChatMessageGroup.spec.js +58 -58
- package/dist/patterns/chat/ChatMessageGroup.svelte +57 -57
- package/dist/patterns/chat/ChatSlotUpdate.spec.js +65 -65
- package/dist/patterns/chat/ChatSlotUpdate.svelte +46 -46
- package/dist/patterns/chat/ChatStatusBadge.spec.js +79 -79
- package/dist/patterns/chat/ChatStatusBadge.svelte +91 -91
- package/dist/patterns/chat/ChatStatusTransition.spec.js +81 -81
- package/dist/patterns/chat/ChatStatusTransition.svelte +64 -64
- package/dist/patterns/chat/ChatTextBubble.spec.js +35 -35
- 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.svelte +45 -45
- package/dist/patterns/data/index.js +4 -4
- 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.svelte +33 -33
- package/dist/patterns/forms/FormSection.svelte +33 -32
- package/dist/patterns/forms/FormSection.svelte.d.ts +2 -0
- package/dist/patterns/forms/FormSection.svelte.d.ts.map +1 -1
- package/dist/patterns/forms/FormValidationSummary.stories.svelte +97 -97
- package/dist/patterns/forms/FormValidationSummary.svelte +82 -82
- package/dist/patterns/forms/index.js +5 -5
- package/dist/patterns/index.js +21 -21
- package/dist/patterns/layout/Sidebar.svelte +39 -39
- package/dist/patterns/layout/SidebarTestWrapper.svelte +34 -34
- package/dist/patterns/layout/Stack.svelte +61 -61
- package/dist/patterns/layout/index.js +29 -29
- package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
- package/dist/patterns/navigation/BottomNav.svelte +82 -82
- package/dist/patterns/navigation/Header.stories.svelte +77 -77
- package/dist/patterns/navigation/Header.svelte +263 -263
- package/dist/patterns/navigation/index.js +3 -3
- package/dist/patterns/page/PageHeader.svelte +49 -49
- 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 +62 -62
- package/dist/patterns/page/SectionHeader.svelte +51 -51
- package/dist/patterns/page/index.js +5 -5
- 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.stories.svelte +75 -75
- package/dist/primitives/Accordion/Accordion.svelte +62 -62
- package/dist/primitives/Accordion/AccordionItem.svelte +103 -103
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte +107 -107
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte +28 -28
- package/dist/primitives/Alert/Alert.spec.js +173 -173
- package/dist/primitives/Alert/Alert.stories.svelte +88 -88
- package/dist/primitives/Alert/Alert.svelte +72 -72
- 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 -238
- 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 -20
- package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +123 -123
- package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +107 -107
- 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.js +44 -44
- 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 +4 -15
- 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 +147 -147
- package/dist/primitives/Drawer/Drawer.stories.svelte +100 -100
- package/dist/primitives/Drawer/Drawer.svelte +224 -224
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte +86 -86
- package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
- package/dist/primitives/Dropdown/Dropdown.svelte +179 -179
- package/dist/primitives/Dropdown/DropdownDivider.spec.js +30 -30
- package/dist/primitives/Dropdown/DropdownDivider.svelte +9 -9
- package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte +43 -43
- package/dist/primitives/Helper/Helper.spec.js +57 -57
- package/dist/primitives/Helper/Helper.svelte +33 -33
- package/dist/primitives/Icons/ArrowLeft.svelte +21 -21
- package/dist/primitives/Icons/ArrowRight.svelte +21 -21
- package/dist/primitives/Icons/Availability.svelte +27 -27
- package/dist/primitives/Icons/Back.svelte +27 -27
- package/dist/primitives/Icons/CheckCircle.svelte +19 -19
- package/dist/primitives/Icons/CheckCircleOutline.svelte +28 -28
- package/dist/primitives/Icons/ChevronLeft.svelte +17 -17
- package/dist/primitives/Icons/ChevronRight.svelte +17 -17
- package/dist/primitives/Icons/Copy.svelte +28 -28
- package/dist/primitives/Icons/Cross.svelte +18 -18
- package/dist/primitives/Icons/DownArrow.svelte +21 -21
- package/dist/primitives/Icons/ErrorCircle.svelte +19 -19
- package/dist/primitives/Icons/FacebookIcon.svelte +15 -15
- package/dist/primitives/Icons/Home.svelte +28 -28
- package/dist/primitives/Icons/Icon.spec.js +175 -175
- package/dist/primitives/Icons/Icon.stories.svelte +100 -100
- package/dist/primitives/Icons/Icon.svelte +79 -79
- package/dist/primitives/Icons/IconGallery.stories.svelte +235 -235
- package/dist/primitives/Icons/ImageOutline.svelte +21 -21
- package/dist/primitives/Icons/Info.svelte +20 -20
- package/dist/primitives/Icons/InstagramIcon.svelte +21 -21
- package/dist/primitives/Icons/LogoInstagram.svelte +15 -15
- package/dist/primitives/Icons/Message.svelte +28 -28
- package/dist/primitives/Icons/MoonIcon.svelte +18 -18
- package/dist/primitives/Icons/More.svelte +34 -34
- package/dist/primitives/Icons/MoreHori.spec.js +67 -67
- package/dist/primitives/Icons/MoreHori.svelte +35 -35
- package/dist/primitives/Icons/Notification.svelte +27 -27
- package/dist/primitives/Icons/Payment.svelte +27 -27
- package/dist/primitives/Icons/Profile.svelte +34 -34
- package/dist/primitives/Icons/Reload.svelte +42 -42
- package/dist/primitives/Icons/Shows.svelte +34 -34
- package/dist/primitives/Icons/Signout.svelte +34 -34
- package/dist/primitives/Icons/SunIcon.svelte +21 -21
- package/dist/primitives/Icons/TiktokIcon.svelte +15 -15
- package/dist/primitives/Icons/TrashBinOutline.svelte +21 -21
- package/dist/primitives/Icons/TwitterIcon.svelte +15 -15
- package/dist/primitives/Icons/WarningIcon.spec.js +30 -30
- package/dist/primitives/Icons/WarningIcon.svelte +24 -24
- package/dist/primitives/Input/Input.spec.js +1237 -1237
- package/dist/primitives/Input/Input.stories.svelte +139 -139
- package/dist/primitives/Input/Input.svelte +444 -444
- package/dist/primitives/Input/Select.spec.js +632 -632
- 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.svelte +37 -37
- package/dist/primitives/LandingButton/LandingButton.spec.js +61 -61
- package/dist/primitives/LandingButton/LandingButton.svelte +92 -92
- package/dist/primitives/MenuItem/MenuItem.spec.js +130 -130
- package/dist/primitives/MenuItem/MenuItem.svelte +85 -85
- package/dist/primitives/Modal/Modal.spec.js +314 -314
- package/dist/primitives/Modal/Modal.stories.svelte +86 -86
- package/dist/primitives/Modal/Modal.svelte +181 -181
- package/dist/primitives/NavItem/NavItem.spec.js +97 -97
- package/dist/primitives/NavItem/NavItem.svelte +75 -75
- package/dist/primitives/NumberInput/NumberInput.svelte +113 -113
- package/dist/primitives/Pagination/DotIndicator.svelte +66 -0
- package/dist/primitives/Pagination/DotIndicator.svelte.d.ts +18 -0
- package/dist/primitives/Pagination/DotIndicator.svelte.d.ts.map +1 -0
- package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
- package/dist/primitives/Pagination/Pagination.svelte +275 -275
- package/dist/primitives/Radio/Radio.stories.svelte +80 -80
- package/dist/primitives/Radio/Radio.svelte +67 -67
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.js +78 -78
- package/dist/primitives/SearchResultItem/SearchResultItem.svelte +109 -109
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.js +61 -61
- package/dist/primitives/SidebarToggle/SidebarToggle.svelte +55 -55
- package/dist/primitives/Skeleton/CardPlaceholder.svelte +96 -96
- package/dist/primitives/Skeleton/ImagePlaceholder.svelte +68 -68
- package/dist/primitives/Skeleton/ListPlaceholder.svelte +85 -85
- package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
- package/dist/primitives/Skeleton/Skeleton.svelte +55 -55
- package/dist/primitives/Spinner/Spinner.spec.js +84 -84
- package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
- package/dist/primitives/Spinner/Spinner.svelte +52 -52
- package/dist/primitives/Tabs/TabItem.svelte +52 -52
- package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
- package/dist/primitives/Tabs/Tabs.svelte +137 -137
- package/dist/primitives/Toggle.spec.js +221 -221
- package/dist/primitives/Toggle.stories.svelte +92 -92
- package/dist/primitives/Toggle.svelte +141 -141
- package/dist/primitives/ToggleTestWrapper.svelte +30 -30
- package/dist/primitives/Tooltip/Tooltip.spec.js +126 -126
- 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 +112 -112
- package/dist/primitives/ValidationError.svelte +29 -29
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.js +114 -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 +994 -994
- package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
- package/dist/recipes/feedback/EmptyState/EmptyState.svelte +75 -75
- package/dist/recipes/feedback/ErrorDisplay.spec.js +69 -69
- package/dist/recipes/feedback/ErrorDisplay.stories.svelte +113 -113
- package/dist/recipes/feedback/ErrorDisplay.svelte +67 -67
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +133 -133
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +176 -176
- package/dist/recipes/feedback/index.js +4 -4
- 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 +101 -101
- package/dist/recipes/fields/ToggleField.svelte +60 -60
- package/dist/recipes/fields/index.js +7 -7
- package/dist/recipes/index.js +24 -24
- package/dist/recipes/inputs/MultiSelect.spec.js +263 -263
- package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
- package/dist/recipes/inputs/MultiSelect.svelte +291 -291
- package/dist/recipes/inputs/OTPInput.spec.js +251 -251
- package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
- package/dist/recipes/inputs/OTPInput.svelte +128 -128
- package/dist/recipes/inputs/PasswordInput.svelte +130 -130
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +142 -142
- package/dist/recipes/inputs/PhoneInput.svelte +254 -254
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +170 -170
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +349 -349
- package/dist/recipes/inputs/Search.svelte +110 -110
- package/dist/recipes/inputs/index.js +8 -8
- package/dist/recipes/inputs/phoneInput/CountrySelector.svelte +240 -240
- package/dist/recipes/modals/AlertModal.svelte +139 -139
- package/dist/recipes/modals/ConfirmationModal.spec.js +396 -396
- package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
- package/dist/recipes/modals/ConfirmationModal.svelte +169 -169
- package/dist/recipes/modals/FeedbackModal.svelte +205 -0
- package/dist/recipes/modals/FeedbackModal.svelte.d.ts +24 -0
- package/dist/recipes/modals/FeedbackModal.svelte.d.ts.map +1 -0
- package/dist/recipes/modals/InputModal.svelte +194 -194
- 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 +216 -216
- package/dist/recipes/modals/index.d.ts +1 -0
- package/dist/recipes/modals/index.js +8 -7
- package/dist/schemas/common.js +1 -1
- package/dist/schemas/event.js +1 -1
- package/dist/schemas/order.js +0 -1
- package/dist/schemas/performer.js +1 -1
- package/dist/schemas/promo.js +2 -2
- package/dist/schemas/ticket.js +1 -1
- package/dist/schemas/user.js +1 -2
- package/dist/services/show.service.d.ts +46 -46
- package/dist/stores/auth.d.ts +8 -8
- package/dist/stores/auth.svelte.spec.js +1 -1
- package/dist/stores/index.js +9 -9
- package/dist/stores/toaster.d.ts +3 -3
- package/dist/stores/toaster.js +13 -13
- package/dist/stores/toaster.spec.js +59 -59
- 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 +399 -399
- 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 +87 -82
- package/dist/tailwind/preset.d.cts +2 -0
- package/dist/tailwind/preset.d.cts.map +1 -1
- 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 +1173 -1173
- package/dist/tokens/__tests__/spacing.test.js +2 -2
- package/dist/tokens/__tests__/variants.test.js +12 -4
- package/dist/tokens/base-resets.css +124 -0
- package/dist/tokens/spacing.d.ts +2 -0
- package/dist/tokens/spacing.d.ts.map +1 -1
- package/dist/tokens/spacing.js +1 -0
- package/dist/tokens/tokens.css +87 -87
- package/dist/tokens/typography-base.css +163 -163
- package/dist/tokens/utilities.css +430 -353
- package/dist/tokens/variants.d.ts +4 -4
- package/dist/tokens/variants.js +4 -4
- package/dist/utils/__tests__/auth.test.js +431 -431
- package/dist/utils/apiConfig.d.ts +29 -29
- package/dist/utils/apiConfig.js +117 -117
- package/dist/utils/apiConfig.spec.js +226 -219
- package/dist/utils/auth.d.ts +46 -46
- package/dist/utils/auth.js +195 -195
- package/dist/utils/clickOutside.d.ts +4 -0
- package/dist/utils/clickOutside.d.ts.map +1 -0
- package/dist/utils/clickOutside.js +13 -0
- package/dist/utils/feedbackContext.d.ts +24 -0
- package/dist/utils/feedbackContext.d.ts.map +1 -0
- package/dist/utils/feedbackContext.js +19 -0
- package/dist/utils/fetchHelpers.d.ts.map +1 -1
- package/dist/utils/fetchHelpers.js +1 -0
- package/dist/utils/focusTrap.d.ts +20 -0
- package/dist/utils/focusTrap.d.ts.map +1 -0
- package/dist/utils/focusTrap.js +130 -0
- package/dist/utils/formatters.js +1 -1
- package/dist/utils/greetings.js +187 -187
- package/dist/utils/greetings.spec.js +337 -337
- package/dist/utils/haptic.spec.js +1 -1
- package/dist/utils/imageValidation.js +121 -121
- package/dist/utils/imageValidation.spec.js +223 -223
- package/dist/utils/logger.d.ts +25 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +59 -1
- package/dist/utils/logger.spec.js +99 -1
- package/dist/utils/portal.d.ts +11 -11
- package/dist/utils/portal.js +25 -25
- package/dist/utils/portal.spec.js +143 -143
- package/dist/utils/transitions.d.ts +99 -1
- package/dist/utils/transitions.d.ts.map +1 -1
- package/dist/utils/transitions.js +148 -6
- package/dist/utils/utils/utils.d.ts +2 -2
- package/dist/utils/utils/utils.js +3 -3
- package/dist/utils/utils/utils.spec.js +698 -698
- package/dist/utils/utils.d.ts +41 -41
- package/dist/utils/utils.js +59 -59
- package/dist/utils/utils.spec.js +643 -643
- package/package.json +310 -301
package/dist/datetime/README.md
CHANGED
|
@@ -1,323 +1,323 @@
|
|
|
1
|
-
# DateTime Module
|
|
2
|
-
|
|
3
|
-
Centralized date/time handling for the MicDrop platform. This module eliminates timezone bugs by enforcing consistent patterns across the application.
|
|
4
|
-
|
|
5
|
-
## Golden Rules
|
|
6
|
-
|
|
7
|
-
1. **Backend is King** - All API requests send/receive UTC ISO strings (`2023-12-25T20:00:00Z`)
|
|
8
|
-
2. **Display is Local** - All UI components receive UTC strings + Timezone ID
|
|
9
|
-
3. **No `new Date()` in components** - Use these helpers instead
|
|
10
|
-
4. **Timezone is always required** - Every function requires explicit timezone parameter
|
|
11
|
-
|
|
12
|
-
## Quick Start
|
|
13
|
-
|
|
14
|
-
```typescript
|
|
15
|
-
import * as datetime from '$lib/datetime';
|
|
16
|
-
|
|
17
|
-
// Get timezone from venue (throws if missing)
|
|
18
|
-
const tz = datetime.getVenueTimezone(venue);
|
|
19
|
-
|
|
20
|
-
// Format for display
|
|
21
|
-
const time = datetime.formatEventTime(event.startTime, tz); // "7:00 PM"
|
|
22
|
-
const date = datetime.formatEventDate(event.startTime, tz); // "Dec 25, 2023"
|
|
23
|
-
const full = datetime.formatEventDateTime(event.startTime, tz); // "Dec 25, 2023 at 7:00 PM"
|
|
24
|
-
|
|
25
|
-
// Parse form input to UTC for API
|
|
26
|
-
const utc = datetime.combineDateAndTime('2023-12-25', '19:00', tz);
|
|
27
|
-
|
|
28
|
-
// Parse API response for form
|
|
29
|
-
const { date, time } = datetime.parseDateTimeFromAPI(event.startTime, tz);
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Module Structure
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
src/lib/datetime/
|
|
36
|
-
├── index.ts # Clean exports
|
|
37
|
-
├── types.ts # Type definitions
|
|
38
|
-
├── constants.ts # Duration constants, format strings
|
|
39
|
-
├── timezone.ts # Timezone utilities
|
|
40
|
-
├── format.ts # Formatting functions
|
|
41
|
-
├── parse.ts # Parsing functions
|
|
42
|
-
├── __tests__/ # Comprehensive tests
|
|
43
|
-
│ ├── timezone.test.ts
|
|
44
|
-
│ ├── format.test.ts
|
|
45
|
-
│ ├── parse.test.ts
|
|
46
|
-
│ └── integration.test.ts
|
|
47
|
-
└── README.md # This file
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## API Reference
|
|
51
|
-
|
|
52
|
-
### Timezone Utilities
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
// Validate timezone
|
|
56
|
-
isValidTimezone('America/Los_Angeles'); // true
|
|
57
|
-
isValidTimezone('PST'); // false (abbreviations not valid)
|
|
58
|
-
|
|
59
|
-
// Get venue timezone (throws if missing)
|
|
60
|
-
const tz = getVenueTimezone(venue);
|
|
61
|
-
|
|
62
|
-
// Get user's browser timezone
|
|
63
|
-
const userTz = getUserTimezone();
|
|
64
|
-
|
|
65
|
-
// Get timezone offset string
|
|
66
|
-
getTimezoneOffset('America/Los_Angeles'); // "PST (UTC-8)"
|
|
67
|
-
|
|
68
|
-
// Normalize legacy timezone abbreviations
|
|
69
|
-
normalizeTimezone('PST'); // "America/Los_Angeles"
|
|
70
|
-
|
|
71
|
-
// Check if DST is active
|
|
72
|
-
isDST('America/Los_Angeles', new Date()); // true/false
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Format Functions
|
|
76
|
-
|
|
77
|
-
All format functions require timezone - no defaults!
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
// Time only
|
|
81
|
-
formatEventTime('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
82
|
-
// "7:00 PM"
|
|
83
|
-
|
|
84
|
-
// Date only
|
|
85
|
-
formatEventDate('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
86
|
-
// "Dec 25, 2023"
|
|
87
|
-
|
|
88
|
-
// Full datetime
|
|
89
|
-
formatEventDateTime('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
90
|
-
// "Dec 25, 2023 at 7:00 PM"
|
|
91
|
-
|
|
92
|
-
// Time range
|
|
93
|
-
formatTimeRange(startUtc, endUtc, 'America/Los_Angeles');
|
|
94
|
-
// "7:00 PM - 10:00 PM"
|
|
95
|
-
|
|
96
|
-
// Date range
|
|
97
|
-
formatDateRange(startUtc, endUtc, 'America/Los_Angeles');
|
|
98
|
-
// "Dec 25 - 27, 2023"
|
|
99
|
-
|
|
100
|
-
// Relative time
|
|
101
|
-
formatRelativeTime(utcIso, 'America/Los_Angeles');
|
|
102
|
-
// "2 hours ago" or "in 3 days"
|
|
103
|
-
|
|
104
|
-
// Date parts
|
|
105
|
-
getDateParts('2023-12-25T20:00:00Z', 'America/Los_Angeles');
|
|
106
|
-
// { day: 'Mon', month: 'Dec', date: 25, year: 2023 }
|
|
107
|
-
|
|
108
|
-
// Get hour (0-23)
|
|
109
|
-
getHourInTimezone('2023-12-25T20:00:00Z', 'America/Los_Angeles');
|
|
110
|
-
// 12
|
|
111
|
-
|
|
112
|
-
// Get date string
|
|
113
|
-
getDateInTimezone('2023-12-25T20:00:00Z', 'America/Los_Angeles');
|
|
114
|
-
// "2023-12-25"
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Parse Functions
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
// Local datetime to UTC
|
|
121
|
-
parseLocalToUTC('2023-12-25T19:00:00', 'America/Los_Angeles');
|
|
122
|
-
// "2023-12-26T03:00:00.000Z"
|
|
123
|
-
|
|
124
|
-
// UTC to local datetime
|
|
125
|
-
parseUTCToLocal('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
126
|
-
// "2023-12-25T19:00:00"
|
|
127
|
-
|
|
128
|
-
// Combine date and time
|
|
129
|
-
combineDateAndTime('2023-12-25', '19:00', 'America/Los_Angeles');
|
|
130
|
-
// "2023-12-26T03:00:00.000Z"
|
|
131
|
-
|
|
132
|
-
// Parse API response for form
|
|
133
|
-
parseDateTimeFromAPI('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
134
|
-
// { date: '2023-12-25', time: '19:00' }
|
|
135
|
-
|
|
136
|
-
// Start of day in UTC
|
|
137
|
-
parseStartOfDay('2023-12-25', 'America/Los_Angeles');
|
|
138
|
-
// "2023-12-25T08:00:00.000Z"
|
|
139
|
-
|
|
140
|
-
// End of day in UTC
|
|
141
|
-
parseEndOfDay('2023-12-25', 'America/Los_Angeles');
|
|
142
|
-
// "2023-12-26T07:59:59.000Z"
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Next-Day Time Handling
|
|
146
|
-
|
|
147
|
-
For overnight events (e.g., 10 PM - 2 AM):
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
// Check for next-day prefix
|
|
151
|
-
isNextDayTime('+1_02:00'); // true
|
|
152
|
-
isNextDayTime('14:00'); // false
|
|
153
|
-
|
|
154
|
-
// Strip prefix
|
|
155
|
-
stripNextDayPrefix('+1_02:00'); // '02:00'
|
|
156
|
-
|
|
157
|
-
// Convert to minutes
|
|
158
|
-
parseTimeToMinutes('22:00'); // 1320
|
|
159
|
-
parseTimeToMinutes('+1_02:00'); // 1560 (26 hours)
|
|
160
|
-
|
|
161
|
-
// Convert back
|
|
162
|
-
minutesToTimeString(1320); // '22:00'
|
|
163
|
-
minutesToTimeString(1560, true); // '+1_02:00'
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Constants
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
import {
|
|
170
|
-
DURATIONS,
|
|
171
|
-
DATE_FORMATS,
|
|
172
|
-
EVENT_DEFAULTS,
|
|
173
|
-
COMMON_US_TIMEZONES,
|
|
174
|
-
} from '$lib/datetime';
|
|
175
|
-
|
|
176
|
-
// Durations in milliseconds
|
|
177
|
-
DURATIONS.MINUTE; // 60000
|
|
178
|
-
DURATIONS.HOUR; // 3600000
|
|
179
|
-
DURATIONS.DAY; // 86400000
|
|
180
|
-
|
|
181
|
-
// Event defaults
|
|
182
|
-
EVENT_DEFAULTS.DEFAULT_DURATION_MINUTES; // 120
|
|
183
|
-
EVENT_DEFAULTS.MIN_DURATION_MINUTES; // 15
|
|
184
|
-
EVENT_DEFAULTS.DEFAULT_DOORS_BEFORE_MINUTES; // 30
|
|
185
|
-
|
|
186
|
-
// Common US timezones for selects
|
|
187
|
-
COMMON_US_TIMEZONES;
|
|
188
|
-
// [{ id: 'America/Los_Angeles', label: 'Pacific Time (PT)', abbr: 'PT' }, ...]
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## Common Patterns
|
|
192
|
-
|
|
193
|
-
### Event Form
|
|
194
|
-
|
|
195
|
-
```typescript
|
|
196
|
-
// Populating form from API response
|
|
197
|
-
function populateForm(event: Event) {
|
|
198
|
-
const tz = datetime.getVenueTimezone(event.venue);
|
|
199
|
-
const start = datetime.parseDateTimeFromAPI(event.startTime, tz);
|
|
200
|
-
const end = datetime.parseDateTimeFromAPI(event.endTime, tz);
|
|
201
|
-
|
|
202
|
-
return {
|
|
203
|
-
date: start.date,
|
|
204
|
-
startTime: start.time,
|
|
205
|
-
endTime: end.time,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// Submitting form to API
|
|
210
|
-
function submitForm(form: FormData, venue: Venue) {
|
|
211
|
-
const tz = datetime.getVenueTimezone(venue);
|
|
212
|
-
|
|
213
|
-
return {
|
|
214
|
-
startTime: datetime.combineDateAndTime(form.date, form.startTime, tz),
|
|
215
|
-
endTime: datetime.combineDateAndTime(form.date, form.endTime, tz),
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### Calendar Display
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
// Display events in venue timezone
|
|
224
|
-
function renderEvent(event: Event, venue: Venue) {
|
|
225
|
-
const tz = datetime.getVenueTimezone(venue);
|
|
226
|
-
|
|
227
|
-
return {
|
|
228
|
-
time: datetime.formatEventTime(event.startTime, tz),
|
|
229
|
-
date: datetime.formatEventDate(event.startTime, tz),
|
|
230
|
-
dateRange: datetime.formatTimeRange(event.startTime, event.endTime, tz),
|
|
231
|
-
dateParts: datetime.getDateParts(event.startTime, tz),
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Grouping Events by Date
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
function groupByDate(events: Event[], timezone: TimezoneId) {
|
|
240
|
-
const groups: Record<string, Event[]> = {};
|
|
241
|
-
|
|
242
|
-
for (const event of events) {
|
|
243
|
-
const dateKey = datetime.getDateInTimezone(event.startTime, timezone);
|
|
244
|
-
groups[dateKey] = groups[dateKey] || [];
|
|
245
|
-
groups[dateKey].push(event);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return groups;
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Error Handling
|
|
253
|
-
|
|
254
|
-
All functions throw `DateTimeError` for invalid inputs:
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
import { DateTimeError, DateTimeErrorCode } from '$lib/datetime';
|
|
258
|
-
|
|
259
|
-
try {
|
|
260
|
-
const tz = datetime.getVenueTimezone(venue);
|
|
261
|
-
} catch (e) {
|
|
262
|
-
if (e instanceof DateTimeError) {
|
|
263
|
-
console.error(e.code); // DateTimeErrorCode.MISSING_TIMEZONE
|
|
264
|
-
console.error(e.message); // "Venue timezone is required"
|
|
265
|
-
console.error(e.details); // { venue: {...} }
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
Error codes:
|
|
271
|
-
|
|
272
|
-
- `INVALID_TIMEZONE` - Timezone string is not a valid IANA identifier
|
|
273
|
-
- `INVALID_ISO_STRING` - ISO date string is malformed
|
|
274
|
-
- `INVALID_DATE` - Date string is invalid
|
|
275
|
-
- `INVALID_TIME` - Time string is invalid
|
|
276
|
-
- `MISSING_TIMEZONE` - Required timezone is missing
|
|
277
|
-
- `PARSE_ERROR` - General parsing error
|
|
278
|
-
|
|
279
|
-
## Migration from Legacy Code
|
|
280
|
-
|
|
281
|
-
### From `src/lib/utils/timezone.js`
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
// Before
|
|
285
|
-
import { localToUTC, utcToLocal, formatForDisplay } from '$lib/utils/timezone';
|
|
286
|
-
|
|
287
|
-
// After
|
|
288
|
-
import {
|
|
289
|
-
parseLocalToUTC,
|
|
290
|
-
parseUTCToLocal,
|
|
291
|
-
formatEventDateTime,
|
|
292
|
-
} from '$lib/datetime';
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### From `src/lib/utils/utils.js`
|
|
296
|
-
|
|
297
|
-
```typescript
|
|
298
|
-
// Before
|
|
299
|
-
import { formatDateTime, formatTimeRange, getDay } from '$lib/utils/utils';
|
|
300
|
-
|
|
301
|
-
// After
|
|
302
|
-
import {
|
|
303
|
-
formatEventDateTime,
|
|
304
|
-
formatTimeRange,
|
|
305
|
-
formatDayOfWeek,
|
|
306
|
-
} from '$lib/datetime';
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## Testing
|
|
310
|
-
|
|
311
|
-
Run tests:
|
|
312
|
-
|
|
313
|
-
```bash
|
|
314
|
-
npm run test -- src/lib/datetime
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
Run with coverage:
|
|
318
|
-
|
|
319
|
-
```bash
|
|
320
|
-
npm run test:coverage -- src/lib/datetime
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
Target: 100% coverage for this critical module.
|
|
1
|
+
# DateTime Module
|
|
2
|
+
|
|
3
|
+
Centralized date/time handling for the MicDrop platform. This module eliminates timezone bugs by enforcing consistent patterns across the application.
|
|
4
|
+
|
|
5
|
+
## Golden Rules
|
|
6
|
+
|
|
7
|
+
1. **Backend is King** - All API requests send/receive UTC ISO strings (`2023-12-25T20:00:00Z`)
|
|
8
|
+
2. **Display is Local** - All UI components receive UTC strings + Timezone ID
|
|
9
|
+
3. **No `new Date()` in components** - Use these helpers instead
|
|
10
|
+
4. **Timezone is always required** - Every function requires explicit timezone parameter
|
|
11
|
+
|
|
12
|
+
## Quick Start
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import * as datetime from '$lib/datetime';
|
|
16
|
+
|
|
17
|
+
// Get timezone from venue (throws if missing)
|
|
18
|
+
const tz = datetime.getVenueTimezone(venue);
|
|
19
|
+
|
|
20
|
+
// Format for display
|
|
21
|
+
const time = datetime.formatEventTime(event.startTime, tz); // "7:00 PM"
|
|
22
|
+
const date = datetime.formatEventDate(event.startTime, tz); // "Dec 25, 2023"
|
|
23
|
+
const full = datetime.formatEventDateTime(event.startTime, tz); // "Dec 25, 2023 at 7:00 PM"
|
|
24
|
+
|
|
25
|
+
// Parse form input to UTC for API
|
|
26
|
+
const utc = datetime.combineDateAndTime('2023-12-25', '19:00', tz);
|
|
27
|
+
|
|
28
|
+
// Parse API response for form
|
|
29
|
+
const { date, time } = datetime.parseDateTimeFromAPI(event.startTime, tz);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Module Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
src/lib/datetime/
|
|
36
|
+
├── index.ts # Clean exports
|
|
37
|
+
├── types.ts # Type definitions
|
|
38
|
+
├── constants.ts # Duration constants, format strings
|
|
39
|
+
├── timezone.ts # Timezone utilities
|
|
40
|
+
├── format.ts # Formatting functions
|
|
41
|
+
├── parse.ts # Parsing functions
|
|
42
|
+
├── __tests__/ # Comprehensive tests
|
|
43
|
+
│ ├── timezone.test.ts
|
|
44
|
+
│ ├── format.test.ts
|
|
45
|
+
│ ├── parse.test.ts
|
|
46
|
+
│ └── integration.test.ts
|
|
47
|
+
└── README.md # This file
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API Reference
|
|
51
|
+
|
|
52
|
+
### Timezone Utilities
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// Validate timezone
|
|
56
|
+
isValidTimezone('America/Los_Angeles'); // true
|
|
57
|
+
isValidTimezone('PST'); // false (abbreviations not valid)
|
|
58
|
+
|
|
59
|
+
// Get venue timezone (throws if missing)
|
|
60
|
+
const tz = getVenueTimezone(venue);
|
|
61
|
+
|
|
62
|
+
// Get user's browser timezone
|
|
63
|
+
const userTz = getUserTimezone();
|
|
64
|
+
|
|
65
|
+
// Get timezone offset string
|
|
66
|
+
getTimezoneOffset('America/Los_Angeles'); // "PST (UTC-8)"
|
|
67
|
+
|
|
68
|
+
// Normalize legacy timezone abbreviations
|
|
69
|
+
normalizeTimezone('PST'); // "America/Los_Angeles"
|
|
70
|
+
|
|
71
|
+
// Check if DST is active
|
|
72
|
+
isDST('America/Los_Angeles', new Date()); // true/false
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Format Functions
|
|
76
|
+
|
|
77
|
+
All format functions require timezone - no defaults!
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Time only
|
|
81
|
+
formatEventTime('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
82
|
+
// "7:00 PM"
|
|
83
|
+
|
|
84
|
+
// Date only
|
|
85
|
+
formatEventDate('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
86
|
+
// "Dec 25, 2023"
|
|
87
|
+
|
|
88
|
+
// Full datetime
|
|
89
|
+
formatEventDateTime('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
90
|
+
// "Dec 25, 2023 at 7:00 PM"
|
|
91
|
+
|
|
92
|
+
// Time range
|
|
93
|
+
formatTimeRange(startUtc, endUtc, 'America/Los_Angeles');
|
|
94
|
+
// "7:00 PM - 10:00 PM"
|
|
95
|
+
|
|
96
|
+
// Date range
|
|
97
|
+
formatDateRange(startUtc, endUtc, 'America/Los_Angeles');
|
|
98
|
+
// "Dec 25 - 27, 2023"
|
|
99
|
+
|
|
100
|
+
// Relative time
|
|
101
|
+
formatRelativeTime(utcIso, 'America/Los_Angeles');
|
|
102
|
+
// "2 hours ago" or "in 3 days"
|
|
103
|
+
|
|
104
|
+
// Date parts
|
|
105
|
+
getDateParts('2023-12-25T20:00:00Z', 'America/Los_Angeles');
|
|
106
|
+
// { day: 'Mon', month: 'Dec', date: 25, year: 2023 }
|
|
107
|
+
|
|
108
|
+
// Get hour (0-23)
|
|
109
|
+
getHourInTimezone('2023-12-25T20:00:00Z', 'America/Los_Angeles');
|
|
110
|
+
// 12
|
|
111
|
+
|
|
112
|
+
// Get date string
|
|
113
|
+
getDateInTimezone('2023-12-25T20:00:00Z', 'America/Los_Angeles');
|
|
114
|
+
// "2023-12-25"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Parse Functions
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// Local datetime to UTC
|
|
121
|
+
parseLocalToUTC('2023-12-25T19:00:00', 'America/Los_Angeles');
|
|
122
|
+
// "2023-12-26T03:00:00.000Z"
|
|
123
|
+
|
|
124
|
+
// UTC to local datetime
|
|
125
|
+
parseUTCToLocal('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
126
|
+
// "2023-12-25T19:00:00"
|
|
127
|
+
|
|
128
|
+
// Combine date and time
|
|
129
|
+
combineDateAndTime('2023-12-25', '19:00', 'America/Los_Angeles');
|
|
130
|
+
// "2023-12-26T03:00:00.000Z"
|
|
131
|
+
|
|
132
|
+
// Parse API response for form
|
|
133
|
+
parseDateTimeFromAPI('2023-12-26T03:00:00Z', 'America/Los_Angeles');
|
|
134
|
+
// { date: '2023-12-25', time: '19:00' }
|
|
135
|
+
|
|
136
|
+
// Start of day in UTC
|
|
137
|
+
parseStartOfDay('2023-12-25', 'America/Los_Angeles');
|
|
138
|
+
// "2023-12-25T08:00:00.000Z"
|
|
139
|
+
|
|
140
|
+
// End of day in UTC
|
|
141
|
+
parseEndOfDay('2023-12-25', 'America/Los_Angeles');
|
|
142
|
+
// "2023-12-26T07:59:59.000Z"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Next-Day Time Handling
|
|
146
|
+
|
|
147
|
+
For overnight events (e.g., 10 PM - 2 AM):
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Check for next-day prefix
|
|
151
|
+
isNextDayTime('+1_02:00'); // true
|
|
152
|
+
isNextDayTime('14:00'); // false
|
|
153
|
+
|
|
154
|
+
// Strip prefix
|
|
155
|
+
stripNextDayPrefix('+1_02:00'); // '02:00'
|
|
156
|
+
|
|
157
|
+
// Convert to minutes
|
|
158
|
+
parseTimeToMinutes('22:00'); // 1320
|
|
159
|
+
parseTimeToMinutes('+1_02:00'); // 1560 (26 hours)
|
|
160
|
+
|
|
161
|
+
// Convert back
|
|
162
|
+
minutesToTimeString(1320); // '22:00'
|
|
163
|
+
minutesToTimeString(1560, true); // '+1_02:00'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Constants
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import {
|
|
170
|
+
DURATIONS,
|
|
171
|
+
DATE_FORMATS,
|
|
172
|
+
EVENT_DEFAULTS,
|
|
173
|
+
COMMON_US_TIMEZONES,
|
|
174
|
+
} from '$lib/datetime';
|
|
175
|
+
|
|
176
|
+
// Durations in milliseconds
|
|
177
|
+
DURATIONS.MINUTE; // 60000
|
|
178
|
+
DURATIONS.HOUR; // 3600000
|
|
179
|
+
DURATIONS.DAY; // 86400000
|
|
180
|
+
|
|
181
|
+
// Event defaults
|
|
182
|
+
EVENT_DEFAULTS.DEFAULT_DURATION_MINUTES; // 120
|
|
183
|
+
EVENT_DEFAULTS.MIN_DURATION_MINUTES; // 15
|
|
184
|
+
EVENT_DEFAULTS.DEFAULT_DOORS_BEFORE_MINUTES; // 30
|
|
185
|
+
|
|
186
|
+
// Common US timezones for selects
|
|
187
|
+
COMMON_US_TIMEZONES;
|
|
188
|
+
// [{ id: 'America/Los_Angeles', label: 'Pacific Time (PT)', abbr: 'PT' }, ...]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Common Patterns
|
|
192
|
+
|
|
193
|
+
### Event Form
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Populating form from API response
|
|
197
|
+
function populateForm(event: Event) {
|
|
198
|
+
const tz = datetime.getVenueTimezone(event.venue);
|
|
199
|
+
const start = datetime.parseDateTimeFromAPI(event.startTime, tz);
|
|
200
|
+
const end = datetime.parseDateTimeFromAPI(event.endTime, tz);
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
date: start.date,
|
|
204
|
+
startTime: start.time,
|
|
205
|
+
endTime: end.time,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Submitting form to API
|
|
210
|
+
function submitForm(form: FormData, venue: Venue) {
|
|
211
|
+
const tz = datetime.getVenueTimezone(venue);
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
startTime: datetime.combineDateAndTime(form.date, form.startTime, tz),
|
|
215
|
+
endTime: datetime.combineDateAndTime(form.date, form.endTime, tz),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Calendar Display
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// Display events in venue timezone
|
|
224
|
+
function renderEvent(event: Event, venue: Venue) {
|
|
225
|
+
const tz = datetime.getVenueTimezone(venue);
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
time: datetime.formatEventTime(event.startTime, tz),
|
|
229
|
+
date: datetime.formatEventDate(event.startTime, tz),
|
|
230
|
+
dateRange: datetime.formatTimeRange(event.startTime, event.endTime, tz),
|
|
231
|
+
dateParts: datetime.getDateParts(event.startTime, tz),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Grouping Events by Date
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
function groupByDate(events: Event[], timezone: TimezoneId) {
|
|
240
|
+
const groups: Record<string, Event[]> = {};
|
|
241
|
+
|
|
242
|
+
for (const event of events) {
|
|
243
|
+
const dateKey = datetime.getDateInTimezone(event.startTime, timezone);
|
|
244
|
+
groups[dateKey] = groups[dateKey] || [];
|
|
245
|
+
groups[dateKey].push(event);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return groups;
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Error Handling
|
|
253
|
+
|
|
254
|
+
All functions throw `DateTimeError` for invalid inputs:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { DateTimeError, DateTimeErrorCode } from '$lib/datetime';
|
|
258
|
+
|
|
259
|
+
try {
|
|
260
|
+
const tz = datetime.getVenueTimezone(venue);
|
|
261
|
+
} catch (e) {
|
|
262
|
+
if (e instanceof DateTimeError) {
|
|
263
|
+
console.error(e.code); // DateTimeErrorCode.MISSING_TIMEZONE
|
|
264
|
+
console.error(e.message); // "Venue timezone is required"
|
|
265
|
+
console.error(e.details); // { venue: {...} }
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Error codes:
|
|
271
|
+
|
|
272
|
+
- `INVALID_TIMEZONE` - Timezone string is not a valid IANA identifier
|
|
273
|
+
- `INVALID_ISO_STRING` - ISO date string is malformed
|
|
274
|
+
- `INVALID_DATE` - Date string is invalid
|
|
275
|
+
- `INVALID_TIME` - Time string is invalid
|
|
276
|
+
- `MISSING_TIMEZONE` - Required timezone is missing
|
|
277
|
+
- `PARSE_ERROR` - General parsing error
|
|
278
|
+
|
|
279
|
+
## Migration from Legacy Code
|
|
280
|
+
|
|
281
|
+
### From `src/lib/utils/timezone.js`
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
// Before
|
|
285
|
+
import { localToUTC, utcToLocal, formatForDisplay } from '$lib/utils/timezone';
|
|
286
|
+
|
|
287
|
+
// After
|
|
288
|
+
import {
|
|
289
|
+
parseLocalToUTC,
|
|
290
|
+
parseUTCToLocal,
|
|
291
|
+
formatEventDateTime,
|
|
292
|
+
} from '$lib/datetime';
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### From `src/lib/utils/utils.js`
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Before
|
|
299
|
+
import { formatDateTime, formatTimeRange, getDay } from '$lib/utils/utils';
|
|
300
|
+
|
|
301
|
+
// After
|
|
302
|
+
import {
|
|
303
|
+
formatEventDateTime,
|
|
304
|
+
formatTimeRange,
|
|
305
|
+
formatDayOfWeek,
|
|
306
|
+
} from '$lib/datetime';
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Testing
|
|
310
|
+
|
|
311
|
+
Run tests:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
npm run test -- src/lib/datetime
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Run with coverage:
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
npm run test:coverage -- src/lib/datetime
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Target: 100% coverage for this critical module.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
2
|
import { formatCleanTimeRange, formatDateRange, formatDayOfWeek, formatEventDate, formatEventDateTime, formatEventTime, formatHour, formatMonth, formatNotificationTime, formatRelativeTime, formatTimeRange, getDateInTimezone, getDateParts, getHourInTimezone, isToday, } from '../format';
|
|
3
|
-
import { DateTimeError
|
|
3
|
+
import { DateTimeError } from '../types';
|
|
4
4
|
describe('format utilities', () => {
|
|
5
5
|
describe('formatEventTime', () => {
|
|
6
6
|
it('formats time in specified timezone', () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { combineDateAndTime, formatDateTimeForAPI, isNextDayTime, minutesToTimeString, parseDateTimeFromAPI, parseEndOfDay, parseLocalToUTC, parseStartOfDay, parseTimeToMinutes, parseUTCToLocal, stripNextDayPrefix, } from '../parse';
|
|
3
|
-
import { DateTimeError
|
|
3
|
+
import { DateTimeError } from '../types';
|
|
4
4
|
describe('parse utilities', () => {
|
|
5
5
|
describe('parseLocalToUTC', () => {
|
|
6
6
|
it('converts local datetime to UTC', () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { getTimezoneDisplayName, getTimezoneOffset, getUserTimezone, getVenueTimezone, isDST, isValidTimezone, normalizeTimezone, getIANATimezone, isValidIANATimezone, getAllTimezones, formatTimezoneForDisplay, getTimezoneOptions, getCommonUSTimezoneOptions, } from '../timezone';
|
|
3
3
|
import { DateTimeError, DateTimeErrorCode } from '../types';
|
|
4
4
|
describe('timezone utilities', () => {
|