Skip to content

Commit fd238fa

Browse files
committed
feat(Map): add showPopup and scrollWheelZoom props for interaction control
Adds two new props to Map, MapView, and MapContent for better control over map interactions: showPopup: - Controls whether popup bubbles appear on marker clicks - Default: true (existing behavior preserved) - Set to false when using external UI (Inspector, sidebars, modals) - Prevents duplicate information and keeps map cleaner scrollWheelZoom: - Controls scroll wheel zoom behavior - Default: false (uses custom pinch-to-zoom for embedded maps) - Set to true for native Leaflet scroll zoom (best for fullscreen) Implementation: - Props threaded through Map → MapView → MapContent - showPopup guards popup open/close logic in MapContent - Conditional popup rendering based on showPopup flag - Comprehensive JSDoc with usage guidance
1 parent e4bd1f3 commit fd238fa

File tree

5 files changed

+44
-17
lines changed

5 files changed

+44
-17
lines changed

packages/ui/src/components/Map/CompactMap.stories.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ const CompactMapDoc: FC = () => {
8080
const [pinSelectedId, setPinSelectedId] = useState<string | undefined>(undefined);
8181
const [dotSelectedId, setDotSelectedId] = useState<string | undefined>(undefined);
8282
const [hybridSelectedId, setHybridSelectedId] = useState<string | undefined>(undefined);
83+
const [withPopupSelectedId, setWithPopupSelectedId] = useState<string | undefined>(undefined);
84+
const [withoutPopupSelectedId, setWithoutPopupSelectedId] = useState<string | undefined>(undefined);
8385
const locations = useMemo(() => sampleLocations, []);
8486

8587
return (
@@ -542,7 +544,9 @@ const CompactMapDoc: FC = () => {
542544
With Popups (default)
543545
</h3>
544546
<CompactMap
545-
locations={locations.slice(0, 2)}
547+
locations={locations}
548+
selectedId={withPopupSelectedId}
549+
onLocationSelect={setWithPopupSelectedId}
546550
showPopup={true}
547551
height={CHATGPT_APP_HEIGHT}
548552
/>
@@ -568,7 +572,9 @@ const CompactMapDoc: FC = () => {
568572
Without Popups
569573
</h3>
570574
<CompactMap
571-
locations={locations.slice(0, 2)}
575+
locations={locations}
576+
selectedId={withoutPopupSelectedId}
577+
onLocationSelect={setWithoutPopupSelectedId}
572578
showPopup={false}
573579
height={CHATGPT_APP_HEIGHT}
574580
/>

packages/ui/src/components/Map/CompactMap.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ export const CompactMap: React.FC<CompactMapProps> = ({
6565
markerVariant,
6666
renderMarker,
6767
isInspectorOpen,
68+
scrollWheelZoom,
69+
showPopup,
6870
loading = false,
6971
error = false,
7072
height = DEFAULT_HEIGHT,
@@ -96,6 +98,8 @@ export const CompactMap: React.FC<CompactMapProps> = ({
9698
markerVariant={markerVariant}
9799
renderMarker={renderMarker}
98100
isInspectorOpen={isInspectorOpen}
101+
scrollWheelZoom={scrollWheelZoom}
102+
showPopup={showPopup}
99103
loading={loading}
100104
error={error}
101105
className={cn(styles.mapView, mapClassName)}

packages/ui/src/components/Map/Map.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export const Map: React.FC<MapProps> = ({
6060
markerVariant,
6161
renderMarker,
6262
isInspectorOpen,
63+
scrollWheelZoom,
64+
showPopup,
6365
loading = false,
6466
error = false,
6567
isFullscreen: controlledIsFullscreen,
@@ -117,6 +119,8 @@ export const Map: React.FC<MapProps> = ({
117119
markerVariant,
118120
renderMarker,
119121
isInspectorOpen,
122+
scrollWheelZoom,
123+
showPopup,
120124
loading,
121125
error,
122126
};

packages/ui/src/components/Map/MapContent.tsx

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ export const MapContent: React.FC<MapViewProps> = ({
366366
style,
367367
isInspectorOpen,
368368
scrollWheelZoom = false,
369+
showPopup = true,
369370
}) => {
370371
const containerClassName = className
371372
? `${styles.mapContainer} ${className}`
@@ -476,8 +477,10 @@ export const MapContent: React.FC<MapViewProps> = ({
476477
});
477478
}, [locations]);
478479

479-
// Open/close popups based on selectedId
480+
// Open/close popups based on selectedId (only if showPopup is enabled)
480481
useEffect(() => {
482+
if (!showPopup) return;
483+
481484
// Close all popups
482485
markerRefs.current.forEach((marker) => {
483486
marker.closePopup();
@@ -490,7 +493,7 @@ export const MapContent: React.FC<MapViewProps> = ({
490493
marker.openPopup();
491494
}
492495
}
493-
}, [selectedId]);
496+
}, [selectedId, showPopup]);
494497

495498
// Update marker icons when selection changes
496499
useEffect(() => {
@@ -555,19 +558,21 @@ export const MapContent: React.FC<MapViewProps> = ({
555558
markerRefs.current.delete(location.id);
556559
}}
557560
>
558-
<Popup>
559-
<article className={styles.popup}>
560-
<div className={styles.popupContent}>
561-
<h3 className={styles.popupTitle}>{location.name}</h3>
562-
{location.subtitle && (
563-
<div className={styles.popupSubtitle}>{location.subtitle}</div>
564-
)}
565-
{location.features && location.features.length > 0 && (
566-
<Features items={location.features} iconSize={14} />
567-
)}
568-
</div>
569-
</article>
570-
</Popup>
561+
{showPopup && (
562+
<Popup>
563+
<article className={styles.popup}>
564+
<div className={styles.popupContent}>
565+
<h3 className={styles.popupTitle}>{location.name}</h3>
566+
{location.subtitle && (
567+
<div className={styles.popupSubtitle}>{location.subtitle}</div>
568+
)}
569+
{location.features && location.features.length > 0 && (
570+
<Features items={location.features} iconSize={14} />
571+
)}
572+
</div>
573+
</article>
574+
</Popup>
575+
)}
571576
</Marker>
572577
);
573578
})}

packages/ui/src/components/Map/MapView.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,14 @@ export interface MapViewProps {
126126
*/
127127
scrollWheelZoom?: boolean;
128128

129+
/**
130+
* Show popup bubbles when markers are clicked.
131+
* When false, disables the Leaflet popup that appears on marker click.
132+
* Useful when you want to handle marker selection with external UI (e.g., a sidebar).
133+
* @default true
134+
*/
135+
showPopup?: boolean;
136+
129137
// Additional map configuration props can be introduced over time.
130138
}
131139

0 commit comments

Comments
 (0)