5
5
6
6
import "./GeoAddressSearch.scss" ;
7
7
import * as React from "react" ;
8
+ import { useActiveViewport } from "@itwin/appui-react" ;
9
+ import { BaseMapLayerSettings } from "@itwin/core-common" ;
8
10
import { SvgCloseSmall , SvgSearch } from "@itwin/itwinui-icons-react" ;
9
11
import { ComboBox , IconButton } from "@itwin/itwinui-react" ;
10
12
import { BingAddressProvider } from "../BingAddressProvider" ;
11
13
import { GeoTools } from "../GeoTools" ;
14
+ import { GoogleAddressProvider } from "../GoogleAddressProvider" ;
12
15
import { IModelGeoView } from "../IModelGeoView" ;
13
16
17
+ import type { Viewport } from "@itwin/core-frontend" ;
14
18
import type { SelectOption } from "@itwin/itwinui-react" ;
15
19
import type { AddressData , AddressProvider } from "../AddressProvider" ;
20
+ /**
21
+ * Properties for the <GeoAddressSearch> component.
22
+ */
16
23
export interface GeoAddressSearchProps {
17
24
/** Address provider object */
18
25
provider ?: AddressProvider ;
19
26
/** Indicates whether to set focus to the input element (default to true)*/
20
27
setFocus ?: boolean ;
21
28
}
22
29
30
+ const isGoogleBaseMap = ( vp ?: Viewport ) : boolean => {
31
+ return (
32
+ vp ?. viewFlags . backgroundMap === true
33
+ && vp ?. displayStyle . backgroundMapBase instanceof BaseMapLayerSettings
34
+ && vp . displayStyle . backgroundMapBase . formatId === "GoogleMaps"
35
+ ) ;
36
+ } ;
37
+ const isValidBaseMap = ( provider : AddressProvider , vp ?: Viewport ) => {
38
+ const isGoogleAddressProvider = provider instanceof GoogleAddressProvider ;
39
+ return ! isGoogleAddressProvider || ( isGoogleAddressProvider && isGoogleBaseMap ( vp ) ) ;
40
+ }
41
+
42
+ /**
43
+ * <GeoAddressSearch> react component
44
+ */
23
45
export function GeoAddressSearch ( props : GeoAddressSearchProps ) {
24
46
const [ inputValue , setInputValue ] = React . useState ( "" ) ;
25
47
const [ options , setOptions ] = React . useState < SelectOption < string > [ ] > ( [ ] ) ;
26
48
const [ addressCache , setAddressCache ] = React . useState < AddressData [ ] > ( [ ] ) ;
49
+ const activeViewport = useActiveViewport ( ) ; // Hook to ensure the component re-renders when the active viewport changes
50
+ const [ disabled , setDisabled ] = React . useState < boolean > ( ( ) => isGoogleBaseMap ( activeViewport ) ) ;
27
51
28
52
// `React.useMemo' is used avoid creating new object on each render cycle
29
53
// Default is Bing provider, but we might want to default to Google in the future
30
54
const addressProvider = React . useMemo ( ( ) => props . provider ?? new BingAddressProvider ( ) , [ props . provider ] ) ;
31
55
56
+ React . useEffect ( ( ) => {
57
+ setDisabled ( ! isValidBaseMap ( addressProvider , activeViewport ) ) ;
58
+ return activeViewport ?. onDisplayStyleChanged . addListener (
59
+ ( vp ) => { setDisabled ( ! isValidBaseMap ( addressProvider , vp ) ) ; }
60
+ ) ;
61
+ } , [ activeViewport ] ) ;
62
+
32
63
const onAddressSelected = async ( selected : string ) => {
33
64
setInputValue ( selected ) ;
34
65
let locatedByPosition = false
@@ -69,12 +100,14 @@ export function GeoAddressSearch(props: GeoAddressSearchProps) {
69
100
< div className = "geotools-geoaddresssearch__container" >
70
101
< div className = "geotools-geoaddresssearch__combobox" >
71
102
< ComboBox
103
+
72
104
options = { options }
73
105
filterFunction = { ( options ) => options } // disable filtering as it can interfere with the address provider
74
106
emptyStateMessage = { GeoTools . translate ( "geoAddressSearch.noResults" ) }
75
107
onHide = { ( ) => clearValue ( ) }
76
108
inputProps = { {
77
- placeholder : GeoTools . translate ( "geoAddressSearch.inputPlaceHolder" ) ,
109
+ disabled,
110
+ placeholder : disabled ? GeoTools . translate ( "geoAddressSearch.invalidBaseMap" ) : GeoTools . translate ( "geoAddressSearch.inputPlaceHolder" ) ,
78
111
onChange : async ( event : React . ChangeEvent < HTMLInputElement > ) => {
79
112
80
113
const items = await getAddressesFunc ( inputValue ) ;
@@ -87,12 +120,15 @@ export function GeoAddressSearch(props: GeoAddressSearchProps) {
87
120
} }
88
121
onChange = { ( value : any ) => {
89
122
onAddressSelected ( value ) ;
123
+
90
124
} }
91
125
value = { inputValue }
92
126
enableVirtualization
93
127
/>
94
128
</ div >
129
+
95
130
< IconButton
131
+ disabled = { disabled }
96
132
className = "geotools-geoaddresssearch__button"
97
133
onClick = { clearValue }
98
134
label = { ! inputValue ? "" : GeoTools . translate ( "geoAddressSearch.clearTooltip" ) } >
0 commit comments