Skip to content

Commit

Permalink
feat: 新增工具组件 AMapRangingTool
Browse files Browse the repository at this point in the history
  • Loading branch information
xyy94813 committed Dec 9, 2023
1 parent 5497042 commit 343cdf7
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 1 deletion.
43 changes: 43 additions & 0 deletions src/components/AMapRangingTool/AMapRangingTool.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { FC } from 'react';
import { useEffect } from 'react';

import useAMapPluginInstance from '../../hooks/useAMapPluginInstance';
import useAMapEventBinder from '../../hooks/useAMapEventBinder';

import type { AMapRangingToolProps } from './interface';

const initInstance = (
AMap: typeof globalThis.AMap,
map: AMap.Map, //
) => new AMap!.RangingTool(map, {} as any);

const AMapRangingTool: FC<AMapRangingToolProps> = ({
disabled,
onNodeAdded,
onNodeRemoved,
onEnd,
}) => {
const curInstance = useAMapPluginInstance<AMap.RangingTool>('RangingTool', initInstance);

useEffect(() => {
if (!curInstance) return;
if (disabled) {
curInstance.turnOff();
} else {
curInstance.turnOn();
}
}, [disabled, curInstance]);

useAMapEventBinder(curInstance, 'addnode', onNodeAdded);
useAMapEventBinder(curInstance, 'removenode', onNodeRemoved);
useAMapEventBinder(curInstance, 'end', onEnd);

return null;
};

AMapRangingTool.defaultProps = {
// eslint-disable-next-line react/default-props-match-prop-types
disabled: false,
};

export default AMapRangingTool;
70 changes: 70 additions & 0 deletions src/components/AMapRangingTool/__tests__/AMapRangingTool.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as React from 'react';
import { render, cleanup } from '@testing-library/react';

import useAMapPluginInstance from '../../../hooks/useAMapPluginInstance';

import AMapRangingTool from '../AMapRangingTool';

const mockInstance = {
turnOn: jest.fn(),
turnOff: jest.fn(),
on: jest.fn(),
off: jest.fn(),
};

jest.mock('../../../hooks/useAMapPluginInstance', () => ({
esModule: true,
default: jest.fn((__, cb) => {
cb(
{
RangingTool: jest.fn(),
},
{},
);

return mockInstance;
}),
}));

describe('AMapRangingTool', () => {
beforeEach(() => {
jest.clearAllMocks();
});
afterEach(cleanup);

test('renders without crashing', () => {
expect(() => {
render(<AMapRangingTool />);
}).not.toThrowError();
expect(useAMapPluginInstance).toHaveBeenCalledWith('RangingTool', expect.any(Function));
});

test('renders without crashing when instance is null', () => {
(useAMapPluginInstance as jest.Mock).mockReturnValueOnce(null);
expect(() => {
render(<AMapRangingTool />);
}).not.toThrowError();
});

test('bind event correctly', () => {
const onNodeAdded = jest.fn();
const onNodeRemoved = jest.fn();
const onEnd = jest.fn();

const { unmount } = render(
<AMapRangingTool onNodeAdded={onNodeAdded} onNodeRemoved={onNodeRemoved} onEnd={onEnd} />,
);

expect(mockInstance.on).toBeCalledTimes(3);
expect(mockInstance.on).toBeCalledWith('addnode', onNodeAdded);
expect(mockInstance.on).toBeCalledWith('removenode', onNodeRemoved);
expect(mockInstance.on).toBeCalledWith('end', onEnd);

unmount();

expect(mockInstance.on).toBeCalledTimes(3);
expect(mockInstance.off).toBeCalledWith('addnode', onNodeAdded);
expect(mockInstance.off).toBeCalledWith('removenode', onNodeRemoved);
expect(mockInstance.off).toBeCalledWith('end', onEnd);
});
});
2 changes: 2 additions & 0 deletions src/components/AMapRangingTool/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './interface';
export { default } from './AMapRangingTool';
6 changes: 6 additions & 0 deletions src/components/AMapRangingTool/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type AMapRangingToolProps = {
disabled?: boolean;
onNodeAdded?: (event?: any) => void;
onNodeRemoved?: (event?: any) => void;
onEnd?: (event?: any) => void;
};
79 changes: 79 additions & 0 deletions src/components/AMapRangingTool/stories/AMapRangingTool.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type { Meta, StoryObj } from '@storybook/react';
import { actions } from '@storybook/addon-actions';

import { AMapRangingTool } from '../../../index';

import withAMap from '../../../storybook-decorators/withAMap';
import withAMapContainer from '../../../storybook-decorators/withAMapContainer';
import withAPIContainer from '../../../storybook-decorators/withAPIContainer';

const eventHandler = actions('onNodeAdded', 'onNodeRemoved', 'onEnd');

const meta: Meta<typeof AMapRangingTool> = {
title: '组件(Components)/工具(Tools)/AMapRangingTool',
component: AMapRangingTool,
decorators: [withAMap(), withAMapContainer, withAPIContainer],
args: {},
argTypes: {
disabled: {
description: '禁用 RangingTool',
type: { required: false, name: 'boolean' },
table: {
type: { summary: 'boolean' },
defaultValue: { summary: false },
},
control: 'boolean',
},
onNodeAdded: {
description: '每添加一个量测点时触发此事件',
type: { required: false, name: 'function' },
table: {
type: {
summary: '(event: AMap.Event<"addnode">) => void',
},
},
},
onNodeRemoved: {
description: '每删除一个量测点时触发此事件',
type: { required: false, name: 'function' },
table: {
type: {
summary: '(event: AMap.Event<"removenode">) => void',
},
},
},
onEnd: {
description: '距离量测结束后触发此事件',
type: { required: false, name: 'function' },
table: {
type: {
summary: '(event: AMap.Event<"end">) => void',
},
},
},
},
};

export default meta;

type AMapRangingToolStory = StoryObj<typeof AMapRangingTool>;

export const CommonUse: AMapRangingToolStory = {
name: '基本使用',
};

export const Disabled: AMapRangingToolStory = {
name: '禁用',
args: {
disabled: true,
},
};

export const BindEvent: AMapRangingToolStory = {
name: '监听事件',
args: {
onNodeAdded: eventHandler.onNodeAdded,
onNodeRemoved: eventHandler.onNodeRemoved,
onEnd: eventHandler.onEnd,
},
};
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export { default as AMapPolylineEditor } from './components/AMapPolylineEditor';

export type { AMapMouseToolProps } from './components/AMapMouseTool';
export { default as AMapMouseTool } from './components/AMapMouseTool';

export type { AMapRangingToolProps } from './components/AMapRangingTool';
export { default as AMapRangingTool } from './components/AMapRangingTool';
// helpers
export { default as coordsOfGeoJSON2AMapPolygonPath } from './helpers/coordsOfGeoJSON2AMapPolygonPath';
export { default as amapPolygonPath2GeoJSONCoords } from './helpers/amapPolygonPath2GeoJSONCoords';

0 comments on commit 343cdf7

Please sign in to comment.