import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; import { HandleEvents } from '../helpers/event'; import { Overlay } from '../overlay'; import type { UIEventHandlers } from '../types/event'; import { useNavermaps } from '../use-navermaps'; import { omitUndefined } from '../utils/omit-undefined'; const primitiveKvoKeys = [ 'content', 'zIndex', 'maxWidth', 'pixelOffset', 'backgroundColor', 'borderColor', 'borderWidth', 'disableAutoPan', 'disableAnchor', 'anchorSkew', 'anchorSize', 'anchorColor', ] as const; const kvoKeys = [ ...primitiveKvoKeys, 'position', ] as const; const kvoEvents = kvoKeys.map(key => `${key}_changed`); const uiEvents = [ 'mousedown', 'mouseup', 'click', 'dblclick', 'rightclick', 'mouseover', 'mouseout', 'mousemove', ] as const; const events = [...uiEvents, ...kvoEvents]; type InfoWindowOptions = { /** * position * @type naver.maps.Coord | naver.maps.CoordLiteral */ position?: naver.maps.Coord | naver.maps.CoordLiteral; content: string; zIndex?: number; maxWidth?: number; /** * @type naver.maps.Point | naver.maps.PointLiteral */ pixelOffset?: naver.maps.Point | naver.maps.PointLiteral; backgroundColor?: string; borderColor?: string; borderWidth?: number; disableAutoPan?: boolean; disableAnchor?: boolean; anchorSkew?: boolean; /** * @type naver.maps.Size | naver.maps.SizeLiteral */ anchorSize?: naver.maps.Size | naver.maps.SizeLiteral; anchorColor?: string; }; export type Props = InfoWindowOptions & { onPositionChanged?: (value: naver.maps.Coord) => void; onContentChanged?: (value: HTMLElement) => void; onZIndexChanged?: (value: number) => void; onMaxWidthChanged?: (value: number) => void; onPixelOffsetChanged?: (value: naver.maps.Point) => void; onBackgroundColorChanged?: (value: string) => void; onBorderColorChanged?: (value: string) => void; onBorderWidthChanged?: (value: number) => void; onDisableAutoPanChanged?: (value: boolean) => void; onDisableAnchorChanged?: (value: boolean) => void; onAnchorSkewChanged?: (value: boolean) => void; onAnchorSizeChanged?: (value: naver.maps.Size) => void; onAnchorColorChanged?: (value: string) => void; } & UIEventHandlers; export const InfoWindow = forwardRef(function InfoWindow(props, ref) { const { position } = props; const navermaps = useNavermaps(); const [infoWindow] = useState(() => new navermaps.InfoWindow(omitUndefined({ position, ...Object.fromEntries(kvoKeys.filter(key => key !== 'position').map(key => [key, props[key]])), }) as InfoWindowOptions)); useImperativeHandle(ref, () => infoWindow); useEffect(() => { const options = { ...Object.fromEntries(primitiveKvoKeys.map(key => [key, props[key]])), position, }; const cleanOptions = omitUndefined(options); if (Object.keys(cleanOptions).length > 0) { infoWindow.setOptions(cleanOptions as InfoWindowOptions); } }, primitiveKvoKeys.map(key => props[key])); useEffect(() => { if (position && infoWindow.getPosition().equals(position as naver.maps.Point)) { infoWindow.setPosition(position); } }, [position]); return ( ); });