@12-apps/ui 6.7.0 → 6.9.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/chunk-3X3JVF6E.js +438 -0
- package/dist/chunk-3X3JVF6E.js.map +1 -0
- package/dist/chunk-AL3W7TXN.js +465 -0
- package/dist/chunk-AL3W7TXN.js.map +1 -0
- package/dist/{chunk-QLBYAYUG.js → chunk-KR2BP7NK.js} +4 -4
- package/dist/chunk-KR2BP7NK.js.map +1 -0
- package/dist/{chunk-DFVRZ3UK.js → chunk-KXARS46L.js} +3 -3
- package/dist/chunk-KXARS46L.js.map +1 -0
- package/dist/{chunk-JP55QWVR.js → chunk-L7L6SX64.js} +5 -2
- package/dist/chunk-L7L6SX64.js.map +1 -0
- package/dist/{chunk-QZZVHY6U.js → chunk-PVLDKXKR.js} +7 -3
- package/dist/chunk-PVLDKXKR.js.map +1 -0
- package/dist/{chunk-H7UAGTVW.js → chunk-TSG5C7MP.js} +4 -3
- package/dist/chunk-TSG5C7MP.js.map +1 -0
- package/dist/{chunk-NUCLEOHF.js → chunk-UNM7KFDX.js} +44 -14
- package/dist/chunk-UNM7KFDX.js.map +1 -0
- package/dist/{chunk-CEKPLUQV.js → chunk-UY7UF7IN.js} +19 -13
- package/dist/chunk-UY7UF7IN.js.map +1 -0
- package/dist/data-display/DataGrid.js +1 -1
- package/dist/data-display/DataViews.js +88 -65
- package/dist/data-display/DataViews.js.map +1 -1
- package/dist/data-display/HoverCard.js +4 -1
- package/dist/data-display/HoverCard.js.map +1 -1
- package/dist/data-display/Table.js +4 -2
- package/dist/data-display/Table.js.map +1 -1
- package/dist/data-display/TimingDiagram.js +3 -2
- package/dist/data-display/TimingDiagram.js.map +1 -1
- package/dist/en-US.js +56 -0
- package/dist/en-US.js.map +1 -0
- package/dist/feedback/Sonner.js +5 -4
- package/dist/feedback/Sonner.js.map +1 -1
- package/dist/feedback/StackedModal.js +1 -1
- package/dist/feedback/TutorialOverlay.js +19 -5
- package/dist/feedback/TutorialOverlay.js.map +1 -1
- package/dist/form/AddressAutocomplete.js +16 -8
- package/dist/form/AddressAutocomplete.js.map +1 -1
- package/dist/form/Autocomplete.js +9 -7
- package/dist/form/Autocomplete.js.map +1 -1
- package/dist/form/Calendar.js +1 -1
- package/dist/form/CodeEditor.js +14 -9
- package/dist/form/CodeEditor.js.map +1 -1
- package/dist/form/DateRangePicker.js +10 -3
- package/dist/form/DateRangePicker.js.map +1 -1
- package/dist/form/Menubar.js +4 -1
- package/dist/form/Menubar.js.map +1 -1
- package/dist/form/PasswordStrength.js +48 -28
- package/dist/form/PasswordStrength.js.map +1 -1
- package/dist/form/PhoneInput.js +11 -5
- package/dist/form/PhoneInput.js.map +1 -1
- package/dist/form/SearchPalette.js +4 -1
- package/dist/form/SearchPalette.js.map +1 -1
- package/dist/form/Textarea.js +21 -19
- package/dist/form/Textarea.js.map +1 -1
- package/dist/form/UploadButton.js +16 -11
- package/dist/form/UploadButton.js.map +1 -1
- package/dist/layout/ContentToolbar.js +1 -1
- package/dist/layout/Dashboard.js +2 -1
- package/dist/layout/Dashboard.js.map +1 -1
- package/dist/layout/ScrollArea.js +9 -3
- package/dist/layout/ScrollArea.js.map +1 -1
- package/dist/layout/TableFilter.js +1 -1
- package/dist/locales.js +171 -0
- package/dist/locales.js.map +1 -0
- package/dist/navigation/Breadcrumbs.js +9 -3
- package/dist/navigation/Breadcrumbs.js.map +1 -1
- package/dist/navigation/CommandPalette.js +20 -7
- package/dist/navigation/CommandPalette.js.map +1 -1
- package/dist/navigation/Pagination.js +1 -1
- package/dist/navigation/Tabs.js +7 -3
- package/dist/navigation/Tabs.js.map +1 -1
- package/dist/pt-BR.js +42 -274
- package/dist/pt-BR.js.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.states.d.ts +1 -0
- package/dist/types/components/data-display/DataGrid/DataGrid.states.d.ts.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts +5 -0
- package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-category-pill.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +27 -1
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts +12 -1
- package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-filter-panel.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-bodies.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-pagination.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-toolbar.d.ts.map +1 -1
- package/dist/types/components/data-display/HoverCard/HoverCard.content.d.ts +1 -1
- package/dist/types/components/data-display/HoverCard/HoverCard.content.d.ts.map +1 -1
- package/dist/types/components/data-display/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/types/components/data-display/HoverCard/HoverCard.types.d.ts +2 -0
- package/dist/types/components/data-display/HoverCard/HoverCard.types.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/Table.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/Table.types.d.ts +5 -0
- package/dist/types/components/data-display/Table/Table.types.d.ts.map +1 -1
- package/dist/types/components/data-display/Table/TableStates.d.ts +3 -1
- package/dist/types/components/data-display/Table/TableStates.d.ts.map +1 -1
- package/dist/types/components/data-display/TimingDiagram/TimingDiagram.d.ts.map +1 -1
- package/dist/types/components/data-display/TimingDiagram/TimingDiagram.types.d.ts +3 -0
- package/dist/types/components/data-display/TimingDiagram/TimingDiagram.types.d.ts.map +1 -1
- package/dist/types/components/feedback/Sonner/Sonner.d.ts +8 -0
- package/dist/types/components/feedback/Sonner/Sonner.d.ts.map +1 -1
- package/dist/types/components/feedback/Sonner/Sonner.types.d.ts +2 -0
- package/dist/types/components/feedback/Sonner/Sonner.types.d.ts.map +1 -1
- package/dist/types/components/feedback/Sonner/SonnerToast.d.ts.map +1 -1
- package/dist/types/components/feedback/StackedModal/StackedModal.d.ts.map +1 -1
- package/dist/types/components/feedback/StackedModal/StackedModal.parts.d.ts +2 -0
- package/dist/types/components/feedback/StackedModal/StackedModal.parts.d.ts.map +1 -1
- package/dist/types/components/feedback/StackedModal/StackedModal.types.d.ts +2 -0
- package/dist/types/components/feedback/StackedModal/StackedModal.types.d.ts.map +1 -1
- package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.d.ts.map +1 -1
- package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.types.d.ts +3 -0
- package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.types.d.ts.map +1 -1
- package/dist/types/components/feedback/TutorialOverlay/TutorialStepBody.d.ts +2 -0
- package/dist/types/components/feedback/TutorialOverlay/TutorialStepBody.d.ts.map +1 -1
- package/dist/types/components/form/AddressAutocomplete/AddressAutocomplete.types.d.ts +7 -0
- package/dist/types/components/form/AddressAutocomplete/AddressAutocomplete.types.d.ts.map +1 -1
- package/dist/types/components/form/AddressAutocomplete/AddressAutocompleteField.d.ts.map +1 -1
- package/dist/types/components/form/AddressAutocomplete/AddressFallbackField.d.ts +1 -0
- package/dist/types/components/form/AddressAutocomplete/AddressFallbackField.d.ts.map +1 -1
- package/dist/types/components/form/AddressAutocomplete/AddressInputField.d.ts +1 -0
- package/dist/types/components/form/AddressAutocomplete/AddressInputField.d.ts.map +1 -1
- package/dist/types/components/form/Autocomplete/Autocomplete.d.ts.map +1 -1
- package/dist/types/components/form/Autocomplete/Autocomplete.parts.d.ts +9 -3
- package/dist/types/components/form/Autocomplete/Autocomplete.parts.d.ts.map +1 -1
- package/dist/types/components/form/Autocomplete/Autocomplete.types.d.ts +7 -0
- package/dist/types/components/form/Autocomplete/Autocomplete.types.d.ts.map +1 -1
- package/dist/types/components/form/Calendar/Calendar.types.d.ts +6 -0
- package/dist/types/components/form/Calendar/Calendar.types.d.ts.map +1 -1
- package/dist/types/components/form/CodeEditor/CodeEditor.d.ts.map +1 -1
- package/dist/types/components/form/CodeEditor/CodeEditor.types.d.ts +7 -0
- package/dist/types/components/form/CodeEditor/CodeEditor.types.d.ts.map +1 -1
- package/dist/types/components/form/CodeEditor/CodeEditorToolbar.d.ts +2 -0
- package/dist/types/components/form/CodeEditor/CodeEditorToolbar.d.ts.map +1 -1
- package/dist/types/components/form/DateRangePicker/DateRangePicker.d.ts.map +1 -1
- package/dist/types/components/form/DateRangePicker/DateRangePicker.range.d.ts.map +1 -1
- package/dist/types/components/form/DateRangePicker/DateRangePicker.types.d.ts +11 -0
- package/dist/types/components/form/DateRangePicker/DateRangePicker.types.d.ts.map +1 -1
- package/dist/types/components/form/DateRangePicker/DateRangePickerFields.d.ts.map +1 -1
- package/dist/types/components/form/Menubar/Menubar.d.ts.map +1 -1
- package/dist/types/components/form/Menubar/Menubar.toolbar.d.ts +1 -0
- package/dist/types/components/form/Menubar/Menubar.toolbar.d.ts.map +1 -1
- package/dist/types/components/form/Menubar/Menubar.types.d.ts +5 -0
- package/dist/types/components/form/Menubar/Menubar.types.d.ts.map +1 -1
- package/dist/types/components/form/PasswordStrength/PasswordStrength.d.ts.map +1 -1
- package/dist/types/components/form/PasswordStrength/PasswordStrength.helpers.d.ts +4 -2
- package/dist/types/components/form/PasswordStrength/PasswordStrength.helpers.d.ts.map +1 -1
- package/dist/types/components/form/PasswordStrength/PasswordStrength.types.d.ts +8 -0
- package/dist/types/components/form/PasswordStrength/PasswordStrength.types.d.ts.map +1 -1
- package/dist/types/components/form/PhoneInput/PhoneInput.d.ts.map +1 -1
- package/dist/types/components/form/PhoneInput/PhoneInput.types.d.ts +7 -0
- package/dist/types/components/form/PhoneInput/PhoneInput.types.d.ts.map +1 -1
- package/dist/types/components/form/SearchPalette/SearchPalette.d.ts.map +1 -1
- package/dist/types/components/form/SearchPalette/SearchPalette.parts.d.ts +2 -0
- package/dist/types/components/form/SearchPalette/SearchPalette.parts.d.ts.map +1 -1
- package/dist/types/components/form/SearchPalette/SearchPalette.types.d.ts +6 -0
- package/dist/types/components/form/SearchPalette/SearchPalette.types.d.ts.map +1 -1
- package/dist/types/components/form/Textarea/Textarea.d.ts.map +1 -1
- package/dist/types/components/form/Textarea/Textarea.types.d.ts +16 -1
- package/dist/types/components/form/Textarea/Textarea.types.d.ts.map +1 -1
- package/dist/types/components/form/Textarea/TextareaRichEditor.d.ts +7 -0
- package/dist/types/components/form/Textarea/TextareaRichEditor.d.ts.map +1 -1
- package/dist/types/components/form/UploadButton/UploadButton.d.ts.map +1 -1
- package/dist/types/components/form/UploadButton/UploadButton.parts.d.ts +6 -3
- package/dist/types/components/form/UploadButton/UploadButton.parts.d.ts.map +1 -1
- package/dist/types/components/form/UploadButton/UploadButton.types.d.ts +7 -0
- package/dist/types/components/form/UploadButton/UploadButton.types.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts +1 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +12 -0
- package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/MultiSelectDropdown.d.ts +1 -1
- package/dist/types/components/layout/ContentToolbar/MultiSelectDropdown.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/SortByDropdown.d.ts +1 -1
- package/dist/types/components/layout/ContentToolbar/SortByDropdown.d.ts.map +1 -1
- package/dist/types/components/layout/ContentToolbar/ViewSelector.d.ts +1 -1
- package/dist/types/components/layout/ContentToolbar/ViewSelector.d.ts.map +1 -1
- package/dist/types/components/layout/Dashboard/Dashboard.d.ts +1 -1
- package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts +4 -0
- package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts.map +1 -1
- package/dist/types/components/layout/Dashboard/DashboardParts.d.ts +1 -1
- package/dist/types/components/layout/Dashboard/DashboardParts.d.ts.map +1 -1
- package/dist/types/components/layout/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts +21 -3
- package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts.map +1 -1
- package/dist/types/components/layout/ScrollArea/ScrollViewport.d.ts +2 -0
- package/dist/types/components/layout/ScrollArea/ScrollViewport.d.ts.map +1 -1
- package/dist/types/components/layout/TableFilter/TableFilter.d.ts +1 -1
- package/dist/types/components/layout/TableFilter/TableFilter.d.ts.map +1 -1
- package/dist/types/components/layout/TableFilter/TableFilter.types.d.ts +7 -0
- package/dist/types/components/layout/TableFilter/TableFilter.types.d.ts.map +1 -1
- package/dist/types/components/layout/TableFilter/TableFilterContext.d.ts +9 -0
- package/dist/types/components/layout/TableFilter/TableFilterContext.d.ts.map +1 -1
- package/dist/types/components/navigation/Breadcrumbs/BreadcrumbEntry.d.ts +2 -0
- package/dist/types/components/navigation/Breadcrumbs/BreadcrumbEntry.d.ts.map +1 -1
- package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
- package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.types.d.ts +3 -0
- package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.types.d.ts.map +1 -1
- package/dist/types/components/navigation/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/types/components/navigation/CommandPalette/CommandPalette.types.d.ts +3 -0
- package/dist/types/components/navigation/CommandPalette/CommandPalette.types.d.ts.map +1 -1
- package/dist/types/components/navigation/CommandPalette/CommandPaletteResults.d.ts +2 -0
- package/dist/types/components/navigation/CommandPalette/CommandPaletteResults.d.ts.map +1 -1
- package/dist/types/components/navigation/Pagination/Pagination.d.ts.map +1 -1
- package/dist/types/components/navigation/Pagination/Pagination.types.d.ts +2 -0
- package/dist/types/components/navigation/Pagination/Pagination.types.d.ts.map +1 -1
- package/dist/types/components/navigation/Pagination/PaginationParts.d.ts +2 -0
- package/dist/types/components/navigation/Pagination/PaginationParts.d.ts.map +1 -1
- package/dist/types/components/navigation/Tabs/Tabs.d.ts.map +1 -1
- package/dist/types/components/navigation/Tabs/Tabs.types.d.ts +2 -0
- package/dist/types/components/navigation/Tabs/Tabs.types.d.ts.map +1 -1
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.d.ts.map +1 -1
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts +6 -2
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts.map +1 -1
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts +6 -0
- package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts.map +1 -1
- package/dist/types/components/utility/InstallPrompt/InstallPrompt.d.ts +4 -2
- package/dist/types/components/utility/InstallPrompt/InstallPrompt.d.ts.map +1 -1
- package/dist/types/components/utility/InstallPrompt/InstallPrompt.types.d.ts +8 -7
- package/dist/types/components/utility/InstallPrompt/InstallPrompt.types.d.ts.map +1 -1
- package/dist/types/copy/data-display.d.ts +56 -0
- package/dist/types/copy/data-display.d.ts.map +1 -0
- package/dist/types/copy/feedback.d.ts +38 -0
- package/dist/types/copy/feedback.d.ts.map +1 -0
- package/dist/types/copy/form.d.ts +146 -0
- package/dist/types/copy/form.d.ts.map +1 -0
- package/dist/types/copy/layout.d.ts +18 -0
- package/dist/types/copy/layout.d.ts.map +1 -0
- package/dist/types/copy/navigation.d.ts +24 -0
- package/dist/types/copy/navigation.d.ts.map +1 -0
- package/dist/types/copy/shared.d.ts +119 -0
- package/dist/types/copy/shared.d.ts.map +1 -0
- package/dist/types/copy/utility.d.ts +35 -0
- package/dist/types/copy/utility.d.ts.map +1 -0
- package/dist/types/copy.d.ts +12 -165
- package/dist/types/copy.d.ts.map +1 -1
- package/dist/types/en-US.d.ts +24 -0
- package/dist/types/en-US.d.ts.map +1 -0
- package/dist/types/en-US.data-display.d.ts +13 -0
- package/dist/types/en-US.data-display.d.ts.map +1 -0
- package/dist/types/en-US.feedback.d.ts +8 -0
- package/dist/types/en-US.feedback.d.ts.map +1 -0
- package/dist/types/en-US.form.d.ts +13 -0
- package/dist/types/en-US.form.d.ts.map +1 -0
- package/dist/types/en-US.layout.d.ts +7 -0
- package/dist/types/en-US.layout.d.ts.map +1 -0
- package/dist/types/en-US.navigation.d.ts +8 -0
- package/dist/types/en-US.navigation.d.ts.map +1 -0
- package/dist/types/en-US.shared.d.ts +26 -0
- package/dist/types/en-US.shared.d.ts.map +1 -0
- package/dist/types/en-US.utility.d.ts +8 -0
- package/dist/types/en-US.utility.d.ts.map +1 -0
- package/dist/types/locales.d.ts +53 -0
- package/dist/types/locales.d.ts.map +1 -0
- package/dist/types/pt-BR.d.ts +15 -22
- package/dist/types/pt-BR.d.ts.map +1 -1
- package/dist/types/pt-BR.data-display.d.ts +13 -0
- package/dist/types/pt-BR.data-display.d.ts.map +1 -0
- package/dist/types/pt-BR.feedback.d.ts +8 -0
- package/dist/types/pt-BR.feedback.d.ts.map +1 -0
- package/dist/types/pt-BR.form.d.ts +13 -0
- package/dist/types/pt-BR.form.d.ts.map +1 -0
- package/dist/types/pt-BR.layout.d.ts +7 -0
- package/dist/types/pt-BR.layout.d.ts.map +1 -0
- package/dist/types/pt-BR.navigation.d.ts +8 -0
- package/dist/types/pt-BR.navigation.d.ts.map +1 -0
- package/dist/types/pt-BR.shared.d.ts +21 -0
- package/dist/types/pt-BR.shared.d.ts.map +1 -0
- package/dist/types/pt-BR.utility.d.ts +8 -0
- package/dist/types/pt-BR.utility.d.ts.map +1 -0
- package/dist/types/user-avatar/user-avatar.d.ts +7 -1
- package/dist/types/user-avatar/user-avatar.d.ts.map +1 -1
- package/dist/user-avatar.js +2 -2
- package/dist/user-avatar.js.map +1 -1
- package/dist/utility/InfiniteScroll.js +7 -5
- package/dist/utility/InfiniteScroll.js.map +1 -1
- package/dist/utility/InstallPrompt.js +14 -13
- package/dist/utility/InstallPrompt.js.map +1 -1
- package/package.json +10 -1
- package/src/components/data-display/DataGrid/DataGrid.states.tsx +3 -3
- package/src/components/data-display/DataGrid/DataGrid.tsx +1 -1
- package/src/components/data-display/DataGrid/DataGrid.types.ts +5 -0
- package/src/components/data-display/DataViews/data-views-category-pill.tsx +2 -0
- package/src/components/data-display/DataViews/data-views-copy.ts +27 -1
- package/src/components/data-display/DataViews/data-views-day-input.tsx +14 -3
- package/src/components/data-display/DataViews/data-views-filter-panel.tsx +2 -1
- package/src/components/data-display/DataViews/data-views-grid-bodies.tsx +3 -0
- package/src/components/data-display/DataViews/data-views-grid-parts.tsx +9 -10
- package/src/components/data-display/DataViews/data-views-more-fields.tsx +3 -1
- package/src/components/data-display/DataViews/data-views-pagination.tsx +3 -0
- package/src/components/data-display/DataViews/data-views-range-pill.tsx +3 -1
- package/src/components/data-display/DataViews/data-views-toolbar.tsx +2 -0
- package/src/components/data-display/HoverCard/HoverCard.content.tsx +10 -2
- package/src/components/data-display/HoverCard/HoverCard.tsx +2 -3
- package/src/components/data-display/HoverCard/HoverCard.types.ts +2 -0
- package/src/components/data-display/Table/Table.tsx +7 -2
- package/src/components/data-display/Table/Table.types.ts +5 -0
- package/src/components/data-display/Table/TableStates.tsx +2 -2
- package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +3 -2
- package/src/components/data-display/TimingDiagram/TimingDiagram.types.ts +3 -0
- package/src/components/feedback/Sonner/Sonner.tsx +15 -3
- package/src/components/feedback/Sonner/Sonner.types.ts +2 -0
- package/src/components/feedback/Sonner/SonnerToast.tsx +2 -1
- package/src/components/feedback/StackedModal/StackedModal.parts.tsx +10 -3
- package/src/components/feedback/StackedModal/StackedModal.tsx +2 -1
- package/src/components/feedback/StackedModal/StackedModal.types.ts +2 -0
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.tsx +13 -1
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.types.ts +3 -0
- package/src/components/feedback/TutorialOverlay/TutorialStepBody.tsx +10 -4
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.types.ts +7 -0
- package/src/components/form/AddressAutocomplete/AddressAutocompleteField.tsx +2 -0
- package/src/components/form/AddressAutocomplete/AddressFallbackField.tsx +4 -2
- package/src/components/form/AddressAutocomplete/AddressInputField.tsx +13 -6
- package/src/components/form/Autocomplete/Autocomplete.parts.tsx +9 -6
- package/src/components/form/Autocomplete/Autocomplete.tsx +2 -1
- package/src/components/form/Autocomplete/Autocomplete.types.ts +7 -0
- package/src/components/form/Calendar/Calendar.tsx +2 -2
- package/src/components/form/Calendar/Calendar.types.ts +7 -0
- package/src/components/form/CodeEditor/CodeEditor.tsx +6 -4
- package/src/components/form/CodeEditor/CodeEditor.types.ts +7 -0
- package/src/components/form/CodeEditor/CodeEditorToolbar.tsx +12 -5
- package/src/components/form/DateRangePicker/DateRangePicker.range.ts +2 -0
- package/src/components/form/DateRangePicker/DateRangePicker.tsx +4 -0
- package/src/components/form/DateRangePicker/DateRangePicker.types.ts +11 -0
- package/src/components/form/DateRangePicker/DateRangePickerFields.tsx +2 -0
- package/src/components/form/Menubar/Menubar.toolbar.tsx +3 -1
- package/src/components/form/Menubar/Menubar.tsx +2 -1
- package/src/components/form/Menubar/Menubar.types.ts +5 -0
- package/src/components/form/PasswordStrength/PasswordStrength.helpers.tsx +33 -17
- package/src/components/form/PasswordStrength/PasswordStrength.tsx +29 -13
- package/src/components/form/PasswordStrength/PasswordStrength.types.ts +9 -0
- package/src/components/form/PhoneInput/PhoneInput.tsx +15 -5
- package/src/components/form/PhoneInput/PhoneInput.types.ts +7 -0
- package/src/components/form/SearchPalette/SearchPalette.parts.tsx +4 -1
- package/src/components/form/SearchPalette/SearchPalette.tsx +4 -1
- package/src/components/form/SearchPalette/SearchPalette.types.ts +6 -0
- package/src/components/form/Textarea/Textarea.tsx +6 -1
- package/src/components/form/Textarea/Textarea.types.ts +14 -1
- package/src/components/form/Textarea/TextareaRichEditor.tsx +28 -18
- package/src/components/form/UploadButton/UploadButton.parts.tsx +16 -7
- package/src/components/form/UploadButton/UploadButton.tsx +4 -1
- package/src/components/form/UploadButton/UploadButton.types.ts +8 -0
- package/src/components/layout/ContentToolbar/ContentToolbar.tsx +10 -2
- package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +12 -0
- package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +15 -4
- package/src/components/layout/ContentToolbar/SortByDropdown.tsx +12 -3
- package/src/components/layout/ContentToolbar/ViewSelector.tsx +2 -1
- package/src/components/layout/Dashboard/Dashboard.types.ts +4 -0
- package/src/components/layout/Dashboard/DashboardParts.tsx +2 -1
- package/src/components/layout/ScrollArea/ScrollArea.tsx +16 -3
- package/src/components/layout/ScrollArea/ScrollArea.types.ts +19 -4
- package/src/components/layout/ScrollArea/ScrollViewport.tsx +4 -1
- package/src/components/layout/TableFilter/TableFilter.tsx +19 -11
- package/src/components/layout/TableFilter/TableFilter.types.ts +8 -0
- package/src/components/layout/TableFilter/TableFilterContext.tsx +10 -0
- package/src/components/navigation/Breadcrumbs/BreadcrumbEntry.tsx +11 -4
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +2 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.types.ts +3 -0
- package/src/components/navigation/CommandPalette/CommandPalette.tsx +15 -5
- package/src/components/navigation/CommandPalette/CommandPalette.types.ts +3 -0
- package/src/components/navigation/CommandPalette/CommandPaletteResults.tsx +5 -2
- package/src/components/navigation/Pagination/Pagination.tsx +2 -0
- package/src/components/navigation/Pagination/Pagination.types.ts +2 -0
- package/src/components/navigation/Pagination/PaginationParts.tsx +4 -1
- package/src/components/navigation/Tabs/Tabs.tsx +8 -3
- package/src/components/navigation/Tabs/Tabs.types.ts +2 -0
- package/src/components/utility/InfiniteScroll/InfiniteScroll.parts.tsx +4 -4
- package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +4 -2
- package/src/components/utility/InfiniteScroll/InfiniteScroll.types.ts +6 -0
- package/src/components/utility/InstallPrompt/InstallPrompt.tsx +18 -13
- package/src/components/utility/InstallPrompt/InstallPrompt.types.ts +9 -7
- package/src/copy/data-display.ts +60 -0
- package/src/copy/feedback.ts +39 -0
- package/src/copy/form.ts +154 -0
- package/src/copy/layout.ts +18 -0
- package/src/copy/navigation.ts +25 -0
- package/src/copy/shared.ts +122 -0
- package/src/copy/utility.ts +36 -0
- package/src/copy.ts +12 -173
- package/src/en-US.data-display.ts +244 -0
- package/src/en-US.feedback.ts +25 -0
- package/src/en-US.form.ts +103 -0
- package/src/en-US.layout.ts +15 -0
- package/src/en-US.navigation.ts +23 -0
- package/src/en-US.shared.ts +105 -0
- package/src/en-US.ts +24 -0
- package/src/en-US.utility.ts +24 -0
- package/src/locales.ts +151 -0
- package/src/pt-BR.data-display.ts +236 -0
- package/src/pt-BR.feedback.ts +25 -0
- package/src/pt-BR.form.ts +96 -0
- package/src/pt-BR.layout.ts +15 -0
- package/src/pt-BR.navigation.ts +21 -0
- package/src/pt-BR.shared.ts +94 -0
- package/src/pt-BR.ts +15 -307
- package/src/pt-BR.utility.ts +21 -0
- package/src/user-avatar/user-avatar.tsx +8 -2
- package/dist/chunk-CEKPLUQV.js.map +0 -1
- package/dist/chunk-DFVRZ3UK.js.map +0 -1
- package/dist/chunk-H7UAGTVW.js.map +0 -1
- package/dist/chunk-JP55QWVR.js.map +0 -1
- package/dist/chunk-NUCLEOHF.js.map +0 -1
- package/dist/chunk-QLBYAYUG.js.map +0 -1
- package/dist/chunk-QZZVHY6U.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/feedback/TutorialOverlay/TutorialOverlay.tsx","../../src/components/feedback/TutorialOverlay/TutorialOverlay.hooks.ts","../../src/components/feedback/TutorialOverlay/TutorialOverlay.geometry.ts","../../src/components/feedback/TutorialOverlay/TutorialStepBody.tsx"],"sourcesContent":["import {\n alpha,\n Box,\n Fade,\n keyframes,\n LinearProgress,\n Paper,\n Portal,\n styled } from '@mui/material';\nimport type { FC} from 'react';\nimport React, { } from 'react';\n\nimport { useTutorialOverlay } from './TutorialOverlay.hooks';\nimport { TutorialStepBody } from './TutorialStepBody';\nimport type { TutorialOverlayProps } from './TutorialOverlay.types';\n\n// Animation keyframes\nconst pulseAnimation = keyframes`\n 0% {\n box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7);\n }\n 70% {\n box-shadow: 0 0 0 20px rgba(255, 255, 255, 0);\n }\n 100% {\n box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);\n }\n`;\n\nconst floatAnimation = keyframes`\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-10px);\n }\n`;\n\n// Styled components\nconst Overlay = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'allowClickThrough' })<{ allowClickThrough?: boolean }>(({ theme, allowClickThrough }) => ({\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: theme.zIndex.modal + 100,\n pointerEvents: allowClickThrough ? 'none' : 'auto',\n transition: 'opacity 0.3s ease' }));\n\nconst Backdrop = styled(Box)(() => ({\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background: alpha('#000', 0.7),\n backdropFilter: 'blur(2px)' }));\n\nconst Spotlight = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'bounds' && prop !== 'padding' })<{ bounds: globalThis.DOMRect; padding: number }>(({ bounds, padding }) => ({\n position: 'absolute',\n top: bounds.top - padding,\n left: bounds.left - padding,\n width: bounds.width + padding * 2,\n height: bounds.height + padding * 2,\n borderRadius: 8,\n border: '2px solid rgba(255, 255, 255, 0.5)',\n animation: `${pulseAnimation} 2s infinite`,\n pointerEvents: 'none',\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n inset: -2,\n borderRadius: 8,\n background: 'transparent',\n boxShadow: '0 0 0 9999px rgba(0, 0, 0, 0.7)' } }));\n\nconst TooltipContainer = styled(Paper, {\n shouldForwardProp: (prop) => prop !== 'placement' })<{ placement: string }>(({ theme, placement }) => ({\n position: 'absolute',\n maxWidth: 360,\n padding: theme.spacing(3),\n background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.98)} 0%, ${alpha(theme.palette.background.paper, 0.95)} 100%)`,\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n boxShadow: theme.shadows[12],\n animation: `${floatAnimation} 3s ease-in-out infinite`,\n pointerEvents: 'auto',\n zIndex: theme.zIndex.modal + 101,\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n width: 12,\n height: 12,\n background: 'inherit',\n transform: 'rotate(45deg)',\n border: 'inherit',\n ...(placement === 'top' && {\n bottom: -7,\n left: '50%',\n marginLeft: -6,\n borderTop: 'none',\n borderLeft: 'none' }),\n ...(placement === 'bottom' && {\n top: -7,\n left: '50%',\n marginLeft: -6,\n borderBottom: 'none',\n borderRight: 'none' }),\n ...(placement === 'left' && {\n right: -7,\n top: '50%',\n marginTop: -6,\n borderLeft: 'none',\n borderBottom: 'none' }),\n ...(placement === 'right' && {\n left: -7,\n top: '50%',\n marginTop: -6,\n borderRight: 'none',\n borderTop: 'none' }) } }));\n\nconst ProgressBar = styled(LinearProgress)(({ theme }) => ({\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n height: 4,\n zIndex: theme.zIndex.modal + 102,\n '& .MuiLinearProgress-bar': {\n background: `linear-gradient(90deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.light} 100%)` } }));\n\ntype TutorialDefaultedKeys =\n | 'initialStep'\n | 'active'\n | 'showProgress'\n | 'allowKeyboardNavigation'\n | 'allowClickThrough'\n | 'variant'\n | 'allowSkip'\n | 'animated';\n\ntype ResolvedTutorialProps = TutorialOverlayProps &\n Required<Pick<TutorialOverlayProps, TutorialDefaultedKeys>>;\n\nconst TUTORIAL_DEFAULTS: Pick<TutorialOverlayProps, TutorialDefaultedKeys> = {\n initialStep: 0,\n active: true,\n showProgress: true,\n allowKeyboardNavigation: true,\n allowClickThrough: false,\n variant: 'tooltip',\n allowSkip: false,\n animated: true };\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}` still\n// falls back to the default exactly as a destructuring default would. Applied as\n// a merge rather than destructuring defaults, which would otherwise put eight\n// branches into the component's own complexity budget.\nconst resolveProps = (props: TutorialOverlayProps): ResolvedTutorialProps =>\n ({\n ...TUTORIAL_DEFAULTS,\n ...(Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<TutorialOverlayProps>) }) as ResolvedTutorialProps;\n\n// The dimming layer and the cut-out over the highlighted element. Local because\n// Backdrop and Spotlight cannot cross a module boundary (TS2742).\nconst TutorialLayers: React.FC<{\n variant: string;\n targetBounds: globalThis.DOMRect | null;\n isVisible: boolean;\n spotlightPadding?: number;\n}> = ({ variant, targetBounds, isVisible, spotlightPadding }) => {\n const isSpotlight = variant === 'spotlight' || variant === 'highlight';\n const dimmed = variant === 'modal' || isSpotlight;\n\n return (\n <>\n {dimmed && <Backdrop />}\n {targetBounds && isVisible && isSpotlight && (\n <Spotlight\n bounds={targetBounds}\n padding={spotlightPadding || 8}\n data-testid=\"tutorial-highlight\"\n />\n )}\n </>\n );\n};\n\n// The positioned card. Local because TooltipContainer cannot cross a module\n// boundary (TS2742).\nconst TutorialTooltip: React.FC<{\n tutorial: ReturnType<typeof useTutorialOverlay> & {\n currentStepData: TutorialOverlayProps['steps'][number];\n };\n steps: TutorialOverlayProps['steps'];\n allowSkip: boolean;\n showProgress: boolean;\n animated: boolean;\n requiresActionBeforeNext: boolean;\n}> = ({ tutorial, steps, allowSkip, showProgress, animated, requiresActionBeforeNext }) => (\n <Fade in={tutorial.isVisible} timeout={300}>\n <TooltipContainer\n ref={tutorial.tooltipRef}\n placement={tutorial.actualPlacement}\n elevation={12}\n style={{\n top: tutorial.tooltipPosition.top,\n left: tutorial.tooltipPosition.left,\n animation: animated ? undefined : 'none' }}\n role=\"dialog\"\n aria-labelledby={`tutorial-title-${tutorial.currentStep}`}\n aria-describedby={`tutorial-content-${tutorial.currentStep}`}\n data-testid={`tutorial-step-${tutorial.currentStep}`}\n >\n <TutorialStepBody\n step={tutorial.currentStepData}\n currentStep={tutorial.currentStep}\n stepCount={steps.length}\n progress={tutorial.progress}\n isLastStep={tutorial.isLastStep}\n allowSkip={allowSkip}\n showProgress={showProgress}\n requiresActionBeforeNext={requiresActionBeforeNext}\n onNext={tutorial.handleNext}\n onPrev={tutorial.handlePrev}\n onSkip={tutorial.handleSkip}\n onRestart={tutorial.handleRestart}\n />\n </TooltipContainer>\n </Fade>\n);\n\nexport const TutorialOverlay: FC<TutorialOverlayProps> = (componentProps) => {\n const {\n steps,\n onComplete,\n onSkip,\n onStepComplete,\n initialStep,\n active,\n showProgress,\n allowKeyboardNavigation,\n allowClickThrough,\n variant,\n allowSkip,\n animated } = resolveProps(componentProps);\n\n const tutorial = useTutorialOverlay({\n steps,\n initialStep,\n active,\n allowKeyboardNavigation,\n onComplete,\n onSkip,\n onStepComplete });\n const { currentStepData, isLastStep, isVisible, targetBounds, progress } = tutorial;\n\n const requiresActionBeforeNext = Boolean(currentStepData?.requiresAction) && !isLastStep;\n\n if (!active || !currentStepData) return null;\n\n // Handle empty steps array\n if (steps.length === 0) return null;\n\n return (\n <Portal>\n <Overlay allowClickThrough={allowClickThrough} data-testid=\"tutorial-overlay\">\n {showProgress && <ProgressBar variant=\"determinate\" value={progress} />}\n\n <TutorialLayers\n variant={variant}\n targetBounds={targetBounds}\n isVisible={isVisible}\n spotlightPadding={currentStepData.spotlightPadding}\n />\n\n <TutorialTooltip\n tutorial={{ ...tutorial, currentStepData }}\n steps={steps}\n allowSkip={allowSkip}\n showProgress={showProgress}\n animated={animated}\n requiresActionBeforeNext={requiresActionBeforeNext}\n />\n </Overlay>\n </Portal>\n );\n};\n\n// Export default\nexport default TutorialOverlay;\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { calculateTooltipPosition, getElementBounds } from './TutorialOverlay.geometry';\nimport type { TutorialOverlayProps } from './TutorialOverlay.types';\n\n// Tracks the highlighted element's box, re-measuring on resize and scroll. Scroll\n// is captured (third argument true) so it fires for any scrolling ancestor, not\n// just the window.\nconst useTargetBounds = ({\n active,\n target,\n}: {\n active: boolean;\n target?: string;\n}) => {\n const [targetBounds, setTargetBounds] = useState<globalThis.DOMRect | null>(null);\n const [isVisible, setIsVisible] = useState(false);\n\n useEffect(() => {\n if (!active || !target) return;\n\n const updateBounds = () => {\n const bounds = getElementBounds(target);\n setTargetBounds(bounds);\n setIsVisible(Boolean(bounds));\n };\n\n updateBounds();\n\n window.addEventListener('resize', updateBounds);\n window.addEventListener('scroll', updateBounds, true);\n\n return () => {\n window.removeEventListener('resize', updateBounds);\n window.removeEventListener('scroll', updateBounds, true);\n };\n }, [active, target]);\n\n return { targetBounds, isVisible };\n};\n\n// Places the tooltip against the measured target once both boxes are known.\nconst useTooltipPlacement = ({\n targetBounds,\n isVisible,\n preferredPosition,\n}: {\n targetBounds: globalThis.DOMRect | null;\n isVisible: boolean;\n preferredPosition?: string;\n}) => {\n const tooltipRef = useRef<HTMLDivElement>(null);\n const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 });\n const [actualPlacement, setActualPlacement] = useState<string>('bottom');\n\n useEffect(() => {\n if (!targetBounds || !tooltipRef.current || !isVisible) return;\n\n const { position, placement } = calculateTooltipPosition(\n targetBounds,\n tooltipRef.current.getBoundingClientRect(),\n preferredPosition || 'auto',\n );\n\n setTooltipPosition(position);\n setActualPlacement(placement);\n }, [targetBounds, isVisible, preferredPosition]);\n\n return { tooltipRef, tooltipPosition, actualPlacement };\n};\n\n// Arrow keys step through the tour, Escape skips it.\nconst useTutorialKeyboard = ({\n enabled,\n onNext,\n onPrev,\n onSkip,\n}: {\n enabled: boolean;\n onNext: () => void;\n onPrev: () => void;\n onSkip: () => void;\n}) => {\n useEffect(() => {\n if (!enabled) return;\n\n const handleKeyPress = (e: globalThis.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowLeft':\n onPrev();\n break;\n case 'ArrowRight':\n onNext();\n break;\n case 'Escape':\n onSkip();\n break;\n }\n };\n\n window.addEventListener('keydown', handleKeyPress);\n return () => window.removeEventListener('keydown', handleKeyPress);\n }, [enabled, onNext, onPrev, onSkip]);\n};\n\nexport const useTutorialOverlay = ({\n steps,\n initialStep,\n active,\n allowKeyboardNavigation,\n onComplete,\n onSkip,\n onStepComplete,\n}: {\n steps: TutorialOverlayProps['steps'];\n initialStep: number;\n active: boolean;\n allowKeyboardNavigation: boolean;\n onComplete?: () => void;\n onSkip?: () => void;\n onStepComplete?: (stepId: string) => void;\n}) => {\n const [currentStep, setCurrentStep] = useState(initialStep);\n\n const currentStepData = steps[currentStep];\n const isLastStep = currentStep === steps.length - 1;\n\n const { targetBounds, isVisible } = useTargetBounds({\n active,\n target: currentStepData?.target,\n });\n\n const { tooltipRef, tooltipPosition, actualPlacement } = useTooltipPlacement({\n targetBounds,\n isVisible,\n preferredPosition: currentStepData?.position,\n });\n\n const handleNext = useCallback(() => {\n const currentStepId = steps[currentStep]?.id;\n if (currentStepId) onStepComplete?.(currentStepId);\n\n if (currentStep < steps.length - 1) {\n setCurrentStep(currentStep + 1);\n return;\n }\n\n onComplete?.();\n }, [currentStep, steps, onComplete, onStepComplete]);\n\n const handlePrev = useCallback(() => {\n setCurrentStep((step) => Math.max(step - 1, 0));\n }, []);\n\n const handleSkip = useCallback(() => {\n onSkip?.();\n }, [onSkip]);\n\n const handleRestart = useCallback(() => {\n setCurrentStep(0);\n }, []);\n\n useTutorialKeyboard({\n enabled: allowKeyboardNavigation && active,\n onNext: handleNext,\n onPrev: handlePrev,\n onSkip: handleSkip,\n });\n\n return {\n currentStep,\n currentStepData,\n isLastStep,\n isVisible,\n targetBounds,\n tooltipRef,\n tooltipPosition,\n actualPlacement,\n progress: ((currentStep + 1) / steps.length) * 100,\n handleNext,\n handlePrev,\n handleSkip,\n handleRestart,\n };\n};\n","const DEFAULT_PADDING = 16;\n\nexport const getElementBounds = (selector: string): globalThis.DOMRect | null =>\n document.querySelector(selector)?.getBoundingClientRect() ?? null;\n\n// With placement 'auto', the side with the most free space around the target\n// wins.\nconst pickPlacement = (targetBounds: globalThis.DOMRect): string => {\n const spaces = {\n top: targetBounds.top,\n bottom: window.innerHeight - targetBounds.bottom,\n left: targetBounds.left,\n right: window.innerWidth - targetBounds.right,\n };\n\n return Object.entries(spaces).reduce((a, b) => (b[1] > a[1] ? b : a))[0];\n};\n\nconst offsetFor = (\n placement: string,\n targetBounds: globalThis.DOMRect,\n tooltipBounds: globalThis.DOMRect,\n padding: number,\n): { top: number; left: number } => {\n const centredLeft = targetBounds.left + targetBounds.width / 2 - tooltipBounds.width / 2;\n const centredTop = targetBounds.top + targetBounds.height / 2 - tooltipBounds.height / 2;\n\n switch (placement) {\n case 'top':\n return { top: targetBounds.top - tooltipBounds.height - padding, left: centredLeft };\n case 'bottom':\n return { top: targetBounds.bottom + padding, left: centredLeft };\n case 'left':\n return { top: centredTop, left: targetBounds.left - tooltipBounds.width - padding };\n case 'right':\n return { top: centredTop, left: targetBounds.right + padding };\n default:\n return { top: 0, left: 0 };\n }\n};\n\n// Keeps the tooltip fully on screen, whatever the chosen side works out to.\nconst clampToViewport = (\n position: { top: number; left: number },\n tooltipBounds: globalThis.DOMRect,\n padding: number,\n) => ({\n top: Math.max(padding, Math.min(position.top, window.innerHeight - tooltipBounds.height - padding)),\n left: Math.max(padding, Math.min(position.left, window.innerWidth - tooltipBounds.width - padding)),\n});\n\nexport const calculateTooltipPosition = (\n targetBounds: globalThis.DOMRect,\n tooltipBounds: globalThis.DOMRect,\n placement: string,\n padding = DEFAULT_PADDING,\n) => {\n const finalPlacement = placement === 'auto' ? pickPlacement(targetBounds) : placement;\n const offset = offsetFor(finalPlacement, targetBounds, tooltipBounds, padding);\n\n return {\n position: clampToViewport(offset, tooltipBounds, padding),\n placement: finalPlacement,\n };\n};\n","import CompleteIcon from '@mui/icons-material/CheckCircle';\nimport CloseIcon from '@mui/icons-material/Close';\nimport PrevIcon from '@mui/icons-material/NavigateBefore';\nimport NextIcon from '@mui/icons-material/NavigateNext';\nimport RestartIcon from '@mui/icons-material/Refresh';\nimport {\n alpha,\n Box,\n Button,\n IconButton,\n Stack,\n styled,\n Typography } from '@mui/material';\nimport React, { } from 'react';\n\nimport type { TutorialOverlayProps } from './TutorialOverlay.types';\n\n// Animation keyframes\n\nconst StepIndicator = styled(Box)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(1),\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(2) }));\n\n\nconst StepDot = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'active' && prop !== 'completed' })<{ active?: boolean; completed?: boolean }>(({ theme, active, completed }) => ({\n width: 8,\n height: 8,\n borderRadius: '50%',\n background: completed\n ? theme.palette.success.main\n : active\n ? theme.palette.primary.main\n : alpha(theme.palette.text.primary, 0.3),\n transition: 'all 0.3s ease',\n ...(active && {\n transform: 'scale(1.5)' }) }));\n\n// Title, body copy, the step dots and the navigation row.\n\n// The step's controls: skip/restart on the left, previous/next on the right.\nconst TutorialStepNav: React.FC<{\n currentStep: number;\n stepCount: number;\n isLastStep: boolean;\n allowSkip: boolean;\n requiresActionBeforeNext?: boolean;\n onNext: () => void;\n onPrev: () => void;\n onSkip: () => void;\n onRestart: () => void;\n}> = ({\n currentStep,\n stepCount,\n isLastStep,\n allowSkip,\n requiresActionBeforeNext,\n onNext,\n onPrev,\n onSkip,\n onRestart }) => (\n <Stack\n direction=\"row\"\n spacing={1}\n justifyContent=\"space-between\"\n data-testid=\"tutorial-navigation\"\n >\n <Stack direction=\"row\" spacing={1}>\n {allowSkip && (\n <Button size=\"small\" onClick={onSkip} variant=\"text\">\n Skip\n </Button>\n )}\n {stepCount > 1 && (\n <IconButton\n size=\"small\"\n onClick={onRestart}\n disabled={currentStep === 0}\n title=\"Restart\"\n >\n <RestartIcon fontSize=\"small\" />\n </IconButton>\n )}\n </Stack>\n\n <Stack direction=\"row\" spacing={1}>\n {stepCount > 1 && currentStep > 0 && (\n <Button\n size=\"small\"\n startIcon={<PrevIcon />}\n onClick={onPrev}\n disabled={currentStep === 0}\n data-testid=\"tutorial-prev-button\"\n >\n Previous\n </Button>\n )}\n\n {!isLastStep ? (\n <Button\n variant=\"contained\"\n size=\"small\"\n endIcon={<NextIcon />}\n onClick={onNext}\n disabled={requiresActionBeforeNext}\n title={requiresActionBeforeNext ? 'Complete the required action first' : ''}\n data-testid=\"tutorial-next-button\"\n >\n Next\n </Button>\n ) : (\n <Button\n variant=\"contained\"\n size=\"small\"\n endIcon={<CompleteIcon />}\n onClick={onNext}\n sx={{\n background: 'linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%)' }}\n data-testid=\"tutorial-finish-button\"\n >\n {stepCount === 1 ? 'Complete' : 'Finish'}\n </Button>\n )}\n </Stack>\n </Stack>\n);\n\nconst StepDots: React.FC<{ currentStep: number; stepCount: number }> = ({\n currentStep,\n stepCount }) => (\n <StepIndicator data-testid=\"tutorial-step-indicators\">\n {Array.from({ length: stepCount }).map((_, index) => (\n <StepDot\n key={index}\n active={index === currentStep}\n completed={index < currentStep}\n data-testid={`tutorial-indicator-${index}`}\n />\n ))}\n </StepIndicator>\n);\n\n// Title, and the close button when skipping is allowed.\nconst TutorialStepHeader: React.FC<{\n title: React.ReactNode;\n currentStep: number;\n allowSkip: boolean;\n onSkip: () => void;\n}> = ({ title, currentStep, allowSkip, onSkip }) => (\n <Box\n sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}\n >\n <Typography\n id={`tutorial-title-${currentStep}`}\n variant=\"h6\"\n fontWeight=\"bold\"\n sx={{ flex: 1 }}\n data-testid=\"tutorial-step-title\"\n >\n {title}\n </Typography>\n {allowSkip && (\n <IconButton\n size=\"small\"\n onClick={onSkip}\n sx={{ ml: 1, mt: -1, mr: -1 }}\n data-testid=\"tutorial-close-button\"\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n )}\n </Box>\n);\n\nexport const TutorialStepBody: React.FC<{\n step: TutorialOverlayProps['steps'][number];\n currentStep: number;\n stepCount: number;\n progress: number;\n isLastStep: boolean;\n allowSkip: boolean;\n showProgress: boolean;\n requiresActionBeforeNext?: boolean;\n onNext: () => void;\n onPrev: () => void;\n onSkip: () => void;\n onRestart: () => void;\n}> = ({\n step,\n currentStep,\n stepCount,\n progress: _progress,\n isLastStep,\n allowSkip,\n showProgress,\n requiresActionBeforeNext,\n onNext,\n onPrev,\n onSkip,\n onRestart }) => (\n <Stack spacing={2}>\n <TutorialStepHeader\n title={step.title}\n currentStep={currentStep}\n allowSkip={allowSkip}\n onSkip={onSkip}\n />\n\n <Typography\n id={`tutorial-content-${currentStep}`}\n variant=\"body2\"\n color=\"text.secondary\"\n data-testid=\"tutorial-step-content\"\n >\n {step.content}\n </Typography>\n\n {showProgress && (\n <Typography variant=\"caption\" color=\"text.secondary\" align=\"center\">\n {currentStep + 1} of {stepCount}\n </Typography>\n )}\n\n {step.action && (\n <Button\n variant=\"contained\"\n size=\"small\"\n onClick={step.action.onClick}\n sx={{\n background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n color: 'white' }}\n >\n {step.action.label}\n </Button>\n )}\n\n <StepDots currentStep={currentStep} stepCount={stepCount} />\n\n <TutorialStepNav\n currentStep={currentStep}\n stepCount={stepCount}\n isLastStep={isLastStep}\n allowSkip={allowSkip}\n requiresActionBeforeNext={requiresActionBeforeNext}\n onNext={onNext}\n onPrev={onPrev}\n onSkip={onSkip}\n onRestart={onRestart}\n />\n </Stack>\n);\n\n// Main component\n"],"mappings":";;;AAAA;AAAA,EACE,SAAAA;AAAA,EACA,OAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAAC;AAAA,OAAc;;;ACRhB,SAAS,aAAa,WAAW,QAAQ,gBAAgB;;;ACAzD,IAAM,kBAAkB;AAEjB,IAAM,mBAAmB,CAAC,aAC/B,SAAS,cAAc,QAAQ,GAAG,sBAAsB,KAAK;AAI/D,IAAM,gBAAgB,CAAC,iBAA6C;AAClE,QAAM,SAAS;AAAA,IACb,KAAK,aAAa;AAAA,IAClB,QAAQ,OAAO,cAAc,aAAa;AAAA,IAC1C,MAAM,aAAa;AAAA,IACnB,OAAO,OAAO,aAAa,aAAa;AAAA,EAC1C;AAEA,SAAO,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,GAAG,MAAO,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAE,EAAE,CAAC;AACzE;AAEA,IAAM,YAAY,CAChB,WACA,cACA,eACA,YACkC;AAClC,QAAM,cAAc,aAAa,OAAO,aAAa,QAAQ,IAAI,cAAc,QAAQ;AACvF,QAAM,aAAa,aAAa,MAAM,aAAa,SAAS,IAAI,cAAc,SAAS;AAEvF,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,EAAE,KAAK,aAAa,MAAM,cAAc,SAAS,SAAS,MAAM,YAAY;AAAA,IACrF,KAAK;AACH,aAAO,EAAE,KAAK,aAAa,SAAS,SAAS,MAAM,YAAY;AAAA,IACjE,KAAK;AACH,aAAO,EAAE,KAAK,YAAY,MAAM,aAAa,OAAO,cAAc,QAAQ,QAAQ;AAAA,IACpF,KAAK;AACH,aAAO,EAAE,KAAK,YAAY,MAAM,aAAa,QAAQ,QAAQ;AAAA,IAC/D;AACE,aAAO,EAAE,KAAK,GAAG,MAAM,EAAE;AAAA,EAC7B;AACF;AAGA,IAAM,kBAAkB,CACtB,UACA,eACA,aACI;AAAA,EACJ,KAAK,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,KAAK,OAAO,cAAc,cAAc,SAAS,OAAO,CAAC;AAAA,EAClG,MAAM,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,MAAM,OAAO,aAAa,cAAc,QAAQ,OAAO,CAAC;AACpG;AAEO,IAAM,2BAA2B,CACtC,cACA,eACA,WACA,UAAU,oBACP;AACH,QAAM,iBAAiB,cAAc,SAAS,cAAc,YAAY,IAAI;AAC5E,QAAM,SAAS,UAAU,gBAAgB,cAAc,eAAe,OAAO;AAE7E,SAAO;AAAA,IACL,UAAU,gBAAgB,QAAQ,eAAe,OAAO;AAAA,IACxD,WAAW;AAAA,EACb;AACF;;;ADxDA,IAAM,kBAAkB,CAAC;AAAA,EACvB;AAAA,EACA;AACF,MAGM;AACJ,QAAM,CAAC,cAAc,eAAe,IAAI,SAAoC,IAAI;AAChF,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,OAAQ;AAExB,UAAM,eAAe,MAAM;AACzB,YAAM,SAAS,iBAAiB,MAAM;AACtC,sBAAgB,MAAM;AACtB,mBAAa,QAAQ,MAAM,CAAC;AAAA,IAC9B;AAEA,iBAAa;AAEb,WAAO,iBAAiB,UAAU,YAAY;AAC9C,WAAO,iBAAiB,UAAU,cAAc,IAAI;AAEpD,WAAO,MAAM;AACX,aAAO,oBAAoB,UAAU,YAAY;AACjD,aAAO,oBAAoB,UAAU,cAAc,IAAI;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,QAAQ,MAAM,CAAC;AAEnB,SAAO,EAAE,cAAc,UAAU;AACnC;AAGA,IAAM,sBAAsB,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,MAIM;AACJ,QAAM,aAAa,OAAuB,IAAI;AAC9C,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AAC1E,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAiB,QAAQ;AAEvE,YAAU,MAAM;AACd,QAAI,CAAC,gBAAgB,CAAC,WAAW,WAAW,CAAC,UAAW;AAExD,UAAM,EAAE,UAAU,UAAU,IAAI;AAAA,MAC9B;AAAA,MACA,WAAW,QAAQ,sBAAsB;AAAA,MACzC,qBAAqB;AAAA,IACvB;AAEA,uBAAmB,QAAQ;AAC3B,uBAAmB,SAAS;AAAA,EAC9B,GAAG,CAAC,cAAc,WAAW,iBAAiB,CAAC;AAE/C,SAAO,EAAE,YAAY,iBAAiB,gBAAgB;AACxD;AAGA,IAAM,sBAAsB,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAKM;AACJ,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,UAAM,iBAAiB,CAAC,MAAgC;AACtD,cAAQ,EAAE,KAAK;AAAA,QACb,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AACH,iBAAO;AACP;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,iBAAiB,WAAW,cAAc;AACjD,WAAO,MAAM,OAAO,oBAAoB,WAAW,cAAc;AAAA,EACnE,GAAG,CAAC,SAAS,QAAQ,QAAQ,MAAM,CAAC;AACtC;AAEO,IAAM,qBAAqB,CAAC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAQM;AACJ,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,WAAW;AAE1D,QAAM,kBAAkB,MAAM,WAAW;AACzC,QAAM,aAAa,gBAAgB,MAAM,SAAS;AAElD,QAAM,EAAE,cAAc,UAAU,IAAI,gBAAgB;AAAA,IAClD;AAAA,IACA,QAAQ,iBAAiB;AAAA,EAC3B,CAAC;AAED,QAAM,EAAE,YAAY,iBAAiB,gBAAgB,IAAI,oBAAoB;AAAA,IAC3E;AAAA,IACA;AAAA,IACA,mBAAmB,iBAAiB;AAAA,EACtC,CAAC;AAED,QAAM,aAAa,YAAY,MAAM;AACnC,UAAM,gBAAgB,MAAM,WAAW,GAAG;AAC1C,QAAI,cAAe,kBAAiB,aAAa;AAEjD,QAAI,cAAc,MAAM,SAAS,GAAG;AAClC,qBAAe,cAAc,CAAC;AAC9B;AAAA,IACF;AAEA,iBAAa;AAAA,EACf,GAAG,CAAC,aAAa,OAAO,YAAY,cAAc,CAAC;AAEnD,QAAM,aAAa,YAAY,MAAM;AACnC,mBAAe,CAAC,SAAS,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,YAAY,MAAM;AACnC,aAAS;AAAA,EACX,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,gBAAgB,YAAY,MAAM;AACtC,mBAAe,CAAC;AAAA,EAClB,GAAG,CAAC,CAAC;AAEL,sBAAoB;AAAA,IAClB,SAAS,2BAA2B;AAAA,IACpC,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAY,cAAc,KAAK,MAAM,SAAU;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AExLA,OAAO,kBAAkB;AACzB,OAAO,eAAe;AACtB,OAAO,cAAc;AACrB,OAAO,cAAc;AACrB,OAAO,iBAAiB;AACxB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAAkB;AAyDV,SAEI,KAFJ;AAlDV,IAAM,gBAAgB,OAAO,GAAG,EAAE,CAAC,EAAE,MAAM,OAAO;AAAA,EAChD,SAAS;AAAA,EACT,KAAK,MAAM,QAAQ,CAAC;AAAA,EACpB,WAAW,MAAM,QAAQ,CAAC;AAAA,EAC1B,cAAc,MAAM,QAAQ,CAAC;AAAE,EAAE;AAGnC,IAAM,UAAU,OAAO,KAAK;AAAA,EAC1B,mBAAmB,CAAC,SAAS,SAAS,YAAY,SAAS;AAAY,CAAC,EAA6C,CAAC,EAAE,OAAO,QAAQ,UAAU,OAAO;AAAA,EACxJ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,YAAY,YACR,MAAM,QAAQ,QAAQ,OACtB,SACE,MAAM,QAAQ,QAAQ,OACtB,MAAM,MAAM,QAAQ,KAAK,SAAS,GAAG;AAAA,EAC3C,YAAY;AAAA,EACZ,GAAI,UAAU;AAAA,IACZ,WAAW;AAAA,EAAa;AAAG,EAAE;AAKjC,IAAM,kBAUD,CAAC;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAU,MACJ;AAAA,EAAC;AAAA;AAAA,IACC,WAAU;AAAA,IACV,SAAS;AAAA,IACT,gBAAe;AAAA,IACf,eAAY;AAAA,IAEZ;AAAA,2BAAC,SAAM,WAAU,OAAM,SAAS,GAC7B;AAAA,qBACC,oBAAC,UAAO,MAAK,SAAQ,SAAS,QAAQ,SAAQ,QAAO,kBAErD;AAAA,QAED,YAAY,KACX;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS;AAAA,YACT,UAAU,gBAAgB;AAAA,YAC1B,OAAM;AAAA,YAEN,8BAAC,eAAY,UAAS,SAAQ;AAAA;AAAA,QAChC;AAAA,SAEJ;AAAA,MAEA,qBAAC,SAAM,WAAU,OAAM,SAAS,GAC7B;AAAA,oBAAY,KAAK,cAAc,KAC9B;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,oBAAC,YAAS;AAAA,YACrB,SAAS;AAAA,YACT,UAAU,gBAAgB;AAAA,YAC1B,eAAY;AAAA,YACb;AAAA;AAAA,QAED;AAAA,QAGD,CAAC,aACA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,oBAAC,YAAS;AAAA,YACnB,SAAS;AAAA,YACT,UAAU;AAAA,YACV,OAAO,2BAA2B,uCAAuC;AAAA,YACzE,eAAY;AAAA,YACb;AAAA;AAAA,QAED,IAEA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,oBAAC,gBAAa;AAAA,YACvB,SAAS;AAAA,YACT,IAAI;AAAA,cACF,YAAY;AAAA,YAAoD;AAAA,YAClE,eAAY;AAAA,YAEX,wBAAc,IAAI,aAAa;AAAA;AAAA,QAClC;AAAA,SAEJ;AAAA;AAAA;AACF;AAGR,IAAM,WAAiE,CAAC;AAAA,EACtE;AAAA,EACA;AAAU,MACV,oBAAC,iBAAc,eAAY,4BACxB,gBAAM,KAAK,EAAE,QAAQ,UAAU,CAAC,EAAE,IAAI,CAAC,GAAG,UACzC;AAAA,EAAC;AAAA;AAAA,IAEC,QAAQ,UAAU;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,eAAa,sBAAsB,KAAK;AAAA;AAAA,EAHnC;AAIP,CACD,GACH;AAIF,IAAM,qBAKD,CAAC,EAAE,OAAO,aAAa,WAAW,OAAO,MACtC;AAAA,EAAC;AAAA;AAAA,IACC,IAAI,EAAE,SAAS,QAAQ,gBAAgB,iBAAiB,YAAY,aAAa;AAAA,IAEjF;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,IAAI,kBAAkB,WAAW;AAAA,UACjC,SAAQ;AAAA,UACR,YAAW;AAAA,UACX,IAAI,EAAE,MAAM,EAAE;AAAA,UACd,eAAY;AAAA,UAEX;AAAA;AAAA,MACH;AAAA,MACC,aACC;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS;AAAA,UACT,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG;AAAA,UAC5B,eAAY;AAAA,UAEZ,8BAAC,aAAU,UAAS,SAAQ;AAAA;AAAA,MAC9B;AAAA;AAAA;AAEJ;AAGD,IAAM,mBAaR,CAAC;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAU,MACN,qBAAC,SAAM,SAAS,GACd;AAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,KAAK;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAAA,EAEA;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,oBAAoB,WAAW;AAAA,MACnC,SAAQ;AAAA,MACR,OAAM;AAAA,MACN,eAAY;AAAA,MAEX,eAAK;AAAA;AAAA,EACR;AAAA,EAEC,gBACC,qBAAC,cAAW,SAAQ,WAAU,OAAM,kBAAiB,OAAM,UACxD;AAAA,kBAAc;AAAA,IAAE;AAAA,IAAK;AAAA,KACxB;AAAA,EAGD,KAAK,UACJ;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,SAAS,KAAK,OAAO;AAAA,MACrB,IAAI;AAAA,QACF,YAAY;AAAA,QACZ,OAAO;AAAA,MAAQ;AAAA,MAEhB,eAAK,OAAO;AAAA;AAAA,EACf;AAAA,EAGF,oBAAC,YAAS,aAA0B,WAAsB;AAAA,EAE1D;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAAA,GACF;;;AHvEF,mBACa,OAAAC,MADb,QAAAC,aAAA;AAnKJ,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYvB,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvB,IAAM,UAAUC,QAAOC,MAAK;AAAA,EAC1B,mBAAmB,CAAC,SAAS,SAAS;AAAoB,CAAC,EAAmC,CAAC,EAAE,OAAO,kBAAkB,OAAO;AAAA,EACjI,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ,MAAM,OAAO,QAAQ;AAAA,EAC7B,eAAe,oBAAoB,SAAS;AAAA,EAC5C,YAAY;AAAoB,EAAE;AAEpC,IAAM,WAAWD,QAAOC,IAAG,EAAE,OAAO;AAAA,EAClC,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAYC,OAAM,QAAQ,GAAG;AAAA,EAC7B,gBAAgB;AAAY,EAAE;AAEhC,IAAM,YAAYF,QAAOC,MAAK;AAAA,EAC5B,mBAAmB,CAAC,SAAS,SAAS,YAAY,SAAS;AAAU,CAAC,EAAmD,CAAC,EAAE,QAAQ,QAAQ,OAAO;AAAA,EACnJ,UAAU;AAAA,EACV,KAAK,OAAO,MAAM;AAAA,EAClB,MAAM,OAAO,OAAO;AAAA,EACpB,OAAO,OAAO,QAAQ,UAAU;AAAA,EAChC,QAAQ,OAAO,SAAS,UAAU;AAAA,EAClC,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,WAAW,GAAG,cAAc;AAAA,EAC5B,eAAe;AAAA,EACf,aAAa;AAAA,IACX,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,WAAW;AAAA,EAAkC;AAAE,EAAE;AAErD,IAAM,mBAAmBD,QAAO,OAAO;AAAA,EACrC,mBAAmB,CAAC,SAAS,SAAS;AAAY,CAAC,EAAyB,CAAC,EAAE,OAAO,UAAU,OAAO;AAAA,EACvG,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS,MAAM,QAAQ,CAAC;AAAA,EACxB,YAAY,2BAA2BE,OAAM,MAAM,QAAQ,WAAW,OAAO,IAAI,CAAC,QAAQA,OAAM,MAAM,QAAQ,WAAW,OAAO,IAAI,CAAC;AAAA,EACrI,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,QAAQ,aAAaA,OAAM,MAAM,QAAQ,SAAS,IAAI,CAAC;AAAA,EACvD,WAAW,MAAM,QAAQ,EAAE;AAAA,EAC3B,WAAW,GAAG,cAAc;AAAA,EAC5B,eAAe;AAAA,EACf,QAAQ,MAAM,OAAO,QAAQ;AAAA,EAC7B,aAAa;AAAA,IACX,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,GAAI,cAAc,SAAS;AAAA,MACzB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,YAAY;AAAA,IAAO;AAAA,IACrB,GAAI,cAAc,YAAY;AAAA,MAC5B,KAAK;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,aAAa;AAAA,IAAO;AAAA,IACtB,GAAI,cAAc,UAAU;AAAA,MAC1B,OAAO;AAAA,MACP,KAAK;AAAA,MACL,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,cAAc;AAAA,IAAO;AAAA,IACvB,GAAI,cAAc,WAAW;AAAA,MAC3B,MAAM;AAAA,MACN,KAAK;AAAA,MACL,WAAW;AAAA,MACX,aAAa;AAAA,MACb,WAAW;AAAA,IAAO;AAAA,EAAG;AAAE,EAAE;AAE/B,IAAM,cAAcF,QAAO,cAAc,EAAE,CAAC,EAAE,MAAM,OAAO;AAAA,EACzD,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ,MAAM,OAAO,QAAQ;AAAA,EAC7B,4BAA4B;AAAA,IAC1B,YAAY,0BAA0B,MAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,QAAQ,QAAQ,KAAK;AAAA,EAAS;AAAE,EAAE;AAepH,IAAM,oBAAuE;AAAA,EAC3E,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,yBAAyB;AAAA,EACzB,mBAAmB;AAAA,EACnB,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAK;AAMjB,IAAM,eAAe,CAAC,WACnB;AAAA,EACC,GAAG;AAAA,EACH,GAAI,OAAO;AAAA,IACT,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS;AAAA,EACjE;AAAoC;AAIxC,IAAM,iBAKD,CAAC,EAAE,SAAS,cAAc,WAAW,iBAAiB,MAAM;AAC/D,QAAM,cAAc,YAAY,eAAe,YAAY;AAC3D,QAAM,SAAS,YAAY,WAAW;AAEtC,SACE,gBAAAD,MAAA,YACG;AAAA,cAAU,gBAAAD,KAAC,YAAS;AAAA,IACpB,gBAAgB,aAAa,eAC5B,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS,oBAAoB;AAAA,QAC7B,eAAY;AAAA;AAAA,IACd;AAAA,KAEJ;AAEJ;AAIA,IAAM,kBASD,CAAC,EAAE,UAAU,OAAO,WAAW,cAAc,UAAU,yBAAyB,MAC7E,gBAAAA,KAAC,QAAK,IAAI,SAAS,WAAW,SAAS,KACrC,0BAAAA;AAAA,EAAC;AAAA;AAAA,IACC,KAAK,SAAS;AAAA,IACd,WAAW,SAAS;AAAA,IACpB,WAAW;AAAA,IACX,OAAO;AAAA,MACL,KAAK,SAAS,gBAAgB;AAAA,MAC9B,MAAM,SAAS,gBAAgB;AAAA,MAC/B,WAAW,WAAW,SAAY;AAAA,IAAO;AAAA,IAC3C,MAAK;AAAA,IACL,mBAAiB,kBAAkB,SAAS,WAAW;AAAA,IACvD,oBAAkB,oBAAoB,SAAS,WAAW;AAAA,IAC1D,eAAa,iBAAiB,SAAS,WAAW;AAAA,IAElD,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,SAAS;AAAA,QACf,aAAa,SAAS;AAAA,QACtB,WAAW,MAAM;AAAA,QACjB,UAAU,SAAS;AAAA,QACnB,YAAY,SAAS;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,SAAS;AAAA,QACjB,QAAQ,SAAS;AAAA,QACjB,QAAQ,SAAS;AAAA,QACjB,WAAW,SAAS;AAAA;AAAA,IACtB;AAAA;AACF,GACF;AAGD,IAAM,kBAA4C,CAAC,mBAAmB;AAC3E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAS,IAAI,aAAa,cAAc;AAE1C,QAAM,WAAW,mBAAmB;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAe,CAAC;AAClB,QAAM,EAAE,iBAAiB,YAAY,WAAW,cAAc,SAAS,IAAI;AAE3E,QAAM,2BAA2B,QAAQ,iBAAiB,cAAc,KAAK,CAAC;AAE9E,MAAI,CAAC,UAAU,CAAC,gBAAiB,QAAO;AAGxC,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,SACE,gBAAAA,KAAC,UACC,0BAAAC,MAAC,WAAQ,mBAAsC,eAAY,oBACxD;AAAA,oBAAgB,gBAAAD,KAAC,eAAY,SAAQ,eAAc,OAAO,UAAU;AAAA,IAErE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,kBAAkB,gBAAgB;AAAA;AAAA,IACpC;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,EAAE,GAAG,UAAU,gBAAgB;AAAA,QACzC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,KACF,GACF;AAEJ;","names":["alpha","Box","styled","jsx","jsxs","styled","Box","alpha"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/feedback/TutorialOverlay/TutorialOverlay.tsx","../../src/components/feedback/TutorialOverlay/TutorialOverlay.hooks.ts","../../src/components/feedback/TutorialOverlay/TutorialOverlay.geometry.ts","../../src/components/feedback/TutorialOverlay/TutorialStepBody.tsx"],"sourcesContent":["import {\n alpha,\n Box,\n Fade,\n keyframes,\n LinearProgress,\n Paper,\n Portal,\n styled } from '@mui/material';\nimport type { FC} from 'react';\nimport React, { } from 'react';\n\nimport { useTutorialOverlay } from './TutorialOverlay.hooks';\nimport { TutorialStepBody } from './TutorialStepBody';\nimport type { TutorialOverlayProps } from './TutorialOverlay.types';\n\n// Animation keyframes\nconst pulseAnimation = keyframes`\n 0% {\n box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7);\n }\n 70% {\n box-shadow: 0 0 0 20px rgba(255, 255, 255, 0);\n }\n 100% {\n box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);\n }\n`;\n\nconst floatAnimation = keyframes`\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-10px);\n }\n`;\n\n// Styled components\nconst Overlay = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'allowClickThrough' })<{ allowClickThrough?: boolean }>(({ theme, allowClickThrough }) => ({\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: theme.zIndex.modal + 100,\n pointerEvents: allowClickThrough ? 'none' : 'auto',\n transition: 'opacity 0.3s ease' }));\n\nconst Backdrop = styled(Box)(() => ({\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background: alpha('#000', 0.7),\n backdropFilter: 'blur(2px)' }));\n\nconst Spotlight = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'bounds' && prop !== 'padding' })<{ bounds: globalThis.DOMRect; padding: number }>(({ bounds, padding }) => ({\n position: 'absolute',\n top: bounds.top - padding,\n left: bounds.left - padding,\n width: bounds.width + padding * 2,\n height: bounds.height + padding * 2,\n borderRadius: 8,\n border: '2px solid rgba(255, 255, 255, 0.5)',\n animation: `${pulseAnimation} 2s infinite`,\n pointerEvents: 'none',\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n inset: -2,\n borderRadius: 8,\n background: 'transparent',\n boxShadow: '0 0 0 9999px rgba(0, 0, 0, 0.7)' } }));\n\nconst TooltipContainer = styled(Paper, {\n shouldForwardProp: (prop) => prop !== 'placement' })<{ placement: string }>(({ theme, placement }) => ({\n position: 'absolute',\n maxWidth: 360,\n padding: theme.spacing(3),\n background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.98)} 0%, ${alpha(theme.palette.background.paper, 0.95)} 100%)`,\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n boxShadow: theme.shadows[12],\n animation: `${floatAnimation} 3s ease-in-out infinite`,\n pointerEvents: 'auto',\n zIndex: theme.zIndex.modal + 101,\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n width: 12,\n height: 12,\n background: 'inherit',\n transform: 'rotate(45deg)',\n border: 'inherit',\n ...(placement === 'top' && {\n bottom: -7,\n left: '50%',\n marginLeft: -6,\n borderTop: 'none',\n borderLeft: 'none' }),\n ...(placement === 'bottom' && {\n top: -7,\n left: '50%',\n marginLeft: -6,\n borderBottom: 'none',\n borderRight: 'none' }),\n ...(placement === 'left' && {\n right: -7,\n top: '50%',\n marginTop: -6,\n borderLeft: 'none',\n borderBottom: 'none' }),\n ...(placement === 'right' && {\n left: -7,\n top: '50%',\n marginTop: -6,\n borderRight: 'none',\n borderTop: 'none' }) } }));\n\nconst ProgressBar = styled(LinearProgress)(({ theme }) => ({\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n height: 4,\n zIndex: theme.zIndex.modal + 102,\n '& .MuiLinearProgress-bar': {\n background: `linear-gradient(90deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.light} 100%)` } }));\n\ntype TutorialDefaultedKeys =\n | 'initialStep'\n | 'active'\n | 'showProgress'\n | 'allowKeyboardNavigation'\n | 'allowClickThrough'\n | 'variant'\n | 'allowSkip'\n | 'animated';\n\ntype ResolvedTutorialProps = TutorialOverlayProps &\n Required<Pick<TutorialOverlayProps, TutorialDefaultedKeys>>;\n\nconst TUTORIAL_DEFAULTS: Pick<TutorialOverlayProps, TutorialDefaultedKeys> = {\n initialStep: 0,\n active: true,\n showProgress: true,\n allowKeyboardNavigation: true,\n allowClickThrough: false,\n variant: 'tooltip',\n allowSkip: false,\n animated: true };\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}` still\n// falls back to the default exactly as a destructuring default would. Applied as\n// a merge rather than destructuring defaults, which would otherwise put eight\n// branches into the component's own complexity budget.\nconst resolveProps = (props: TutorialOverlayProps): ResolvedTutorialProps =>\n ({\n ...TUTORIAL_DEFAULTS,\n ...(Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<TutorialOverlayProps>) }) as ResolvedTutorialProps;\n\n// The dimming layer and the cut-out over the highlighted element. Local because\n// Backdrop and Spotlight cannot cross a module boundary (TS2742).\nconst TutorialLayers: React.FC<{\n variant: string;\n targetBounds: globalThis.DOMRect | null;\n isVisible: boolean;\n spotlightPadding?: number;\n}> = ({ variant, targetBounds, isVisible, spotlightPadding }) => {\n const isSpotlight = variant === 'spotlight' || variant === 'highlight';\n const dimmed = variant === 'modal' || isSpotlight;\n\n return (\n <>\n {dimmed && <Backdrop />}\n {targetBounds && isVisible && isSpotlight && (\n <Spotlight\n bounds={targetBounds}\n padding={spotlightPadding || 8}\n data-testid=\"tutorial-highlight\"\n />\n )}\n </>\n );\n};\n\n// The positioned card. Local because TooltipContainer cannot cross a module\n// boundary (TS2742).\nconst TutorialTooltip: React.FC<{\n tutorial: ReturnType<typeof useTutorialOverlay> & {\n currentStepData: TutorialOverlayProps['steps'][number];\n };\n steps: TutorialOverlayProps['steps'];\n allowSkip: boolean;\n showProgress: boolean;\n animated: boolean;\n requiresActionBeforeNext: boolean;\n copy: TutorialOverlayProps['copy'];\n}> = ({\n tutorial,\n steps,\n allowSkip,\n showProgress,\n animated,\n requiresActionBeforeNext,\n copy,\n}) => (\n <Fade in={tutorial.isVisible} timeout={300}>\n <TooltipContainer\n ref={tutorial.tooltipRef}\n placement={tutorial.actualPlacement}\n elevation={12}\n style={{\n top: tutorial.tooltipPosition.top,\n left: tutorial.tooltipPosition.left,\n animation: animated ? undefined : 'none' }}\n role=\"dialog\"\n aria-labelledby={`tutorial-title-${tutorial.currentStep}`}\n aria-describedby={`tutorial-content-${tutorial.currentStep}`}\n data-testid={`tutorial-step-${tutorial.currentStep}`}\n >\n <TutorialStepBody\n copy={copy}\n step={tutorial.currentStepData}\n currentStep={tutorial.currentStep}\n stepCount={steps.length}\n progress={tutorial.progress}\n isLastStep={tutorial.isLastStep}\n allowSkip={allowSkip}\n showProgress={showProgress}\n requiresActionBeforeNext={requiresActionBeforeNext}\n onNext={tutorial.handleNext}\n onPrev={tutorial.handlePrev}\n onSkip={tutorial.handleSkip}\n onRestart={tutorial.handleRestart}\n />\n </TooltipContainer>\n </Fade>\n);\n\nexport const TutorialOverlay: FC<TutorialOverlayProps> = (componentProps) => {\n const {\n copy,\n steps,\n onComplete,\n onSkip,\n onStepComplete,\n initialStep,\n active,\n showProgress,\n allowKeyboardNavigation,\n allowClickThrough,\n variant,\n allowSkip,\n animated } = resolveProps(componentProps);\n\n const tutorial = useTutorialOverlay({\n steps,\n initialStep,\n active,\n allowKeyboardNavigation,\n onComplete,\n onSkip,\n onStepComplete });\n const { currentStepData, isLastStep, isVisible, targetBounds, progress } = tutorial;\n\n const requiresActionBeforeNext = Boolean(currentStepData?.requiresAction) && !isLastStep;\n\n if (!active || !currentStepData) return null;\n\n // Handle empty steps array\n if (steps.length === 0) return null;\n\n return (\n <Portal>\n <Overlay allowClickThrough={allowClickThrough} data-testid=\"tutorial-overlay\">\n {showProgress && <ProgressBar variant=\"determinate\" value={progress} />}\n\n <TutorialLayers\n variant={variant}\n targetBounds={targetBounds}\n isVisible={isVisible}\n spotlightPadding={currentStepData.spotlightPadding}\n />\n\n <TutorialTooltip\n copy={copy}\n tutorial={{ ...tutorial, currentStepData }}\n steps={steps}\n allowSkip={allowSkip}\n showProgress={showProgress}\n animated={animated}\n requiresActionBeforeNext={requiresActionBeforeNext}\n />\n </Overlay>\n </Portal>\n );\n};\n\n// Export default\nexport default TutorialOverlay;\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { calculateTooltipPosition, getElementBounds } from './TutorialOverlay.geometry';\nimport type { TutorialOverlayProps } from './TutorialOverlay.types';\n\n// Tracks the highlighted element's box, re-measuring on resize and scroll. Scroll\n// is captured (third argument true) so it fires for any scrolling ancestor, not\n// just the window.\nconst useTargetBounds = ({\n active,\n target,\n}: {\n active: boolean;\n target?: string;\n}) => {\n const [targetBounds, setTargetBounds] = useState<globalThis.DOMRect | null>(null);\n const [isVisible, setIsVisible] = useState(false);\n\n useEffect(() => {\n if (!active || !target) return;\n\n const updateBounds = () => {\n const bounds = getElementBounds(target);\n setTargetBounds(bounds);\n setIsVisible(Boolean(bounds));\n };\n\n updateBounds();\n\n window.addEventListener('resize', updateBounds);\n window.addEventListener('scroll', updateBounds, true);\n\n return () => {\n window.removeEventListener('resize', updateBounds);\n window.removeEventListener('scroll', updateBounds, true);\n };\n }, [active, target]);\n\n return { targetBounds, isVisible };\n};\n\n// Places the tooltip against the measured target once both boxes are known.\nconst useTooltipPlacement = ({\n targetBounds,\n isVisible,\n preferredPosition,\n}: {\n targetBounds: globalThis.DOMRect | null;\n isVisible: boolean;\n preferredPosition?: string;\n}) => {\n const tooltipRef = useRef<HTMLDivElement>(null);\n const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 });\n const [actualPlacement, setActualPlacement] = useState<string>('bottom');\n\n useEffect(() => {\n if (!targetBounds || !tooltipRef.current || !isVisible) return;\n\n const { position, placement } = calculateTooltipPosition(\n targetBounds,\n tooltipRef.current.getBoundingClientRect(),\n preferredPosition || 'auto',\n );\n\n setTooltipPosition(position);\n setActualPlacement(placement);\n }, [targetBounds, isVisible, preferredPosition]);\n\n return { tooltipRef, tooltipPosition, actualPlacement };\n};\n\n// Arrow keys step through the tour, Escape skips it.\nconst useTutorialKeyboard = ({\n enabled,\n onNext,\n onPrev,\n onSkip,\n}: {\n enabled: boolean;\n onNext: () => void;\n onPrev: () => void;\n onSkip: () => void;\n}) => {\n useEffect(() => {\n if (!enabled) return;\n\n const handleKeyPress = (e: globalThis.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowLeft':\n onPrev();\n break;\n case 'ArrowRight':\n onNext();\n break;\n case 'Escape':\n onSkip();\n break;\n }\n };\n\n window.addEventListener('keydown', handleKeyPress);\n return () => window.removeEventListener('keydown', handleKeyPress);\n }, [enabled, onNext, onPrev, onSkip]);\n};\n\nexport const useTutorialOverlay = ({\n steps,\n initialStep,\n active,\n allowKeyboardNavigation,\n onComplete,\n onSkip,\n onStepComplete,\n}: {\n steps: TutorialOverlayProps['steps'];\n initialStep: number;\n active: boolean;\n allowKeyboardNavigation: boolean;\n onComplete?: () => void;\n onSkip?: () => void;\n onStepComplete?: (stepId: string) => void;\n}) => {\n const [currentStep, setCurrentStep] = useState(initialStep);\n\n const currentStepData = steps[currentStep];\n const isLastStep = currentStep === steps.length - 1;\n\n const { targetBounds, isVisible } = useTargetBounds({\n active,\n target: currentStepData?.target,\n });\n\n const { tooltipRef, tooltipPosition, actualPlacement } = useTooltipPlacement({\n targetBounds,\n isVisible,\n preferredPosition: currentStepData?.position,\n });\n\n const handleNext = useCallback(() => {\n const currentStepId = steps[currentStep]?.id;\n if (currentStepId) onStepComplete?.(currentStepId);\n\n if (currentStep < steps.length - 1) {\n setCurrentStep(currentStep + 1);\n return;\n }\n\n onComplete?.();\n }, [currentStep, steps, onComplete, onStepComplete]);\n\n const handlePrev = useCallback(() => {\n setCurrentStep((step) => Math.max(step - 1, 0));\n }, []);\n\n const handleSkip = useCallback(() => {\n onSkip?.();\n }, [onSkip]);\n\n const handleRestart = useCallback(() => {\n setCurrentStep(0);\n }, []);\n\n useTutorialKeyboard({\n enabled: allowKeyboardNavigation && active,\n onNext: handleNext,\n onPrev: handlePrev,\n onSkip: handleSkip,\n });\n\n return {\n currentStep,\n currentStepData,\n isLastStep,\n isVisible,\n targetBounds,\n tooltipRef,\n tooltipPosition,\n actualPlacement,\n progress: ((currentStep + 1) / steps.length) * 100,\n handleNext,\n handlePrev,\n handleSkip,\n handleRestart,\n };\n};\n","const DEFAULT_PADDING = 16;\n\nexport const getElementBounds = (selector: string): globalThis.DOMRect | null =>\n document.querySelector(selector)?.getBoundingClientRect() ?? null;\n\n// With placement 'auto', the side with the most free space around the target\n// wins.\nconst pickPlacement = (targetBounds: globalThis.DOMRect): string => {\n const spaces = {\n top: targetBounds.top,\n bottom: window.innerHeight - targetBounds.bottom,\n left: targetBounds.left,\n right: window.innerWidth - targetBounds.right,\n };\n\n return Object.entries(spaces).reduce((a, b) => (b[1] > a[1] ? b : a))[0];\n};\n\nconst offsetFor = (\n placement: string,\n targetBounds: globalThis.DOMRect,\n tooltipBounds: globalThis.DOMRect,\n padding: number,\n): { top: number; left: number } => {\n const centredLeft = targetBounds.left + targetBounds.width / 2 - tooltipBounds.width / 2;\n const centredTop = targetBounds.top + targetBounds.height / 2 - tooltipBounds.height / 2;\n\n switch (placement) {\n case 'top':\n return { top: targetBounds.top - tooltipBounds.height - padding, left: centredLeft };\n case 'bottom':\n return { top: targetBounds.bottom + padding, left: centredLeft };\n case 'left':\n return { top: centredTop, left: targetBounds.left - tooltipBounds.width - padding };\n case 'right':\n return { top: centredTop, left: targetBounds.right + padding };\n default:\n return { top: 0, left: 0 };\n }\n};\n\n// Keeps the tooltip fully on screen, whatever the chosen side works out to.\nconst clampToViewport = (\n position: { top: number; left: number },\n tooltipBounds: globalThis.DOMRect,\n padding: number,\n) => ({\n top: Math.max(padding, Math.min(position.top, window.innerHeight - tooltipBounds.height - padding)),\n left: Math.max(padding, Math.min(position.left, window.innerWidth - tooltipBounds.width - padding)),\n});\n\nexport const calculateTooltipPosition = (\n targetBounds: globalThis.DOMRect,\n tooltipBounds: globalThis.DOMRect,\n placement: string,\n padding = DEFAULT_PADDING,\n) => {\n const finalPlacement = placement === 'auto' ? pickPlacement(targetBounds) : placement;\n const offset = offsetFor(finalPlacement, targetBounds, tooltipBounds, padding);\n\n return {\n position: clampToViewport(offset, tooltipBounds, padding),\n placement: finalPlacement,\n };\n};\n","import CompleteIcon from '@mui/icons-material/CheckCircle';\nimport CloseIcon from '@mui/icons-material/Close';\nimport PrevIcon from '@mui/icons-material/NavigateBefore';\nimport NextIcon from '@mui/icons-material/NavigateNext';\nimport RestartIcon from '@mui/icons-material/Refresh';\nimport {\n alpha,\n Box,\n Button,\n IconButton,\n Stack,\n styled,\n Typography } from '@mui/material';\nimport React, { } from 'react';\n\nimport type { TutorialOverlayProps } from './TutorialOverlay.types';\nimport type { TutorialCopy } from '../../../copy';\n\n// Animation keyframes\n\nconst StepIndicator = styled(Box)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(1),\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(2) }));\n\n\nconst StepDot = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'active' && prop !== 'completed' })<{ active?: boolean; completed?: boolean }>(({ theme, active, completed }) => ({\n width: 8,\n height: 8,\n borderRadius: '50%',\n background: completed\n ? theme.palette.success.main\n : active\n ? theme.palette.primary.main\n : alpha(theme.palette.text.primary, 0.3),\n transition: 'all 0.3s ease',\n ...(active && {\n transform: 'scale(1.5)' }) }));\n\n// Title, body copy, the step dots and the navigation row.\n\n// The step's controls: skip/restart on the left, previous/next on the right.\nconst TutorialStepNav: React.FC<{\n copy: TutorialCopy;\n currentStep: number;\n stepCount: number;\n isLastStep: boolean;\n allowSkip: boolean;\n requiresActionBeforeNext?: boolean;\n onNext: () => void;\n onPrev: () => void;\n onSkip: () => void;\n onRestart: () => void;\n}> = ({\n copy,\n currentStep,\n stepCount,\n isLastStep,\n allowSkip,\n requiresActionBeforeNext,\n onNext,\n onPrev,\n onSkip,\n onRestart }) => (\n <Stack\n direction=\"row\"\n spacing={1}\n justifyContent=\"space-between\"\n data-testid=\"tutorial-navigation\"\n >\n <Stack direction=\"row\" spacing={1}>\n {allowSkip && (\n <Button size=\"small\" onClick={onSkip} variant=\"text\">\n {copy.skip}\n </Button>\n )}\n {stepCount > 1 && (\n <IconButton\n size=\"small\"\n onClick={onRestart}\n disabled={currentStep === 0}\n title={copy.restart}\n >\n <RestartIcon fontSize=\"small\" />\n </IconButton>\n )}\n </Stack>\n\n <Stack direction=\"row\" spacing={1}>\n {stepCount > 1 && currentStep > 0 && (\n <Button\n size=\"small\"\n startIcon={<PrevIcon />}\n onClick={onPrev}\n disabled={currentStep === 0}\n data-testid=\"tutorial-prev-button\"\n >\n {copy.previous}\n </Button>\n )}\n\n {!isLastStep ? (\n <Button\n variant=\"contained\"\n size=\"small\"\n endIcon={<NextIcon />}\n onClick={onNext}\n disabled={requiresActionBeforeNext}\n title={requiresActionBeforeNext ? 'Complete the required action first' : ''}\n data-testid=\"tutorial-next-button\"\n >\n {copy.next}\n </Button>\n ) : (\n <Button\n variant=\"contained\"\n size=\"small\"\n endIcon={<CompleteIcon />}\n onClick={onNext}\n sx={{\n background: 'linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%)' }}\n data-testid=\"tutorial-finish-button\"\n >\n {stepCount === 1 ? 'Complete' : 'Finish'}\n </Button>\n )}\n </Stack>\n </Stack>\n);\n\nconst StepDots: React.FC<{ currentStep: number; stepCount: number }> = ({\n currentStep,\n stepCount }) => (\n <StepIndicator data-testid=\"tutorial-step-indicators\">\n {Array.from({ length: stepCount }).map((_, index) => (\n <StepDot\n key={index}\n active={index === currentStep}\n completed={index < currentStep}\n data-testid={`tutorial-indicator-${index}`}\n />\n ))}\n </StepIndicator>\n);\n\n// Title, and the close button when skipping is allowed.\nconst TutorialStepHeader: React.FC<{\n title: React.ReactNode;\n currentStep: number;\n allowSkip: boolean;\n onSkip: () => void;\n}> = ({ title, currentStep, allowSkip, onSkip }) => (\n <Box\n sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}\n >\n <Typography\n id={`tutorial-title-${currentStep}`}\n variant=\"h6\"\n fontWeight=\"bold\"\n sx={{ flex: 1 }}\n data-testid=\"tutorial-step-title\"\n >\n {title}\n </Typography>\n {allowSkip && (\n <IconButton\n size=\"small\"\n onClick={onSkip}\n sx={{ ml: 1, mt: -1, mr: -1 }}\n data-testid=\"tutorial-close-button\"\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n )}\n </Box>\n);\n\nexport const TutorialStepBody: React.FC<{\n copy: TutorialCopy;\n step: TutorialOverlayProps['steps'][number];\n currentStep: number;\n stepCount: number;\n progress: number;\n isLastStep: boolean;\n allowSkip: boolean;\n showProgress: boolean;\n requiresActionBeforeNext?: boolean;\n onNext: () => void;\n onPrev: () => void;\n onSkip: () => void;\n onRestart: () => void;\n}> = ({\n copy,\n step,\n currentStep,\n stepCount,\n progress: _progress,\n isLastStep,\n allowSkip,\n showProgress,\n requiresActionBeforeNext,\n onNext,\n onPrev,\n onSkip,\n onRestart }) => (\n <Stack spacing={2}>\n <TutorialStepHeader\n title={step.title}\n currentStep={currentStep}\n allowSkip={allowSkip}\n onSkip={onSkip}\n />\n\n <Typography\n id={`tutorial-content-${currentStep}`}\n variant=\"body2\"\n color=\"text.secondary\"\n data-testid=\"tutorial-step-content\"\n >\n {step.content}\n </Typography>\n\n {showProgress && (\n <Typography variant=\"caption\" color=\"text.secondary\" align=\"center\">\n {currentStep + 1} of {stepCount}\n </Typography>\n )}\n\n {step.action && (\n <Button\n variant=\"contained\"\n size=\"small\"\n onClick={step.action.onClick}\n sx={{\n background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n color: 'white' }}\n >\n {step.action.label}\n </Button>\n )}\n\n <StepDots currentStep={currentStep} stepCount={stepCount} />\n\n <TutorialStepNav\n copy={copy}\n currentStep={currentStep}\n stepCount={stepCount}\n isLastStep={isLastStep}\n allowSkip={allowSkip}\n requiresActionBeforeNext={requiresActionBeforeNext}\n onNext={onNext}\n onPrev={onPrev}\n onSkip={onSkip}\n onRestart={onRestart}\n />\n </Stack>\n);\n\n// Main component\n"],"mappings":"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","names":["alpha","Box","styled","jsx","jsxs","styled","Box","alpha"]}
|
|
@@ -614,22 +614,20 @@ var AddressTextField = ({ addressVariant, ...props }) => addressVariant === "gla
|
|
|
614
614
|
|
|
615
615
|
// src/components/form/AddressAutocomplete/AddressInputField.tsx
|
|
616
616
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
617
|
-
var CurrentLocationButton = ({
|
|
618
|
-
disabled,
|
|
619
|
-
onClick
|
|
620
|
-
}) => /* @__PURE__ */ jsx2(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx2(
|
|
617
|
+
var CurrentLocationButton = ({ disabled, onClick, currentLocationLabel }) => /* @__PURE__ */ jsx2(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx2(
|
|
621
618
|
IconButton,
|
|
622
619
|
{
|
|
623
620
|
edge: "end",
|
|
624
621
|
onClick,
|
|
625
622
|
size: "small",
|
|
626
|
-
title:
|
|
623
|
+
title: currentLocationLabel,
|
|
627
624
|
disabled,
|
|
628
625
|
"data-testid": "address-current-location-button",
|
|
629
626
|
children: /* @__PURE__ */ jsx2(CurrentLocationIcon, {})
|
|
630
627
|
}
|
|
631
628
|
) });
|
|
632
629
|
var AddressInputField = ({
|
|
630
|
+
copy,
|
|
633
631
|
params,
|
|
634
632
|
addressVariant,
|
|
635
633
|
label,
|
|
@@ -657,7 +655,14 @@ var AddressInputField = ({
|
|
|
657
655
|
startAdornment: icon && /* @__PURE__ */ jsx2(InputAdornment, { position: "start", children: icon }),
|
|
658
656
|
endAdornment: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
659
657
|
loading && /* @__PURE__ */ jsx2(CircularProgress, { color: "inherit", size: 20, "data-testid": "address-loading" }),
|
|
660
|
-
showCurrentLocation && /* @__PURE__ */ jsx2(
|
|
658
|
+
showCurrentLocation && /* @__PURE__ */ jsx2(
|
|
659
|
+
CurrentLocationButton,
|
|
660
|
+
{
|
|
661
|
+
disabled,
|
|
662
|
+
onClick: onGetCurrentLocation,
|
|
663
|
+
currentLocationLabel: copy.useCurrentLocation
|
|
664
|
+
}
|
|
665
|
+
),
|
|
661
666
|
params.InputProps.endAdornment
|
|
662
667
|
] })
|
|
663
668
|
},
|
|
@@ -747,6 +752,7 @@ var AddressSuggestionsPaper = (props) => {
|
|
|
747
752
|
// src/components/form/AddressAutocomplete/AddressAutocompleteField.tsx
|
|
748
753
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
749
754
|
var AddressAutocompleteField = ({
|
|
755
|
+
copy,
|
|
750
756
|
variant,
|
|
751
757
|
label,
|
|
752
758
|
placeholder,
|
|
@@ -793,6 +799,7 @@ var AddressAutocompleteField = ({
|
|
|
793
799
|
renderInput: (params) => /* @__PURE__ */ jsx5(
|
|
794
800
|
AddressInputField,
|
|
795
801
|
{
|
|
802
|
+
copy,
|
|
796
803
|
params,
|
|
797
804
|
addressVariant: variant,
|
|
798
805
|
label: floating ? void 0 : label,
|
|
@@ -816,6 +823,7 @@ var AddressAutocompleteField = ({
|
|
|
816
823
|
import { Alert as Alert2, Box as Box3, CircularProgress as CircularProgress2, InputAdornment as InputAdornment2 } from "@mui/material";
|
|
817
824
|
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
818
825
|
var AddressFallbackField = ({
|
|
826
|
+
copy,
|
|
819
827
|
variant,
|
|
820
828
|
label,
|
|
821
829
|
placeholder,
|
|
@@ -831,7 +839,7 @@ var AddressFallbackField = ({
|
|
|
831
839
|
{
|
|
832
840
|
addressVariant: variant,
|
|
833
841
|
label: floating ? void 0 : label,
|
|
834
|
-
placeholder:
|
|
842
|
+
placeholder: copy.loadingMaps,
|
|
835
843
|
disabled: true,
|
|
836
844
|
fullWidth,
|
|
837
845
|
InputProps: {
|
|
@@ -855,7 +863,7 @@ var AddressFallbackField = ({
|
|
|
855
863
|
InputProps: { startAdornment }
|
|
856
864
|
}
|
|
857
865
|
),
|
|
858
|
-
/* @__PURE__ */ jsx6(Alert2, { severity: "error", sx: { mt: 1 }, children:
|
|
866
|
+
/* @__PURE__ */ jsx6(Alert2, { severity: "error", sx: { mt: 1 }, children: copy.mapsLoadFailed })
|
|
859
867
|
] });
|
|
860
868
|
};
|
|
861
869
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/form/AddressAutocomplete/AddressAutocomplete.tsx","../../src/components/form/AddressAutocomplete/AddressAutocomplete.helpers.ts","../../src/components/form/AddressAutocomplete/AddressAutocomplete.hooks.ts","../../src/components/form/AddressAutocomplete/useAddressPredictions.ts","../../src/components/form/AddressAutocomplete/mockPlaces.ts","../../src/components/form/AddressAutocomplete/useAddressSelection.ts","../../src/components/form/AddressAutocomplete/AddressAutocomplete.mapper.ts","../../src/components/form/AddressAutocomplete/useCurrentLocation.ts","../../src/components/form/AddressAutocomplete/useGoogleMapsAPI.ts","../../src/components/form/AddressAutocomplete/AddressAutocompleteField.tsx","../../src/components/form/AddressAutocomplete/AddressInputField.tsx","../../src/components/form/AddressAutocomplete/AddressTextField.tsx","../../src/components/form/AddressAutocomplete/AddressOption.tsx","../../src/components/form/AddressAutocomplete/AddressSuggestionsPaper.tsx","../../src/components/form/AddressAutocomplete/AddressFallbackField.tsx"],"sourcesContent":["import LocationIcon from '@mui/icons-material/LocationOn';\nimport type { FC } from 'react';\nimport React from 'react';\n\nimport { resolveAddressProps } from './AddressAutocomplete.helpers';\nimport { useAddressAutocomplete } from './AddressAutocomplete.hooks';\nimport type { AddressAutocompleteProps } from './AddressAutocomplete.types';\nimport { AddressAutocompleteField } from './AddressAutocompleteField';\nimport { AddressFallbackField } from './AddressFallbackField';\n\nexport const AddressAutocomplete: FC<AddressAutocompleteProps> = (componentProps) => {\n const resolved = resolveAddressProps(componentProps);\n const { defaultValue, googleMapsApiKey, restrictions, onSelect, icon = <LocationIcon /> } =\n resolved;\n const fieldProps = { ...resolved, icon };\n\n const state = useAddressAutocomplete({\n defaultValue,\n googleMapsApiKey,\n restrictions,\n onSelect,\n });\n\n // Until the API answers there is nothing to autocomplete against, so the field\n // stands in disabled — spinning, or explaining why it never loaded.\n if (!state.isLoaded || state.mapsError) {\n return <AddressFallbackField {...fieldProps} mapsError={state.mapsError} />;\n }\n\n return <AddressAutocompleteField {...fieldProps} {...state} />;\n};\n\nexport default AddressAutocomplete;\n","import type { AddressAutocompleteProps, AddressOptionValue } from './AddressAutocomplete.types';\n\n// Below this the field clears its options rather than querying Places.\nexport const MIN_QUERY_LENGTH = 2;\n\ntype DefaultedKeys =\n | 'variant'\n | 'label'\n | 'placeholder'\n | 'floating'\n | 'error'\n | 'disabled'\n | 'required'\n | 'fullWidth'\n | 'defaultValue'\n | 'getCurrentLocation';\n\nexport type ResolvedAddressProps = AddressAutocompleteProps &\n Required<Pick<AddressAutocompleteProps, DefaultedKeys>>;\n\nconst ADDRESS_AUTOCOMPLETE_DEFAULTS: Pick<AddressAutocompleteProps, DefaultedKeys> = {\n variant: 'outlined',\n label: 'Address',\n placeholder: 'Enter an address',\n floating: false,\n error: false,\n disabled: false,\n required: false,\n fullWidth: true,\n defaultValue: '',\n getCurrentLocation: false,\n};\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}` still\n// falls back to the default exactly as a destructuring default would.\nconst definedProps = (props: AddressAutocompleteProps): Partial<AddressAutocompleteProps> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<AddressAutocompleteProps>;\n\n// Applied as a merge rather than destructuring defaults, which would otherwise\n// put ten branches into the component's own complexity budget.\nexport const resolveAddressProps = (props: AddressAutocompleteProps): ResolvedAddressProps =>\n ({ ...ADDRESS_AUTOCOMPLETE_DEFAULTS, ...definedProps(props) }) as ResolvedAddressProps;\n\nexport const addressOptionLabel = (option: AddressOptionValue): string => {\n if (typeof option === 'string') return option;\n return option.description || '';\n};\n\n// A string only ever equals the same string, so a mixed pair is never a match.\nexport const isSameAddressOption = (\n option: AddressOptionValue,\n value: AddressOptionValue,\n): boolean => {\n if (typeof option === 'string' || typeof value === 'string') return option === value;\n return option.place_id === value.place_id;\n};\n","import type React from 'react';\nimport { useCallback, useState } from 'react';\n\nimport type {\n AddressAutocompleteProps,\n AddressDetails,\n AddressOptionValue,\n} from './AddressAutocomplete.types';\nimport { useAddressPredictions } from './useAddressPredictions';\nimport { useAddressSelection } from './useAddressSelection';\nimport { useCurrentLocation } from './useCurrentLocation';\nimport { useGoogleMapsAPI } from './useGoogleMapsAPI';\n\nexport interface AddressAutocompleteState {\n inputValue: string;\n options: AddressOptionValue[];\n loading: boolean;\n apiError: string | null;\n mapsError: string | null;\n isLoaded: boolean;\n handleInputChange: (event: React.SyntheticEvent, value: string) => void;\n handleSelect: (event: React.SyntheticEvent, value: AddressOptionValue | null) => void;\n handleGetCurrentLocation: () => void;\n}\n\n// Owns the state the three Places concerns share — the field's text, whether a\n// request is in flight, and the last error — then hands each concern the slice it\n// writes to.\nexport const useAddressAutocomplete = ({\n defaultValue,\n googleMapsApiKey,\n restrictions,\n onSelect,\n}: {\n defaultValue: string;\n googleMapsApiKey: string;\n restrictions: AddressAutocompleteProps['restrictions'];\n onSelect: (address: AddressDetails) => void;\n}): AddressAutocompleteState => {\n const [inputValue, setInputValue] = useState(defaultValue);\n const [loading, setLoading] = useState(false);\n const [apiError, setApiError] = useState<string | null>(null);\n\n const { isLoaded, error: mapsError, services, useMockData } = useGoogleMapsAPI(googleMapsApiKey);\n\n // A resolved address both notifies the caller and becomes the field's text.\n const applyAddress = useCallback(\n (address: AddressDetails) => {\n onSelect(address);\n setInputValue(address.formatted);\n },\n [onSelect],\n );\n\n const { options, handleInputChange } = useAddressPredictions({\n isLoaded,\n services,\n restrictions,\n useMockData,\n setInputValue,\n setLoading,\n setApiError,\n });\n\n const handleSelect = useAddressSelection({\n services,\n useMockData,\n setLoading,\n setApiError,\n onSelect,\n applyAddress,\n });\n\n const handleGetCurrentLocation = useCurrentLocation({\n services,\n useMockData,\n setLoading,\n setApiError,\n applyAddress,\n });\n\n return {\n inputValue,\n options,\n loading,\n apiError,\n mapsError,\n isLoaded,\n handleInputChange,\n handleSelect,\n handleGetCurrentLocation,\n };\n};\n","import type React from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { MIN_QUERY_LENGTH } from './AddressAutocomplete.helpers';\nimport type { AddressAutocompleteProps, AddressOptionValue } from './AddressAutocomplete.types';\nimport { searchMockAddresses } from './mockPlaces';\nimport type { GoogleMapsService } from './useGoogleMapsAPI';\n\nconst DEBOUNCE_MS = 300;\n// Long enough to exercise the loading state, short enough not to slow tests down.\nconst MOCK_PREDICTION_DELAY_MS = 100;\n\ntype Restrictions = AddressAutocompleteProps['restrictions'];\n\ninterface PredictionSink {\n setOptions: (options: AddressOptionValue[]) => void;\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n}\n\nconst predictionRequest = (\n input: string,\n restrictions: Restrictions,\n): google.maps.places.AutocompletionRequest => ({\n input: input.trim(),\n componentRestrictions: restrictions?.country ? { country: restrictions.country } : undefined,\n types: restrictions?.types || [],\n});\n\nconst fetchMockPredictions = (input: string, sink: PredictionSink) => {\n window.setTimeout(() => {\n sink.setLoading(false);\n sink.setOptions(searchMockAddresses(input));\n sink.setApiError(null);\n }, MOCK_PREDICTION_DELAY_MS);\n};\n\nconst fetchLivePredictions = (\n service: google.maps.places.AutocompleteService,\n input: string,\n restrictions: Restrictions,\n sink: PredictionSink,\n) => {\n service.getPlacePredictions(predictionRequest(input, restrictions), (predictions, status) => {\n sink.setLoading(false);\n\n if (status === google.maps.places.PlacesServiceStatus.OK && predictions) {\n sink.setOptions(predictions);\n sink.setApiError(null);\n return;\n }\n\n // No matches is a normal outcome, not something to complain about.\n sink.setOptions([]);\n sink.setApiError(\n status === google.maps.places.PlacesServiceStatus.ZERO_RESULTS\n ? null\n : 'Failed to fetch address suggestions',\n );\n });\n};\n\nexport const useAddressPredictions = ({\n isLoaded,\n services,\n restrictions,\n useMockData,\n setInputValue,\n setLoading,\n setApiError,\n}: {\n isLoaded: boolean;\n services: GoogleMapsService;\n restrictions: Restrictions;\n useMockData: boolean;\n setInputValue: (value: string) => void;\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n}) => {\n const [options, setOptions] = useState<AddressOptionValue[]>([]);\n const debounceTimeoutRef = useRef<number | undefined>(undefined);\n\n const sink = useMemo<PredictionSink>(\n () => ({ setOptions, setLoading, setApiError }),\n [setLoading, setApiError],\n );\n\n const debouncedAutocomplete = useCallback(\n (input: string) => {\n window.clearTimeout(debounceTimeoutRef.current);\n\n debounceTimeoutRef.current = window.setTimeout(() => {\n if (!input.trim() || !isLoaded) {\n setOptions([]);\n setLoading(false);\n return;\n }\n\n if (useMockData) {\n fetchMockPredictions(input, sink);\n return;\n }\n\n if (!services.autocompleteService) {\n setOptions([]);\n setLoading(false);\n return;\n }\n\n fetchLivePredictions(services.autocompleteService, input, restrictions, sink);\n }, DEBOUNCE_MS);\n },\n [isLoaded, services, restrictions, useMockData, sink, setLoading],\n );\n\n useEffect(() => () => window.clearTimeout(debounceTimeoutRef.current), []);\n\n const handleInputChange = useCallback(\n (_event: React.SyntheticEvent, value: string) => {\n setInputValue(value);\n setApiError(null);\n\n if (value.length > MIN_QUERY_LENGTH) {\n setLoading(true);\n debouncedAutocomplete(value);\n return;\n }\n\n setOptions([]);\n setLoading(false);\n },\n [debouncedAutocomplete, setInputValue, setApiError, setLoading],\n );\n\n return { options, handleInputChange };\n};\n","export interface MockPrediction {\n place_id: string;\n description: string;\n structured_formatting: {\n main_text: string;\n secondary_text: string;\n };\n matched_substrings?: google.maps.places.PredictionSubstring[];\n terms?: google.maps.places.PredictionTerm[];\n types?: string[];\n}\n\n// Canned Places data so the component renders and is testable without a Google\n// Maps key.\nexport const MOCK_ADDRESSES: MockPrediction[] = [\n {\n place_id: 'mock_1',\n description: '123 Main Street, San Francisco, CA 94105, USA',\n structured_formatting: {\n main_text: '123 Main Street',\n secondary_text: 'San Francisco, CA 94105, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n {\n place_id: 'mock_2',\n description: '456 Oak Avenue, New York, NY 10001, USA',\n structured_formatting: {\n main_text: '456 Oak Avenue',\n secondary_text: 'New York, NY 10001, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n {\n place_id: 'mock_3',\n description: '789 Pine Boulevard, Los Angeles, CA 90001, USA',\n structured_formatting: {\n main_text: '789 Pine Boulevard',\n secondary_text: 'Los Angeles, CA 90001, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n {\n place_id: 'mock_4',\n description: '321 Elm Street, Chicago, IL 60601, USA',\n structured_formatting: {\n main_text: '321 Elm Street',\n secondary_text: 'Chicago, IL 60601, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n {\n place_id: 'mock_5',\n description: '654 Maple Drive, Austin, TX 78701, USA',\n structured_formatting: {\n main_text: '654 Maple Drive',\n secondary_text: 'Austin, TX 78701, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n];\n\ninterface MockPlaceDetails {\n formatted_address: string;\n address_components: Array<{\n long_name: string;\n types: string[];\n }>;\n geometry: {\n location: {\n lat: () => number;\n lng: () => number;\n };\n };\n}\n\nexport const MOCK_PLACE_DETAILS: Record<string, MockPlaceDetails> = {\n mock_1: {\n formatted_address: '123 Main Street, San Francisco, CA 94105, USA',\n address_components: [\n { long_name: '123', types: ['street_number'] },\n { long_name: 'Main Street', types: ['route'] },\n { long_name: 'San Francisco', types: ['locality'] },\n { long_name: 'California', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '94105', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 37.7749, lng: () => -122.4194 } },\n },\n mock_2: {\n formatted_address: '456 Oak Avenue, New York, NY 10001, USA',\n address_components: [\n { long_name: '456', types: ['street_number'] },\n { long_name: 'Oak Avenue', types: ['route'] },\n { long_name: 'New York', types: ['locality'] },\n { long_name: 'New York', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '10001', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 40.7128, lng: () => -74.0060 } },\n },\n mock_3: {\n formatted_address: '789 Pine Boulevard, Los Angeles, CA 90001, USA',\n address_components: [\n { long_name: '789', types: ['street_number'] },\n { long_name: 'Pine Boulevard', types: ['route'] },\n { long_name: 'Los Angeles', types: ['locality'] },\n { long_name: 'California', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '90001', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 34.0522, lng: () => -118.2437 } },\n },\n mock_4: {\n formatted_address: '321 Elm Street, Chicago, IL 60601, USA',\n address_components: [\n { long_name: '321', types: ['street_number'] },\n { long_name: 'Elm Street', types: ['route'] },\n { long_name: 'Chicago', types: ['locality'] },\n { long_name: 'Illinois', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '60601', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 41.8781, lng: () => -87.6298 } },\n },\n mock_5: {\n formatted_address: '654 Maple Drive, Austin, TX 78701, USA',\n address_components: [\n { long_name: '654', types: ['street_number'] },\n { long_name: 'Maple Drive', types: ['route'] },\n { long_name: 'Austin', types: ['locality'] },\n { long_name: 'Texas', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '78701', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 30.2672, lng: () => -97.7431 } },\n },\n mock_6: {\n formatted_address: '1000 Broadway, New York, NY 10001, USA',\n address_components: [\n { long_name: '1000', types: ['street_number'] },\n { long_name: 'Broadway', types: ['route'] },\n { long_name: 'New York', types: ['locality'] },\n { long_name: 'New York', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '10001', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 40.7589, lng: () => -73.9851 } },\n },\n mock_7: {\n formatted_address: '250 Market Street, San Francisco, CA 94102, USA',\n address_components: [\n { long_name: '250', types: ['street_number'] },\n { long_name: 'Market Street', types: ['route'] },\n { long_name: 'San Francisco', types: ['locality'] },\n { long_name: 'California', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '94102', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 37.7879, lng: () => -122.4075 } },\n },\n};\n\n// Every word has to appear somewhere in the address, which is roughly how Google\n// treats a multi-word query.\nconst matchesAllWords = (address: MockPrediction, searchTerm: string): boolean => {\n const description = address.description.toLowerCase();\n const mainText = address.structured_formatting.main_text.toLowerCase();\n const secondaryText = address.structured_formatting.secondary_text?.toLowerCase() || '';\n\n return searchTerm\n .split(' ')\n .every(\n (word) =>\n description.includes(word) || mainText.includes(word) || secondaryText.includes(word),\n );\n};\n\n// Addresses whose street line starts with the query come first; the rest sort\n// alphabetically.\nconst byRelevance =\n (searchTerm: string) =>\n (a: MockPrediction, b: MockPrediction): number => {\n const aMain = a.structured_formatting.main_text.toLowerCase();\n const bMain = b.structured_formatting.main_text.toLowerCase();\n\n if (aMain.startsWith(searchTerm) && !bMain.startsWith(searchTerm)) return -1;\n if (!aMain.startsWith(searchTerm) && bMain.startsWith(searchTerm)) return 1;\n return aMain.localeCompare(bMain);\n };\n\nexport const searchMockAddresses = (input: string): MockPrediction[] => {\n const searchTerm = input.toLowerCase().trim();\n\n return MOCK_ADDRESSES.filter((address) => matchesAllWords(address, searchTerm)).sort(\n byRelevance(searchTerm),\n );\n};\n","import type React from 'react';\nimport { useCallback } from 'react';\n\nimport { coordinatesOf, freeSoloAddress, toAddressDetails } from './AddressAutocomplete.mapper';\nimport type {\n AddressDetails,\n AddressOptionValue,\n AddressPrediction,\n} from './AddressAutocomplete.types';\nimport { MOCK_PLACE_DETAILS } from './mockPlaces';\nimport type { GoogleMapsService } from './useGoogleMapsAPI';\n\nconst MOCK_DETAILS_DELAY_MS = 50;\n\nconst PLACE_DETAIL_FIELDS = ['formatted_address', 'address_components', 'geometry'];\n\ninterface SelectionSink {\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n applyAddress: (address: AddressDetails) => void;\n}\n\nconst resolveMockPlace = (value: AddressPrediction, sink: SelectionSink) => {\n window.setTimeout(() => {\n sink.setLoading(false);\n\n const place = MOCK_PLACE_DETAILS[value.place_id];\n if (!place) {\n sink.setApiError('Address details not found');\n return;\n }\n\n sink.applyAddress(\n toAddressDetails({\n components: place.address_components,\n formatted: place.formatted_address || value.description,\n coordinates: coordinatesOf(place.geometry),\n }),\n );\n }, MOCK_DETAILS_DELAY_MS);\n};\n\nconst resolveLivePlace = (\n service: google.maps.places.PlacesService,\n value: AddressPrediction,\n sink: SelectionSink,\n) => {\n const request: google.maps.places.PlaceDetailsRequest = {\n placeId: value.place_id,\n fields: PLACE_DETAIL_FIELDS,\n };\n\n service.getDetails(request, (place, status) => {\n sink.setLoading(false);\n\n if (status !== google.maps.places.PlacesServiceStatus.OK || !place) {\n sink.setApiError('Failed to get address details');\n return;\n }\n\n sink.applyAddress(\n toAddressDetails({\n components: place.address_components ?? [],\n formatted: place.formatted_address || value.description,\n coordinates: coordinatesOf(place.geometry),\n }),\n );\n });\n};\n\nexport const useAddressSelection = ({\n services,\n useMockData,\n setLoading,\n setApiError,\n onSelect,\n applyAddress,\n}: {\n services: GoogleMapsService;\n useMockData: boolean;\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n onSelect: (address: AddressDetails) => void;\n applyAddress: (address: AddressDetails) => void;\n}) =>\n useCallback(\n (_event: React.SyntheticEvent, value: AddressOptionValue | null) => {\n // freeSolo text is reported as typed; there is no place to look up, and the\n // input already holds it.\n if (typeof value === 'string') {\n onSelect(freeSoloAddress(value));\n return;\n }\n\n if (!value) return;\n\n setLoading(true);\n const sink: SelectionSink = { setLoading, setApiError, applyAddress };\n\n if (useMockData && 'place_id' in value) {\n resolveMockPlace(value, sink);\n return;\n }\n\n if (!services.placesService) {\n setLoading(false);\n return;\n }\n\n resolveLivePlace(services.placesService, value, sink);\n },\n [services, useMockData, setLoading, setApiError, onSelect, applyAddress],\n );\n","import type { AddressDetails } from './AddressAutocomplete.types';\n\n// The shape shared by google.maps.GeocoderAddressComponent and the canned mock\n// components: enough to read a part out by type.\ninterface AddressComponentLike {\n long_name: string;\n types: string[];\n}\n\ninterface LatLngLike {\n lat: () => number;\n lng: () => number;\n}\n\n// Google reports address parts as an unordered list tagged by type, so every part\n// has to be looked up rather than indexed.\nconst componentReader =\n (components: readonly AddressComponentLike[]) =>\n (type: string): string =>\n components.find((component) => component.types.includes(type))?.long_name || '';\n\n// Places and Geocoder results both make the whole geometry chain optional.\nexport const coordinatesOf = (geometry?: { location?: LatLngLike }): AddressDetails['coordinates'] => ({\n lat: geometry?.location?.lat() || 0,\n lng: geometry?.location?.lng() || 0,\n});\n\n// The four ways an address can arrive — a mock or live prediction, a mock or live\n// reverse geocode — all land here, so they agree on how a place becomes an\n// AddressDetails.\nexport const toAddressDetails = ({\n components,\n formatted,\n coordinates,\n}: {\n components: readonly AddressComponentLike[];\n formatted: string;\n coordinates: AddressDetails['coordinates'];\n}): AddressDetails => {\n const read = componentReader(components);\n const street = `${read('street_number')} ${read('route')}`.trim();\n\n return {\n formatted,\n // A street number on its own is not an address; fall back to the route name.\n street: street || read('route'),\n city: read('locality') || read('administrative_area_level_2'),\n state: read('administrative_area_level_1'),\n country: read('country'),\n postalCode: read('postal_code'),\n coordinates,\n };\n};\n\n// freeSolo mode hands back whatever was typed, with no components to read.\nexport const freeSoloAddress = (value: string): AddressDetails =>\n toAddressDetails({ components: [], formatted: value, coordinates: { lat: 0, lng: 0 } });\n","import { useCallback } from 'react';\n\nimport { coordinatesOf, toAddressDetails } from './AddressAutocomplete.mapper';\nimport type { AddressDetails } from './AddressAutocomplete.types';\nimport { MOCK_ADDRESSES, MOCK_PLACE_DETAILS } from './mockPlaces';\nimport type { GoogleMapsService } from './useGoogleMapsAPI';\n\nconst MOCK_GEOLOCATION_DELAY_MS = 500;\n\nconst GEOLOCATION_OPTIONS: PositionOptions = {\n enableHighAccuracy: true,\n timeout: 10_000,\n maximumAge: 600_000, // 10 minutes\n};\n\ninterface LocationSink {\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n applyAddress: (address: AddressDetails) => void;\n}\n\n// Mock mode answers with the first canned address after a pause, so the button\n// behaves like a real geolocation round trip.\nconst resolveMockLocation = (sink: LocationSink) => {\n window.setTimeout(() => {\n sink.setLoading(false);\n\n const mockLocation = MOCK_ADDRESSES[0];\n if (!mockLocation) {\n sink.setApiError('No mock location available');\n return;\n }\n\n const mockDetails = MOCK_PLACE_DETAILS[mockLocation.place_id];\n if (!mockDetails) {\n sink.setApiError('Mock location details not found');\n return;\n }\n\n sink.applyAddress(\n toAddressDetails({\n components: mockDetails.address_components,\n formatted: mockDetails.formatted_address,\n coordinates: coordinatesOf(mockDetails.geometry),\n }),\n );\n }, MOCK_GEOLOCATION_DELAY_MS);\n};\n\nconst geocodePosition =\n (geocoder: google.maps.Geocoder, sink: LocationSink) => (position: GeolocationPosition) => {\n const { latitude, longitude } = position.coords;\n const location = new google.maps.LatLng(latitude, longitude);\n\n geocoder.geocode({ location }, (results, status) => {\n sink.setLoading(false);\n\n const place = status === 'OK' ? results?.[0] : undefined;\n if (!place) {\n sink.setApiError('Unable to retrieve address for current location');\n return;\n }\n\n sink.applyAddress(\n toAddressDetails({\n components: place.address_components,\n formatted: place.formatted_address,\n // The device's own fix is more precise than the geocoded place's.\n coordinates: { lat: latitude, lng: longitude },\n }),\n );\n });\n };\n\nexport const useCurrentLocation = ({\n services,\n useMockData,\n setLoading,\n setApiError,\n applyAddress,\n}: {\n services: GoogleMapsService;\n useMockData: boolean;\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n applyAddress: (address: AddressDetails) => void;\n}) =>\n useCallback(() => {\n if (!navigator.geolocation) {\n setApiError('Geolocation is not supported by this browser');\n return;\n }\n\n const sink: LocationSink = { setLoading, setApiError, applyAddress };\n\n if (useMockData) {\n setLoading(true);\n resolveMockLocation(sink);\n return;\n }\n\n if (!services.geocoder) {\n setApiError('Geocoding service not available');\n return;\n }\n\n setLoading(true);\n navigator.geolocation.getCurrentPosition(\n geocodePosition(services.geocoder, sink),\n () => {\n setLoading(false);\n setApiError('Unable to retrieve your location');\n },\n GEOLOCATION_OPTIONS,\n );\n }, [services, useMockData, setLoading, setApiError, applyAddress]);\n","import { useEffect, useRef, useState } from 'react';\n\nexport interface GoogleMapsService {\n autocompleteService: google.maps.places.AutocompleteService | null;\n placesService: google.maps.places.PlacesService | null;\n geocoder: google.maps.Geocoder | null;\n}\n\nexport const useGoogleMapsAPI = (apiKey: string) => {\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [useMockData, setUseMockData] = useState(false);\n const serviceRef = useRef<GoogleMapsService>({\n autocompleteService: null,\n placesService: null,\n geocoder: null,\n });\n\n useEffect(() => {\n // Use mock data for demo key or test environment\n if (!apiKey || apiKey === 'demo-key' || apiKey === 'test-key') {\n setUseMockData(true);\n setIsLoaded(true);\n setError(null);\n return;\n }\n\n // Check if Google Maps is already loaded\n if (window.google && window.google.maps && window.google.maps.places) {\n initializeServices();\n return;\n }\n\n // Load Google Maps API\n const script = document.createElement('script');\n script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`;\n script.async = true;\n script.defer = true;\n \n script.onload = () => {\n initializeServices();\n };\n \n script.onerror = () => {\n setError('Failed to load Google Maps API');\n };\n\n document.head.appendChild(script);\n\n return () => {\n // Cleanup script if component unmounts\n if (document.head.contains(script)) {\n document.head.removeChild(script);\n }\n };\n }, [apiKey]);\n\n const initializeServices = () => {\n try {\n if (window.google && window.google.maps && window.google.maps.places) {\n serviceRef.current = {\n autocompleteService: new window.google.maps.places.AutocompleteService(),\n placesService: new window.google.maps.places.PlacesService(document.createElement('div')),\n geocoder: new window.google.maps.Geocoder(),\n };\n setIsLoaded(true);\n setError(null);\n }\n } catch {\n setError('Failed to initialize Google Maps services');\n }\n };\n\n return { isLoaded, error, services: serviceRef.current, useMockData };\n};\n","import { Alert, Autocomplete, Box } from '@mui/material';\nimport type { FC } from 'react';\nimport React from 'react';\n\nimport {\n addressOptionLabel,\n isSameAddressOption,\n MIN_QUERY_LENGTH,\n type ResolvedAddressProps,\n} from './AddressAutocomplete.helpers';\nimport type { AddressAutocompleteState } from './AddressAutocomplete.hooks';\nimport { AddressInputField } from './AddressInputField';\nimport { AddressOption } from './AddressOption';\nimport { AddressSuggestionsPaper } from './AddressSuggestionsPaper';\n\nexport type AddressAutocompleteFieldProps = ResolvedAddressProps & AddressAutocompleteState;\n\n// The live field, rendered once Google Maps (or the mock stand-in) is ready.\nexport const AddressAutocompleteField: FC<AddressAutocompleteFieldProps> = ({\n variant,\n label,\n placeholder,\n icon,\n floating,\n error,\n helperText,\n disabled,\n required,\n fullWidth,\n getCurrentLocation,\n inputValue,\n options,\n loading,\n apiError,\n handleInputChange,\n handleSelect,\n handleGetCurrentLocation,\n}) => (\n <Box data-testid=\"address-autocomplete-container\">\n <Autocomplete\n freeSolo\n options={options}\n inputValue={inputValue}\n onInputChange={handleInputChange}\n onChange={handleSelect}\n loading={loading}\n disabled={disabled}\n fullWidth={fullWidth}\n getOptionLabel={addressOptionLabel}\n isOptionEqualToValue={isSameAddressOption}\n PaperComponent={AddressSuggestionsPaper}\n noOptionsText={\n inputValue.length <= MIN_QUERY_LENGTH ? 'Type at least 3 characters' : 'No addresses found'\n }\n renderOption={({ key, ...optionProps }, option, state) => (\n <AddressOption\n key={key}\n optionProps={optionProps}\n option={option}\n index={state.index}\n />\n )}\n renderInput={(params) => (\n <AddressInputField\n params={params}\n addressVariant={variant}\n label={floating ? undefined : label}\n placeholder={placeholder}\n icon={icon}\n error={error || !!apiError}\n helperText={apiError || helperText}\n required={required}\n disabled={disabled}\n loading={loading}\n showCurrentLocation={getCurrentLocation && !loading}\n onGetCurrentLocation={handleGetCurrentLocation}\n />\n )}\n />\n {apiError && (\n <Alert severity=\"warning\" sx={{ mt: 1 }}>\n {apiError}\n </Alert>\n )}\n </Box>\n);\n","import CurrentLocationIcon from '@mui/icons-material/MyLocation';\nimport type { AutocompleteRenderInputParams } from '@mui/material';\nimport { CircularProgress, IconButton, InputAdornment } from '@mui/material';\nimport type { FC, ReactNode } from 'react';\nimport React from 'react';\n\nimport type { AddressAutocompleteProps } from './AddressAutocomplete.types';\nimport { AddressTextField } from './AddressTextField';\n\nconst CurrentLocationButton: FC<{ disabled: boolean; onClick: () => void }> = ({\n disabled,\n onClick,\n}) => (\n <InputAdornment position=\"end\">\n <IconButton\n edge=\"end\"\n onClick={onClick}\n size=\"small\"\n title=\"Use current location\"\n disabled={disabled}\n data-testid=\"address-current-location-button\"\n >\n <CurrentLocationIcon />\n </IconButton>\n </InputAdornment>\n);\n\nexport interface AddressInputFieldProps {\n params: AutocompleteRenderInputParams;\n addressVariant: AddressAutocompleteProps['variant'];\n label?: string;\n placeholder?: string;\n icon?: ReactNode;\n error: boolean;\n helperText?: string;\n required: boolean;\n disabled: boolean;\n loading: boolean;\n showCurrentLocation: boolean;\n onGetCurrentLocation: () => void;\n}\n\nexport const AddressInputField: FC<AddressInputFieldProps> = ({\n params,\n addressVariant,\n label,\n placeholder,\n icon,\n error,\n helperText,\n required,\n disabled,\n loading,\n showCurrentLocation,\n onGetCurrentLocation,\n}) => (\n <AddressTextField\n {...params}\n addressVariant={addressVariant}\n label={label}\n placeholder={placeholder}\n error={error}\n helperText={helperText}\n required={required}\n InputProps={{\n ...params.InputProps,\n startAdornment: icon && <InputAdornment position=\"start\">{icon}</InputAdornment>,\n endAdornment: (\n <>\n {loading && <CircularProgress color=\"inherit\" size={20} data-testid=\"address-loading\" />}\n {showCurrentLocation && (\n <CurrentLocationButton disabled={disabled} onClick={onGetCurrentLocation} />\n )}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n inputProps={{ ...params.inputProps, 'data-testid': 'address-input' }}\n />\n);\n","import type { TextFieldProps } from '@mui/material';\nimport { alpha, styled, TextField } from '@mui/material';\nimport type { FC } from 'react';\nimport React from 'react';\n\nimport type { AddressAutocompleteProps } from './AddressAutocomplete.types';\n\n// Kept module-local on purpose: the inferred type of a styled() component cannot\n// be named across a module boundary here (TS2742), so the plain component below\n// is what the rest of the folder imports.\nconst GlassTextField = styled(TextField)(({ theme }) => ({\n '& .MuiOutlinedInput-root': {\n background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.8)} 0%, ${alpha(theme.palette.background.paper, 0.6)} 100%)`,\n backdropFilter: 'blur(10px)',\n WebkitBackdropFilter: 'blur(10px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n transition: theme.transitions.create(['border-color', 'box-shadow', 'background']),\n '&:hover': {\n background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha(theme.palette.background.paper, 0.7)} 100%)`,\n borderColor: theme.palette.primary.main,\n },\n '&.Mui-focused': {\n background: theme.palette.background.paper,\n boxShadow: `0 0 0 2px ${alpha(theme.palette.primary.main, 0.25)}`,\n },\n '& fieldset': {\n border: 'none',\n },\n },\n}));\n\nexport type AddressTextFieldProps = Omit<TextFieldProps, 'variant'> & {\n addressVariant: AddressAutocompleteProps['variant'];\n};\n\n// 'glass' is not a MUI variant: it renders the outlined field with the frosted\n// treatment on top.\nexport const AddressTextField: FC<AddressTextFieldProps> = ({ addressVariant, ...props }) =>\n addressVariant === 'glass' ? (\n <GlassTextField variant=\"outlined\" {...props} />\n ) : (\n <TextField variant={addressVariant} {...props} />\n );\n","import LocationIcon from '@mui/icons-material/LocationOn';\nimport { alpha, Box, styled } from '@mui/material';\nimport type { FC, HTMLAttributes } from 'react';\nimport React from 'react';\n\nimport type { AddressOptionValue } from './AddressAutocomplete.types';\n\n// Module-local: styled() components cannot be exported across a module boundary\n// here without tripping TS2742.\nconst SuggestionItem = styled(Box)(({ theme }) => ({\n padding: theme.spacing(1.5),\n display: 'flex',\n alignItems: 'flex-start',\n gap: theme.spacing(1.5),\n cursor: 'pointer',\n transition: theme.transitions.create(['background-color']),\n '&:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.08),\n },\n}));\n\nconst LocationIconWrapper = styled(Box)(({ theme }) => ({\n marginTop: theme.spacing(0.5),\n color: theme.palette.text.secondary,\n}));\n\nconst AddressText = styled(Box)(({ theme }) => ({\n flex: 1,\n '& .primary': {\n fontSize: '0.9rem',\n fontWeight: 500,\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(0.25),\n },\n '& .secondary': {\n fontSize: '0.8rem',\n color: theme.palette.text.secondary,\n },\n}));\n\n// Predictions carry the street line and the rest already split; freeSolo text has\n// to be split on the first comma to get the same two lines.\nconst optionText = (option: AddressOptionValue) => {\n if (typeof option === 'string') {\n return {\n testId: 'address-suggestion-text',\n primary: option.split(',')[0],\n secondary: option.split(',').slice(1).join(','),\n };\n }\n\n return {\n testId: 'address-prediction-text',\n primary: option.structured_formatting?.main_text || option.description?.split(',')[0],\n secondary:\n option.structured_formatting?.secondary_text ||\n option.description?.split(',').slice(1).join(','),\n };\n};\n\nexport interface AddressOptionProps {\n optionProps: HTMLAttributes<HTMLLIElement>;\n option: AddressOptionValue;\n index: number;\n}\n\nexport const AddressOption: FC<AddressOptionProps> = ({ optionProps, option, index }) => {\n const { testId, primary, secondary } = optionText(option);\n\n return (\n <li {...optionProps} data-testid={`address-suggestion-${index}`}>\n <SuggestionItem>\n <LocationIconWrapper>\n <LocationIcon fontSize=\"small\" />\n </LocationIconWrapper>\n <AddressText data-testid={testId}>\n <div className=\"primary\">{primary}</div>\n <div className=\"secondary\">{secondary}</div>\n </AddressText>\n </SuggestionItem>\n </li>\n );\n};\n","import type { PaperProps } from '@mui/material';\nimport { alpha, Paper, useTheme } from '@mui/material';\nimport type { FC } from 'react';\nimport React from 'react';\n\n// The dropdown surface, frosted to match the glass field.\nexport const AddressSuggestionsPaper: FC<PaperProps> = (props) => {\n const theme = useTheme();\n\n return (\n <Paper\n {...props}\n elevation={8}\n data-testid=\"address-suggestions-dropdown\"\n sx={{\n mt: 1,\n background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.98)} 0%, ${alpha(theme.palette.background.paper, 0.95)} 100%)`,\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n }}\n />\n );\n};\n","import { Alert, Box, CircularProgress, InputAdornment } from '@mui/material';\nimport type { FC, ReactNode } from 'react';\nimport React from 'react';\n\nimport type { AddressAutocompleteProps } from './AddressAutocomplete.types';\nimport { AddressTextField } from './AddressTextField';\n\nexport interface AddressFallbackFieldProps {\n variant: AddressAutocompleteProps['variant'];\n label?: string;\n placeholder?: string;\n icon?: ReactNode;\n floating: boolean;\n fullWidth: boolean;\n mapsError: string | null;\n}\n\n// Stands in for the Autocomplete before Google Maps is usable: a disabled field\n// that either spins or explains why it never loaded.\nexport const AddressFallbackField: FC<AddressFallbackFieldProps> = ({\n variant,\n label,\n placeholder,\n icon,\n floating,\n fullWidth,\n mapsError,\n}) => {\n const startAdornment = icon ? <InputAdornment position=\"start\">{icon}</InputAdornment> : undefined;\n\n if (!mapsError) {\n return (\n <AddressTextField\n addressVariant={variant}\n label={floating ? undefined : label}\n placeholder=\"Loading Google Maps...\"\n disabled\n fullWidth={fullWidth}\n InputProps={{\n startAdornment,\n endAdornment: <CircularProgress color=\"inherit\" size={20} />,\n }}\n />\n );\n }\n\n return (\n <Box>\n <AddressTextField\n addressVariant={variant}\n label={floating ? undefined : label}\n placeholder={placeholder}\n error\n disabled\n fullWidth={fullWidth}\n helperText={mapsError}\n InputProps={{ startAdornment }}\n />\n <Alert severity=\"error\" sx={{ mt: 1 }}>\n Google Maps API failed to load. Please check your API key and internet connection.\n </Alert>\n </Box>\n );\n};\n"],"mappings":"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","names":["LocationIcon","useCallback","useState","useCallback","useCallback","useCallback","useCallback","useEffect","useRef","useState","useState","useCallback","Box","jsx","alpha","styled","jsx","jsxs","alpha","jsx","jsx","jsxs","Box","Alert","Box","CircularProgress","InputAdornment","jsx","jsxs","InputAdornment","CircularProgress","Box","Alert","jsx","LocationIcon"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/form/AddressAutocomplete/AddressAutocomplete.tsx","../../src/components/form/AddressAutocomplete/AddressAutocomplete.helpers.ts","../../src/components/form/AddressAutocomplete/AddressAutocomplete.hooks.ts","../../src/components/form/AddressAutocomplete/useAddressPredictions.ts","../../src/components/form/AddressAutocomplete/mockPlaces.ts","../../src/components/form/AddressAutocomplete/useAddressSelection.ts","../../src/components/form/AddressAutocomplete/AddressAutocomplete.mapper.ts","../../src/components/form/AddressAutocomplete/useCurrentLocation.ts","../../src/components/form/AddressAutocomplete/useGoogleMapsAPI.ts","../../src/components/form/AddressAutocomplete/AddressAutocompleteField.tsx","../../src/components/form/AddressAutocomplete/AddressInputField.tsx","../../src/components/form/AddressAutocomplete/AddressTextField.tsx","../../src/components/form/AddressAutocomplete/AddressOption.tsx","../../src/components/form/AddressAutocomplete/AddressSuggestionsPaper.tsx","../../src/components/form/AddressAutocomplete/AddressFallbackField.tsx"],"sourcesContent":["import LocationIcon from '@mui/icons-material/LocationOn';\nimport type { FC } from 'react';\nimport React from 'react';\n\nimport { resolveAddressProps } from './AddressAutocomplete.helpers';\nimport { useAddressAutocomplete } from './AddressAutocomplete.hooks';\nimport type { AddressAutocompleteProps } from './AddressAutocomplete.types';\nimport { AddressAutocompleteField } from './AddressAutocompleteField';\nimport { AddressFallbackField } from './AddressFallbackField';\n\nexport const AddressAutocomplete: FC<AddressAutocompleteProps> = (componentProps) => {\n const resolved = resolveAddressProps(componentProps);\n const { defaultValue, googleMapsApiKey, restrictions, onSelect, icon = <LocationIcon /> } =\n resolved;\n const fieldProps = { ...resolved, icon };\n\n const state = useAddressAutocomplete({\n defaultValue,\n googleMapsApiKey,\n restrictions,\n onSelect,\n });\n\n // Until the API answers there is nothing to autocomplete against, so the field\n // stands in disabled — spinning, or explaining why it never loaded.\n if (!state.isLoaded || state.mapsError) {\n return <AddressFallbackField {...fieldProps} mapsError={state.mapsError} />;\n }\n\n return <AddressAutocompleteField {...fieldProps} {...state} />;\n};\n\nexport default AddressAutocomplete;\n","import type { AddressAutocompleteProps, AddressOptionValue } from './AddressAutocomplete.types';\n\n// Below this the field clears its options rather than querying Places.\nexport const MIN_QUERY_LENGTH = 2;\n\ntype DefaultedKeys =\n | 'variant'\n | 'label'\n | 'placeholder'\n | 'floating'\n | 'error'\n | 'disabled'\n | 'required'\n | 'fullWidth'\n | 'defaultValue'\n | 'getCurrentLocation';\n\nexport type ResolvedAddressProps = AddressAutocompleteProps &\n Required<Pick<AddressAutocompleteProps, DefaultedKeys>>;\n\nconst ADDRESS_AUTOCOMPLETE_DEFAULTS: Pick<AddressAutocompleteProps, DefaultedKeys> = {\n variant: 'outlined',\n label: 'Address',\n placeholder: 'Enter an address',\n floating: false,\n error: false,\n disabled: false,\n required: false,\n fullWidth: true,\n defaultValue: '',\n getCurrentLocation: false,\n};\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}` still\n// falls back to the default exactly as a destructuring default would.\nconst definedProps = (props: AddressAutocompleteProps): Partial<AddressAutocompleteProps> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<AddressAutocompleteProps>;\n\n// Applied as a merge rather than destructuring defaults, which would otherwise\n// put ten branches into the component's own complexity budget.\nexport const resolveAddressProps = (props: AddressAutocompleteProps): ResolvedAddressProps =>\n ({ ...ADDRESS_AUTOCOMPLETE_DEFAULTS, ...definedProps(props) }) as ResolvedAddressProps;\n\nexport const addressOptionLabel = (option: AddressOptionValue): string => {\n if (typeof option === 'string') return option;\n return option.description || '';\n};\n\n// A string only ever equals the same string, so a mixed pair is never a match.\nexport const isSameAddressOption = (\n option: AddressOptionValue,\n value: AddressOptionValue,\n): boolean => {\n if (typeof option === 'string' || typeof value === 'string') return option === value;\n return option.place_id === value.place_id;\n};\n","import type React from 'react';\nimport { useCallback, useState } from 'react';\n\nimport type {\n AddressAutocompleteProps,\n AddressDetails,\n AddressOptionValue,\n} from './AddressAutocomplete.types';\nimport { useAddressPredictions } from './useAddressPredictions';\nimport { useAddressSelection } from './useAddressSelection';\nimport { useCurrentLocation } from './useCurrentLocation';\nimport { useGoogleMapsAPI } from './useGoogleMapsAPI';\n\nexport interface AddressAutocompleteState {\n inputValue: string;\n options: AddressOptionValue[];\n loading: boolean;\n apiError: string | null;\n mapsError: string | null;\n isLoaded: boolean;\n handleInputChange: (event: React.SyntheticEvent, value: string) => void;\n handleSelect: (event: React.SyntheticEvent, value: AddressOptionValue | null) => void;\n handleGetCurrentLocation: () => void;\n}\n\n// Owns the state the three Places concerns share — the field's text, whether a\n// request is in flight, and the last error — then hands each concern the slice it\n// writes to.\nexport const useAddressAutocomplete = ({\n defaultValue,\n googleMapsApiKey,\n restrictions,\n onSelect,\n}: {\n defaultValue: string;\n googleMapsApiKey: string;\n restrictions: AddressAutocompleteProps['restrictions'];\n onSelect: (address: AddressDetails) => void;\n}): AddressAutocompleteState => {\n const [inputValue, setInputValue] = useState(defaultValue);\n const [loading, setLoading] = useState(false);\n const [apiError, setApiError] = useState<string | null>(null);\n\n const { isLoaded, error: mapsError, services, useMockData } = useGoogleMapsAPI(googleMapsApiKey);\n\n // A resolved address both notifies the caller and becomes the field's text.\n const applyAddress = useCallback(\n (address: AddressDetails) => {\n onSelect(address);\n setInputValue(address.formatted);\n },\n [onSelect],\n );\n\n const { options, handleInputChange } = useAddressPredictions({\n isLoaded,\n services,\n restrictions,\n useMockData,\n setInputValue,\n setLoading,\n setApiError,\n });\n\n const handleSelect = useAddressSelection({\n services,\n useMockData,\n setLoading,\n setApiError,\n onSelect,\n applyAddress,\n });\n\n const handleGetCurrentLocation = useCurrentLocation({\n services,\n useMockData,\n setLoading,\n setApiError,\n applyAddress,\n });\n\n return {\n inputValue,\n options,\n loading,\n apiError,\n mapsError,\n isLoaded,\n handleInputChange,\n handleSelect,\n handleGetCurrentLocation,\n };\n};\n","import type React from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { MIN_QUERY_LENGTH } from './AddressAutocomplete.helpers';\nimport type { AddressAutocompleteProps, AddressOptionValue } from './AddressAutocomplete.types';\nimport { searchMockAddresses } from './mockPlaces';\nimport type { GoogleMapsService } from './useGoogleMapsAPI';\n\nconst DEBOUNCE_MS = 300;\n// Long enough to exercise the loading state, short enough not to slow tests down.\nconst MOCK_PREDICTION_DELAY_MS = 100;\n\ntype Restrictions = AddressAutocompleteProps['restrictions'];\n\ninterface PredictionSink {\n setOptions: (options: AddressOptionValue[]) => void;\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n}\n\nconst predictionRequest = (\n input: string,\n restrictions: Restrictions,\n): google.maps.places.AutocompletionRequest => ({\n input: input.trim(),\n componentRestrictions: restrictions?.country ? { country: restrictions.country } : undefined,\n types: restrictions?.types || [],\n});\n\nconst fetchMockPredictions = (input: string, sink: PredictionSink) => {\n window.setTimeout(() => {\n sink.setLoading(false);\n sink.setOptions(searchMockAddresses(input));\n sink.setApiError(null);\n }, MOCK_PREDICTION_DELAY_MS);\n};\n\nconst fetchLivePredictions = (\n service: google.maps.places.AutocompleteService,\n input: string,\n restrictions: Restrictions,\n sink: PredictionSink,\n) => {\n service.getPlacePredictions(predictionRequest(input, restrictions), (predictions, status) => {\n sink.setLoading(false);\n\n if (status === google.maps.places.PlacesServiceStatus.OK && predictions) {\n sink.setOptions(predictions);\n sink.setApiError(null);\n return;\n }\n\n // No matches is a normal outcome, not something to complain about.\n sink.setOptions([]);\n sink.setApiError(\n status === google.maps.places.PlacesServiceStatus.ZERO_RESULTS\n ? null\n : 'Failed to fetch address suggestions',\n );\n });\n};\n\nexport const useAddressPredictions = ({\n isLoaded,\n services,\n restrictions,\n useMockData,\n setInputValue,\n setLoading,\n setApiError,\n}: {\n isLoaded: boolean;\n services: GoogleMapsService;\n restrictions: Restrictions;\n useMockData: boolean;\n setInputValue: (value: string) => void;\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n}) => {\n const [options, setOptions] = useState<AddressOptionValue[]>([]);\n const debounceTimeoutRef = useRef<number | undefined>(undefined);\n\n const sink = useMemo<PredictionSink>(\n () => ({ setOptions, setLoading, setApiError }),\n [setLoading, setApiError],\n );\n\n const debouncedAutocomplete = useCallback(\n (input: string) => {\n window.clearTimeout(debounceTimeoutRef.current);\n\n debounceTimeoutRef.current = window.setTimeout(() => {\n if (!input.trim() || !isLoaded) {\n setOptions([]);\n setLoading(false);\n return;\n }\n\n if (useMockData) {\n fetchMockPredictions(input, sink);\n return;\n }\n\n if (!services.autocompleteService) {\n setOptions([]);\n setLoading(false);\n return;\n }\n\n fetchLivePredictions(services.autocompleteService, input, restrictions, sink);\n }, DEBOUNCE_MS);\n },\n [isLoaded, services, restrictions, useMockData, sink, setLoading],\n );\n\n useEffect(() => () => window.clearTimeout(debounceTimeoutRef.current), []);\n\n const handleInputChange = useCallback(\n (_event: React.SyntheticEvent, value: string) => {\n setInputValue(value);\n setApiError(null);\n\n if (value.length > MIN_QUERY_LENGTH) {\n setLoading(true);\n debouncedAutocomplete(value);\n return;\n }\n\n setOptions([]);\n setLoading(false);\n },\n [debouncedAutocomplete, setInputValue, setApiError, setLoading],\n );\n\n return { options, handleInputChange };\n};\n","export interface MockPrediction {\n place_id: string;\n description: string;\n structured_formatting: {\n main_text: string;\n secondary_text: string;\n };\n matched_substrings?: google.maps.places.PredictionSubstring[];\n terms?: google.maps.places.PredictionTerm[];\n types?: string[];\n}\n\n// Canned Places data so the component renders and is testable without a Google\n// Maps key.\nexport const MOCK_ADDRESSES: MockPrediction[] = [\n {\n place_id: 'mock_1',\n description: '123 Main Street, San Francisco, CA 94105, USA',\n structured_formatting: {\n main_text: '123 Main Street',\n secondary_text: 'San Francisco, CA 94105, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n {\n place_id: 'mock_2',\n description: '456 Oak Avenue, New York, NY 10001, USA',\n structured_formatting: {\n main_text: '456 Oak Avenue',\n secondary_text: 'New York, NY 10001, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n {\n place_id: 'mock_3',\n description: '789 Pine Boulevard, Los Angeles, CA 90001, USA',\n structured_formatting: {\n main_text: '789 Pine Boulevard',\n secondary_text: 'Los Angeles, CA 90001, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n {\n place_id: 'mock_4',\n description: '321 Elm Street, Chicago, IL 60601, USA',\n structured_formatting: {\n main_text: '321 Elm Street',\n secondary_text: 'Chicago, IL 60601, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n {\n place_id: 'mock_5',\n description: '654 Maple Drive, Austin, TX 78701, USA',\n structured_formatting: {\n main_text: '654 Maple Drive',\n secondary_text: 'Austin, TX 78701, USA',\n },\n matched_substrings: [],\n terms: [],\n types: ['street_address'],\n },\n];\n\ninterface MockPlaceDetails {\n formatted_address: string;\n address_components: Array<{\n long_name: string;\n types: string[];\n }>;\n geometry: {\n location: {\n lat: () => number;\n lng: () => number;\n };\n };\n}\n\nexport const MOCK_PLACE_DETAILS: Record<string, MockPlaceDetails> = {\n mock_1: {\n formatted_address: '123 Main Street, San Francisco, CA 94105, USA',\n address_components: [\n { long_name: '123', types: ['street_number'] },\n { long_name: 'Main Street', types: ['route'] },\n { long_name: 'San Francisco', types: ['locality'] },\n { long_name: 'California', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '94105', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 37.7749, lng: () => -122.4194 } },\n },\n mock_2: {\n formatted_address: '456 Oak Avenue, New York, NY 10001, USA',\n address_components: [\n { long_name: '456', types: ['street_number'] },\n { long_name: 'Oak Avenue', types: ['route'] },\n { long_name: 'New York', types: ['locality'] },\n { long_name: 'New York', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '10001', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 40.7128, lng: () => -74.0060 } },\n },\n mock_3: {\n formatted_address: '789 Pine Boulevard, Los Angeles, CA 90001, USA',\n address_components: [\n { long_name: '789', types: ['street_number'] },\n { long_name: 'Pine Boulevard', types: ['route'] },\n { long_name: 'Los Angeles', types: ['locality'] },\n { long_name: 'California', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '90001', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 34.0522, lng: () => -118.2437 } },\n },\n mock_4: {\n formatted_address: '321 Elm Street, Chicago, IL 60601, USA',\n address_components: [\n { long_name: '321', types: ['street_number'] },\n { long_name: 'Elm Street', types: ['route'] },\n { long_name: 'Chicago', types: ['locality'] },\n { long_name: 'Illinois', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '60601', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 41.8781, lng: () => -87.6298 } },\n },\n mock_5: {\n formatted_address: '654 Maple Drive, Austin, TX 78701, USA',\n address_components: [\n { long_name: '654', types: ['street_number'] },\n { long_name: 'Maple Drive', types: ['route'] },\n { long_name: 'Austin', types: ['locality'] },\n { long_name: 'Texas', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '78701', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 30.2672, lng: () => -97.7431 } },\n },\n mock_6: {\n formatted_address: '1000 Broadway, New York, NY 10001, USA',\n address_components: [\n { long_name: '1000', types: ['street_number'] },\n { long_name: 'Broadway', types: ['route'] },\n { long_name: 'New York', types: ['locality'] },\n { long_name: 'New York', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '10001', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 40.7589, lng: () => -73.9851 } },\n },\n mock_7: {\n formatted_address: '250 Market Street, San Francisco, CA 94102, USA',\n address_components: [\n { long_name: '250', types: ['street_number'] },\n { long_name: 'Market Street', types: ['route'] },\n { long_name: 'San Francisco', types: ['locality'] },\n { long_name: 'California', types: ['administrative_area_level_1'] },\n { long_name: 'United States', types: ['country'] },\n { long_name: '94102', types: ['postal_code'] },\n ],\n geometry: { location: { lat: () => 37.7879, lng: () => -122.4075 } },\n },\n};\n\n// Every word has to appear somewhere in the address, which is roughly how Google\n// treats a multi-word query.\nconst matchesAllWords = (address: MockPrediction, searchTerm: string): boolean => {\n const description = address.description.toLowerCase();\n const mainText = address.structured_formatting.main_text.toLowerCase();\n const secondaryText = address.structured_formatting.secondary_text?.toLowerCase() || '';\n\n return searchTerm\n .split(' ')\n .every(\n (word) =>\n description.includes(word) || mainText.includes(word) || secondaryText.includes(word),\n );\n};\n\n// Addresses whose street line starts with the query come first; the rest sort\n// alphabetically.\nconst byRelevance =\n (searchTerm: string) =>\n (a: MockPrediction, b: MockPrediction): number => {\n const aMain = a.structured_formatting.main_text.toLowerCase();\n const bMain = b.structured_formatting.main_text.toLowerCase();\n\n if (aMain.startsWith(searchTerm) && !bMain.startsWith(searchTerm)) return -1;\n if (!aMain.startsWith(searchTerm) && bMain.startsWith(searchTerm)) return 1;\n return aMain.localeCompare(bMain);\n };\n\nexport const searchMockAddresses = (input: string): MockPrediction[] => {\n const searchTerm = input.toLowerCase().trim();\n\n return MOCK_ADDRESSES.filter((address) => matchesAllWords(address, searchTerm)).sort(\n byRelevance(searchTerm),\n );\n};\n","import type React from 'react';\nimport { useCallback } from 'react';\n\nimport { coordinatesOf, freeSoloAddress, toAddressDetails } from './AddressAutocomplete.mapper';\nimport type {\n AddressDetails,\n AddressOptionValue,\n AddressPrediction,\n} from './AddressAutocomplete.types';\nimport { MOCK_PLACE_DETAILS } from './mockPlaces';\nimport type { GoogleMapsService } from './useGoogleMapsAPI';\n\nconst MOCK_DETAILS_DELAY_MS = 50;\n\nconst PLACE_DETAIL_FIELDS = ['formatted_address', 'address_components', 'geometry'];\n\ninterface SelectionSink {\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n applyAddress: (address: AddressDetails) => void;\n}\n\nconst resolveMockPlace = (value: AddressPrediction, sink: SelectionSink) => {\n window.setTimeout(() => {\n sink.setLoading(false);\n\n const place = MOCK_PLACE_DETAILS[value.place_id];\n if (!place) {\n sink.setApiError('Address details not found');\n return;\n }\n\n sink.applyAddress(\n toAddressDetails({\n components: place.address_components,\n formatted: place.formatted_address || value.description,\n coordinates: coordinatesOf(place.geometry),\n }),\n );\n }, MOCK_DETAILS_DELAY_MS);\n};\n\nconst resolveLivePlace = (\n service: google.maps.places.PlacesService,\n value: AddressPrediction,\n sink: SelectionSink,\n) => {\n const request: google.maps.places.PlaceDetailsRequest = {\n placeId: value.place_id,\n fields: PLACE_DETAIL_FIELDS,\n };\n\n service.getDetails(request, (place, status) => {\n sink.setLoading(false);\n\n if (status !== google.maps.places.PlacesServiceStatus.OK || !place) {\n sink.setApiError('Failed to get address details');\n return;\n }\n\n sink.applyAddress(\n toAddressDetails({\n components: place.address_components ?? [],\n formatted: place.formatted_address || value.description,\n coordinates: coordinatesOf(place.geometry),\n }),\n );\n });\n};\n\nexport const useAddressSelection = ({\n services,\n useMockData,\n setLoading,\n setApiError,\n onSelect,\n applyAddress,\n}: {\n services: GoogleMapsService;\n useMockData: boolean;\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n onSelect: (address: AddressDetails) => void;\n applyAddress: (address: AddressDetails) => void;\n}) =>\n useCallback(\n (_event: React.SyntheticEvent, value: AddressOptionValue | null) => {\n // freeSolo text is reported as typed; there is no place to look up, and the\n // input already holds it.\n if (typeof value === 'string') {\n onSelect(freeSoloAddress(value));\n return;\n }\n\n if (!value) return;\n\n setLoading(true);\n const sink: SelectionSink = { setLoading, setApiError, applyAddress };\n\n if (useMockData && 'place_id' in value) {\n resolveMockPlace(value, sink);\n return;\n }\n\n if (!services.placesService) {\n setLoading(false);\n return;\n }\n\n resolveLivePlace(services.placesService, value, sink);\n },\n [services, useMockData, setLoading, setApiError, onSelect, applyAddress],\n );\n","import type { AddressDetails } from './AddressAutocomplete.types';\n\n// The shape shared by google.maps.GeocoderAddressComponent and the canned mock\n// components: enough to read a part out by type.\ninterface AddressComponentLike {\n long_name: string;\n types: string[];\n}\n\ninterface LatLngLike {\n lat: () => number;\n lng: () => number;\n}\n\n// Google reports address parts as an unordered list tagged by type, so every part\n// has to be looked up rather than indexed.\nconst componentReader =\n (components: readonly AddressComponentLike[]) =>\n (type: string): string =>\n components.find((component) => component.types.includes(type))?.long_name || '';\n\n// Places and Geocoder results both make the whole geometry chain optional.\nexport const coordinatesOf = (geometry?: { location?: LatLngLike }): AddressDetails['coordinates'] => ({\n lat: geometry?.location?.lat() || 0,\n lng: geometry?.location?.lng() || 0,\n});\n\n// The four ways an address can arrive — a mock or live prediction, a mock or live\n// reverse geocode — all land here, so they agree on how a place becomes an\n// AddressDetails.\nexport const toAddressDetails = ({\n components,\n formatted,\n coordinates,\n}: {\n components: readonly AddressComponentLike[];\n formatted: string;\n coordinates: AddressDetails['coordinates'];\n}): AddressDetails => {\n const read = componentReader(components);\n const street = `${read('street_number')} ${read('route')}`.trim();\n\n return {\n formatted,\n // A street number on its own is not an address; fall back to the route name.\n street: street || read('route'),\n city: read('locality') || read('administrative_area_level_2'),\n state: read('administrative_area_level_1'),\n country: read('country'),\n postalCode: read('postal_code'),\n coordinates,\n };\n};\n\n// freeSolo mode hands back whatever was typed, with no components to read.\nexport const freeSoloAddress = (value: string): AddressDetails =>\n toAddressDetails({ components: [], formatted: value, coordinates: { lat: 0, lng: 0 } });\n","import { useCallback } from 'react';\n\nimport { coordinatesOf, toAddressDetails } from './AddressAutocomplete.mapper';\nimport type { AddressDetails } from './AddressAutocomplete.types';\nimport { MOCK_ADDRESSES, MOCK_PLACE_DETAILS } from './mockPlaces';\nimport type { GoogleMapsService } from './useGoogleMapsAPI';\n\nconst MOCK_GEOLOCATION_DELAY_MS = 500;\n\nconst GEOLOCATION_OPTIONS: PositionOptions = {\n enableHighAccuracy: true,\n timeout: 10_000,\n maximumAge: 600_000, // 10 minutes\n};\n\ninterface LocationSink {\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n applyAddress: (address: AddressDetails) => void;\n}\n\n// Mock mode answers with the first canned address after a pause, so the button\n// behaves like a real geolocation round trip.\nconst resolveMockLocation = (sink: LocationSink) => {\n window.setTimeout(() => {\n sink.setLoading(false);\n\n const mockLocation = MOCK_ADDRESSES[0];\n if (!mockLocation) {\n sink.setApiError('No mock location available');\n return;\n }\n\n const mockDetails = MOCK_PLACE_DETAILS[mockLocation.place_id];\n if (!mockDetails) {\n sink.setApiError('Mock location details not found');\n return;\n }\n\n sink.applyAddress(\n toAddressDetails({\n components: mockDetails.address_components,\n formatted: mockDetails.formatted_address,\n coordinates: coordinatesOf(mockDetails.geometry),\n }),\n );\n }, MOCK_GEOLOCATION_DELAY_MS);\n};\n\nconst geocodePosition =\n (geocoder: google.maps.Geocoder, sink: LocationSink) => (position: GeolocationPosition) => {\n const { latitude, longitude } = position.coords;\n const location = new google.maps.LatLng(latitude, longitude);\n\n geocoder.geocode({ location }, (results, status) => {\n sink.setLoading(false);\n\n const place = status === 'OK' ? results?.[0] : undefined;\n if (!place) {\n sink.setApiError('Unable to retrieve address for current location');\n return;\n }\n\n sink.applyAddress(\n toAddressDetails({\n components: place.address_components,\n formatted: place.formatted_address,\n // The device's own fix is more precise than the geocoded place's.\n coordinates: { lat: latitude, lng: longitude },\n }),\n );\n });\n };\n\nexport const useCurrentLocation = ({\n services,\n useMockData,\n setLoading,\n setApiError,\n applyAddress,\n}: {\n services: GoogleMapsService;\n useMockData: boolean;\n setLoading: (loading: boolean) => void;\n setApiError: (message: string | null) => void;\n applyAddress: (address: AddressDetails) => void;\n}) =>\n useCallback(() => {\n if (!navigator.geolocation) {\n setApiError('Geolocation is not supported by this browser');\n return;\n }\n\n const sink: LocationSink = { setLoading, setApiError, applyAddress };\n\n if (useMockData) {\n setLoading(true);\n resolveMockLocation(sink);\n return;\n }\n\n if (!services.geocoder) {\n setApiError('Geocoding service not available');\n return;\n }\n\n setLoading(true);\n navigator.geolocation.getCurrentPosition(\n geocodePosition(services.geocoder, sink),\n () => {\n setLoading(false);\n setApiError('Unable to retrieve your location');\n },\n GEOLOCATION_OPTIONS,\n );\n }, [services, useMockData, setLoading, setApiError, applyAddress]);\n","import { useEffect, useRef, useState } from 'react';\n\nexport interface GoogleMapsService {\n autocompleteService: google.maps.places.AutocompleteService | null;\n placesService: google.maps.places.PlacesService | null;\n geocoder: google.maps.Geocoder | null;\n}\n\nexport const useGoogleMapsAPI = (apiKey: string) => {\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [useMockData, setUseMockData] = useState(false);\n const serviceRef = useRef<GoogleMapsService>({\n autocompleteService: null,\n placesService: null,\n geocoder: null,\n });\n\n useEffect(() => {\n // Use mock data for demo key or test environment\n if (!apiKey || apiKey === 'demo-key' || apiKey === 'test-key') {\n setUseMockData(true);\n setIsLoaded(true);\n setError(null);\n return;\n }\n\n // Check if Google Maps is already loaded\n if (window.google && window.google.maps && window.google.maps.places) {\n initializeServices();\n return;\n }\n\n // Load Google Maps API\n const script = document.createElement('script');\n script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`;\n script.async = true;\n script.defer = true;\n \n script.onload = () => {\n initializeServices();\n };\n \n script.onerror = () => {\n setError('Failed to load Google Maps API');\n };\n\n document.head.appendChild(script);\n\n return () => {\n // Cleanup script if component unmounts\n if (document.head.contains(script)) {\n document.head.removeChild(script);\n }\n };\n }, [apiKey]);\n\n const initializeServices = () => {\n try {\n if (window.google && window.google.maps && window.google.maps.places) {\n serviceRef.current = {\n autocompleteService: new window.google.maps.places.AutocompleteService(),\n placesService: new window.google.maps.places.PlacesService(document.createElement('div')),\n geocoder: new window.google.maps.Geocoder(),\n };\n setIsLoaded(true);\n setError(null);\n }\n } catch {\n setError('Failed to initialize Google Maps services');\n }\n };\n\n return { isLoaded, error, services: serviceRef.current, useMockData };\n};\n","import { Alert, Autocomplete, Box } from '@mui/material';\nimport type { FC } from 'react';\nimport React from 'react';\n\nimport {\n addressOptionLabel,\n isSameAddressOption,\n MIN_QUERY_LENGTH,\n type ResolvedAddressProps,\n} from './AddressAutocomplete.helpers';\nimport type { AddressAutocompleteState } from './AddressAutocomplete.hooks';\nimport { AddressInputField } from './AddressInputField';\nimport { AddressOption } from './AddressOption';\nimport { AddressSuggestionsPaper } from './AddressSuggestionsPaper';\n\nexport type AddressAutocompleteFieldProps = ResolvedAddressProps & AddressAutocompleteState;\n\n// The live field, rendered once Google Maps (or the mock stand-in) is ready.\nexport const AddressAutocompleteField: FC<AddressAutocompleteFieldProps> = ({\n copy,\n variant,\n label,\n placeholder,\n icon,\n floating,\n error,\n helperText,\n disabled,\n required,\n fullWidth,\n getCurrentLocation,\n inputValue,\n options,\n loading,\n apiError,\n handleInputChange,\n handleSelect,\n handleGetCurrentLocation,\n}) => (\n <Box data-testid=\"address-autocomplete-container\">\n <Autocomplete\n freeSolo\n options={options}\n inputValue={inputValue}\n onInputChange={handleInputChange}\n onChange={handleSelect}\n loading={loading}\n disabled={disabled}\n fullWidth={fullWidth}\n getOptionLabel={addressOptionLabel}\n isOptionEqualToValue={isSameAddressOption}\n PaperComponent={AddressSuggestionsPaper}\n noOptionsText={\n inputValue.length <= MIN_QUERY_LENGTH ? 'Type at least 3 characters' : 'No addresses found'\n }\n renderOption={({ key, ...optionProps }, option, state) => (\n <AddressOption\n key={key}\n optionProps={optionProps}\n option={option}\n index={state.index}\n />\n )}\n renderInput={(params) => (\n <AddressInputField\n copy={copy}\n params={params}\n addressVariant={variant}\n label={floating ? undefined : label}\n placeholder={placeholder}\n icon={icon}\n error={error || !!apiError}\n helperText={apiError || helperText}\n required={required}\n disabled={disabled}\n loading={loading}\n showCurrentLocation={getCurrentLocation && !loading}\n onGetCurrentLocation={handleGetCurrentLocation}\n />\n )}\n />\n {apiError && (\n <Alert severity=\"warning\" sx={{ mt: 1 }}>\n {apiError}\n </Alert>\n )}\n </Box>\n);\n","import CurrentLocationIcon from '@mui/icons-material/MyLocation';\nimport type { AutocompleteRenderInputParams } from '@mui/material';\nimport { CircularProgress, IconButton, InputAdornment } from '@mui/material';\nimport type { FC, ReactNode } from 'react';\nimport React from 'react';\n\nimport type { AddressAutocompleteProps } from './AddressAutocomplete.types';\nimport { AddressTextField } from './AddressTextField';\n\nconst CurrentLocationButton: FC<{\n disabled: boolean;\n onClick: () => void;\n currentLocationLabel: string;\n}> = ({ disabled, onClick, currentLocationLabel }) => (\n <InputAdornment position=\"end\">\n <IconButton\n edge=\"end\"\n onClick={onClick}\n size=\"small\"\n title={currentLocationLabel}\n disabled={disabled}\n data-testid=\"address-current-location-button\"\n >\n <CurrentLocationIcon />\n </IconButton>\n </InputAdornment>\n);\n\nexport interface AddressInputFieldProps {\n copy: AddressAutocompleteProps['copy'];\n params: AutocompleteRenderInputParams;\n addressVariant: AddressAutocompleteProps['variant'];\n label?: string;\n placeholder?: string;\n icon?: ReactNode;\n error: boolean;\n helperText?: string;\n required: boolean;\n disabled: boolean;\n loading: boolean;\n showCurrentLocation: boolean;\n onGetCurrentLocation: () => void;\n}\n\nexport const AddressInputField: FC<AddressInputFieldProps> = ({\n copy,\n params,\n addressVariant,\n label,\n placeholder,\n icon,\n error,\n helperText,\n required,\n disabled,\n loading,\n showCurrentLocation,\n onGetCurrentLocation,\n}) => (\n <AddressTextField\n {...params}\n addressVariant={addressVariant}\n label={label}\n placeholder={placeholder}\n error={error}\n helperText={helperText}\n required={required}\n InputProps={{\n ...params.InputProps,\n startAdornment: icon && <InputAdornment position=\"start\">{icon}</InputAdornment>,\n endAdornment: (\n <>\n {loading && <CircularProgress color=\"inherit\" size={20} data-testid=\"address-loading\" />}\n {showCurrentLocation && (\n <CurrentLocationButton\n disabled={disabled}\n onClick={onGetCurrentLocation}\n currentLocationLabel={copy.useCurrentLocation}\n />\n )}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n inputProps={{ ...params.inputProps, 'data-testid': 'address-input' }}\n />\n);\n","import type { TextFieldProps } from '@mui/material';\nimport { alpha, styled, TextField } from '@mui/material';\nimport type { FC } from 'react';\nimport React from 'react';\n\nimport type { AddressAutocompleteProps } from './AddressAutocomplete.types';\n\n// Kept module-local on purpose: the inferred type of a styled() component cannot\n// be named across a module boundary here (TS2742), so the plain component below\n// is what the rest of the folder imports.\nconst GlassTextField = styled(TextField)(({ theme }) => ({\n '& .MuiOutlinedInput-root': {\n background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.8)} 0%, ${alpha(theme.palette.background.paper, 0.6)} 100%)`,\n backdropFilter: 'blur(10px)',\n WebkitBackdropFilter: 'blur(10px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n transition: theme.transitions.create(['border-color', 'box-shadow', 'background']),\n '&:hover': {\n background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha(theme.palette.background.paper, 0.7)} 100%)`,\n borderColor: theme.palette.primary.main,\n },\n '&.Mui-focused': {\n background: theme.palette.background.paper,\n boxShadow: `0 0 0 2px ${alpha(theme.palette.primary.main, 0.25)}`,\n },\n '& fieldset': {\n border: 'none',\n },\n },\n}));\n\nexport type AddressTextFieldProps = Omit<TextFieldProps, 'variant'> & {\n addressVariant: AddressAutocompleteProps['variant'];\n};\n\n// 'glass' is not a MUI variant: it renders the outlined field with the frosted\n// treatment on top.\nexport const AddressTextField: FC<AddressTextFieldProps> = ({ addressVariant, ...props }) =>\n addressVariant === 'glass' ? (\n <GlassTextField variant=\"outlined\" {...props} />\n ) : (\n <TextField variant={addressVariant} {...props} />\n );\n","import LocationIcon from '@mui/icons-material/LocationOn';\nimport { alpha, Box, styled } from '@mui/material';\nimport type { FC, HTMLAttributes } from 'react';\nimport React from 'react';\n\nimport type { AddressOptionValue } from './AddressAutocomplete.types';\n\n// Module-local: styled() components cannot be exported across a module boundary\n// here without tripping TS2742.\nconst SuggestionItem = styled(Box)(({ theme }) => ({\n padding: theme.spacing(1.5),\n display: 'flex',\n alignItems: 'flex-start',\n gap: theme.spacing(1.5),\n cursor: 'pointer',\n transition: theme.transitions.create(['background-color']),\n '&:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.08),\n },\n}));\n\nconst LocationIconWrapper = styled(Box)(({ theme }) => ({\n marginTop: theme.spacing(0.5),\n color: theme.palette.text.secondary,\n}));\n\nconst AddressText = styled(Box)(({ theme }) => ({\n flex: 1,\n '& .primary': {\n fontSize: '0.9rem',\n fontWeight: 500,\n color: theme.palette.text.primary,\n marginBottom: theme.spacing(0.25),\n },\n '& .secondary': {\n fontSize: '0.8rem',\n color: theme.palette.text.secondary,\n },\n}));\n\n// Predictions carry the street line and the rest already split; freeSolo text has\n// to be split on the first comma to get the same two lines.\nconst optionText = (option: AddressOptionValue) => {\n if (typeof option === 'string') {\n return {\n testId: 'address-suggestion-text',\n primary: option.split(',')[0],\n secondary: option.split(',').slice(1).join(','),\n };\n }\n\n return {\n testId: 'address-prediction-text',\n primary: option.structured_formatting?.main_text || option.description?.split(',')[0],\n secondary:\n option.structured_formatting?.secondary_text ||\n option.description?.split(',').slice(1).join(','),\n };\n};\n\nexport interface AddressOptionProps {\n optionProps: HTMLAttributes<HTMLLIElement>;\n option: AddressOptionValue;\n index: number;\n}\n\nexport const AddressOption: FC<AddressOptionProps> = ({ optionProps, option, index }) => {\n const { testId, primary, secondary } = optionText(option);\n\n return (\n <li {...optionProps} data-testid={`address-suggestion-${index}`}>\n <SuggestionItem>\n <LocationIconWrapper>\n <LocationIcon fontSize=\"small\" />\n </LocationIconWrapper>\n <AddressText data-testid={testId}>\n <div className=\"primary\">{primary}</div>\n <div className=\"secondary\">{secondary}</div>\n </AddressText>\n </SuggestionItem>\n </li>\n );\n};\n","import type { PaperProps } from '@mui/material';\nimport { alpha, Paper, useTheme } from '@mui/material';\nimport type { FC } from 'react';\nimport React from 'react';\n\n// The dropdown surface, frosted to match the glass field.\nexport const AddressSuggestionsPaper: FC<PaperProps> = (props) => {\n const theme = useTheme();\n\n return (\n <Paper\n {...props}\n elevation={8}\n data-testid=\"address-suggestions-dropdown\"\n sx={{\n mt: 1,\n background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.98)} 0%, ${alpha(theme.palette.background.paper, 0.95)} 100%)`,\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n }}\n />\n );\n};\n","import { Alert, Box, CircularProgress, InputAdornment } from '@mui/material';\nimport type { FC, ReactNode } from 'react';\nimport React from 'react';\n\nimport type { AddressAutocompleteProps } from './AddressAutocomplete.types';\nimport { AddressTextField } from './AddressTextField';\n\nexport interface AddressFallbackFieldProps {\n copy: AddressAutocompleteProps['copy'];\n variant: AddressAutocompleteProps['variant'];\n label?: string;\n placeholder?: string;\n icon?: ReactNode;\n floating: boolean;\n fullWidth: boolean;\n mapsError: string | null;\n}\n\n// Stands in for the Autocomplete before Google Maps is usable: a disabled field\n// that either spins or explains why it never loaded.\nexport const AddressFallbackField: FC<AddressFallbackFieldProps> = ({\n copy,\n variant,\n label,\n placeholder,\n icon,\n floating,\n fullWidth,\n mapsError,\n}) => {\n const startAdornment = icon ? <InputAdornment position=\"start\">{icon}</InputAdornment> : undefined;\n\n if (!mapsError) {\n return (\n <AddressTextField\n addressVariant={variant}\n label={floating ? undefined : label}\n placeholder={copy.loadingMaps}\n disabled\n fullWidth={fullWidth}\n InputProps={{\n startAdornment,\n endAdornment: <CircularProgress color=\"inherit\" size={20} />,\n }}\n />\n );\n }\n\n return (\n <Box>\n <AddressTextField\n addressVariant={variant}\n label={floating ? undefined : label}\n placeholder={placeholder}\n error\n disabled\n fullWidth={fullWidth}\n helperText={mapsError}\n InputProps={{ startAdornment }}\n />\n <Alert severity=\"error\" sx={{ mt: 1 }}>\n {copy.mapsLoadFailed}\n </Alert>\n </Box>\n );\n};\n"],"mappings":"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","names":["LocationIcon","useCallback","useState","useCallback","useCallback","useCallback","useCallback","useEffect","useRef","useState","useState","useCallback","Box","jsx","alpha","styled","jsx","jsxs","alpha","jsx","jsx","jsxs","Box","Alert","Box","CircularProgress","InputAdornment","jsx","jsxs","InputAdornment","CircularProgress","Box","Alert","jsx","LocationIcon"]}
|