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 = [ 'radius', 'strokeWeight', 'strokeOpacity', 'strokeColor', 'strokeStyle', 'strokeLineCap', 'strokeLineJoin', 'fillColor', 'fillOpacity', 'clickable', 'visible', 'zIndex', ] as const; const kvoKeys = [ ...primitiveKvoKeys, 'center', ] 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 CircleOptions = { /** * center * @type naver.maps.Coord | naver.maps.CoordLiteral */ center: naver.maps.Coord | naver.maps.CoordLiteral; radius?: number; strokeWeight?: number; strokeOpacity?: number; strokeColor?: string; strokeStyle?: naver.maps.StrokeStyleType; strokeLineCap?: naver.maps.StrokeLineCapType; strokeLineJoin?: naver.maps.StrokeLineJoinType; fillColor?: string; fillOpacity?: number; clickable?: boolean; visible?: boolean; zIndex?: number; }; export type Props = CircleOptions & { onCenterChanged?: (value: naver.maps.Coord) => void; onRadiusChanged?: (value: number) => void; onStrokeWeightChanged?: (value: number) => void; onStrokeOpacityChanged?: (value: number) => void; onStrokeColorChanged?: (value: string) => void; onStrokeStyleChanged?: (value: naver.maps.StrokeStyleType) => void; onStrokeLineCapChanged?: (value: naver.maps.StrokeLineCapType) => void; onStrokeLineJoinChanged?: (value: naver.maps.StrokeLineJoinType) => void; onFillColorChanged?: (value: string) => void; onFillOpacityChanged?: (value: number) => void; onClickableChanged?: (event: boolean) => void; onVisibleChanged?: (event: boolean) => void; onZIndexChanged?: (event: number) => void; } & UIEventHandlers; export const Circle = forwardRef(function Circle(props, ref) { const { center } = props; const navermaps = useNavermaps(); const [circle] = useState(() => new navermaps.Circle(omitUndefined({ ...Object.fromEntries(kvoKeys.map(key => [key, props[key]])), center: props.center, }) as CircleOptions)); useImperativeHandle(ref, () => circle); useEffect(() => { if (center && !circle.getCenter().equals(center as naver.maps.Point)) { circle.setCenter(center); } }, [center]); useEffect(() => { const options = omitUndefined(Object.fromEntries(primitiveKvoKeys.map(key => [key, props[key]]))); if (Object.keys(options).length > 0) { circle.setOptions(options as unknown as CircleOptions); } }, primitiveKvoKeys.map(key => props[key])); return ( ); });