Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(advanced-marker): add style prop to add styles to content-element #337

Merged
merged 1 commit into from
May 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading