Skip to content

Commit bd149d2

Browse files
dnlkochTreffN
andcommitted
feat: refactor handling of shrinked map if drawer is opened
Co-authored-by: TreffN <ntreff@terrestris.de>
1 parent 1897062 commit bd149d2

12 files changed

Lines changed: 179 additions & 86 deletions

File tree

src/App.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import EditFeatureDrawer from './components/EditFeatureDrawer';
1010
import Footer from './components/Footer';
1111
import Header from './components/Header';
1212
import LayerDetailsModal from './components/LayerDetailsModal';
13-
import MapToolbar from './components/MapToolbar';
1413
import SearchResultDrawer from './components/SearchResultDrawer';
1514
import StylingDrawer from './components/StylingDrawer';
1615
import ToolMenu from './components/ToolMenu';
@@ -44,7 +43,6 @@ export const App: React.FC<AppProps> = ({
4443
<Header />
4544
<BasicMapComponent />
4645
<ToolMenu />
47-
<MapToolbar />
4846
<Footer />
4947
<CookieBanner />
5048
<AddLayerModal />

src/components/BasicMapComponent/index.less

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
.map {
2+
.toolbar-control {
3+
top: calc(var(--headerHeight) + 10px);
4+
right: 10px;
5+
6+
&.ol-control {
7+
background-color: unset;
8+
9+
button {
10+
height: var(--ant-control-height);
11+
}
12+
}
13+
}
14+
215
.bg-layer-chooser {
316
bottom: 95px;
417
right: 10px;

src/components/BasicMapComponent/index.tsx

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import React, {
22
useEffect
33
} from 'react';
44

5-
import { ObjectEvent as OlObjectEvent } from 'ol/Object';
5+
import {
6+
ObjectEvent as OlObjectEvent
7+
} from 'ol/Object';
68

79
import {
810
useTranslation
911
} from 'react-i18next';
1012

11-
import { MapUtil } from '@terrestris/ol-util/dist/MapUtil/MapUtil';
13+
import {
14+
MapUtil
15+
} from '@terrestris/ol-util/dist/MapUtil/MapUtil';
1216

1317
import {
1418
BackgroundLayerChooser
@@ -18,7 +22,9 @@ import {
1822
MapComponent,
1923
MapComponentProps
2024
} from '@terrestris/react-geo/dist/Map/MapComponent/MapComponent';
21-
import { useMap } from '@terrestris/react-util/dist/Hooks/useMap/useMap';
25+
import {
26+
useMap
27+
} from '@terrestris/react-util/dist/Hooks/useMap/useMap';
2228

2329
import useAppSelector from '../../hooks/useAppSelector';
2430
import usePlugins from '../../hooks/usePlugins';
@@ -27,6 +33,9 @@ import {
2733
isMapIntegration
2834
} from '../../plugin';
2935

36+
import MapControl from '../MapControl';
37+
import MapToolbar from '../MapToolbar';
38+
3039
import './index.less';
3140

3241
export const BasicMapComponent: React.FC<Partial<MapComponentProps>> = ({
@@ -42,6 +51,7 @@ export const BasicMapComponent: React.FC<Partial<MapComponentProps>> = ({
4251

4352
const blcVisible = useAppSelector(state => state.backgroundLayerChooser.visible);
4453
const allowEmptyBackground = useAppSelector(state => state.backgroundLayerChooser.allowEmptyBackground);
54+
const mapToolbarVisible = useAppSelector(state => state.mapToolbarVisible.visible);
4555

4656
/**
4757
* Updates external layer group name when language changes.
@@ -90,11 +100,22 @@ export const BasicMapComponent: React.FC<Partial<MapComponentProps>> = ({
90100
map={map}
91101
{...restProps}
92102
>
93-
{blcVisible &&
94-
<BackgroundLayerChooser
95-
layers={map.getAllLayers().filter(l => l.get('isBackgroundLayer') === true).reverse()}
96-
allowEmptyBackground = {allowEmptyBackground}
97-
/>
103+
{
104+
mapToolbarVisible && (
105+
<MapControl
106+
className="toolbar-control"
107+
>
108+
<MapToolbar />
109+
</MapControl>
110+
)
111+
}
112+
{
113+
blcVisible && (
114+
<BackgroundLayerChooser
115+
layers={map.getAllLayers().filter(l => l.get('isBackgroundLayer') === true).reverse()}
116+
allowEmptyBackground = {allowEmptyBackground}
117+
/>
118+
)
98119
}
99120
{
100121
pluginComponents

src/components/ClassificationDrawer/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const ClassificationDrawer: FC<ClassificationDrawerProps> = ({
8585
open={isOpen}
8686
maskClosable={false}
8787
destroyOnHidden={true}
88+
shrinkMapOnOpen={false}
8889
mask={false}
8990
{...passThroughProps}
9091
>

src/components/EditFeatureDrawer/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ export const EditFeatureDrawer: React.FC<EditFeatureDrawerProps> = ({
157157
className="map-drawer edit-feature-drawer"
158158
onClose={onDrawerClose}
159159
open={isDrawerOpen}
160+
shrinkMapOnOpen={false}
160161
title={drawerTitle}
161162
{...passThroughProps}
162163
>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React, {
2+
useState,
3+
useEffect
4+
} from 'react';
5+
6+
import {
7+
Control as OlControl
8+
} from 'ol/control';
9+
10+
import {
11+
createPortal
12+
} from 'react-dom';
13+
14+
import {
15+
useMap
16+
} from '@terrestris/react-util/dist/Hooks/useMap/useMap';
17+
18+
interface MapControlProps {
19+
className?: string;
20+
children: React.ReactNode;
21+
}
22+
23+
export const MapControl = ({
24+
className = '',
25+
children
26+
}: MapControlProps) => {
27+
const [element] = useState(() => document.createElement('div'));
28+
29+
const map = useMap();
30+
31+
useEffect(() => {
32+
if (!map) {
33+
return;
34+
}
35+
36+
element.className = `${className} ol-unselectable ol-control`.trim();
37+
const control = new OlControl({ element });
38+
map.addControl(control);
39+
40+
return () => {
41+
map.removeControl(control);
42+
};
43+
}, [map, element, className]);
44+
45+
return createPortal(children, element);
46+
};
47+
48+
export default MapControl;

src/components/MapDrawer/index.less

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
#map {
2+
transition: width 0.3s;
3+
4+
&.bisected {
5+
width: calc(100vw - var(--drawerWidth));
6+
}
7+
8+
.ol-control {
9+
transition: right 0.3s;
10+
11+
&.bisected {
12+
right: calc(10px + var(--drawerWidth));
13+
}
14+
}
15+
}
16+
117
.ant-drawer.map-drawer {
218
position: absolute;
319
top: var(--headerHeight);

src/components/MapDrawer/index.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,30 @@ import { useMap } from '@terrestris/react-util/dist/Hooks/useMap/useMap';
1414

1515
import './index.less';
1616

17-
export type MapDrawerProps = DrawerProps;
17+
export type MapDrawerProps = {
18+
shrinkMapOnOpen?: boolean;
19+
additionalMapElementClassName?: string;
20+
} & DrawerProps;
1821

1922
export const MapDrawer: React.FC<MapDrawerProps> = ({
2023
open,
2124
children,
25+
shrinkMapOnOpen = true,
26+
additionalMapElementClassName = 'bisected',
2227
...passThroughProps
2328
}) => {
2429

2530
const map = useMap();
2631

2732
useEffect(() => {
28-
document.querySelectorAll('#map')[0]?.classList.toggle('bisected', !!open);
29-
}, [open]);
33+
if (!shrinkMapOnOpen) {
34+
document.querySelectorAll('#map .ol-control')?.forEach(element => {
35+
element.classList.toggle(additionalMapElementClassName, !!open);
36+
});
37+
} else {
38+
document.querySelectorAll('#map')[0]?.classList.toggle(additionalMapElementClassName, !!open);
39+
}
40+
}, [open, additionalMapElementClassName, shrinkMapOnOpen]);
3041

3142
const onAfterDrawerOpenChange = () => {
3243
map?.updateSize();

src/components/MapToolbar/index.less

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
#map-toolbar {
2-
position: absolute;
3-
top: calc(var(--headerHeight) + 16px);
4-
right: 10px;
5-
transition: 0.3s;
62
flex-direction: column;
73
z-index: 1;
84

9-
&.drawer-open {
10-
right: calc(var(--drawerWidth) + 10px);
11-
}
12-
135
.ant-btn {
146
margin: 5px;
157
display: block;

src/components/MapToolbar/index.tsx

Lines changed: 55 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import React, { useState } from 'react';
1+
import React, {
2+
useState
3+
} from 'react';
24

35
import {
46
faPlus,
@@ -27,8 +29,9 @@ import {
2729
useMap
2830
} from '@terrestris/react-util/dist/Hooks/useMap/useMap';
2931

30-
import useAppSelector from '../../hooks/useAppSelector';
31-
import Toolbar, { ToolbarProps } from '../Toolbar';
32+
import Toolbar, {
33+
ToolbarProps
34+
} from '../Toolbar';
3235

3336
import './index.less';
3437

@@ -42,14 +45,6 @@ export const MapToolbar: React.FC = (): JSX.Element => {
4245

4346
const [geolocationButtonPressed, setGeolocationButtonPressed] = useState(false);
4447

45-
const mapToolbarVisible = useAppSelector(state => state.mapToolbarVisible.visible);
46-
47-
const stylingDrawerVisibility = useAppSelector(state => state.stylingDrawerVisibility);
48-
const editFeatureDrawerOpen = useAppSelector(state => state.editFeatureDrawerOpen);
49-
const searchResultDrawerOpen = useAppSelector(state => state.searchResult.drawerVisibility);
50-
const drawerOpen = stylingDrawerVisibility || editFeatureDrawerOpen || searchResultDrawerOpen;
51-
const className = drawerOpen ? 'drawer-open' : '';
52-
5348
const btnTooltipProps = {
5449
tooltipPlacement: 'left' as TooltipPlacement,
5550
tooltipProps: {
@@ -58,60 +53,55 @@ export const MapToolbar: React.FC = (): JSX.Element => {
5853
};
5954

6055
return (
61-
<>
62-
{mapToolbarVisible &&
63-
<Toolbar
64-
id='map-toolbar'
65-
className={className}
66-
alignment="vertical"
67-
role="toolbar"
68-
>
69-
{map &&
70-
<ZoomButton
71-
aria-label='zoom-in'
72-
tooltip={t('MapToolbar.zoomInTooltip')}
73-
icon={
74-
<FontAwesomeIcon
75-
icon={faPlus}
76-
/>
77-
}
78-
{...btnTooltipProps}
79-
/>}
80-
{map &&
81-
<ZoomButton
82-
aria-label='zoom-out'
83-
tooltip={t('MapToolbar.zoomOutTooltip')}
84-
delta={-1}
85-
icon={
86-
<FontAwesomeIcon
87-
icon={faMinus}
88-
/>
89-
}
90-
{...btnTooltipProps}
91-
/>}
92-
{map &&
93-
<GeoLocationButton
94-
aria-label='geolocation'
95-
showMarker={true}
96-
follow={true}
97-
pressed={geolocationButtonPressed}
98-
onChange={() => setGeolocationButtonPressed(!geolocationButtonPressed)}
99-
tooltip={t('MapToolbar.geoLocation')}
100-
icon={
101-
<FontAwesomeIcon
102-
icon={faLocation}
103-
/>
104-
}
105-
pressedIcon={
106-
<FontAwesomeIcon
107-
icon={faLocationPin}
108-
/>
109-
}
110-
{...btnTooltipProps}
111-
/>}
112-
</Toolbar>
113-
}
114-
</>
56+
<Toolbar
57+
id="map-toolbar"
58+
alignment="vertical"
59+
role="toolbar"
60+
>
61+
{map &&
62+
<ZoomButton
63+
aria-label="zoom-in"
64+
tooltip={t('MapToolbar.zoomInTooltip')}
65+
icon={
66+
<FontAwesomeIcon
67+
icon={faPlus}
68+
/>
69+
}
70+
{...btnTooltipProps}
71+
/>}
72+
{map &&
73+
<ZoomButton
74+
aria-label="zoom-out"
75+
tooltip={t('MapToolbar.zoomOutTooltip')}
76+
delta={-1}
77+
icon={
78+
<FontAwesomeIcon
79+
icon={faMinus}
80+
/>
81+
}
82+
{...btnTooltipProps}
83+
/>}
84+
{map &&
85+
<GeoLocationButton
86+
aria-label="geolocation"
87+
showMarker={true}
88+
follow={true}
89+
pressed={geolocationButtonPressed}
90+
onChange={() => setGeolocationButtonPressed(!geolocationButtonPressed)}
91+
tooltip={t('MapToolbar.geoLocation')}
92+
icon={
93+
<FontAwesomeIcon
94+
icon={faLocation}
95+
/>
96+
}
97+
pressedIcon={
98+
<FontAwesomeIcon
99+
icon={faLocationPin}
100+
/>
101+
}
102+
{...btnTooltipProps}
103+
/>}
104+
</Toolbar>
115105
);
116106
};
117107

0 commit comments

Comments
 (0)