Skip to content

Commit

Permalink
Merge pull request #3777 from terrestris/RotationButton
Browse files Browse the repository at this point in the history
feat: add RotationButton
  • Loading branch information
TreffN authored Mar 22, 2024
2 parents 92f8e44 + 1df8a6f commit 784c748
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/Button/RotationButton/RotationButton.example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
This demonstrates the use of the RotationButton

```jsx
import { useEffect, useState } from 'react';

import OlMap from 'ol/Map';
import OlView from 'ol/View';
import OlLayerTile from 'ol/layer/Tile';
import OlSourceOsm from 'ol/source/OSM';
import { fromLonLat } from 'ol/proj';

import MapContext from '@terrestris/react-geo/dist/Context/MapContext/MapContext'
import MapComponent from '@terrestris/react-geo/dist/Map/MapComponent/MapComponent';
import RotationButton from '@terrestris/react-geo/dist/Button/RotationButton/RotationButton';

const RotationButtonExample = () => {

const [map, setMap] = useState();

useEffect(() => {

setMap(new OlMap({
layers: [
new OlLayerTile({
name: 'OSM',
source: new OlSourceOsm()
})
],
view: new OlView({
center: fromLonLat([8, 50]),
zoom: 4
})
}));
},[] );

if (!map) {
return null;
}

return (
<div>
<MapContext.Provider value={map}>
<MapComponent
map={map}
style={{
height: '400px'
}}
/>
<RotationButton/>
</MapContext.Provider>
</div>
);
}

<RotationButtonExample />
```
49 changes: 49 additions & 0 deletions src/Button/RotationButton/RotationButton.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as React from 'react';
import { within } from '@testing-library/react';

import OlMap from 'ol/Map';
import OlView from 'ol/View';
import OlSourceOsm from 'ol/source/OSM';
import OlLayerTile from 'ol/layer/Tile';

import { renderInMapContext } from '../../Util/rtlTestUtils';
import RotationButton from './RotationButton';

describe('<RotationButton />', () => {

const coord = [829729, 6708850];
let map: OlMap;
let layer: OlLayerTile<OlSourceOsm>;

beforeEach(() => {

layer = new OlLayerTile({
source: new OlSourceOsm()
});

map = new OlMap({
view: new OlView({
center: coord,
zoom: 10
}),
controls: [],
layers: [
layer
]
});
});

describe('#Basics', () => {

it('is defined', () => {
expect(RotationButton).not.toBeUndefined();
});

it('can be rendered', () => {
const { container } = renderInMapContext(map, <RotationButton />);

const button = within(container).getByRole('button');
expect(button).toBeVisible();
});
});
});
46 changes: 46 additions & 0 deletions src/Button/RotationButton/RotationButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';

import { faArrowsRotate } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

import { DragRotateAndZoom } from 'ol/interaction.js';

import { useMap } from '../../Hook/useMap';
import ToggleButton, {
ToggleButtonProps
} from '../ToggleButton/ToggleButton';

export type RotationButtonProps = Partial<ToggleButtonProps>;

export const RotationButton: React.FC<RotationButtonProps> = ({
tooltip = 'Shift + Drag to rotate and zoom the map around its center',
pressedIcon = <FontAwesomeIcon icon={faArrowsRotate} />,
tooltipProps,
...passThroughProps}
) => {
const map = useMap();

if (!map) {
return <></>;
}
let action = new DragRotateAndZoom();
const onToggle = (pressed: boolean) => {
if (pressed) {
map.addInteraction(action);
} else {
map.removeInteraction(action);
}
};

return (
<ToggleButton
tooltip={'Shift + Drag to rotate and zoom the map around its center'}
icon={<FontAwesomeIcon icon={faArrowsRotate} />}
pressedIcon={<FontAwesomeIcon icon={faArrowsRotate} />}
onToggle={onToggle}
tooltipProps={tooltipProps}
{...passThroughProps}
/>
);
};
export default RotationButton;

0 comments on commit 784c748

Please sign in to comment.