Skip to content

Commit

Permalink
feat(marker): 优化事件绑定
Browse files Browse the repository at this point in the history
  • Loading branch information
wangxingkang committed Aug 31, 2022
1 parent 6db8116 commit 2c8673f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 24 deletions.
4 changes: 3 additions & 1 deletion src/hooks/useReact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface Options<Ins, Events> {
events: Events;
setterMap?: Record<string, Function>;
converterMap?: Record<string, Function>;
unmount?: () => void;
}

/**
Expand Down Expand Up @@ -49,7 +50,7 @@ export const useReact = <
props: P = {} as P,
options: Options<Ins, Events>,
) => {
const { ins, events, setterMap = {}, converterMap = {} } = options;
const { ins, events, setterMap = {}, converterMap = {}, unmount } = options;
const { eventProps, notEventProps } = splitPropsByEvent(props);
const prevProps = usePrevious(notEventProps);

Expand All @@ -65,6 +66,7 @@ export const useReact = <
if (ins && 'remove' in ins) {
ins.remove();
}
unmount?.();
});

const reactivePropChange = (nextProps: P, shouldDetectChange = true) => {
Expand Down
6 changes: 2 additions & 4 deletions src/marker/demos/basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ export default () => {
<Marker
lngLat={[30.5, 50.5]}
onDragEnd={(e) => {
//@ts-ignore
console.log(e.target.getLngLat());
console.log(e);
}}
onClick={(e) => {
//@ts-ignore
console.log(e.target.getLngLat());
console.log(e);
}}
draggable={true}
>
Expand Down
31 changes: 20 additions & 11 deletions src/marker/marker.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Marker as MapboxMarker } from 'mapbox-gl';
import { useState } from 'react';
import { useGetState } from '@pansy/react-hooks';
import { createPortal } from 'react-dom';
import { forwardRef, useEffect, useRef, useImperativeHandle } from 'react';

Expand All @@ -8,30 +8,47 @@ import { useReact } from '@/hooks/useReact';

import { allProps, setterMap, converterMap, mapEventMap } from './config';

import type { MarkerProps, EventMapping } from './types';
import type { MarkerOptions } from 'mapbox-gl';
import type { MarkerProps, EventMapping } from './types';

export const Marker = forwardRef<MapboxMarker, MarkerProps>((props, ref) => {
const map = useMap();
const contentWrapper = useRef<HTMLDivElement>();
const [marker, setMarker] = useState<MapboxMarker>();
const [marker, setMarker, getMarker] = useGetState<MapboxMarker | undefined>(undefined);

const { onInstanceCreated } = useReact<MarkerProps, MapboxMarker, EventMapping>(props, {
ins: marker,
events: mapEventMap,
setterMap,
converterMap,
unmount: () => {
if (contentWrapper.current) {
contentWrapper.current.removeEventListener('click', handleClick);
contentWrapper.current = undefined;
}
},
});

useImperativeHandle(ref, () => marker as MapboxMarker, [marker]);

const handleClick = (e: MouseEvent) => {
props.onClick?.({
type: 'click',
target: getMarker() as MapboxMarker,
originalEvent: e,
});
};

useEffect(() => {
if (map) {
createInstance().then((marker) => {
setMarker(marker);

marker.setLngLat(props.lngLat);
marker.addTo(map);

contentWrapper.current?.addEventListener('click', handleClick);

onInstanceCreated();
});
}
Expand All @@ -43,14 +60,6 @@ export const Marker = forwardRef<MapboxMarker, MarkerProps>((props, ref) => {
contentWrapper.current = document.createElement('div');

const marker = new MapboxMarker(contentWrapper.current, options);
marker.getElement().addEventListener('click', (e: MouseEvent) => {
//@ts-ignore
options.onClick?.({
type: 'click',
target: marker,
originalEvent: e,
});
});
return Promise.resolve(marker);
};

Expand Down
29 changes: 21 additions & 8 deletions src/marker/types.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
import type { MarkerOptions, LngLatLike, MapEventType } from 'mapbox-gl';
import type { Marker, MarkerOptions, LngLatLike, MapEventType } from 'mapbox-gl';

export type MarkerEvents = {
onDragStart: (e: MapEventType['dragstart']) => void;
onDrag: (e: MapEventType['drag']) => void;
onDragEnd: (e: MapEventType['dragend']) => void;
};
export interface MarkerEvent<TOrig = undefined> {
type: string;
target: Marker;
originalEvent: TOrig;
}

export interface MarkerEvents {
onDragStart: (e: MarkerEvent<MouseEvent | TouchEvent | undefined>) => void;
onDrag: (e: MarkerEvent<MouseEvent | TouchEvent | undefined>) => void;
onDragEnd: (e: MarkerEvent<MouseEvent | TouchEvent | undefined>) => void;
}

export interface CustomizeMarkerEvents {
onClick: (e: MarkerEvent<Event | undefined>) => void;
}

export type EventMapping = { [T in keyof MarkerEvents]: string };

export type KeysOfUnion<T> = T extends T ? keyof T : never;

export interface MarkerProps extends MarkerOptions, Partial<MarkerEvents> {
export interface MarkerProps
extends MarkerOptions,
Partial<MarkerEvents>,
Partial<CustomizeMarkerEvents> {
className?: string;
/** 经纬度坐标 */
lngLat: LngLatLike;
children: any;
onClick?: (e: MapEventType['click']) => void;
}

export type PropKey = KeysOfUnion<MarkerProps>;

0 comments on commit 2c8673f

Please sign in to comment.