@@ -113,6 +113,7 @@ const PIN_HALO_MIN_ZOOM = 8;
113113const PIN_HALO_MIN_SCALE = 0.18 ;
114114const PIN_HALO_FULL_ZOOM = MAP_MAX_ZOOM ;
115115const PIN_HALO_GROWTH_EXPONENT = 2.2 ;
116+ const MAP_ZOOM_DISABLED_EPSILON = 0.001 ;
116117
117118type MapPinZoomStyle = CSSProperties & {
118119 "--map-pin-compact-scale" : string ;
@@ -167,6 +168,10 @@ function resolveMapPinZoomVariables(zoom: number): MapPinZoomStyle {
167168 } ;
168169}
169170
171+ function isMapZoomAtMax ( zoom : number ) {
172+ return zoom >= MAP_MAX_ZOOM - MAP_ZOOM_DISABLED_EPSILON ;
173+ }
174+
170175function resolveInitialViewState (
171176 selectedListing : SelectedListing | null ,
172177 initialCoordinates : InitialMapCoordinates | null
@@ -229,6 +234,9 @@ export default function MapView({
229234 ( ) => resolveInitialViewState ( selectedListing , initialCoordinates ) ,
230235 [ initialCoordinates , selectedListing ]
231236 ) ;
237+ const [ isZoomInDisabled , setIsZoomInDisabled ] = useState ( ( ) =>
238+ isMapZoomAtMax ( initialViewState . zoom )
239+ ) ;
232240 const hasInitialPosition =
233241 hasValidCoordinates ( selectedListing ) || initialCoordinates !== null ;
234242
@@ -258,6 +266,16 @@ export default function MapView({
258266 [ requestBounds ]
259267 ) ;
260268
269+ const syncZoomControlState = useCallback ( ( zoom : number ) => {
270+ const nextIsZoomInDisabled = isMapZoomAtMax ( zoom ) ;
271+
272+ setIsZoomInDisabled ( ( currentIsZoomInDisabled ) =>
273+ currentIsZoomInDisabled === nextIsZoomInDisabled
274+ ? currentIsZoomInDisabled
275+ : nextIsZoomInDisabled
276+ ) ;
277+ } , [ ] ) ;
278+
261279 const applyMapPinZoomVariables = useCallback ( ( zoom : number ) => {
262280 const container = mapContainerRef . current ;
263281 if ( ! container ) return ;
@@ -324,10 +342,11 @@ export default function MapView({
324342 if ( ! map ) return null ;
325343
326344 applyMapPinZoomVariables ( map . getZoom ( ) ) ;
345+ syncZoomControlState ( map . getZoom ( ) ) ;
327346 emitBoundsChange ( map . getBounds ( ) ) ;
328347
329348 return map ;
330- } , [ applyMapPinZoomVariables , emitBoundsChange ] ) ;
349+ } , [ applyMapPinZoomVariables , emitBoundsChange , syncZoomControlState ] ) ;
331350
332351 const handleLoad = useCallback ( ( ) => {
333352 handleMapLoad ( ) ;
@@ -389,8 +408,9 @@ export default function MapView({
389408 const handleMove = useCallback (
390409 ( event : ViewStateChangeEvent ) => {
391410 scheduleMapPinZoomUpdate ( event . viewState . zoom ) ;
411+ syncZoomControlState ( event . viewState . zoom ) ;
392412 } ,
393- [ scheduleMapPinZoomUpdate ]
413+ [ scheduleMapPinZoomUpdate , syncZoomControlState ]
394414 ) ;
395415
396416 const handleMoveEnd = useCallback (
@@ -517,6 +537,7 @@ export default function MapView({
517537 onZoomIn = { zoomIn }
518538 onZoomOut = { zoomOut }
519539 searchLabel = { t ( "searchLabel" ) }
540+ zoomInDisabled = { isZoomInDisabled }
520541 zoomInLabel = { t ( "zoomInControl" ) }
521542 zoomOutLabel = { t ( "zoomOutControl" ) }
522543 />
0 commit comments