Skip to content

Commit

Permalink
feat(advanced-marker): add style prop to add styles to content-element (
Browse files Browse the repository at this point in the history
  • Loading branch information
usefulthink authored May 3, 2024
1 parent f93e43e commit e942fb5
Showing 1 changed file with 30 additions and 24 deletions.
54 changes: 30 additions & 24 deletions src/components/advanced-marker.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
/* eslint-disable complexity */
import React, {
Children,
CSSProperties,
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useMemo,
useRef,
useState
} from 'react';

import {createPortal} from 'react-dom';
import {useMap} from '../hooks/use-map';
import {useMapsLibrary} from '../hooks/use-maps-library';
import {setValueForStyles} from '../libraries/set-value-for-styles';

import type {Ref, PropsWithChildren} from 'react';

Expand All @@ -36,10 +39,14 @@ export type AdvancedMarkerProps = PropsWithChildren<
> &
AdvancedMarkerEventProps & {
/**
* className to add a class to the advanced marker element
* Can only be used with HTML Marker content
* A className for the content element.
* (can only be used with HTML Marker content)
*/
className?: string;
/**
* Additional styles to apply to the content element.
*/
style?: CSSProperties;
draggable?: boolean;
}
>;
Expand All @@ -51,12 +58,15 @@ function useAdvancedMarker(props: AdvancedMarkerProps) {
const [contentContainer, setContentContainer] =
useState<HTMLDivElement | null>(null);

const prevStyleRef = useRef<CSSProperties | null>(null);

const map = useMap();
const markerLibrary = useMapsLibrary('marker');

const {
children,
className,
style,
onClick,
onDrag,
onDragStart,
Expand All @@ -68,9 +78,9 @@ function useAdvancedMarker(props: AdvancedMarkerProps) {
zIndex
} = props;

const numChilds = Children.count(children);
const numChildren = Children.count(children);

// create marker instance and add it to the map when map becomes available
// create an AdvancedMarkerElement instance and add it to the map once available
useEffect(() => {
if (!map || !markerLibrary) return;

Expand All @@ -79,33 +89,31 @@ function useAdvancedMarker(props: AdvancedMarkerProps) {

setMarker(newMarker);

// create container for marker content if there are children
if (numChilds > 0) {
const el = document.createElement('div');
if (className) el.className = className;

newMarker.content = el;
// create the container for marker content if there are children
if (numChildren > 0) {
const contentElement = document.createElement('div');

setContentContainer(el);
newMarker.content = contentElement;
setContentContainer(contentElement);
}

return () => {
newMarker.map = null;
setMarker(null);
setContentContainer(null);
};
// We do not want to re-render the whole marker when the className changes
// because that causes a short flickering of the marker.
// The className update is handled in the useEffect below.
// Excluding the className from the dependency array onm purpose here
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [map, markerLibrary, numChilds]);

// update className of advanced marker element
}, [map, markerLibrary, numChildren]);

// update className and styles of marker.content element
useEffect(() => {
if (!contentContainer) return;
contentContainer.className = className ?? '';
}, [contentContainer, className]);

setValueForStyles(contentContainer, style || null, prevStyleRef.current);
prevStyleRef.current = style || null;

if (className !== contentContainer.className)
contentContainer.className = className ?? '';
}, [contentContainer, className, style]);

// bind all marker events
useEffect(() => {
Expand Down Expand Up @@ -155,9 +163,7 @@ export const AdvancedMarker = forwardRef(

useImperativeHandle(ref, () => marker, [marker]);

if (!marker) {
return null;
}
if (!marker) return null;

return (
<AdvancedMarkerContext.Provider value={advancedMarkerContextValue}>
Expand Down

0 comments on commit e942fb5

Please sign in to comment.