{"version":3,"sources":["../src/naver-map.tsx"],"sourcesContent":["import upperfirst from 'lodash.upperfirst';\nimport { forwardRef, useImperativeHandle, useLayoutEffect, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { useContainerContext } from './contexts/container';\nimport { EventTargetContext } from './contexts/event-target';\nimport { NaverMapContext } from './contexts/naver-map';\nimport { HandleEvents } from './helpers/event';\nimport { usePrevious } from './hooks/use-previous';\nimport { useNavermaps } from './use-navermaps';\n\ntype MapPaddingOptions = {\n  top?: number;\n  right?: number;\n  bottom?: number;\n  left?: number;\n};\n\ntype MapOptions = {\n  background?: string;\n  baseTileOpacity?: number;\n  /**\n   * @type naver.maps.Bounds | naver.maps.BoundsLiteral | null\n   */\n  bounds?: naver.maps.Bounds | naver.maps.BoundsLiteral | null;\n  /**\n   * @type naver.maps.Coord | naver.maps.CoordLiteral\n   */\n  center?: naver.maps.Coord | naver.maps.CoordLiteral;\n  disableDoubleClickZoom?: boolean;\n  disableDoubleTapZoom?: boolean;\n  disableKineticPan?: boolean;\n  disableTwoFingerTapZoom?: boolean;\n  draggable?: boolean;\n  keyboardShortcuts?: boolean;\n  logoControl?: boolean;\n  logoControlOptions?: naver.maps.LogoControlOptions;\n  mapDataControl?: boolean;\n  mapDataControlOptions?: naver.maps.MapDataControlOptions;\n  mapTypeControl?: boolean;\n  mapTypeControlOptions?: naver.maps.MapTypeControlOptions;\n  mapTypeId?: string;\n  mapTypes?: naver.maps.MapTypeRegistry;\n  maxBounds?: naver.maps.Bounds | naver.maps.BoundsLiteral | null;\n  maxZoom?: number;\n  minZoom?: number;\n  padding?: MapPaddingOptions;\n  pinchZoom?: boolean;\n  resizeOrigin?: naver.maps.Position;\n  scaleControl?: boolean;\n  scaleControlOptions?: naver.maps.ScaleControlOptions;\n  scrollWheel?: boolean;\n  size?: naver.maps.Size | naver.maps.SizeLiteral;\n  overlayZoomEffect?: string | null;\n  tileSpare?: number;\n  tileTransition?: boolean;\n  zoom?: number;\n  zoomControl?: boolean;\n  zoomControlOptions?: naver.maps.ZoomControlOptions;\n  zoomOrigin?: naver.maps.Coord | naver.maps.CoordLiteral | null;\n  blankTileImage?: string | null;\n\n  // special.\n  centerPoint?: naver.maps.Point | naver.maps.PointLiteral;\n};\n\ntype Uncontrolled = {\n  /**\n   * Uncontrolled prop of mapTypeId\n   */\n  defaultMapTypeId?: MapOptions['mapTypeId'];\n  /**\n   * Uncontrolled prop of size\n   * @type naver.maps.Coord | naver.maps.CoordLiteral\n   */\n  defaultSize?: MapOptions['size'];\n  /**\n   * Uncontrolled prop of bounds\n   * @type naver.maps.Bounds | naver.maps.BoundsLiteral | null\n   */\n  defaultBounds?: MapOptions['bounds'];\n  /**\n   * Uncontrolled prop of center\n   * @type naver.maps.Coord | naver.maps.CoordLiteral\n   */\n  defaultCenter?: MapOptions['center'];\n  /**\n   * Uncontrolled prop of zoom\n   */\n  defaultZoom?: MapOptions['zoom'];\n  /**\n   * Uncontrolled prop of centerPoint\n   * @type naver.maps.Point | naver.maps.PointLiteral\n   */\n  defaultCenterPoint?: MapOptions['centerPoint'];\n};\n\ntype MapEventCallbacks = {\n  onMapTypeIdChanged?: (value: string) => void;\n  onMapTypeChanged?: (value: naver.maps.MapType) => void;\n  onSizeChanged?: (value: naver.maps.Size) => void;\n  onBoundsChanged?: (value: naver.maps.Bounds) => void;\n  onCenterChanged?: (value: naver.maps.Coord) => void;\n  onCenterPointChanged?: (value: naver.maps.Point) => void;\n  onZoomChanged?: (value: number) => void;\n};\n\nconst basicMapOptionKeys: Array<keyof MapOptions> = [\n  'background',\n  'baseTileOpacity',\n  // 'bounds',\n  // 'center',\n  'disableDoubleClickZoom',\n  'disableDoubleTapZoom',\n  'disableKineticPan',\n  'disableTwoFingerTapZoom',\n  'draggable',\n  'keyboardShortcuts',\n  'logoControl',\n  'logoControlOptions',\n  'mapDataControl',\n  'mapDataControlOptions',\n  'mapTypeControl',\n  'mapTypeControlOptions',\n  // 'mapTypeId',\n  'mapTypes',\n  'maxBounds',\n  'maxZoom',\n  'minZoom',\n  'padding',\n  'pinchZoom',\n  'resizeOrigin',\n  'scaleControl',\n  'scaleControlOptions',\n  'scrollWheel',\n  // 'size',\n  'overlayZoomEffect',\n  'tileSpare',\n  'tileTransition',\n  // 'zoom',\n  'zoomControl',\n  'zoomControlOptions',\n  'zoomOrigin',\n  'blankTileImage',\n];\n\nconst kvoKeys = [\n  'mapTypeId',\n  'size',\n  'bounds',\n  'center',\n  'zoom',\n  'centerPoint',\n] as const;\n\nconst kvoEvents = [\n  ...kvoKeys.map(key => `${key}_changed`),\n  'mapType_changed', // special. https://navermaps.github.io/maps.js.ncp/docs/naver.maps.Map.html#event:mapType_changed__anchor\n];\nconst uiEvents = [\n  'mousedown',\n  'mouseup',\n  'click',\n  'dblclick',\n  'rightclick',\n  'mouseover',\n  'mouseout',\n  'mousemove',\n  'dragstart',\n  'drag',\n  'dragend',\n  'touchstart',\n  'touchmove',\n  'touchend',\n  'pinchstart',\n  'pinch',\n  'pinchend',\n  'tap',\n  'longtap',\n  'twofingertap',\n  'doubletap',\n] as const;\nconst mapOnlyEvents = [\n  'addLayer',\n  'idle',\n  'init',\n  'keydown',\n  'keyup',\n  'panning',\n  'projection_changed',\n  'removeLayer',\n  'resize',\n  'tilesloaded',\n  'zooming',\n] as const;\nconst events = [...uiEvents, ...kvoEvents, ...mapOnlyEvents];\n\n// type FunctionTypeChildren = (nmap: naver.maps.Map) => React.ReactNode;\n\nconst defaultOptionKeyMap = {\n  mapTypeId: 'defaultMapTypeId',\n  size: 'defaultSize',\n  bounds: 'defaultBounds',\n  center: 'defaultCenter',\n  zoom: 'defaultZoom',\n  centerPoint: 'defaultCenterPoint',\n} as const;\n\nexport type Props = Uncontrolled & {\n  /**\n   * Map 관련 components\n   */\n  children?: ReactNode;\n} & MapOptions & MapEventCallbacks;\n\nexport const NaverMap = forwardRef<naver.maps.Map | null, Props>(function NaverMap(props, ref) {\n  const navermaps = useNavermaps();\n  const { element: mapDiv } = useContainerContext();\n  const [nmap, setNmap] = useState<naver.maps.Map>();\n  const nmapRef = useRef<naver.maps.Map>(null);\n\n  // https://github.com/facebook/react/issues/20090\n  useLayoutEffect(() => {\n    if (!mapDiv) {\n      throw new Error('react-naver-maps: MapDiv is not found. Did you correctly wrap with `MapDiv`?');\n    }\n\n    const basicMapOptions = Object.fromEntries(basicMapOptionKeys.map(key => [key, props[key]]));\n    const kvos = kvoKeys.reduce((acc, key) => {\n      // default kvo\n      if (props[defaultOptionKeyMap[key]]) {\n        return {\n          ...acc,\n          [key]: props[defaultOptionKeyMap[key]],\n        };\n      }\n\n      // kvo\n      if (props[key]) {\n        return {\n          ...acc,\n          [key]: props[key],\n        };\n      }\n\n      return acc;\n    }, {});\n\n    const _nmap = new navermaps.Map(mapDiv, { ...basicMapOptions, ...kvos } as naver.maps.MapOptions);\n    setNmap(_nmap);\n    // for ref hack\n    nmapRef.current = _nmap;\n\n    return () => {\n      _nmap.destroy();\n    };\n  }, []);\n\n  const uncontrolledOmittedProps = (Object.keys(props) as Array<keyof Props>).reduce((acc, key) => {\n    // kvo key가 defaultKvo key와 함께 있을 경우 무시한다.\n    if (key in defaultOptionKeyMap && props[defaultOptionKeyMap[key as keyof typeof defaultOptionKeyMap]]) {\n      return acc;\n    }\n\n    return {\n      ...acc,\n      [key]: props[key],\n    };\n  }, {}) as Props;\n\n  // nmap 이 layoutEffect에서 생성되므로 항상 Map이 존재한다.\n  useImperativeHandle<naver.maps.Map | null, naver.maps.Map | null>(ref, () => nmapRef.current);\n\n  return (\n    <>{nmap && <NaverMapCore {...uncontrolledOmittedProps} nmap={nmap} />}</>\n  );\n});\n\nfunction NaverMapCore({ nmap, children, ...mapProps }: Props & { nmap: naver.maps.Map }) {\n  const basicMapOptions = Object.fromEntries(basicMapOptionKeys.map(key => [key, mapProps[key]]));\n  const {\n    mapTypeId,\n    size,\n    bounds,\n    center,\n    centerPoint,\n    zoom,\n  } = mapProps;\n\n  const prevKVOs = usePrevious({\n    mapTypeId,\n    size,\n    bounds,\n    center,\n    centerPoint,\n    zoom,\n  }, [\n    mapTypeId,\n    size,\n    bounds,\n    center,\n    centerPoint,\n    zoom,\n  ]);\n\n  function getDirtyKVOs(keys: Array<typeof kvoKeys[number]>): Pick<Props, typeof kvoKeys[number]> {\n    return keys.reduce((acc, key) => {\n      /* eslint-disable */\n      const currentValue = (nmap[`get${upperfirst(key)}` as keyof naver.maps.Map] as Function)();\n      const propValue = mapProps[key];\n\n      if (!propValue || prevKVOs && prevKVOs[key] === propValue) {\n        return acc;\n      }\n\n      const isEqual = typeof currentValue.equals === 'function' ? currentValue.equals(propValue) : currentValue === propValue;\n\n      if (isEqual) {\n        return acc;\n      }\n\n      return {\n        ...acc,\n        [key]: propValue,\n      };\n    }, {} as Pick<Props, typeof kvoKeys[number]>);\n  }\n\n  useLayoutEffect(() => {\n    nmap.setOptions(basicMapOptions);\n  }, [Object.values(basicMapOptions)]);\n\n  useLayoutEffect(() => {\n    const updated = getDirtyKVOs(['size']).size;\n    if (updated) {\n      nmap.setSize(updated);\n    }\n  }, [size]);\n\n  useLayoutEffect(() => {\n    const updated = getDirtyKVOs(['mapTypeId']).mapTypeId;\n    if (updated) {\n      nmap.setMapTypeId(updated);\n    }\n  }, [mapTypeId]);\n\n  useLayoutEffect(() => {\n    const dirties = getDirtyKVOs(['bounds', 'center', 'centerPoint', 'zoom']);\n\n    if (dirties.bounds) {\n      // TODO\n      nmap.fitBounds(dirties.bounds);\n\n      // Ignore rest kvos\n      return;\n    }\n\n    if (dirties.center && dirties.zoom) {\n\n      nmap.morph(dirties.center, dirties.zoom);\n\n      // Ignore rest kvos\n      return;\n    }\n\n    if (dirties.centerPoint) {\n      nmap.setCenterPoint(dirties.centerPoint);\n    }\n\n    if (dirties.center) {\n      // TODO\n      nmap.panTo(dirties.center, {});\n    }\n\n    if (dirties.zoom) {\n      nmap.setZoom(dirties.zoom);\n    }\n  }, [bounds, center, centerPoint, zoom]);\n\n  return (\n    <NaverMapContext.Provider value={nmap}>\n      <EventTargetContext.Provider value={nmap}>\n        <>\n          <HandleEvents\n            events={events}\n            listeners={mapProps as any}\n          />\n          {children}\n        </>\n      </EventTargetContext.Provider>\n    </NaverMapContext.Provider>\n  );\n}\n"],"mappings":"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","names":["NaverMap"]}