Skip to content

Commit 3f1f630

Browse files
feat(Cluster): Cluster component의 icons prop에 React element를 사용할 수 있도록 변경 (#55)
* feat(Cluster): Cluster component의 icons prop에 React element를 사용할 수 있도록 변경 * fix: script-id와 전역객체에 naver 지도 객체가 있을 때 얼리 리턴되도록 변경 --------- Co-authored-by: socar-dosii <dosii@socar.kr>
1 parent dd12019 commit 3f1f630

6 files changed

Lines changed: 36 additions & 7 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@r2don/react-naver-map",
3-
"version": "0.0.14",
3+
"version": "0.0.15",
44
"author": {
55
"name": "r2don",
66
"email": "leejj2002@naver.com"

src/classes/Cluster.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { MarkerClustering } from "./MarkerClustering";
21
import type { Nullable } from "../types";
2+
import { MarkerClustering } from "./MarkerClustering";
33

44
/**
55
* 마커를 가지고 있는 클러스터를 정의합니다.

src/components/Cluster.tsx

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
1-
import React, { cloneElement, ReactElement, Ref, useRef } from "react";
2-
import { useMapContext } from "../context";
1+
import React, {
2+
Ref,
3+
cloneElement,
4+
isValidElement,
5+
useRef,
6+
type ReactElement,
7+
} from "react";
8+
import { renderToStaticMarkup } from "react-dom/server";
39
import { ClusterOptions, MarkerClustering } from "../classes";
10+
import { useMapContext } from "../context";
411
import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect";
12+
import type { ArrayToUnion } from "../types";
513
import type { MarkerRef } from "./marker/type";
614

15+
interface ClusterPropsOptions
16+
extends Omit<Partial<ClusterOptions>, "map" | "markers" | "icons"> {
17+
icons?: Array<ArrayToUnion<ClusterOptions["icons"]> | ReactElement>;
18+
}
19+
720
interface ClusterProps {
821
children: Array<ReactElement<{ ref: Ref<MarkerRef> }>>;
9-
options?: Omit<Partial<ClusterOptions>, "map" | "markers">;
22+
options?: ClusterPropsOptions;
1023
}
1124

1225
export const Cluster = ({ children, options }: ClusterProps) => {
@@ -17,8 +30,21 @@ export const Cluster = ({ children, options }: ClusterProps) => {
1730
useIsomorphicLayoutEffect(() => {
1831
import("../classes/MarkerClustering").then(({ MarkerClustering }) => {
1932
if (clusterRef.current) return;
33+
34+
const icons = options?.icons?.map((icon) => {
35+
// ReactElement 타입(React.ReactElement<any, string | React.JSXElementConstructor<any>>)일 경우, HTML 문자열로 변환합니다.
36+
if (isValidElement<any>(icon)) {
37+
return {
38+
content: renderToStaticMarkup(icon),
39+
};
40+
}
41+
// 그 외 타입(string | naver.maps.ImageIcon | naver.maps.SymbolIcon | naver.maps.HtmlIcon)이면 그대로 반환합니다.
42+
return icon;
43+
});
44+
2045
const cluster = new MarkerClustering({
2146
...options,
47+
icons,
2248
map,
2349
markers: Object.values(markersRef.current)
2450
.filter((ref) => !!ref.getMarker)

src/hooks/useNaverMapInit/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const useNaverMapInit: UseNaverMapInit = ({
3232
setInitResult({ isLoaded: false, isError: false });
3333
return;
3434
}
35-
if (document.getElementById(SCRIPT_ID)) {
35+
if (document.getElementById(SCRIPT_ID) && Boolean(window?.naver.maps)) {
3636
setInitResult({ isLoaded: true, isError: false });
3737
return;
3838
}

src/types/ArrayToUnion.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export type ArrayToUnion<T extends readonly unknown[]> =
2+
T extends readonly (infer R)[] ? R : never;

src/types/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from "./AnyFunction";
2+
export * from "./ArrayToUnion";
13
export * from "./Nullable";
24
export * from "./ValueOf";
3-
export * from "./AnyFunction";

0 commit comments

Comments
 (0)