Skip to content

Commit

Permalink
feat(MarkerCluster): 支持传入泛型
Browse files Browse the repository at this point in the history
  • Loading branch information
wangxingkang committed Jan 19, 2024
1 parent 31d9c48 commit e1cca4e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
19 changes: 13 additions & 6 deletions src/components/MarkerCluster/MarkerCluster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ import { defaultSuperclusterOptions } from './config';
import { Marker } from '../Marker';
import { useMap } from '../../hooks/useMap';

import type { MarkerClusterProps } from './types';
import type { MarkerClusterProps, AnyObject, RefMarkerCluster } from './types';

export const MarkerCluster = forwardRef<Supercluster, MarkerClusterProps>((props, ref) => {
const { cluster, render, renderCluster, zoomOnClickPadding = 20 } = props;
const InternalMarkerCluster = <D extends AnyObject = AnyObject>(
props: MarkerClusterProps<D>,
ref: React.Ref<Supercluster>,
) => {
const { cluster, render, renderCluster, data = [], zoomOnClick, zoomOnClickPadding = 20 } = props;
const { map } = useMap();
const [list, setList] = useState<any[]>([]);

Expand Down Expand Up @@ -102,8 +105,10 @@ export const MarkerCluster = forwardRef<Supercluster, MarkerClusterProps>((props
<Marker
key={item.id}
lngLat={geometry.coordinates}
onClick={(e) => {
handleClusterMarkerClick(JSON.parse(JSON.stringify(item)));
onClick={() => {
if (zoomOnClick) {
handleClusterMarkerClick(JSON.parse(JSON.stringify(item)));
}
}}
>
{isFunction(renderCluster) ? renderCluster(point_count, cluster_id) : renderCluster}
Expand All @@ -119,4 +124,6 @@ export const MarkerCluster = forwardRef<Supercluster, MarkerClusterProps>((props
})}
</>
);
});
};

export const MarkerCluster = forwardRef(InternalMarkerCluster) as RefMarkerCluster;
28 changes: 26 additions & 2 deletions src/components/MarkerCluster/types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
import type Supercluster from 'supercluster';
import type { GeoJsonProperties, GeoJsonObject, Point } from 'geojson';
import type { PaddingOptions } from 'mapbox-gl';

export type AnyObject = Record<PropertyKey, any>;
export type RenderMarkerFun = (data: any) => React.ReactNode;
export type RenderClusterMarkerFun = (count: number, clusterId: string) => React.ReactNode;

export type { Supercluster };

export interface MarkerClusterProps {
export interface Feature<P = GeoJsonProperties> extends GeoJsonObject {
type: 'Feature';
/**
* The feature's geometry
*/
geometry: Point;
/**
* A value that uniquely identifies this feature in a
* https://tools.ietf.org/html/rfc7946#section-3.2.
*/
id?: string | number | undefined;
/**
* Properties associated with this feature.
*/
properties: P;
}

export interface MarkerClusterProps<D extends object = any> {
data?: Feature<D>[];
/**
* 聚合参数设置
*/
cluster?: Supercluster.Options<any, any>;
/**
* 点击聚合点时,是否散开。
* @default true
* @default false
*/
zoomOnClick?: boolean;
/**
Expand All @@ -32,3 +52,7 @@ export interface MarkerClusterProps {
onClick?: any;
onClusterClick?: any;
}

export type RefMarkerCluster = <D extends AnyObject = AnyObject>(
props: React.PropsWithChildren<MarkerClusterProps<D>> & React.RefAttributes<Supercluster>,
) => React.ReactElement;
1 change: 1 addition & 0 deletions stories/examples/ClusterPro.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const meta = {
<MarkerCluster
cluster={{ radius: 50 }}
ref={clusterRef}
zoomOnClick
render={<Avatar style={{ backgroundColor: '#fde3cf', color: '#f56a00' }}>U</Avatar>}
renderCluster={(count) => {
return (
Expand Down

0 comments on commit e1cca4e

Please sign in to comment.