Skip to content

Commit

Permalink
fix(map): 支持传递参数
Browse files Browse the repository at this point in the history
  • Loading branch information
wangxingkang committed Jan 15, 2024
1 parent 43bb1d6 commit 9b4e6be
Show file tree
Hide file tree
Showing 27 changed files with 86 additions and 188 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"dependencies": {
"@pansy/react-hooks": "^1.0.6",
"@pansy/shared": "^1.15.0",
"lodash": "^4.17.21"
"type-fest": "^4.9.0",
"lodash-es": "^4.17.21"
},
"devDependencies": {
"@commitlint/cli": "17.7.1",
Expand All @@ -52,7 +53,7 @@
"@testing-library/jest-dom": "^6.2.0",
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.2",
"@types/lodash": "^4.14.198",
"@types/lodash-es": "^4.17.12",
"@types/mapbox-gl": "^2.7.19",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
Expand Down
40 changes: 24 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/map/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Map } from 'mapbox-gl';
import type { PropKey, EventMapping } from './types';
import type { MapboxOptionKeys, EventMapping } from './types';

export const mapEventMap: EventMapping = {
onError: 'error',
Expand Down Expand Up @@ -63,7 +63,7 @@ export const mapEventMap: EventMapping = {
};

/** 静态属性 */
export const StaticProps: PropKey[] = [
export const StaticProps: MapboxOptionKeys[] = [
'hash',
'interactive',
'bearingSnap',
Expand Down Expand Up @@ -94,7 +94,7 @@ export const StaticProps: PropKey[] = [
];

/** 动态属性 */
export const NativeDynamicProps: PropKey[] = [
export const NativeDynamicProps: MapboxOptionKeys[] = [
'zoom',
'minZoom',
'maxZoom',
Expand Down
71 changes: 48 additions & 23 deletions src/map/map.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,74 @@
import mapbox from 'mapbox-gl';
import React, { useRef, useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import Mapbox from 'mapbox-gl';
import { useRef, useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import { MapContext } from './context';
import { useReact } from '@/hooks/useReact';
import { allProps, mapEventMap, setterMap, converterMap } from './config';

import 'mapbox-gl/dist/mapbox-gl.css';
import './map.css';

import type { MapContextValue } from './context';
import type { MapProps, EventMapping, MapboxOptionKeys } from './types';

export interface MapProps {
/** 地图加载前的加载效果 */
loading?: React.ReactNode;
children?: React.ReactNode;
}
Mapbox.accessToken =
'pk.eyJ1IjoienQyMDIzMTEwOSIsImEiOiJjbG9xdGgxcDMwbDAyMmpwODVrNG5seXphIn0.1xKSk8Ll-80kkEwtzfLWhw';

export const Map: React.FC<MapProps> = (props) => {
export const Map = forwardRef<Mapbox.Map, MapProps>((props, ref) => {
const { loading, children } = props;
const containerRef = useRef<HTMLDivElement>(null);
const [mapInstance, setMapInstance] = useState<mapbox.Map>();
const [mapInstance, setMapInstance] = useState<Mapbox.Map>();

const { current: contextValue } = useRef<MapContextValue>({} as MapContextValue);

const { onInstanceCreated } = useReact<MapProps, Mapbox.Map, EventMapping>(props, {
ins: mapInstance,
events: mapEventMap,
setterMap,
converterMap,
});

useImperativeHandle(ref, () => mapInstance as Mapbox.Map, [mapInstance]);

useEffect(() => {
if (!containerRef.current) return;
let instance: mapbox.Map;

mapbox.accessToken =
'pk.eyJ1IjoienQyMDIzMTEwOSIsImEiOiJjbG9xdGgxcDMwbDAyMmpwODVrNG5seXphIn0.1xKSk8Ll-80kkEwtzfLWhw';
instance = new mapbox.Map({
container: containerRef.current,
style: 'mapbox://styles/mapbox/streets-v12',
center: [-74.5, 40],
zoom: 0,
});
createInstance().then((map) => {
onInstanceCreated();

contextValue.map = instance;
contextValue.map = map;

instance.once('load', () => {
setMapInstance(instance);
map.once('load', () => {
setMapInstance(map);
});
});
}, [containerRef]);

/** 创建地图实例 */
const createInstance = () => {
const options = getCreateOptions(props);
return Promise.resolve(new Mapbox.Map(options));
};

/** 获取创建地图的参数 */
const getCreateOptions = (props: MapProps) => {
const container = containerRef.current as HTMLDivElement;

const options: Partial<Record<MapboxOptionKeys, any>> = {
container,
};

allProps.forEach((key) => {
if (key in props && key !== 'container') {
options[key] = props[key];
}
});

return options as Mapbox.MapboxOptions;
};

return (
<div ref={containerRef} style={{ width: 500, height: 500 }}>
{!mapInstance && loading}
{mapInstance && <MapContext.Provider value={contextValue}>{children}</MapContext.Provider>}
</div>
);
};
});
9 changes: 6 additions & 3 deletions src/map/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import type { MapboxOptions, MapEventType } from 'mapbox-gl';
import type { KeysOfUnion } from '@pansy/shared/types';
import type { KeysOfUnion } from '../types';

export interface MapOptions extends MapboxOptions {}

Expand Down Expand Up @@ -66,9 +67,11 @@ export type MapEvents = {

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

export type PropKey = KeysOfUnion<MapboxOptions>;
export type MapboxOptionKeys = KeysOfUnion<MapboxOptions>;

export interface MapProps extends Omit<MapOptions, 'container'>, Partial<MapEvents> {
/** 地图加载前的加载效果 */
loading?: React.ReactNode;
className?: string;
children?: any;
children?: React.ReactNode;
}
1 change: 0 additions & 1 deletion src/marker/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Marker } from 'mapbox-gl';

import type { LngLatLike } from 'mapbox-gl';

import type { EventMapping, PropKey } from './types';

export const mapEventMap: EventMapping = {
Expand Down
2 changes: 1 addition & 1 deletion src/marker/marker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { MarkerOptions } from 'mapbox-gl';
import type { MarkerProps, EventMapping } from './types';

export const Marker = forwardRef<MapboxMarker, MarkerProps>((props, ref) => {
const map = useMap();
const { map } = useMap();
const { Portal, container } = usePortal();
const [marker, setMarker, getMarker] = useGetState<MapboxMarker | undefined>(undefined);

Expand Down
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { KeysOfUnion } from 'type-fest';
22 changes: 0 additions & 22 deletions stories/Button.stories.ts

This file was deleted.

48 changes: 0 additions & 48 deletions stories/Button.tsx

This file was deleted.

Binary file removed stories/assets/accessibility.png
Binary file not shown.
5 changes: 0 additions & 5 deletions stories/assets/accessibility.svg

This file was deleted.

Binary file removed stories/assets/addon-library.png
Binary file not shown.
Binary file removed stories/assets/assets.png
Binary file not shown.
Binary file removed stories/assets/avif-test-image.avif
Binary file not shown.
Binary file removed stories/assets/context.png
Binary file not shown.
Loading

0 comments on commit 9b4e6be

Please sign in to comment.