@mailwoman/react 10.0.0 → 10.1.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/README.md +17 -16
- package/fonts.css +97 -22
- package/lib/common/About.tsx +7 -7
- package/lib/common/ClientOnly.tsx +2 -14
- package/lib/common/CopyButton.tsx +3 -1
- package/lib/common/LoadingIndicator.tsx +4 -2
- package/lib/common/PresetChips.tsx +9 -8
- package/lib/common/confidence-tiers.ts +7 -6
- package/lib/common/cx.ts +3 -1
- package/lib/common/text-tokens.ts +7 -4
- package/lib/common/useBuildInfo.ts +54 -0
- package/lib/common/useClipboard.ts +2 -11
- package/lib/common.ts +22 -0
- package/lib/index.ts +27 -17
- package/lib/map/AppIdentity.tsx +85 -0
- package/lib/map/BackendControl.tsx +9 -10
- package/lib/map/CompareToggle.tsx +8 -31
- package/lib/map/DebugInfo.tsx +88 -0
- package/lib/map/Geocoder.tsx +60 -46
- package/lib/map/GeocoderControls.tsx +430 -134
- package/lib/map/GraticuleLayer.tsx +54 -0
- package/lib/map/MapCanvas.tsx +23 -12
- package/lib/map/MapChipRow.tsx +4 -8
- package/lib/map/MapCompass.tsx +15 -24
- package/lib/map/MapControlStack.tsx +8 -9
- package/lib/map/MapFooter.tsx +2 -16
- package/lib/map/MapProgressBar.tsx +10 -13
- package/lib/map/MapSearchBar.tsx +31 -17
- package/lib/map/MapSheet.tsx +24 -15
- package/lib/map/OverlayLayers.tsx +1 -1
- package/lib/map/PlaceAutocomplete.tsx +10 -21
- package/lib/map/PlaceMarker.tsx +4 -2
- package/lib/map/ResolvedPlaceLayers.tsx +5 -14
- package/lib/map/ResultCamera.tsx +8 -31
- package/lib/map/ResultOverlay.tsx +2 -12
- package/lib/map/ResultPanel.tsx +1 -20
- package/lib/map/VersionPicker.tsx +10 -19
- package/lib/map/fake-runtime.ts +10 -12
- package/lib/map/geometry.ts +14 -47
- package/lib/map/graticule.ts +80 -0
- package/lib/map/map-debug.ts +1 -1
- package/lib/map/place-render.ts +28 -60
- package/lib/map/types.ts +58 -104
- package/lib/map/useCompareState.ts +5 -4
- package/lib/map/useGeocode.ts +7 -5
- package/lib/map/useMapBearing.ts +13 -13
- package/lib/map/useMapLabelPick.ts +21 -30
- package/lib/map/useMapPlaceRender.ts +2 -6
- package/lib/map/usePlaceAutocomplete.ts +44 -50
- package/lib/map.ts +95 -0
- package/lib/pipeline/CandidatePicker.tsx +13 -5
- package/lib/pipeline/ConfidenceCell.tsx +1 -1
- package/lib/pipeline/FailureDiagnostic.tsx +8 -2
- package/lib/pipeline/QueryForm.tsx +5 -2
- package/lib/pipeline/ResolvedPlace.tsx +1 -1
- package/lib/pipeline/SpanHighlight.tsx +7 -5
- package/lib/pipeline/TimingPanel.tsx +1 -1
- package/lib/pipeline/TreeView.tsx +1 -1
- package/lib/pipeline/copy.ts +22 -25
- package/lib/pipeline/presets.ts +15 -13
- package/lib/pipeline/types.ts +21 -14
- package/lib/pipeline/useParsePipeline.ts +16 -13
- package/lib/pipeline.ts +36 -0
- package/lib/poi/AbstainPanel.tsx +1 -1
- package/lib/poi/LiveResultsBlock.tsx +2 -1
- package/lib/poi/POIExplorer.tsx +24 -15
- package/lib/poi/QueryInput.tsx +1 -1
- package/lib/poi/SubjectPanel.tsx +4 -3
- package/lib/poi/runtime.ts +5 -16
- package/lib/poi/types.ts +39 -27
- package/lib/poi/usePOISearch.ts +39 -44
- package/lib/poi.ts +39 -0
- package/lib/runtime/useReleaseRuntime.ts +125 -74
- package/lib/search/SearchModal.tsx +317 -0
- package/lib/search/search.css +144 -0
- package/lib/search/types.ts +67 -0
- package/lib/search.ts +11 -0
- package/out/common/About.d.ts +5 -5
- package/out/common/About.d.ts.map +1 -1
- package/out/common/About.js +1 -1
- package/out/common/About.js.map +1 -1
- package/out/common/ClientOnly.d.ts +2 -11
- package/out/common/ClientOnly.d.ts.map +1 -1
- package/out/common/ClientOnly.js +1 -13
- package/out/common/ClientOnly.js.map +1 -1
- package/out/common/CopyButton.d.ts +3 -1
- package/out/common/CopyButton.d.ts.map +1 -1
- package/out/common/CopyButton.js.map +1 -1
- package/out/common/LoadingIndicator.d.ts +4 -2
- package/out/common/LoadingIndicator.d.ts.map +1 -1
- package/out/common/LoadingIndicator.js.map +1 -1
- package/out/common/PresetChips.d.ts +9 -8
- package/out/common/PresetChips.d.ts.map +1 -1
- package/out/common/PresetChips.js.map +1 -1
- package/out/common/confidence-tiers.d.ts +7 -6
- package/out/common/confidence-tiers.d.ts.map +1 -1
- package/out/common/confidence-tiers.js +7 -6
- package/out/common/confidence-tiers.js.map +1 -1
- package/out/common/cx.d.ts +3 -1
- package/out/common/cx.d.ts.map +1 -1
- package/out/common/cx.js +3 -1
- package/out/common/cx.js.map +1 -1
- package/out/common/text-tokens.d.ts +4 -3
- package/out/common/text-tokens.d.ts.map +1 -1
- package/out/common/text-tokens.js +6 -3
- package/out/common/text-tokens.js.map +1 -1
- package/out/common/useBuildInfo.d.ts +27 -0
- package/out/common/useBuildInfo.d.ts.map +1 -0
- package/out/common/useBuildInfo.js +32 -0
- package/out/common/useBuildInfo.js.map +1 -0
- package/out/common/useClipboard.d.ts +1 -3
- package/out/common/useClipboard.d.ts.map +1 -1
- package/out/common/useClipboard.js +2 -11
- package/out/common/useClipboard.js.map +1 -1
- package/out/common.d.ts +22 -0
- package/out/common.d.ts.map +1 -0
- package/out/common.js +15 -0
- package/out/common.js.map +1 -0
- package/out/index.d.ts +26 -16
- package/out/index.d.ts.map +1 -1
- package/out/index.js +21 -15
- package/out/index.js.map +1 -1
- package/out/map/AppIdentity.d.ts +42 -0
- package/out/map/AppIdentity.d.ts.map +1 -0
- package/out/map/AppIdentity.js +16 -0
- package/out/map/AppIdentity.js.map +1 -0
- package/out/map/BackendControl.d.ts +9 -10
- package/out/map/BackendControl.d.ts.map +1 -1
- package/out/map/BackendControl.js +1 -1
- package/out/map/BackendControl.js.map +1 -1
- package/out/map/CompareToggle.d.ts +8 -31
- package/out/map/CompareToggle.d.ts.map +1 -1
- package/out/map/CompareToggle.js +4 -1
- package/out/map/CompareToggle.js.map +1 -1
- package/out/map/DebugInfo.d.ts +34 -0
- package/out/map/DebugInfo.d.ts.map +1 -0
- package/out/map/DebugInfo.js +39 -0
- package/out/map/DebugInfo.js.map +1 -0
- package/out/map/Geocoder.d.ts +41 -30
- package/out/map/Geocoder.d.ts.map +1 -1
- package/out/map/Geocoder.js +20 -36
- package/out/map/Geocoder.js.map +1 -1
- package/out/map/GeocoderControls.d.ts +14 -42
- package/out/map/GeocoderControls.d.ts.map +1 -1
- package/out/map/GeocoderControls.js +250 -38
- package/out/map/GeocoderControls.js.map +1 -1
- package/out/map/GraticuleLayer.d.ts +28 -0
- package/out/map/GraticuleLayer.d.ts.map +1 -0
- package/out/map/GraticuleLayer.js +25 -0
- package/out/map/GraticuleLayer.js.map +1 -0
- package/out/map/MapCanvas.d.ts +23 -12
- package/out/map/MapCanvas.d.ts.map +1 -1
- package/out/map/MapCanvas.js +5 -2
- package/out/map/MapCanvas.js.map +1 -1
- package/out/map/MapChipRow.d.ts +4 -8
- package/out/map/MapChipRow.d.ts.map +1 -1
- package/out/map/MapChipRow.js.map +1 -1
- package/out/map/MapCompass.d.ts +11 -20
- package/out/map/MapCompass.d.ts.map +1 -1
- package/out/map/MapCompass.js +5 -1
- package/out/map/MapCompass.js.map +1 -1
- package/out/map/MapControlStack.d.ts +8 -9
- package/out/map/MapControlStack.d.ts.map +1 -1
- package/out/map/MapControlStack.js +4 -1
- package/out/map/MapControlStack.js.map +1 -1
- package/out/map/MapFooter.d.ts +2 -15
- package/out/map/MapFooter.d.ts.map +1 -1
- package/out/map/MapFooter.js +0 -14
- package/out/map/MapFooter.js.map +1 -1
- package/out/map/MapProgressBar.d.ts +10 -13
- package/out/map/MapProgressBar.d.ts.map +1 -1
- package/out/map/MapProgressBar.js.map +1 -1
- package/out/map/MapSearchBar.d.ts +16 -17
- package/out/map/MapSearchBar.d.ts.map +1 -1
- package/out/map/MapSearchBar.js +6 -0
- package/out/map/MapSearchBar.js.map +1 -1
- package/out/map/MapSheet.d.ts +15 -12
- package/out/map/MapSheet.d.ts.map +1 -1
- package/out/map/MapSheet.js +8 -12
- package/out/map/MapSheet.js.map +1 -1
- package/out/map/OverlayLayers.d.ts +1 -1
- package/out/map/OverlayLayers.js +1 -1
- package/out/map/PlaceAutocomplete.d.ts +10 -21
- package/out/map/PlaceAutocomplete.d.ts.map +1 -1
- package/out/map/PlaceAutocomplete.js +2 -1
- package/out/map/PlaceAutocomplete.js.map +1 -1
- package/out/map/PlaceMarker.d.ts +4 -2
- package/out/map/PlaceMarker.d.ts.map +1 -1
- package/out/map/PlaceMarker.js +3 -1
- package/out/map/PlaceMarker.js.map +1 -1
- package/out/map/ResolvedPlaceLayers.d.ts +5 -14
- package/out/map/ResolvedPlaceLayers.d.ts.map +1 -1
- package/out/map/ResolvedPlaceLayers.js +1 -1
- package/out/map/ResolvedPlaceLayers.js.map +1 -1
- package/out/map/ResultCamera.d.ts +8 -31
- package/out/map/ResultCamera.d.ts.map +1 -1
- package/out/map/ResultCamera.js +3 -28
- package/out/map/ResultCamera.js.map +1 -1
- package/out/map/ResultOverlay.d.ts +2 -12
- package/out/map/ResultOverlay.d.ts.map +1 -1
- package/out/map/ResultOverlay.js +1 -2
- package/out/map/ResultOverlay.js.map +1 -1
- package/out/map/ResultPanel.d.ts +1 -20
- package/out/map/ResultPanel.d.ts.map +1 -1
- package/out/map/ResultPanel.js.map +1 -1
- package/out/map/VersionPicker.d.ts +7 -19
- package/out/map/VersionPicker.d.ts.map +1 -1
- package/out/map/VersionPicker.js +5 -2
- package/out/map/VersionPicker.js.map +1 -1
- package/out/map/fake-runtime.d.ts +9 -11
- package/out/map/fake-runtime.d.ts.map +1 -1
- package/out/map/fake-runtime.js +9 -12
- package/out/map/fake-runtime.js.map +1 -1
- package/out/map/geometry.d.ts +13 -34
- package/out/map/geometry.d.ts.map +1 -1
- package/out/map/geometry.js +9 -34
- package/out/map/geometry.js.map +1 -1
- package/out/map/graticule.d.ts +17 -0
- package/out/map/graticule.d.ts.map +1 -0
- package/out/map/graticule.js +67 -0
- package/out/map/graticule.js.map +1 -0
- package/out/map/map-debug.d.ts +1 -1
- package/out/map/map-debug.js +1 -1
- package/out/map/place-render.d.ts +23 -43
- package/out/map/place-render.d.ts.map +1 -1
- package/out/map/place-render.js +4 -39
- package/out/map/place-render.js.map +1 -1
- package/out/map/types.d.ts +58 -102
- package/out/map/types.d.ts.map +1 -1
- package/out/map/types.js +1 -10
- package/out/map/types.js.map +1 -1
- package/out/map/useCompareState.d.ts +5 -4
- package/out/map/useCompareState.d.ts.map +1 -1
- package/out/map/useCompareState.js +3 -3
- package/out/map/useCompareState.js.map +1 -1
- package/out/map/useGeocode.d.ts +5 -3
- package/out/map/useGeocode.d.ts.map +1 -1
- package/out/map/useGeocode.js +4 -4
- package/out/map/useGeocode.js.map +1 -1
- package/out/map/useMapBearing.d.ts +11 -11
- package/out/map/useMapBearing.d.ts.map +1 -1
- package/out/map/useMapBearing.js +6 -11
- package/out/map/useMapBearing.js.map +1 -1
- package/out/map/useMapLabelPick.d.ts +4 -14
- package/out/map/useMapLabelPick.d.ts.map +1 -1
- package/out/map/useMapLabelPick.js +21 -30
- package/out/map/useMapLabelPick.js.map +1 -1
- package/out/map/useMapPlaceRender.d.ts +2 -6
- package/out/map/useMapPlaceRender.d.ts.map +1 -1
- package/out/map/useMapPlaceRender.js +2 -6
- package/out/map/useMapPlaceRender.js.map +1 -1
- package/out/map/usePlaceAutocomplete.d.ts +30 -28
- package/out/map/usePlaceAutocomplete.d.ts.map +1 -1
- package/out/map/usePlaceAutocomplete.js +6 -33
- package/out/map/usePlaceAutocomplete.js.map +1 -1
- package/out/map.d.ts +69 -0
- package/out/map.d.ts.map +1 -0
- package/out/map.js +46 -0
- package/out/map.js.map +1 -0
- package/out/pipeline/CandidatePicker.d.ts +12 -2
- package/out/pipeline/CandidatePicker.d.ts.map +1 -1
- package/out/pipeline/CandidatePicker.js +1 -1
- package/out/pipeline/CandidatePicker.js.map +1 -1
- package/out/pipeline/ConfidenceCell.d.ts +1 -1
- package/out/pipeline/ConfidenceCell.js +1 -1
- package/out/pipeline/FailureDiagnostic.d.ts +8 -2
- package/out/pipeline/FailureDiagnostic.d.ts.map +1 -1
- package/out/pipeline/FailureDiagnostic.js +3 -0
- package/out/pipeline/FailureDiagnostic.js.map +1 -1
- package/out/pipeline/QueryForm.d.ts +5 -2
- package/out/pipeline/QueryForm.d.ts.map +1 -1
- package/out/pipeline/QueryForm.js.map +1 -1
- package/out/pipeline/SpanHighlight.d.ts +4 -3
- package/out/pipeline/SpanHighlight.d.ts.map +1 -1
- package/out/pipeline/SpanHighlight.js +3 -2
- package/out/pipeline/SpanHighlight.js.map +1 -1
- package/out/pipeline/TimingPanel.d.ts +1 -1
- package/out/pipeline/TreeView.d.ts +1 -1
- package/out/pipeline/copy.d.ts +1 -1
- package/out/pipeline/copy.d.ts.map +1 -1
- package/out/pipeline/copy.js +4 -3
- package/out/pipeline/copy.js.map +1 -1
- package/out/pipeline/presets.d.ts +5 -4
- package/out/pipeline/presets.d.ts.map +1 -1
- package/out/pipeline/presets.js +15 -13
- package/out/pipeline/presets.js.map +1 -1
- package/out/pipeline/types.d.ts +21 -14
- package/out/pipeline/types.d.ts.map +1 -1
- package/out/pipeline/types.js +2 -4
- package/out/pipeline/types.js.map +1 -1
- package/out/pipeline/useParsePipeline.d.ts +14 -9
- package/out/pipeline/useParsePipeline.d.ts.map +1 -1
- package/out/pipeline/useParsePipeline.js +7 -8
- package/out/pipeline/useParsePipeline.js.map +1 -1
- package/out/pipeline.d.ts +33 -0
- package/out/pipeline.d.ts.map +1 -0
- package/out/pipeline.js +21 -0
- package/out/pipeline.js.map +1 -0
- package/out/poi/AbstainPanel.d.ts +1 -1
- package/out/poi/LiveResultsBlock.d.ts +2 -1
- package/out/poi/LiveResultsBlock.d.ts.map +1 -1
- package/out/poi/LiveResultsBlock.js.map +1 -1
- package/out/poi/POIExplorer.d.ts +22 -12
- package/out/poi/POIExplorer.d.ts.map +1 -1
- package/out/poi/POIExplorer.js +9 -8
- package/out/poi/POIExplorer.js.map +1 -1
- package/out/poi/QueryInput.d.ts +1 -1
- package/out/poi/SubjectPanel.d.ts +2 -2
- package/out/poi/SubjectPanel.d.ts.map +1 -1
- package/out/poi/SubjectPanel.js +2 -1
- package/out/poi/SubjectPanel.js.map +1 -1
- package/out/poi/runtime.d.ts +5 -14
- package/out/poi/runtime.d.ts.map +1 -1
- package/out/poi/runtime.js +5 -16
- package/out/poi/runtime.js.map +1 -1
- package/out/poi/types.d.ts +39 -27
- package/out/poi/types.d.ts.map +1 -1
- package/out/poi/types.js +2 -4
- package/out/poi/types.js.map +1 -1
- package/out/poi/usePOISearch.d.ts +28 -17
- package/out/poi/usePOISearch.d.ts.map +1 -1
- package/out/poi/usePOISearch.js +6 -32
- package/out/poi/usePOISearch.js.map +1 -1
- package/out/poi.d.ts +23 -0
- package/out/poi.d.ts.map +1 -0
- package/out/poi.js +15 -0
- package/out/poi.js.map +1 -0
- package/out/runtime/useReleaseRuntime.d.ts +64 -65
- package/out/runtime/useReleaseRuntime.d.ts.map +1 -1
- package/out/runtime/useReleaseRuntime.js +31 -26
- package/out/runtime/useReleaseRuntime.js.map +1 -1
- package/out/{runtime/index.d.ts → runtime.d.ts} +1 -1
- package/out/runtime.d.ts.map +1 -0
- package/out/{runtime/index.js → runtime.js} +1 -1
- package/out/runtime.js.map +1 -0
- package/out/search/SearchModal.d.ts +33 -0
- package/out/search/SearchModal.d.ts.map +1 -0
- package/out/search/SearchModal.js +187 -0
- package/out/search/SearchModal.js.map +1 -0
- package/out/search/types.d.ts +64 -0
- package/out/search/types.d.ts.map +1 -0
- package/out/search/types.js +13 -0
- package/out/search/types.js.map +1 -0
- package/out/search.d.ts +11 -0
- package/out/search.d.ts.map +1 -0
- package/out/search.js +9 -0
- package/out/search.js.map +1 -0
- package/package.json +60 -142
- package/styles.css +482 -266
- package/tokens/index.css +24 -6
- package/tokens/tokens.json +114 -6
- package/lib/common/index.ts +0 -22
- package/lib/map/index.ts +0 -95
- package/lib/pipeline/index.ts +0 -36
- package/lib/poi/index.ts +0 -39
- package/out/common/index.d.ts +0 -22
- package/out/common/index.d.ts.map +0 -1
- package/out/common/index.js +0 -15
- package/out/common/index.js.map +0 -1
- package/out/map/index.d.ts +0 -69
- package/out/map/index.d.ts.map +0 -1
- package/out/map/index.js +0 -46
- package/out/map/index.js.map +0 -1
- package/out/pipeline/index.d.ts +0 -33
- package/out/pipeline/index.d.ts.map +0 -1
- package/out/pipeline/index.js +0 -21
- package/out/pipeline/index.js.map +0 -1
- package/out/poi/index.d.ts +0 -23
- package/out/poi/index.d.ts.map +0 -1
- package/out/poi/index.js +0 -15
- package/out/poi/index.js.map +0 -1
- package/out/runtime/index.d.ts.map +0 -1
- package/out/runtime/index.js.map +0 -1
- package/styleframe.config.ts +0 -329
- package/vitest.node.config.ts +0 -20
- /package/lib/{runtime/index.ts → runtime.ts} +0 -0
|
@@ -2,18 +2,10 @@
|
|
|
2
2
|
* @copyright Sister Software
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* The geocoder's chrome over the map: a search pill on top, example chips on one line beneath it, a control column
|
|
7
|
-
* down the right edge, and a result sheet that rises from the bottom when there is something to show.
|
|
8
|
-
*
|
|
9
|
-
* It replaces a 400px full-height panel that carried every control at once. The layout is the one the reference
|
|
10
|
-
* map apps use, and the reason is the map: chrome that floats over it leaves the map the page, where a slab makes
|
|
11
|
-
* the map the leftover third.
|
|
12
|
-
*
|
|
13
|
-
* NODE-SAFE: pure React + the shared units, no maplibre.
|
|
14
5
|
*/
|
|
15
6
|
|
|
16
|
-
import
|
|
7
|
+
import type React from "react"
|
|
8
|
+
import { type ReactNode, useCallback, useEffect, useRef, useState } from "react"
|
|
17
9
|
import type { MapInstance } from "react-map-gl/maplibre"
|
|
18
10
|
|
|
19
11
|
import type { GeocoderPanels, GeocoderRuntime } from "#map/types"
|
|
@@ -27,79 +19,74 @@ import { LoadingIndicator } from "../common/LoadingIndicator.tsx"
|
|
|
27
19
|
import type { Preset } from "../common/PresetChips.tsx"
|
|
28
20
|
import { BackendControl } from "./BackendControl.tsx"
|
|
29
21
|
import { CompareToggle } from "./CompareToggle.tsx"
|
|
22
|
+
import { DebugInfo } from "./DebugInfo.tsx"
|
|
30
23
|
import { MapChipRow } from "./MapChipRow.tsx"
|
|
31
24
|
import { MapCompass } from "./MapCompass.tsx"
|
|
32
25
|
import { MapControlButton, MapControlGroup, MapControlStack } from "./MapControlStack.tsx"
|
|
33
26
|
import { MapProgressBar } from "./MapProgressBar.tsx"
|
|
34
|
-
import { MapSearchBar } from "./MapSearchBar.tsx"
|
|
35
|
-
import { MapSheet } from "./MapSheet.tsx"
|
|
27
|
+
import { MapSearchBar, SearchGlyph } from "./MapSearchBar.tsx"
|
|
28
|
+
import { MapSheet, SheetClose } from "./MapSheet.tsx"
|
|
36
29
|
import { PlaceAutocomplete } from "./PlaceAutocomplete.tsx"
|
|
37
30
|
import { ResultPanel } from "./ResultPanel.tsx"
|
|
38
31
|
import { VersionPicker } from "./VersionPicker.tsx"
|
|
39
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Props for {@linkcode GeocoderControls}.
|
|
35
|
+
*/
|
|
40
36
|
export interface GeocoderControlsProps {
|
|
41
|
-
/**
|
|
42
|
-
* The injected geocoder runtime.
|
|
43
|
-
*/
|
|
44
37
|
runtime: GeocoderRuntime
|
|
45
|
-
/**
|
|
46
|
-
* The parse+resolve state machine.
|
|
47
|
-
*/
|
|
48
38
|
geocode: UseGeocode
|
|
49
|
-
/**
|
|
50
|
-
* The place-autocomplete combobox state.
|
|
51
|
-
*/
|
|
52
39
|
autocomplete: UsePlaceAutocomplete
|
|
53
|
-
/**
|
|
54
|
-
* The compare-mode state.
|
|
55
|
-
*/
|
|
56
40
|
compare: UseCompareState
|
|
57
41
|
/**
|
|
58
|
-
*
|
|
42
|
+
* A query from the URL to run once the runtime is ready.
|
|
59
43
|
*/
|
|
44
|
+
initialQuery?: string | null
|
|
60
45
|
panels: GeocoderPanels
|
|
61
|
-
/**
|
|
62
|
-
* Example chips.
|
|
63
|
-
*/
|
|
64
46
|
presets: ReadonlyArray<Preset>
|
|
65
47
|
/**
|
|
66
|
-
*
|
|
48
|
+
* The input placeholder.
|
|
49
|
+
*
|
|
50
|
+
* The field also selects its value on focus while it still equals this text.
|
|
67
51
|
*/
|
|
68
52
|
placeholder: string
|
|
69
|
-
/**
|
|
70
|
-
* The live map, for the controls that read it: the compass takes its bearing, the host's layer control reads its
|
|
71
|
-
* style. `null` until react-map-gl instantiates the map.
|
|
72
|
-
*/
|
|
73
53
|
map?: MapInstance | null
|
|
74
54
|
/**
|
|
75
|
-
*
|
|
76
|
-
* package never touches `location`, because the address bar is the app's state, not a control's.
|
|
55
|
+
* Called before each user-initiated query, so the host can write the query to its URL.
|
|
77
56
|
*/
|
|
78
57
|
onSubmitQuery?: (query: string) => void
|
|
79
|
-
/**
|
|
80
|
-
* Select a model version (the composed geocoder also clears a now-colliding compare selection).
|
|
81
|
-
*/
|
|
82
58
|
onSelectVersion: (version: string) => void
|
|
83
|
-
/**
|
|
84
|
-
* Toggle the forced WASM backend.
|
|
85
|
-
*/
|
|
86
59
|
onForceWASMChange: (forceWASM: boolean) => void
|
|
87
60
|
/**
|
|
88
|
-
*
|
|
89
|
-
* the model rather than on an address, and above the query field they were the first thing every visitor met.
|
|
61
|
+
* Whether the developer panel starts open.
|
|
90
62
|
*
|
|
91
63
|
* @default false
|
|
92
64
|
*/
|
|
93
65
|
developer?: boolean
|
|
94
66
|
}
|
|
95
67
|
|
|
68
|
+
type SheetName = "about" | "layers" | "developer" | null
|
|
69
|
+
|
|
96
70
|
/**
|
|
97
|
-
*
|
|
71
|
+
* The media query for the bottom-drawer layout.
|
|
72
|
+
* It must match the breakpoint in `styles.css`.
|
|
98
73
|
*/
|
|
99
|
-
|
|
74
|
+
const DRAWER_LAYOUT = "(max-width: 600px)"
|
|
100
75
|
|
|
101
76
|
/**
|
|
102
|
-
* The
|
|
77
|
+
* The pointer travel, in px, that turns a press on the header into a drag instead of a tap.
|
|
78
|
+
*/
|
|
79
|
+
const DRAG_TRAVEL_PX = 3
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The downward travel, in px, that turns a pull at the top of the panel's scroll into a drawer drag.
|
|
83
|
+
*/
|
|
84
|
+
const OVERSCROLL_PROMOTE_PX = 8
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Renders the search and result panels, map control rail and side sheets over the map.
|
|
88
|
+
*
|
|
89
|
+
* On narrow screens, users can drag the search panel between bottom-drawer detents.
|
|
103
90
|
*/
|
|
104
91
|
export function GeocoderControls({
|
|
105
92
|
runtime,
|
|
@@ -110,6 +97,7 @@ export function GeocoderControls({
|
|
|
110
97
|
presets,
|
|
111
98
|
placeholder,
|
|
112
99
|
map = null,
|
|
100
|
+
initialQuery = null,
|
|
113
101
|
onSubmitQuery,
|
|
114
102
|
onSelectVersion,
|
|
115
103
|
onForceWASMChange,
|
|
@@ -120,24 +108,270 @@ export function GeocoderControls({
|
|
|
120
108
|
const loading = runtime.loading
|
|
121
109
|
const errorMessage = geocode.parseError ?? runtime.errorMessage ?? null
|
|
122
110
|
|
|
123
|
-
//
|
|
111
|
+
// Only one side sheet is open at a time, because two would stack on the same edge.
|
|
124
112
|
const [openSheet, setOpenSheet] = useState<SheetName>(developer ? "developer" : null)
|
|
113
|
+
|
|
114
|
+
// This flag hides the result panel until the next query resets it.
|
|
115
|
+
const [resultDismissed, setResultDismissed] = useState(false)
|
|
116
|
+
|
|
117
|
+
// The drawer height is in px.
|
|
118
|
+
// A `null` height leaves the size to the stylesheet.
|
|
119
|
+
const sheetRef = useRef<HTMLElement>(null)
|
|
120
|
+
const [sheetHeight, setSheetHeight] = useState<number | null>(null)
|
|
121
|
+
const sheetDragRef = useRef<{ startY: number; startHeight: number; moved: boolean } | null>(null)
|
|
122
|
+
|
|
123
|
+
// The detents are computed on each call, so a rotated or resized viewport needs no resize listener.
|
|
124
|
+
const sheetDetents = useCallback(() => {
|
|
125
|
+
const viewport = window.innerHeight
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
medium: viewport * 0.52,
|
|
129
|
+
large: viewport * 0.88,
|
|
130
|
+
floor: viewport * 0.15,
|
|
131
|
+
// A drag released below this height dismisses the result.
|
|
132
|
+
dismissBelow: viewport * 0.28,
|
|
133
|
+
// At or below this height, the drawer counts as collapsed.
|
|
134
|
+
// The control rail then returns.
|
|
135
|
+
collapsedBelow: viewport * 0.2,
|
|
136
|
+
}
|
|
137
|
+
}, [])
|
|
138
|
+
|
|
139
|
+
// This ref holds a pull that started at the top of the panel's scroll.
|
|
140
|
+
// It becomes a drag after `OVERSCROLL_PROMOTE_PX` of downward travel.
|
|
141
|
+
const overscrollRef = useRef<{ startY: number; pointerId: number } | null>(null)
|
|
142
|
+
|
|
143
|
+
// Drag gestures apply only in the drawer layout.
|
|
144
|
+
// The desktop column is sized by its content.
|
|
145
|
+
const isDrawerLayout = () => globalThis.window !== undefined && globalThis.matchMedia(DRAWER_LAYOUT).matches
|
|
146
|
+
|
|
147
|
+
const beginSheetDrag = useCallback((clientY: number, pointerId: number) => {
|
|
148
|
+
const sheet = sheetRef.current
|
|
149
|
+
|
|
150
|
+
if (!sheet) return
|
|
151
|
+
|
|
152
|
+
sheet.setPointerCapture(pointerId)
|
|
153
|
+
sheetDragRef.current = { startY: clientY, startHeight: sheet.getBoundingClientRect().height, moved: false }
|
|
154
|
+
}, [])
|
|
155
|
+
|
|
156
|
+
// The whole header is the grab target, except the search input and the close button.
|
|
157
|
+
const onHeaderPointerDown = useCallback(
|
|
158
|
+
(event: React.PointerEvent<HTMLDivElement>) => {
|
|
159
|
+
if (!isDrawerLayout()) return
|
|
160
|
+
|
|
161
|
+
if (event.target instanceof Element && event.target.closest("input, .mw-map-sheet__close")) return
|
|
162
|
+
|
|
163
|
+
beginSheetDrag(event.clientY, event.pointerId)
|
|
164
|
+
},
|
|
165
|
+
[beginSheetDrag]
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
const onGripPointerMove = useCallback(
|
|
169
|
+
(event: React.PointerEvent<HTMLElement>) => {
|
|
170
|
+
const drag = sheetDragRef.current
|
|
171
|
+
|
|
172
|
+
if (!drag) return
|
|
173
|
+
|
|
174
|
+
// An upward drag makes the drawer taller, so the delta is inverted against the pointer's y.
|
|
175
|
+
const delta = drag.startY - event.clientY
|
|
176
|
+
|
|
177
|
+
if (Math.abs(delta) > DRAG_TRAVEL_PX) {
|
|
178
|
+
drag.moved = true
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const { floor, large } = sheetDetents()
|
|
182
|
+
|
|
183
|
+
setSheetHeight(Math.min(large, Math.max(floor, drag.startHeight + delta)))
|
|
184
|
+
},
|
|
185
|
+
[sheetDetents]
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
// A tap, keyboard activation of the handle and the handle's `aria-expanded` state
|
|
189
|
+
// all use this midpoint to select the drawer detent.
|
|
190
|
+
const detentMidpoint = useCallback(() => {
|
|
191
|
+
const { medium, large } = sheetDetents()
|
|
192
|
+
|
|
193
|
+
return (medium + large) / 2
|
|
194
|
+
}, [sheetDetents])
|
|
195
|
+
|
|
196
|
+
const atLargeDetent = () => sheetHeight !== null && sheetHeight > detentMidpoint()
|
|
197
|
+
|
|
198
|
+
const toggleDetent = useCallback(() => {
|
|
199
|
+
const { medium, large } = sheetDetents()
|
|
200
|
+
const current = sheetRef.current?.getBoundingClientRect().height ?? medium
|
|
201
|
+
|
|
202
|
+
setSheetHeight(current > detentMidpoint() ? medium : large)
|
|
203
|
+
}, [sheetDetents, detentMidpoint])
|
|
204
|
+
|
|
205
|
+
const onGripPointerUp = useCallback(() => {
|
|
206
|
+
const drag = sheetDragRef.current
|
|
207
|
+
|
|
208
|
+
if (!drag) return
|
|
209
|
+
|
|
210
|
+
sheetDragRef.current = null
|
|
211
|
+
|
|
212
|
+
const { medium, large, dismissBelow } = sheetDetents()
|
|
213
|
+
const midpoint = (medium + large) / 2
|
|
214
|
+
const current = sheetRef.current?.getBoundingClientRect().height ?? medium
|
|
215
|
+
|
|
216
|
+
// A press without travel counts as a tap.
|
|
217
|
+
// It toggles between the two detents.
|
|
218
|
+
if (!drag.moved) {
|
|
219
|
+
toggleDetent()
|
|
220
|
+
|
|
221
|
+
return
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (current < dismissBelow) {
|
|
225
|
+
setResultDismissed(true)
|
|
226
|
+
setSheetHeight(null)
|
|
227
|
+
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
setSheetHeight(current > midpoint ? large : medium)
|
|
232
|
+
}, [sheetDetents, toggleDetent])
|
|
233
|
+
|
|
234
|
+
// A downward pull on a panel scrolled to its top drags the drawer down.
|
|
235
|
+
// This handler only arms the pull; `onPanelPointerMove` promotes it, so taps
|
|
236
|
+
// and upward scrolls are unaffected.
|
|
237
|
+
const onPanelPointerDown = useCallback((event: React.PointerEvent<HTMLElement>) => {
|
|
238
|
+
if (!isDrawerLayout()) return
|
|
239
|
+
|
|
240
|
+
if (sheetDragRef.current) return
|
|
241
|
+
|
|
242
|
+
const sheet = sheetRef.current
|
|
243
|
+
|
|
244
|
+
if (!sheet || sheet.scrollTop > 0) return
|
|
245
|
+
|
|
246
|
+
if (event.target instanceof Element && event.target.closest(".mw-map-panel__header")) return
|
|
247
|
+
|
|
248
|
+
overscrollRef.current = { startY: event.clientY, pointerId: event.pointerId }
|
|
249
|
+
}, [])
|
|
250
|
+
|
|
251
|
+
const onPanelPointerMove = useCallback(
|
|
252
|
+
(event: React.PointerEvent<HTMLElement>) => {
|
|
253
|
+
if (sheetDragRef.current) {
|
|
254
|
+
onGripPointerMove(event)
|
|
255
|
+
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const armed = overscrollRef.current
|
|
260
|
+
|
|
261
|
+
if (!armed || armed.pointerId !== event.pointerId) return
|
|
262
|
+
|
|
263
|
+
const sheet = sheetRef.current
|
|
264
|
+
|
|
265
|
+
if (!sheet) return
|
|
266
|
+
|
|
267
|
+
if (sheet.scrollTop > 0) {
|
|
268
|
+
overscrollRef.current = null
|
|
269
|
+
|
|
270
|
+
return
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (event.clientY - armed.startY < OVERSCROLL_PROMOTE_PX) return
|
|
274
|
+
|
|
275
|
+
overscrollRef.current = null
|
|
276
|
+
// The drag starts from the pull's origin, so the drawer does not jump by the threshold.
|
|
277
|
+
sheetDragRef.current = { startY: armed.startY, startHeight: sheet.getBoundingClientRect().height, moved: true }
|
|
278
|
+
sheet.setPointerCapture(event.pointerId)
|
|
279
|
+
onGripPointerMove(event)
|
|
280
|
+
},
|
|
281
|
+
[onGripPointerMove]
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
const onPanelPointerUp = useCallback(() => {
|
|
285
|
+
overscrollRef.current = null
|
|
286
|
+
onGripPointerUp()
|
|
287
|
+
}, [onGripPointerUp])
|
|
288
|
+
|
|
125
289
|
const { bearing, resetNorth } = useMapBearing(map)
|
|
126
290
|
|
|
127
291
|
const toggleSheet = (name: Exclude<SheetName, null>) => setOpenSheet((current) => (current === name ? null : name))
|
|
128
292
|
const closeSheet = useCallback(() => setOpenSheet(null), [])
|
|
129
293
|
|
|
130
|
-
// Every
|
|
131
|
-
// caused it, rather than an effect watching the result after the fact.
|
|
294
|
+
// Every user-initiated query goes through this function, so `onSubmitQuery` fires from one place.
|
|
132
295
|
const runQuery = useCallback(
|
|
133
296
|
(query: string) => {
|
|
297
|
+
// A new query shows the result panel again at its default height.
|
|
298
|
+
setResultDismissed(false)
|
|
299
|
+
setSheetHeight(null)
|
|
134
300
|
onSubmitQuery?.(query)
|
|
135
301
|
void geocode.submit(query)
|
|
136
302
|
},
|
|
137
303
|
[onSubmitQuery, geocode]
|
|
138
304
|
)
|
|
139
305
|
|
|
140
|
-
//
|
|
306
|
+
// The initial query waits for `runtime.ready` because the parse pipeline drops
|
|
307
|
+
// a submit made before the model loads.
|
|
308
|
+
// The ref makes it run once, so a later render cannot overwrite the user's own query.
|
|
309
|
+
const autoRanInitialQuery = useRef(false)
|
|
310
|
+
|
|
311
|
+
useEffect(() => {
|
|
312
|
+
if (autoRanInitialQuery.current) return
|
|
313
|
+
|
|
314
|
+
if (!initialQuery || !runtime.ready) return
|
|
315
|
+
|
|
316
|
+
autoRanInitialQuery.current = true
|
|
317
|
+
// This calls `geocode.submit` directly because the query is already in the URL.
|
|
318
|
+
void geocode.submit(initialQuery)
|
|
319
|
+
}, [initialQuery, runtime.ready, geocode])
|
|
320
|
+
|
|
321
|
+
// A drawer-breakpoint crossing clears any dragged height.
|
|
322
|
+
// The height could clip the desktop column.
|
|
323
|
+
useEffect(() => {
|
|
324
|
+
const query = globalThis.matchMedia(DRAWER_LAYOUT)
|
|
325
|
+
const onChange = () => setSheetHeight(null)
|
|
326
|
+
|
|
327
|
+
query.addEventListener("change", onChange)
|
|
328
|
+
|
|
329
|
+
return () => query.removeEventListener("change", onChange)
|
|
330
|
+
}, [])
|
|
331
|
+
|
|
332
|
+
// A user pan, zoom, or rotate shrinks the drawer to its floor detent without dismissing the result.
|
|
333
|
+
// Programmatic camera moves, such as the fly-to after a query, have no `originalEvent` and are ignored.
|
|
334
|
+
useEffect(() => {
|
|
335
|
+
if (!map) return
|
|
336
|
+
|
|
337
|
+
const collapse = (event: { originalEvent?: unknown }) => {
|
|
338
|
+
if (!event.originalEvent) return
|
|
339
|
+
|
|
340
|
+
if (!isDrawerLayout()) return
|
|
341
|
+
|
|
342
|
+
const { floor } = sheetDetents()
|
|
343
|
+
|
|
344
|
+
setSheetHeight((current) => (current !== null && current <= floor ? current : floor))
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
map.on("dragstart", collapse)
|
|
348
|
+
map.on("zoomstart", collapse)
|
|
349
|
+
map.on("rotatestart", collapse)
|
|
350
|
+
|
|
351
|
+
return () => {
|
|
352
|
+
map.off("dragstart", collapse)
|
|
353
|
+
map.off("zoomstart", collapse)
|
|
354
|
+
map.off("rotatestart", collapse)
|
|
355
|
+
}
|
|
356
|
+
}, [map, sheetDetents])
|
|
357
|
+
|
|
358
|
+
// Escape dismisses the result only while no side sheet is open.
|
|
359
|
+
// `MapSheet` also listens for Escape on the document, so one keystroke would otherwise close both.
|
|
360
|
+
useEffect(() => {
|
|
361
|
+
if (openSheet) return
|
|
362
|
+
|
|
363
|
+
const onKeyDown = (event: KeyboardEvent) => {
|
|
364
|
+
if (event.key === "Escape") {
|
|
365
|
+
setResultDismissed(true)
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
document.addEventListener("keydown", onKeyDown)
|
|
370
|
+
|
|
371
|
+
return () => document.removeEventListener("keydown", onKeyDown)
|
|
372
|
+
}, [openSheet])
|
|
373
|
+
|
|
374
|
+
// A map-label click searches for its name.
|
|
141
375
|
const pickLabel = useCallback(
|
|
142
376
|
(name: string) => {
|
|
143
377
|
geocode.setText(name)
|
|
@@ -150,48 +384,105 @@ export function GeocoderControls({
|
|
|
150
384
|
useMapLabelPick(map, pickLabel)
|
|
151
385
|
|
|
152
386
|
const chips = presets.map((preset) => ({ label: preset.label, value: preset.value }))
|
|
153
|
-
// The
|
|
154
|
-
//
|
|
155
|
-
const showSheet = Boolean(busy || result || errorMessage)
|
|
387
|
+
// The model download does not open the result panel.
|
|
388
|
+
// The progress bar reports it instead.
|
|
389
|
+
const showSheet = Boolean(busy || result || errorMessage) && !resultDismissed
|
|
390
|
+
|
|
391
|
+
// The control rail hides while the drawer is raised above its collapsed height.
|
|
392
|
+
const drawerRaised =
|
|
393
|
+
showSheet &&
|
|
394
|
+
(sheetHeight === null || (globalThis.window !== undefined && sheetHeight > sheetDetents().collapsedBelow))
|
|
156
395
|
|
|
157
396
|
const bundleLoading = Boolean(loading && !runtime.ready)
|
|
158
397
|
const steps = loading?.stepLabels.length ?? 0
|
|
159
398
|
|
|
399
|
+
// The model downloads during the first step.
|
|
400
|
+
// While bytes arrive, the bar follows the byte fraction scaled into the first step's share,
|
|
401
|
+
// so it does not move backwards when step progress takes over.
|
|
402
|
+
const stepFraction = steps ? ((loading?.stepIndex ?? 0) + 1) / steps : null
|
|
403
|
+
const byteFraction = loading?.byteFraction
|
|
404
|
+
|
|
405
|
+
const fraction =
|
|
406
|
+
typeof byteFraction === "number" && steps ? (byteFraction * 1) / steps : (byteFraction ?? stepFraction)
|
|
407
|
+
|
|
160
408
|
return (
|
|
161
409
|
<>
|
|
162
|
-
<MapProgressBar
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
<
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
410
|
+
<MapProgressBar active={bundleLoading} fraction={fraction} label="Loading the geocoder" />
|
|
411
|
+
|
|
412
|
+
{/* One panel holds the search, examples and result. On desktop it is a left column sized to its content.
|
|
413
|
+
On narrow screens it is a bottom drawer. */}
|
|
414
|
+
<section
|
|
415
|
+
className="mw-map-panel"
|
|
416
|
+
aria-label="Search and results"
|
|
417
|
+
ref={sheetRef}
|
|
418
|
+
onPointerDown={onPanelPointerDown}
|
|
419
|
+
onPointerMove={onPanelPointerMove}
|
|
420
|
+
onPointerUp={onPanelPointerUp}
|
|
421
|
+
onPointerCancel={onPanelPointerUp}
|
|
422
|
+
{...(sheetHeight === null ? {} : { style: { maxHeight: `${Math.round(sheetHeight)}px` } })}
|
|
423
|
+
>
|
|
424
|
+
{/*
|
|
425
|
+
* The header holds the grab bar and search field.
|
|
426
|
+
* It stays pinned while the result scrolls.
|
|
427
|
+
*/}
|
|
428
|
+
<div className="mw-map-panel__header" onPointerDown={onHeaderPointerDown}>
|
|
429
|
+
<div className="mw-map-panel__grip">
|
|
430
|
+
{/* The handle appears only with a result, because there is no content to expand without one. */}
|
|
431
|
+
{showSheet ? (
|
|
432
|
+
<button
|
|
433
|
+
type="button"
|
|
434
|
+
className="mw-map-sheet__handle"
|
|
435
|
+
aria-label="Resize the panel"
|
|
436
|
+
aria-expanded={atLargeDetent()}
|
|
437
|
+
// The header handles pointer gestures.
|
|
438
|
+
// A click with `detail === 0` comes from the keyboard,
|
|
439
|
+
// so only that toggles the detent here.
|
|
440
|
+
onClick={(event) => {
|
|
441
|
+
if (event.detail !== 0) return
|
|
442
|
+
|
|
443
|
+
toggleDetent()
|
|
444
|
+
}}
|
|
445
|
+
/>
|
|
446
|
+
) : null}
|
|
447
|
+
|
|
448
|
+
{showSheet ? (
|
|
449
|
+
<SheetClose
|
|
450
|
+
label="Close the result"
|
|
451
|
+
className="mw-map-sheet__close--floating"
|
|
452
|
+
onClose={() => setResultDismissed(true)}
|
|
453
|
+
/>
|
|
454
|
+
) : null}
|
|
455
|
+
</div>
|
|
456
|
+
|
|
457
|
+
<form
|
|
458
|
+
className="mw-map-panel__search"
|
|
459
|
+
onSubmit={(event) => {
|
|
460
|
+
event.preventDefault()
|
|
461
|
+
runQuery(geocode.text)
|
|
462
|
+
}}
|
|
463
|
+
>
|
|
464
|
+
{/* The search bar has no trailing control because `type="search"` provides a native clear button. */}
|
|
465
|
+
<MapSearchBar label="Search addresses" leading={<SearchGlyph />} busy={busy}>
|
|
466
|
+
<input
|
|
467
|
+
id="mw-pipeline-input"
|
|
468
|
+
type="search"
|
|
469
|
+
aria-label="Address"
|
|
470
|
+
value={geocode.text}
|
|
471
|
+
onChange={(event) => geocode.setText(event.target.value)}
|
|
472
|
+
// Focus selects the value only while it equals the placeholder, so typing replaces it.
|
|
473
|
+
onFocus={(event) => {
|
|
474
|
+
if (placeholder && event.currentTarget.value === placeholder) {
|
|
475
|
+
event.currentTarget.select()
|
|
476
|
+
}
|
|
477
|
+
}}
|
|
478
|
+
disabled={!runtime.ready}
|
|
479
|
+
placeholder={placeholder}
|
|
480
|
+
onKeyDown={autocomplete.onInputKeyDown}
|
|
481
|
+
{...autocomplete.inputProps}
|
|
482
|
+
/>
|
|
483
|
+
</MapSearchBar>
|
|
484
|
+
</form>
|
|
485
|
+
</div>
|
|
195
486
|
|
|
196
487
|
<PlaceAutocomplete
|
|
197
488
|
suggestions={autocomplete.suggestions}
|
|
@@ -215,14 +506,49 @@ export function GeocoderControls({
|
|
|
215
506
|
/>
|
|
216
507
|
|
|
217
508
|
{panels.bias}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
509
|
+
|
|
510
|
+
{showSheet ? (
|
|
511
|
+
<div className="mw-map-panel__result">
|
|
512
|
+
{errorMessage ? <p className="mw-error">{errorMessage}</p> : null}
|
|
513
|
+
|
|
514
|
+
{panels.aboveResult ? panels.aboveResult({ result }) : null}
|
|
515
|
+
|
|
516
|
+
{busy ? (
|
|
517
|
+
<div className="mw-result">
|
|
518
|
+
<LoadingIndicator mode="staged" steps={runtime.parseStageLabels} activeStep={geocode.parseStage} />
|
|
519
|
+
</div>
|
|
520
|
+
) : result ? (
|
|
521
|
+
panels.result ? (
|
|
522
|
+
panels.result({
|
|
523
|
+
result,
|
|
524
|
+
selectedCandidate,
|
|
525
|
+
selectedCandidateIndex: geocode.selectedCandidateIndex,
|
|
526
|
+
onSelectCandidate: geocode.selectCandidate,
|
|
527
|
+
})
|
|
528
|
+
) : (
|
|
529
|
+
<ResultPanel
|
|
530
|
+
result={result}
|
|
531
|
+
selectedCandidate={selectedCandidate}
|
|
532
|
+
selectedCandidateIndex={geocode.selectedCandidateIndex}
|
|
533
|
+
onSelectCandidate={geocode.selectCandidate}
|
|
534
|
+
extras={panels.extras}
|
|
535
|
+
failure={panels.failure}
|
|
536
|
+
/>
|
|
537
|
+
)
|
|
538
|
+
) : null}
|
|
539
|
+
|
|
540
|
+
{panels.compare
|
|
541
|
+
? panels.compare({ result, compareMode: compare.compareMode, compareVersion: compare.compareVersion })
|
|
542
|
+
: null}
|
|
543
|
+
|
|
544
|
+
{panels.permalink ? <div className="mw-map-sheet__actions">{panels.permalink(geocode.text)}</div> : null}
|
|
545
|
+
</div>
|
|
546
|
+
) : null}
|
|
547
|
+
</section>
|
|
548
|
+
|
|
549
|
+
{/* Every floating control uses this rail to prevent overlap. The compass has its own group because it appears
|
|
550
|
+
and disappears. The rail hides while the drawer is raised. */}
|
|
551
|
+
<MapControlStack label="Map controls" className={drawerRaised ? "mw-map-control-stack--drawer-open" : undefined}>
|
|
226
552
|
<MapControlGroup>
|
|
227
553
|
<MapControlButton
|
|
228
554
|
label="About this geocoder"
|
|
@@ -290,6 +616,16 @@ export function GeocoderControls({
|
|
|
290
616
|
/>
|
|
291
617
|
</div>
|
|
292
618
|
|
|
619
|
+
<div className="mw-map-sheet__row">
|
|
620
|
+
<span className="mw-map-sheet__label">Debug info</span>
|
|
621
|
+
<DebugInfo
|
|
622
|
+
activeBackend={runtime.activeBackend}
|
|
623
|
+
forceWASM={runtime.forceWASM}
|
|
624
|
+
selectedVersion={runtime.selectedVersion}
|
|
625
|
+
ready={runtime.ready}
|
|
626
|
+
/>
|
|
627
|
+
</div>
|
|
628
|
+
|
|
293
629
|
<div className="mw-map-sheet__row">
|
|
294
630
|
<CompareToggle
|
|
295
631
|
versions={versions}
|
|
@@ -306,46 +642,6 @@ export function GeocoderControls({
|
|
|
306
642
|
</MapSheet>
|
|
307
643
|
) : null}
|
|
308
644
|
|
|
309
|
-
{showSheet ? (
|
|
310
|
-
<section className="mw-map-sheet mw-map-sheet--bottom" aria-label="Result">
|
|
311
|
-
<div className="mw-map-sheet__handle" aria-hidden="true" />
|
|
312
|
-
|
|
313
|
-
{errorMessage ? <p className="mw-error">{errorMessage}</p> : null}
|
|
314
|
-
|
|
315
|
-
{panels.aboveResult ? panels.aboveResult({ result }) : null}
|
|
316
|
-
|
|
317
|
-
{busy ? (
|
|
318
|
-
<div className="mw-result">
|
|
319
|
-
<LoadingIndicator mode="staged" steps={runtime.parseStageLabels} activeStep={geocode.parseStage} />
|
|
320
|
-
</div>
|
|
321
|
-
) : result ? (
|
|
322
|
-
panels.result ? (
|
|
323
|
-
panels.result({
|
|
324
|
-
result,
|
|
325
|
-
selectedCandidate,
|
|
326
|
-
selectedCandidateIndex: geocode.selectedCandidateIndex,
|
|
327
|
-
onSelectCandidate: geocode.selectCandidate,
|
|
328
|
-
})
|
|
329
|
-
) : (
|
|
330
|
-
<ResultPanel
|
|
331
|
-
result={result}
|
|
332
|
-
selectedCandidate={selectedCandidate}
|
|
333
|
-
selectedCandidateIndex={geocode.selectedCandidateIndex}
|
|
334
|
-
onSelectCandidate={geocode.selectCandidate}
|
|
335
|
-
extras={panels.extras}
|
|
336
|
-
failure={panels.failure}
|
|
337
|
-
/>
|
|
338
|
-
)
|
|
339
|
-
) : null}
|
|
340
|
-
|
|
341
|
-
{panels.compare
|
|
342
|
-
? panels.compare({ result, compareMode: compare.compareMode, compareVersion: compare.compareVersion })
|
|
343
|
-
: null}
|
|
344
|
-
|
|
345
|
-
{panels.permalink ? <div className="mw-map-sheet__actions">{panels.permalink(geocode.text)}</div> : null}
|
|
346
|
-
</section>
|
|
347
|
-
) : null}
|
|
348
|
-
|
|
349
645
|
{panels.footer}
|
|
350
646
|
</>
|
|
351
647
|
)
|