Skip to content

Commit 4fce341

Browse files
authored
Design/sketch tool (#222)
Co-authored-by: jannik brack <[email protected]> Co-authored-by: Martin Alzueta <[email protected]> Errors fixed tests done by Martin and myself.
1 parent ddd2371 commit 4fce341

File tree

7 files changed

+128
-26
lines changed

7 files changed

+128
-26
lines changed

public/thumbnails/MlSketchTool.png

102 KB
Loading

src/components/MlGeoJsonLayer/util/getDefaultPaintPropsByType.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const getDefaultPaintPropsByType = (
1313
// 'fill-color': 'rgba(10,240,256,0.6)',
1414
// 'fill-outline-color': 'rgba(20,230,256,0.8)',
1515
'fill-color': '#009EE0',
16-
'fill-outline-color': '#009EE0',
16+
'fill-outline-color': '#009EE0'
1717
};
1818
case 'line':
1919
if (defaultPaintOverrides?.line) {
@@ -25,7 +25,7 @@ const getDefaultPaintPropsByType = (
2525
// 'line-width': 5,
2626
// 'line-blur': 0,
2727
'line-color': '#009EE0',
28-
'line-width': 5,
28+
'line-width': 4,
2929
'line-blur': 0,
3030
};
3131
case 'circle':
@@ -41,6 +41,7 @@ const getDefaultPaintPropsByType = (
4141
'circle-stroke-color': '#fff',
4242
'circle-stroke-width': 2,
4343
'circle-radius': 5,
44+
4445
};
4546
default:
4647
return {};

src/components/MlSketchTool/MlSketchTool.stories.tsx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@ const Template = () => {
4242

4343
const catalgoueTemplate = () => {
4444
// const mediaIsMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down('lg'));
45+
// const mediaIsMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down('lg'));
4546

4647
const [openSidebar, setOpenSidebar] = useState(true);
4748
const [instructionText, setInstructionText] = useState('Select a sketch tool.');
49+
const [showInstruction, setShowInstruction] = useState(true);
4850

4951
const getInstructionText = (drawMode?: keyof MapboxDraw.Modes, selectedGeoJson?: Feature) => {
5052
if (drawMode === 'simple_select' && selectedGeoJson) {
@@ -81,29 +83,33 @@ const catalgoueTemplate = () => {
8183
/>
8284
<Sidebar open={openSidebar} setOpen={setOpenSidebar} name={'Sketch Tool'}>
8385
<MlSketchTool
86+
showInstruction={showInstruction}
87+
onShowInstructionChange={setShowInstruction}
8488
onChange={(state) => {
8589
const { drawMode, selectedGeoJson } = state;
8690
setInstructionText(getInstructionText(drawMode, selectedGeoJson));
8791
}}
8892
/>
8993
</Sidebar>
9094

91-
<Paper
92-
sx={{
93-
position: 'fixed',
94-
bottom: '25px',
95-
left: '50%',
96-
padding: '10px',
97-
zIndex: 101,
98-
}}
99-
>
100-
<Typography>
101-
{/* {mediaIsMobile
95+
{showInstruction && (
96+
<Paper
97+
sx={{
98+
position: 'fixed',
99+
bottom: '25px',
100+
left: '50%',
101+
padding: '10px',
102+
zIndex: 101,
103+
}}
104+
>
105+
<Typography>
106+
{/* {mediaIsMobile
102107
? 'Zum Beenden erneut auf denselben Punkt klicken.'
103108
: 'Die Zeichnung kann beendet werden, indem erneut auf den zuletzt gezeichneten Punkt geklickt wird.'} */}
104-
{instructionText}
105-
</Typography>
106-
</Paper>
109+
{instructionText}
110+
</Typography>
111+
</Paper>
112+
)}
107113
</>
108114
);
109115
};
@@ -113,4 +119,4 @@ ExampleConfig.parameters = {};
113119
ExampleConfig.args = {};
114120

115121
export const CatalogueDemo = catalgoueTemplate.bind({});
116-
CatalogueDemo.args = {};
122+
CatalogueDemo.args = {};

src/components/MlSketchTool/MlSketchTool.tsx

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import GpsFixedIcon from '@mui/icons-material/GpsFixed';
1515
import { Feature } from 'geojson';
1616
import { LngLatLike } from 'maplibre-gl';
1717
import { SxProps } from '@mui/system/styleFunctionSx/styleFunctionSx';
18-
import { Button, Theme } from '@mui/material';
18+
import { Button, Checkbox, FormControlLabel, FormGroup, Theme, Typography } from '@mui/material';
1919
import ScatterPlotIcon from '@mui/icons-material/ScatterPlot';
2020
import PolylineIcon from '@mui/icons-material/Polyline';
2121

@@ -45,6 +45,14 @@ export interface MlSketchToolProps {
4545
* First parameter contains all geometries in the `geometries` prop.
4646
*/
4747
onChange?: (para: SketchStateType) => void;
48+
/**
49+
* Determines whether the instruction text should be shown.
50+
*/
51+
showInstruction?: boolean;
52+
/**
53+
* Callback function triggered when the "Show instructions" checkbox is toggled.
54+
*/
55+
onShowInstructionChange?: (value: boolean) => void;
4856
}
4957

5058
type SketchStateType = {
@@ -136,6 +144,10 @@ const MlSketchTool = (props: MlSketchToolProps) => {
136144
});
137145
};
138146

147+
const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
148+
props.onShowInstructionChange?.(event.target.checked);
149+
};
150+
139151
const SketchToolButtons = () => {
140152
return (
141153
<>
@@ -194,6 +206,21 @@ const MlSketchTool = (props: MlSketchToolProps) => {
194206
</ButtonGroup>
195207
</Box>
196208

209+
<Box sx={{ marginTop: '10px' }}>
210+
<FormGroup>
211+
<FormControlLabel
212+
control={
213+
<Checkbox
214+
size="small"
215+
checked={props.showInstruction}
216+
onChange={handleCheckboxChange}
217+
/>
218+
}
219+
label="Show instructions"
220+
/>
221+
</FormGroup>
222+
</Box>
223+
197224
{sketchState.drawMode && (
198225
<MlFeatureEditor
199226
mode={sketchState.drawMode}
@@ -268,7 +295,7 @@ const MlSketchTool = (props: MlSketchToolProps) => {
268295
)}
269296

270297
<List sx={{ zIndex: 105, marginBottom: '-10px' }}>
271-
{sketchState.geometries.map((el) => (
298+
{sketchState.geometries.map((el, index) => (
272299
<>
273300
<Box key={el.id} sx={{ display: 'flex', flexDirection: 'column' }}>
274301
<br />
@@ -287,6 +314,50 @@ const MlSketchTool = (props: MlSketchToolProps) => {
287314
setHoveredGeometry(undefined);
288315
}}
289316
>
317+
{/* Input field for user-defined name */}
318+
{!el.properties?.customName && (
319+
<input
320+
type="text"
321+
value={el.properties?.name || ''}
322+
placeholder="Assign name"
323+
onChange={(e) => {
324+
const newName = e.target.value;
325+
setSketchState((_sketchState) => {
326+
const updatedGeometries = [..._sketchState.geometries];
327+
if (!updatedGeometries[index].properties) {
328+
updatedGeometries[index].properties = {};
329+
}
330+
updatedGeometries[index].properties!.name = newName;
331+
return {
332+
..._sketchState,
333+
geometries: updatedGeometries,
334+
};
335+
});
336+
}}
337+
style={{
338+
padding: '5px',
339+
border: '1px solid #ccc',
340+
borderRadius: '4px',
341+
outline: 'none',
342+
}}
343+
onFocus={(e) => (e.target.style.borderColor = '#009ee0')}
344+
onBlur={(e) => {
345+
e.target.style.borderColor = '#ccc';
346+
setSketchState((_sketchState) => {
347+
const updatedGeometries = [..._sketchState.geometries];
348+
if (!updatedGeometries[index].properties) {
349+
updatedGeometries[index].properties = {};
350+
}
351+
updatedGeometries[index].properties!.customName = true;
352+
return {
353+
..._sketchState,
354+
geometries: updatedGeometries,
355+
};
356+
});
357+
}}
358+
/>
359+
)}
360+
290361
{/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
291362
{/* @ts-ignore-next-line */}
292363
<LayerListItem
@@ -303,7 +374,30 @@ const MlSketchTool = (props: MlSketchToolProps) => {
303374
/>
304375
}
305376
type={'layer'}
306-
name={String(el.id)}
377+
name={
378+
<Typography
379+
onClick={() => {
380+
setSketchState((_sketchState) => {
381+
const updatedGeometries = [..._sketchState.geometries];
382+
if (!updatedGeometries[index].properties) {
383+
updatedGeometries[index].properties = {};
384+
}
385+
updatedGeometries[index].properties!.customName = false;
386+
return {
387+
..._sketchState,
388+
geometries: updatedGeometries,
389+
};
390+
});
391+
}}
392+
sx={{
393+
cursor: 'pointer',
394+
overflow: 'hidden',
395+
whiteSpace: 'nowrap',
396+
}}
397+
>
398+
{el.properties?.name || String(el.id)}
399+
</Typography>
400+
}
307401
description={el.geometry.type}
308402
></LayerListItem>
309403
<Box

src/hooks/useFeatureEditor/utils/FeatureEditorStyle.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Theme, useMediaQuery } from '@mui/material';
2+
23
function featureEditorStyle() {
34
const mediaIsMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down('md'));
45

@@ -78,8 +79,7 @@ function featureEditorStyle() {
7879
},
7980
paint: {
8081
'line-color': '#009EE0',
81-
'line-width': 10,
82-
'line-opacity': 0.2,
82+
'line-width': 4,
8383
},
8484
},
8585
{
@@ -234,4 +234,5 @@ function featureEditorStyle() {
234234
];
235235
return featureEditorStyle;
236236
}
237+
237238
export default featureEditorStyle;

src/ui_components/LayerList/LayerListFolder.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useMemo, useState } from 'react';
1+
import React, { ReactNode, useMemo, useState } from 'react';
22
import { Box, styled } from '@mui/system';
33
import { Checkbox, IconButton, List, ListItem, ListItemIcon, ListItemText } from '@mui/material';
44
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
@@ -30,7 +30,7 @@ const ListStyled = styled(List)({
3030

3131
interface LayerListFolderProps {
3232
visible: boolean;
33-
name?: string;
33+
name?: string | ReactNode;
3434
children: JSX.Element | JSX.Element[];
3535
setVisible?: (visible: boolean | ((val: unknown) => boolean)) => void;
3636
}

src/ui_components/LayerList/LayerListItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useMemo, useRef, useState } from 'react';
1+
import React, { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
22
import { LayerSpecification } from 'maplibre-gl';
33
import { IconButton, ListItemText, styled, SxProps } from '@mui/material';
44
import DeleteIcon from '@mui/icons-material/Delete';
@@ -28,7 +28,7 @@ interface LayerListItemProps {
2828
visible: boolean;
2929
configurable: boolean;
3030
type?: 'background' | 'background-labels' | 'layer' | 'wms-layer' | 'vector-tile-layer';
31-
name: string;
31+
name: string | ReactNode;
3232
description?: string;
3333
setLayerState?: (state: unknown) => void;
3434
showDeleteButton?: boolean;

0 commit comments

Comments
 (0)