@getmicdrop/svelte-components 5.5.5 → 5.6.1
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 +172 -172
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
- package/dist/calendar/FAQs/FAQs.svelte +75 -75
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
- package/dist/calendar/OrderSummary/OrderSummary.svelte +367 -367
- package/dist/calendar/PublicCard/PublicCard.svelte +134 -134
- package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
- package/dist/components/Layout/AppShell.svelte +104 -0
- package/dist/components/Layout/AppShell.svelte.d.ts +26 -0
- package/dist/components/Layout/AppShell.svelte.d.ts.map +1 -0
- package/dist/components/Layout/ContentSection.svelte +80 -0
- package/dist/components/Layout/ContentSection.svelte.d.ts +23 -0
- package/dist/components/Layout/ContentSection.svelte.d.ts.map +1 -0
- package/dist/components/Layout/Grid.svelte +4 -4
- package/dist/components/Layout/Heading.svelte +81 -0
- package/dist/components/Layout/Heading.svelte.d.ts +24 -0
- package/dist/components/Layout/Heading.svelte.d.ts.map +1 -0
- package/dist/components/Layout/PageContainer.svelte +69 -0
- package/dist/components/Layout/PageContainer.svelte.d.ts +23 -0
- package/dist/components/Layout/PageContainer.svelte.d.ts.map +1 -0
- package/dist/components/Layout/Responsive.svelte +75 -0
- package/dist/components/Layout/Responsive.svelte.d.ts +19 -0
- package/dist/components/Layout/Responsive.svelte.d.ts.map +1 -0
- package/dist/components/Layout/Section.svelte +80 -80
- package/dist/components/Layout/ShowOnDesktop.svelte +37 -0
- package/dist/components/Layout/ShowOnDesktop.svelte.d.ts +16 -0
- package/dist/components/Layout/ShowOnDesktop.svelte.d.ts.map +1 -0
- package/dist/components/Layout/ShowOnMobile.svelte +37 -0
- package/dist/components/Layout/ShowOnMobile.svelte.d.ts +16 -0
- package/dist/components/Layout/ShowOnMobile.svelte.d.ts.map +1 -0
- 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 -0
- package/dist/components/Layout/Text.svelte.d.ts +28 -0
- package/dist/components/Layout/Text.svelte.d.ts.map +1 -0
- package/dist/components/Layout/TwoColumn.svelte +108 -0
- package/dist/components/Layout/TwoColumn.svelte.d.ts +28 -0
- package/dist/components/Layout/TwoColumn.svelte.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/AppShell.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/AppShell.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/AppShell.test.js +95 -0
- package/dist/components/Layout/__tests__/ContentSection.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/ContentSection.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/ContentSection.test.js +112 -0
- package/dist/components/Layout/__tests__/Heading.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/Heading.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/Heading.test.js +123 -0
- package/dist/components/Layout/__tests__/PageContainer.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/PageContainer.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/PageContainer.test.js +133 -0
- package/dist/components/Layout/__tests__/Responsive.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/Responsive.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/Responsive.test.js +123 -0
- package/dist/components/Layout/__tests__/ShowOnDesktop.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/ShowOnDesktop.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/ShowOnDesktop.test.js +84 -0
- package/dist/components/Layout/__tests__/ShowOnMobile.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/ShowOnMobile.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/ShowOnMobile.test.js +80 -0
- package/dist/components/Layout/__tests__/Text.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/Text.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/Text.test.js +146 -0
- package/dist/components/Layout/__tests__/TwoColumn.test.d.ts +2 -0
- package/dist/components/Layout/__tests__/TwoColumn.test.d.ts.map +1 -0
- package/dist/components/Layout/__tests__/TwoColumn.test.js +129 -0
- package/dist/constants/validation.js +91 -91
- package/dist/constants/validation.spec.js +64 -64
- package/dist/datetime/__tests__/format.test.js +1 -1
- package/dist/datetime/__tests__/parse.test.js +1 -1
- package/dist/datetime/__tests__/timezone.test.js +1 -1
- package/dist/datetime/parse.js +1 -1
- package/dist/forms/createFormStore.svelte.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/patterns/data/DataGrid.svelte +45 -45
- package/dist/patterns/data/DataList.svelte +24 -24
- 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.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/layout/Sidebar.svelte +39 -39
- package/dist/patterns/layout/index.d.ts +9 -0
- package/dist/patterns/layout/index.js +22 -0
- package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
- package/dist/patterns/navigation/BottomNav.svelte +74 -64
- package/dist/patterns/navigation/BottomNav.svelte.d.ts.map +1 -1
- package/dist/patterns/navigation/Header.stories.svelte +77 -77
- package/dist/patterns/navigation/Header.svelte +193 -193
- 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.stories.svelte +75 -75
- package/dist/primitives/Accordion/Accordion.svelte +42 -42
- package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte +107 -107
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte.d.ts +2 -2
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte.d.ts.map +1 -1
- 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.stories.svelte +94 -94
- package/dist/primitives/Avatar/Avatar.svelte +66 -66
- package/dist/primitives/Badges/Badge.spec.js +144 -144
- package/dist/primitives/Badges/Badge.stories.svelte +86 -86
- package/dist/primitives/Badges/Badge.svelte +79 -79
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +136 -136
- package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
- package/dist/primitives/BottomSheet/BottomSheet.svelte +100 -100
- package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +122 -122
- package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +89 -89
- package/dist/primitives/Button/Button.spec.js +223 -223
- package/dist/primitives/Button/Button.stories.svelte +76 -76
- package/dist/primitives/Button/Button.svelte +270 -270
- package/dist/primitives/Button/ButtonSaveDemo.spec.js +146 -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/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.stories.svelte +80 -80
- package/dist/primitives/Drawer/Drawer.svelte +120 -120
- package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
- package/dist/primitives/Dropdown/Dropdown.svelte +14 -14
- package/dist/primitives/Dropdown/DropdownDivider.svelte +9 -0
- package/dist/primitives/Dropdown/DropdownDivider.svelte.d.ts +7 -0
- package/dist/primitives/Dropdown/DropdownDivider.svelte.d.ts.map +1 -0
- package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
- package/dist/primitives/Helper/Helper.svelte +33 -0
- package/dist/primitives/Helper/Helper.svelte.d.ts +18 -0
- package/dist/primitives/Helper/Helper.svelte.d.ts.map +1 -0
- 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 +573 -573
- package/dist/primitives/Input/Input.stories.svelte +139 -139
- package/dist/primitives/Input/Input.svelte +1 -2
- package/dist/primitives/Input/Input.svelte.d.ts +2 -4
- package/dist/primitives/Input/Input.svelte.d.ts.map +1 -1
- package/dist/primitives/Input/Select.spec.js +212 -212
- package/dist/primitives/Input/Select.stories.svelte +112 -112
- package/dist/primitives/Input/Select.svelte +128 -128
- package/dist/primitives/Input/Textarea.stories.svelte +137 -137
- package/dist/primitives/Input/Textarea.svelte +35 -35
- package/dist/primitives/Label/Label.svelte +37 -37
- package/dist/primitives/Modal/Modal.spec.js +99 -99
- package/dist/primitives/Modal/Modal.stories.svelte +86 -86
- package/dist/primitives/Modal/Modal.svelte +3 -4
- package/dist/primitives/Modal/Modal.svelte.d.ts +6 -8
- package/dist/primitives/Modal/Modal.svelte.d.ts.map +1 -1
- package/dist/primitives/NumberInput/NumberInput.svelte +0 -1
- package/dist/primitives/NumberInput/NumberInput.svelte.d.ts +0 -2
- package/dist/primitives/NumberInput/NumberInput.svelte.d.ts.map +1 -1
- 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/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 +71 -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 +123 -123
- package/dist/primitives/Toggle.spec.js +143 -143
- package/dist/primitives/Toggle.stories.svelte +92 -92
- package/dist/primitives/Toggle.svelte +1 -2
- package/dist/primitives/Toggle.svelte.d.ts +2 -4
- package/dist/primitives/Toggle.svelte.d.ts.map +1 -1
- package/dist/primitives/Tooltip/Tooltip.svelte +83 -0
- package/dist/primitives/Tooltip/Tooltip.svelte.d.ts +15 -0
- package/dist/primitives/Tooltip/Tooltip.svelte.d.ts.map +1 -0
- package/dist/primitives/Typography/Typography.svelte +53 -53
- package/dist/primitives/ValidationError.spec.js +103 -103
- package/dist/primitives/ValidationError.stories.svelte +69 -69
- package/dist/primitives/ValidationError.svelte +29 -29
- package/dist/primitives/index.d.ts +3 -0
- package/dist/primitives/index.js +91 -84
- package/dist/recipes/CropImage/CropImage.spec.js +208 -208
- package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
- package/dist/recipes/CropImage/CropImage.svelte +238 -238
- package/dist/recipes/ImageUploader/ImageUploader.spec.js +6 -5
- package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
- package/dist/recipes/ImageUploader/ImageUploader.svelte +804 -804
- package/dist/recipes/SuperLogin/SuperLogin.spec.js +17 -17
- 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 +80 -80
- 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 +258 -258
- package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
- package/dist/recipes/inputs/MultiSelect.svelte +29 -8
- package/dist/recipes/inputs/MultiSelect.svelte.d.ts +54 -21
- package/dist/recipes/inputs/MultiSelect.svelte.d.ts.map +1 -1
- package/dist/recipes/inputs/OTPInput.spec.js +251 -251
- package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
- package/dist/recipes/inputs/OTPInput.svelte +29 -29
- package/dist/recipes/inputs/PasswordInput.svelte +22 -22
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +117 -117
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.spec.js +9 -4
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +123 -123
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +30 -25
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte.d.ts +12 -1
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte.d.ts.map +1 -1
- package/dist/recipes/inputs/Search.svelte +37 -37
- package/dist/recipes/inputs/SelectDropdown.svelte +57 -57
- package/dist/recipes/modals/AlertModal.svelte +130 -130
- package/dist/recipes/modals/ConfirmationModal.spec.js +206 -206
- package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
- package/dist/recipes/modals/ConfirmationModal.svelte +152 -152
- package/dist/recipes/modals/InputModal.svelte +182 -182
- package/dist/recipes/modals/ModalStateManager.spec.js +100 -100
- package/dist/recipes/modals/ModalStateManager.svelte +77 -77
- package/dist/recipes/modals/ModalTestWrapper.svelte +65 -65
- package/dist/recipes/modals/StatusModal.svelte +206 -206
- package/dist/services/EventService.js +75 -75
- package/dist/services/EventService.spec.js +217 -217
- package/dist/services/ShowService.spec.js +345 -345
- package/dist/stores/auth.js +44 -36
- package/dist/stores/auth.spec.js +139 -139
- package/dist/stores/auth.svelte.d.ts +39 -0
- package/dist/stores/auth.svelte.d.ts.map +1 -0
- package/dist/stores/auth.svelte.js +60 -0
- package/dist/stores/formDataStore.d.ts.map +1 -1
- package/dist/stores/formDataStore.js +8 -0
- package/dist/stores/formDataStore.svelte.d.ts +47 -0
- package/dist/stores/formDataStore.svelte.d.ts.map +1 -0
- package/dist/stores/formDataStore.svelte.js +84 -0
- package/dist/stores/formSave.d.ts.map +1 -1
- package/dist/stores/formSave.js +8 -0
- package/dist/stores/formSave.svelte.d.ts +33 -0
- package/dist/stores/formSave.svelte.d.ts.map +1 -0
- package/dist/stores/formSave.svelte.js +113 -0
- package/dist/stores/navigation.d.ts.map +1 -1
- package/dist/stores/navigation.js +8 -0
- package/dist/stores/navigation.svelte.d.ts +35 -0
- package/dist/stores/navigation.svelte.d.ts.map +1 -0
- package/dist/stores/navigation.svelte.js +69 -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 +725 -725
- package/dist/stories/RecipesGallery.stories.svelte +19 -19
- package/dist/stories/RecipesGallery.svelte +271 -271
- package/dist/stories/button-audit-manifest.json +11186 -11186
- package/dist/tailwind/preset.cjs +82 -82
- package/dist/telemetry.js +405 -405
- package/dist/telemetry.server.spec.js +11 -8
- package/dist/telemetry.spec.js +1169 -1144
- package/dist/tokens/__tests__/typography-base.test.d.ts +2 -0
- package/dist/tokens/__tests__/typography-base.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/typography-base.test.js +138 -0
- package/dist/tokens/tokens.css +87 -87
- package/dist/tokens/typography-base.css +163 -0
- package/dist/utils/apiConfig.spec.js +219 -219
- package/dist/utils/imageValidation.spec.js +62 -59
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +47 -0
- package/dist/utils/transitions.js +62 -62
- package/dist/utils/utils.js +354 -354
- package/package.json +21 -16
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
import { passwordStrength } from "check-password-strength";
|
|
4
|
-
import { safeSlide } from "../../../utils/transitions.js";
|
|
5
|
-
import { cubicOut } from "svelte/easing";
|
|
6
|
-
|
|
7
|
-
interface Props {
|
|
8
|
-
password?: string;
|
|
9
|
-
strengthText?: string;
|
|
10
|
-
score?: number;
|
|
11
|
-
textColor?: string;
|
|
12
|
-
children?: Snippet;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let {
|
|
16
|
-
password = "",
|
|
17
|
-
strengthText = $bindable(""),
|
|
18
|
-
score = $bindable(-1),
|
|
19
|
-
textColor = $bindable(""),
|
|
20
|
-
children,
|
|
21
|
-
}: Props = $props();
|
|
22
|
-
|
|
23
|
-
let debouncedPassword = $state("");
|
|
24
|
-
let timer = $state<ReturnType<typeof setTimeout> | undefined>();
|
|
25
|
-
|
|
26
|
-
const customOptions = [
|
|
27
|
-
{
|
|
28
|
-
id: 0,
|
|
29
|
-
value: "Too weak",
|
|
30
|
-
minDiversity: 0,
|
|
31
|
-
minLength: 0,
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
id: 1,
|
|
35
|
-
value: "Weak",
|
|
36
|
-
minDiversity: 1,
|
|
37
|
-
minLength: 6,
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
id: 2,
|
|
41
|
-
value: "Good",
|
|
42
|
-
minDiversity: 2,
|
|
43
|
-
minLength: 8,
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
id: 3,
|
|
47
|
-
value: "Strong",
|
|
48
|
-
minDiversity: 3,
|
|
49
|
-
minLength: 10,
|
|
50
|
-
},
|
|
51
|
-
] as const;
|
|
52
|
-
|
|
53
|
-
// Debounce password updates
|
|
54
|
-
$effect(() => {
|
|
55
|
-
clearTimeout(timer);
|
|
56
|
-
if (password.length === 0) {
|
|
57
|
-
debouncedPassword = "";
|
|
58
|
-
} else {
|
|
59
|
-
timer = setTimeout(() => {
|
|
60
|
-
debouncedPassword = password;
|
|
61
|
-
}, 400); // 400ms delay as requested
|
|
62
|
-
}
|
|
63
|
-
return () => clearTimeout(timer);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
let strength = $derived(debouncedPassword
|
|
67
|
-
? passwordStrength(debouncedPassword, customOptions as any)
|
|
68
|
-
: null);
|
|
69
|
-
|
|
70
|
-
// Compute score based on password length and strength
|
|
71
|
-
$effect(() => {
|
|
72
|
-
score = debouncedPassword.length > 12 ? 3 : (strength?.id ?? -1);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// Map score to display text and color
|
|
76
|
-
$effect(() => {
|
|
77
|
-
strengthText =
|
|
78
|
-
score === 0
|
|
79
|
-
? "Too weak"
|
|
80
|
-
: score === 1
|
|
81
|
-
? "Weak"
|
|
82
|
-
: score === 2
|
|
83
|
-
? "Good"
|
|
84
|
-
: score === 3
|
|
85
|
-
? "Strong"
|
|
86
|
-
: "";
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
let strengthColor = $derived(score <= 1 ? "bg-red-600" : "bg-green-600");
|
|
90
|
-
|
|
91
|
-
$effect(() => {
|
|
92
|
-
textColor = score <= 1 ? "text-red-600" : "text-green-600";
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// Calculate how many bars to fill (1-3)
|
|
96
|
-
let filledBars = $derived(score === 0 ? 1 : score === 1 ? 2 : score >= 2 ? 3 : 0);
|
|
97
|
-
</script>
|
|
98
|
-
|
|
99
|
-
{#if debouncedPassword.length > 0}
|
|
100
|
-
<div
|
|
101
|
-
transition:safeSlide={{ duration: 600, easing: cubicOut }}
|
|
102
|
-
class="pt-2 space-y-2"
|
|
103
|
-
>
|
|
104
|
-
<!-- 3 segment bars -->
|
|
105
|
-
<div class="flex gap-1.5">
|
|
106
|
-
{#each [0, 1, 2] as barIndex}
|
|
107
|
-
<div
|
|
108
|
-
class="h-1 flex-1 rounded-full transition-colors duration-300 {barIndex <
|
|
109
|
-
filledBars
|
|
110
|
-
? strengthColor
|
|
111
|
-
: 'bg-gray-200 dark:bg-gray-700'}"
|
|
112
|
-
></div>
|
|
113
|
-
{/each}
|
|
114
|
-
</div>
|
|
115
|
-
{@render children?.()}
|
|
116
|
-
</div>
|
|
117
|
-
{/if}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { passwordStrength } from "check-password-strength";
|
|
4
|
+
import { safeSlide } from "../../../utils/transitions.js";
|
|
5
|
+
import { cubicOut } from "svelte/easing";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
password?: string;
|
|
9
|
+
strengthText?: string;
|
|
10
|
+
score?: number;
|
|
11
|
+
textColor?: string;
|
|
12
|
+
children?: Snippet;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
password = "",
|
|
17
|
+
strengthText = $bindable(""),
|
|
18
|
+
score = $bindable(-1),
|
|
19
|
+
textColor = $bindable(""),
|
|
20
|
+
children,
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
|
|
23
|
+
let debouncedPassword = $state("");
|
|
24
|
+
let timer = $state<ReturnType<typeof setTimeout> | undefined>();
|
|
25
|
+
|
|
26
|
+
const customOptions = [
|
|
27
|
+
{
|
|
28
|
+
id: 0,
|
|
29
|
+
value: "Too weak",
|
|
30
|
+
minDiversity: 0,
|
|
31
|
+
minLength: 0,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 1,
|
|
35
|
+
value: "Weak",
|
|
36
|
+
minDiversity: 1,
|
|
37
|
+
minLength: 6,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 2,
|
|
41
|
+
value: "Good",
|
|
42
|
+
minDiversity: 2,
|
|
43
|
+
minLength: 8,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 3,
|
|
47
|
+
value: "Strong",
|
|
48
|
+
minDiversity: 3,
|
|
49
|
+
minLength: 10,
|
|
50
|
+
},
|
|
51
|
+
] as const;
|
|
52
|
+
|
|
53
|
+
// Debounce password updates
|
|
54
|
+
$effect(() => {
|
|
55
|
+
clearTimeout(timer);
|
|
56
|
+
if (password.length === 0) {
|
|
57
|
+
debouncedPassword = "";
|
|
58
|
+
} else {
|
|
59
|
+
timer = setTimeout(() => {
|
|
60
|
+
debouncedPassword = password;
|
|
61
|
+
}, 400); // 400ms delay as requested
|
|
62
|
+
}
|
|
63
|
+
return () => clearTimeout(timer);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
let strength = $derived(debouncedPassword
|
|
67
|
+
? passwordStrength(debouncedPassword, customOptions as any)
|
|
68
|
+
: null);
|
|
69
|
+
|
|
70
|
+
// Compute score based on password length and strength
|
|
71
|
+
$effect(() => {
|
|
72
|
+
score = debouncedPassword.length > 12 ? 3 : (strength?.id ?? -1);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Map score to display text and color
|
|
76
|
+
$effect(() => {
|
|
77
|
+
strengthText =
|
|
78
|
+
score === 0
|
|
79
|
+
? "Too weak"
|
|
80
|
+
: score === 1
|
|
81
|
+
? "Weak"
|
|
82
|
+
: score === 2
|
|
83
|
+
? "Good"
|
|
84
|
+
: score === 3
|
|
85
|
+
? "Strong"
|
|
86
|
+
: "";
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
let strengthColor = $derived(score <= 1 ? "bg-red-600" : "bg-green-600");
|
|
90
|
+
|
|
91
|
+
$effect(() => {
|
|
92
|
+
textColor = score <= 1 ? "text-red-600" : "text-green-600";
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Calculate how many bars to fill (1-3)
|
|
96
|
+
let filledBars = $derived(score === 0 ? 1 : score === 1 ? 2 : score >= 2 ? 3 : 0);
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
{#if debouncedPassword.length > 0}
|
|
100
|
+
<div
|
|
101
|
+
transition:safeSlide={{ duration: 600, easing: cubicOut }}
|
|
102
|
+
class="pt-2 space-y-2"
|
|
103
|
+
>
|
|
104
|
+
<!-- 3 segment bars -->
|
|
105
|
+
<div class="flex gap-1.5">
|
|
106
|
+
{#each [0, 1, 2] as barIndex}
|
|
107
|
+
<div
|
|
108
|
+
class="h-1 flex-1 rounded-full transition-colors duration-300 {barIndex <
|
|
109
|
+
filledBars
|
|
110
|
+
? strengthColor
|
|
111
|
+
: 'bg-gray-200 dark:bg-gray-700'}"
|
|
112
|
+
></div>
|
|
113
|
+
{/each}
|
|
114
|
+
</div>
|
|
115
|
+
{@render children?.()}
|
|
116
|
+
</div>
|
|
117
|
+
{/if}
|
|
@@ -8,18 +8,23 @@ const mockAutocompleteSuggestion = {
|
|
|
8
8
|
fetchAutocompleteSuggestions: vi.fn(),
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
// Vitest 4.x requires class syntax for constructor mocks
|
|
12
|
+
class MockAutocompleteSessionToken {}
|
|
12
13
|
|
|
13
14
|
const mockLoader = {
|
|
14
15
|
importLibrary: vi.fn().mockResolvedValue({
|
|
15
|
-
AutocompleteSessionToken:
|
|
16
|
+
AutocompleteSessionToken: MockAutocompleteSessionToken,
|
|
16
17
|
AutocompleteSuggestion: mockAutocompleteSuggestion,
|
|
17
18
|
}),
|
|
18
19
|
};
|
|
19
20
|
|
|
20
|
-
// Mock the Google Maps Loader
|
|
21
|
+
// Mock the Google Maps Loader - Vitest 4.x requires class syntax
|
|
21
22
|
vi.mock('@googlemaps/js-api-loader', () => ({
|
|
22
|
-
Loader:
|
|
23
|
+
Loader: class MockLoader {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.importLibrary = mockLoader.importLibrary;
|
|
26
|
+
}
|
|
27
|
+
},
|
|
23
28
|
}));
|
|
24
29
|
|
|
25
30
|
// Mock config
|
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
<script module>
|
|
2
|
-
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
-
|
|
4
|
-
import PlaceAutocomplete from "./PlaceAutocomplete.svelte";
|
|
5
|
-
|
|
6
|
-
const { Story } = defineMeta({
|
|
7
|
-
title: "Components/PlaceAutocomplete",
|
|
8
|
-
component: PlaceAutocomplete,
|
|
9
|
-
argTypes: {
|
|
10
|
-
placeholder: { control: "text" },
|
|
11
|
-
initialValue: { control: "text" },
|
|
12
|
-
mode: { control: "select", options: ["full", "cityState"] },
|
|
13
|
-
language: { control: "text" },
|
|
14
|
-
region: { control: "text" },
|
|
15
|
-
onResponse: { action: "response" },
|
|
16
|
-
onError: { action: "error" },
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
function handleResponse(data) {
|
|
21
|
-
console.log("Place selected:", data);
|
|
22
|
-
alert(`Selected: ${JSON.stringify(data, null, 2)}`);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function handleError(error) {
|
|
26
|
-
console.error("Error:", error);
|
|
27
|
-
alert(`Error: ${error}`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
</script>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<Story
|
|
34
|
-
name="Default Full Address"
|
|
35
|
-
args={{
|
|
36
|
-
placeholder: "Search for location...",
|
|
37
|
-
mode: "full",
|
|
38
|
-
onResponse: handleResponse,
|
|
39
|
-
onError: handleError
|
|
40
|
-
}}
|
|
41
|
-
/>
|
|
42
|
-
|
|
43
|
-
<Story name="City State Only">
|
|
44
|
-
<div style="max-width: 500px; margin: 0 auto;">
|
|
45
|
-
<PlaceAutocomplete
|
|
46
|
-
placeholder="Search for city, state..."
|
|
47
|
-
mode="cityState"
|
|
48
|
-
onResponse={handleResponse}
|
|
49
|
-
onError={handleError}
|
|
50
|
-
/>
|
|
51
|
-
</div>
|
|
52
|
-
</Story>
|
|
53
|
-
|
|
54
|
-
<Story name="With Initial Value">
|
|
55
|
-
<div style="max-width: 500px; margin: 0 auto;">
|
|
56
|
-
<PlaceAutocomplete
|
|
57
|
-
placeholder="Search for location..."
|
|
58
|
-
initialValue="New York, NY"
|
|
59
|
-
mode="cityState"
|
|
60
|
-
onResponse={handleResponse}
|
|
61
|
-
onError={handleError}
|
|
62
|
-
/>
|
|
63
|
-
</div>
|
|
64
|
-
</Story>
|
|
65
|
-
|
|
66
|
-
<Story name="Custom Placeholder">
|
|
67
|
-
<div style="max-width: 500px; margin: 0 auto;">
|
|
68
|
-
<PlaceAutocomplete
|
|
69
|
-
placeholder="Where is your venue located?"
|
|
70
|
-
mode="full"
|
|
71
|
-
onResponse={handleResponse}
|
|
72
|
-
onError={handleError}
|
|
73
|
-
/>
|
|
74
|
-
</div>
|
|
75
|
-
</Story>
|
|
76
|
-
|
|
77
|
-
<Story name="In Form Context">
|
|
78
|
-
<div style="max-width: 600px; margin: 0 auto; padding: 20px;">
|
|
79
|
-
<h2 class="text-2xl font-bold mb-6">Event Location</h2>
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
|
|
4
|
+
import PlaceAutocomplete from "./PlaceAutocomplete.svelte";
|
|
5
|
+
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: "Components/PlaceAutocomplete",
|
|
8
|
+
component: PlaceAutocomplete,
|
|
9
|
+
argTypes: {
|
|
10
|
+
placeholder: { control: "text" },
|
|
11
|
+
initialValue: { control: "text" },
|
|
12
|
+
mode: { control: "select", options: ["full", "cityState"] },
|
|
13
|
+
language: { control: "text" },
|
|
14
|
+
region: { control: "text" },
|
|
15
|
+
onResponse: { action: "response" },
|
|
16
|
+
onError: { action: "error" },
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
function handleResponse(data) {
|
|
21
|
+
console.log("Place selected:", data);
|
|
22
|
+
alert(`Selected: ${JSON.stringify(data, null, 2)}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function handleError(error) {
|
|
26
|
+
console.error("Error:", error);
|
|
27
|
+
alert(`Error: ${error}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
<Story
|
|
34
|
+
name="Default Full Address"
|
|
35
|
+
args={{
|
|
36
|
+
placeholder: "Search for location...",
|
|
37
|
+
mode: "full",
|
|
38
|
+
onResponse: handleResponse,
|
|
39
|
+
onError: handleError
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
<Story name="City State Only">
|
|
44
|
+
<div style="max-width: 500px; margin: 0 auto;">
|
|
45
|
+
<PlaceAutocomplete
|
|
46
|
+
placeholder="Search for city, state..."
|
|
47
|
+
mode="cityState"
|
|
48
|
+
onResponse={handleResponse}
|
|
49
|
+
onError={handleError}
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
</Story>
|
|
53
|
+
|
|
54
|
+
<Story name="With Initial Value">
|
|
55
|
+
<div style="max-width: 500px; margin: 0 auto;">
|
|
56
|
+
<PlaceAutocomplete
|
|
57
|
+
placeholder="Search for location..."
|
|
58
|
+
initialValue="New York, NY"
|
|
59
|
+
mode="cityState"
|
|
60
|
+
onResponse={handleResponse}
|
|
61
|
+
onError={handleError}
|
|
62
|
+
/>
|
|
63
|
+
</div>
|
|
64
|
+
</Story>
|
|
65
|
+
|
|
66
|
+
<Story name="Custom Placeholder">
|
|
67
|
+
<div style="max-width: 500px; margin: 0 auto;">
|
|
68
|
+
<PlaceAutocomplete
|
|
69
|
+
placeholder="Where is your venue located?"
|
|
70
|
+
mode="full"
|
|
71
|
+
onResponse={handleResponse}
|
|
72
|
+
onError={handleError}
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
</Story>
|
|
76
|
+
|
|
77
|
+
<Story name="In Form Context">
|
|
78
|
+
<div style="max-width: 600px; margin: 0 auto; padding: 20px;">
|
|
79
|
+
<h2 class="text-2xl font-bold mb-6">Event Location</h2>
|
|
80
80
|
<div class="space-y-4">
|
|
81
81
|
<div>
|
|
82
82
|
<label for="venue-name" class="block text-sm font-medium text-gray-500 dark:text-gray-400 mb-2">
|
|
@@ -95,19 +95,19 @@
|
|
|
95
95
|
Venue Location
|
|
96
96
|
</label>
|
|
97
97
|
<PlaceAutocomplete
|
|
98
|
-
placeholder="Search for venue location..."
|
|
99
|
-
mode="full"
|
|
100
|
-
onResponse={handleResponse}
|
|
101
|
-
onError={handleError}
|
|
102
|
-
/>
|
|
103
|
-
</div>
|
|
104
|
-
<button class="px-4 py-2 bg-primary text-white rounded-lg">
|
|
105
|
-
Save Location
|
|
106
|
-
</button>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
</Story>
|
|
110
|
-
|
|
98
|
+
placeholder="Search for venue location..."
|
|
99
|
+
mode="full"
|
|
100
|
+
onResponse={handleResponse}
|
|
101
|
+
onError={handleError}
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
<button class="px-4 py-2 bg-primary text-white rounded-lg">
|
|
105
|
+
Save Location
|
|
106
|
+
</button>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</Story>
|
|
110
|
+
|
|
111
111
|
<Story name="Performer Location">
|
|
112
112
|
<div style="max-width: 500px; margin: 0 auto;">
|
|
113
113
|
<!-- svelte-ignore a11y_label_has_associated_control -->
|
|
@@ -118,17 +118,17 @@
|
|
|
118
118
|
Let venues know where you're based
|
|
119
119
|
</p>
|
|
120
120
|
<PlaceAutocomplete
|
|
121
|
-
placeholder="Enter your city and state..."
|
|
122
|
-
mode="cityState"
|
|
123
|
-
onResponse={handleResponse}
|
|
124
|
-
onError={handleError}
|
|
125
|
-
/>
|
|
126
|
-
</div>
|
|
127
|
-
</Story>
|
|
128
|
-
|
|
129
|
-
<Story name="Multiple Locations">
|
|
130
|
-
<div style="max-width: 700px; margin: 0 auto; padding: 20px;">
|
|
131
|
-
<h2 class="text-xl font-bold mb-6">Tour Locations</h2>
|
|
121
|
+
placeholder="Enter your city and state..."
|
|
122
|
+
mode="cityState"
|
|
123
|
+
onResponse={handleResponse}
|
|
124
|
+
onError={handleError}
|
|
125
|
+
/>
|
|
126
|
+
</div>
|
|
127
|
+
</Story>
|
|
128
|
+
|
|
129
|
+
<Story name="Multiple Locations">
|
|
130
|
+
<div style="max-width: 700px; margin: 0 auto; padding: 20px;">
|
|
131
|
+
<h2 class="text-xl font-bold mb-6">Tour Locations</h2>
|
|
132
132
|
<div class="space-y-6">
|
|
133
133
|
<div>
|
|
134
134
|
<!-- svelte-ignore a11y_label_has_associated_control -->
|
|
@@ -148,23 +148,23 @@
|
|
|
148
148
|
Destination City
|
|
149
149
|
</label>
|
|
150
150
|
<PlaceAutocomplete
|
|
151
|
-
placeholder="Where will you end?"
|
|
152
|
-
mode="cityState"
|
|
153
|
-
onResponse={handleResponse}
|
|
154
|
-
onError={handleError}
|
|
155
|
-
/>
|
|
156
|
-
</div>
|
|
157
|
-
</div>
|
|
158
|
-
</div>
|
|
159
|
-
</Story>
|
|
160
|
-
|
|
161
|
-
<Story name="Compact Layout">
|
|
162
|
-
<div style="max-width: 350px; margin: 0 auto;">
|
|
163
|
-
<PlaceAutocomplete
|
|
164
|
-
placeholder="City..."
|
|
165
|
-
mode="cityState"
|
|
166
|
-
onResponse={handleResponse}
|
|
167
|
-
onError={handleError}
|
|
168
|
-
/>
|
|
169
|
-
</div>
|
|
170
|
-
</Story>
|
|
151
|
+
placeholder="Where will you end?"
|
|
152
|
+
mode="cityState"
|
|
153
|
+
onResponse={handleResponse}
|
|
154
|
+
onError={handleError}
|
|
155
|
+
/>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</Story>
|
|
160
|
+
|
|
161
|
+
<Story name="Compact Layout">
|
|
162
|
+
<div style="max-width: 350px; margin: 0 auto;">
|
|
163
|
+
<PlaceAutocomplete
|
|
164
|
+
placeholder="City..."
|
|
165
|
+
mode="cityState"
|
|
166
|
+
onResponse={handleResponse}
|
|
167
|
+
onError={handleError}
|
|
168
|
+
/>
|
|
169
|
+
</div>
|
|
170
|
+
</Story>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { PUBLIC_GOOGLE_MAPS_API_KEY } from '../../../config.js';
|
|
5
5
|
import { typography } from '../../../tokens/typography';
|
|
6
6
|
const { Loader } = GMaps;
|
|
7
|
+
/** Google Places API address component */ interface AddressComponent { longText: string; shortText: string; types: string[]; } /** Google Places API response data */ interface PlaceData { formattedAddress?: string; addressComponents?: AddressComponent[]; text?: string; [key: string]: unknown; } /** Google Places autocomplete suggestion */ interface AutocompleteSuggestion { placePrediction: { types: string[]; text: { toString(): string }; toPlace(): PlaceObject; }; } /** Google Places place object */ interface PlaceObject { fetchFields(options: { fields: string[] }): Promise<void>; toJSON(): PlaceData; } /** Google Places API interface */ interface PlacesApiInterface { AutocompleteSessionToken: new () => AutocompleteSessionToken; AutocompleteSuggestion: { fetchAutocompleteSuggestions(request: AutocompleteRequest): Promise<{ suggestions: AutocompleteSuggestion[] }>; }; } /** Google Places autocomplete session token */ interface AutocompleteSessionToken {} /** Autocomplete request parameters */ interface AutocompleteRequest { input: string; language: string; region: string; sessionToken: AutocompleteSessionToken | string; } /** Search result item */ interface SearchResult { to_place: PlaceObject; text: string; originalText?: string; }
|
|
7
8
|
|
|
8
9
|
interface Props {
|
|
9
10
|
fetchFields?: string[];
|
|
@@ -12,7 +13,7 @@
|
|
|
12
13
|
region?: string;
|
|
13
14
|
autocomplete?: string;
|
|
14
15
|
initialValue?: string;
|
|
15
|
-
onResponse?: (data:
|
|
16
|
+
onResponse?: (data: PlaceData) => void;
|
|
16
17
|
onError?: (error: string) => void;
|
|
17
18
|
mode?: 'full' | 'cityState';
|
|
18
19
|
animateFocus?: boolean;
|
|
@@ -39,16 +40,16 @@
|
|
|
39
40
|
let containerRef: HTMLDivElement;
|
|
40
41
|
let currentSuggestion = $state(-1);
|
|
41
42
|
let title = $state('');
|
|
42
|
-
let results = $state<
|
|
43
|
-
let token:
|
|
43
|
+
let results = $state<SearchResult[]>([]);
|
|
44
|
+
let token: AutocompleteSessionToken | undefined;
|
|
44
45
|
let loader: GMaps.Loader;
|
|
45
|
-
let placesApi:
|
|
46
|
+
let placesApi: Partial<PlacesApiInterface> = {};
|
|
46
47
|
|
|
47
48
|
let request = $state<{
|
|
48
49
|
input: string;
|
|
49
50
|
language: string;
|
|
50
51
|
region: string;
|
|
51
|
-
sessionToken:
|
|
52
|
+
sessionToken: AutocompleteSessionToken | string;
|
|
52
53
|
}>({
|
|
53
54
|
input: (() => initialValue)(),
|
|
54
55
|
language: (() => language)(),
|
|
@@ -94,13 +95,13 @@
|
|
|
94
95
|
|
|
95
96
|
try {
|
|
96
97
|
const { suggestions } =
|
|
97
|
-
await placesApi.AutocompleteSuggestion
|
|
98
|
+
await placesApi.AutocompleteSuggestion!.fetchAutocompleteSuggestions(
|
|
98
99
|
request
|
|
99
100
|
);
|
|
100
101
|
|
|
101
102
|
if (mode === 'cityState') {
|
|
102
103
|
results = suggestions
|
|
103
|
-
.filter((s:
|
|
104
|
+
.filter((s: AutocompleteSuggestion) => {
|
|
104
105
|
const types = s.placePrediction.types || [];
|
|
105
106
|
|
|
106
107
|
// Accept cities (locality) and city-level neighborhoods (sublocality)
|
|
@@ -112,7 +113,7 @@
|
|
|
112
113
|
type === 'sublocality_level_1'
|
|
113
114
|
);
|
|
114
115
|
})
|
|
115
|
-
.map((s:
|
|
116
|
+
.map((s: AutocompleteSuggestion) => {
|
|
116
117
|
let displayText = s.placePrediction.text.toString();
|
|
117
118
|
|
|
118
119
|
// Format as "City, State" (first two parts)
|
|
@@ -128,22 +129,23 @@
|
|
|
128
129
|
};
|
|
129
130
|
});
|
|
130
131
|
} else {
|
|
131
|
-
results = suggestions.map((s:
|
|
132
|
+
results = suggestions.map((s: AutocompleteSuggestion) => ({
|
|
132
133
|
to_place: s.placePrediction.toPlace(),
|
|
133
134
|
text: s.placePrediction.text.toString(),
|
|
134
135
|
}));
|
|
135
136
|
}
|
|
136
|
-
} catch (e:
|
|
137
|
+
} catch (e: unknown) {
|
|
138
|
+
const error = e as { name?: string; message?: string };
|
|
137
139
|
onError(
|
|
138
|
-
(
|
|
140
|
+
(error.name || 'An error occurred') +
|
|
139
141
|
' - ' +
|
|
140
|
-
(
|
|
142
|
+
(error.message || 'see console for details.')
|
|
141
143
|
);
|
|
142
144
|
}
|
|
143
145
|
};
|
|
144
146
|
|
|
145
147
|
const onPlaceSelected = async (
|
|
146
|
-
place:
|
|
148
|
+
place: PlaceObject,
|
|
147
149
|
originalText?: string
|
|
148
150
|
): Promise<void> => {
|
|
149
151
|
results = [];
|
|
@@ -157,11 +159,12 @@
|
|
|
157
159
|
request.input = originalText || placeData.text || '';
|
|
158
160
|
title = originalText || placeData.text || '';
|
|
159
161
|
onResponse(placeData);
|
|
160
|
-
} catch (e:
|
|
162
|
+
} catch (e: unknown) {
|
|
163
|
+
const error = e as { name?: string; message?: string };
|
|
161
164
|
onError(
|
|
162
|
-
(
|
|
165
|
+
(error.name || 'An error occurred') +
|
|
163
166
|
' - ' +
|
|
164
|
-
(
|
|
167
|
+
(error.message || 'error fetching place details')
|
|
165
168
|
);
|
|
166
169
|
}
|
|
167
170
|
|
|
@@ -170,16 +173,17 @@
|
|
|
170
173
|
}, 100);
|
|
171
174
|
};
|
|
172
175
|
|
|
173
|
-
const refreshToken = async (req:
|
|
176
|
+
const refreshToken = async (req: AutocompleteRequest) => {
|
|
174
177
|
try {
|
|
175
|
-
token = new placesApi.AutocompleteSessionToken();
|
|
178
|
+
token = new placesApi.AutocompleteSessionToken!();
|
|
176
179
|
req.sessionToken = token;
|
|
177
180
|
return req;
|
|
178
|
-
} catch (e:
|
|
181
|
+
} catch (e: unknown) {
|
|
182
|
+
const error = e as { name?: string; message?: string };
|
|
179
183
|
onError(
|
|
180
|
-
(
|
|
184
|
+
(error.name || 'An error occurred') +
|
|
181
185
|
' - ' +
|
|
182
|
-
(
|
|
186
|
+
(error.message || 'error fetch token')
|
|
183
187
|
);
|
|
184
188
|
return req;
|
|
185
189
|
}
|
|
@@ -253,13 +257,14 @@
|
|
|
253
257
|
await loader.importLibrary('places');
|
|
254
258
|
placesApi.AutocompleteSessionToken = AutocompleteSessionToken;
|
|
255
259
|
placesApi.AutocompleteSuggestion = AutocompleteSuggestion;
|
|
256
|
-
token = new placesApi.AutocompleteSessionToken();
|
|
260
|
+
token = new placesApi.AutocompleteSessionToken!();
|
|
257
261
|
request.sessionToken = token;
|
|
258
|
-
} catch (e:
|
|
262
|
+
} catch (e: unknown) {
|
|
263
|
+
const error = e as { name?: string; message?: string };
|
|
259
264
|
onError(
|
|
260
|
-
(
|
|
265
|
+
(error.name || 'An error occurred') +
|
|
261
266
|
' - ' +
|
|
262
|
-
(
|
|
267
|
+
(error.message || 'Error loading Google Maps API')
|
|
263
268
|
);
|
|
264
269
|
}
|
|
265
270
|
};
|