ublo-lib 1.6.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/common/components/editable-map/edit-form.js +4 -2
- package/es/common/components/editable-map/editable-map.js +30 -24
- package/es/common/components/editable-map/icon-picker.js +3 -2
- package/es/common/components/editable-map/{icons.js → icons/esf.js} +0 -0
- package/es/common/components/editable-map/icons/index.js +2 -0
- package/es/common/components/editable-map/icons/lavovelo.js +20 -0
- package/es/common/components/editable-map/index.js +5 -2
- package/es/common/components/editable-map/map-events.js +51 -0
- package/es/common/components/editable-map/markers.js +12 -64
- package/es/common/components/editable-map/markers.module.css +0 -28
- package/es/common/components/editable-map/popup-data.js +36 -0
- package/es/common/components/editable-map/popup-data.module.css +27 -0
- package/package.json +1 -1
|
@@ -11,7 +11,8 @@ import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
11
11
|
const EditForm = ({
|
|
12
12
|
popupRef,
|
|
13
13
|
marker,
|
|
14
|
-
setMarkers
|
|
14
|
+
setMarkers,
|
|
15
|
+
iconSet
|
|
15
16
|
}) => {
|
|
16
17
|
const {
|
|
17
18
|
id,
|
|
@@ -51,7 +52,8 @@ const EditForm = ({
|
|
|
51
52
|
className: css.row,
|
|
52
53
|
children: [_jsx(IconPicker, {
|
|
53
54
|
callback: updateMarker("icon"),
|
|
54
|
-
selectedIcon: icon
|
|
55
|
+
selectedIcon: icon,
|
|
56
|
+
iconSet: iconSet
|
|
55
57
|
}), _jsx(Input, {
|
|
56
58
|
label: "Titre",
|
|
57
59
|
value: title,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { MapContainer, TileLayer } from "react-leaflet";
|
|
3
3
|
import { useUbloContext } from "ublo/with-ublo";
|
|
4
|
+
import MapEvents from "./map-events";
|
|
4
5
|
import Markers from "./markers";
|
|
5
6
|
import Helper from "./helper";
|
|
6
7
|
import css from "./editable-map.module.css";
|
|
@@ -11,7 +12,8 @@ const FRANCE_CENTER = [46.807934, 3.645097];
|
|
|
11
12
|
const DEFAULT_ZOOM = 6;
|
|
12
13
|
|
|
13
14
|
const EditableMap = ({
|
|
14
|
-
format
|
|
15
|
+
format,
|
|
16
|
+
iconSet
|
|
15
17
|
}) => {
|
|
16
18
|
const ref = React.useRef();
|
|
17
19
|
const {
|
|
@@ -24,16 +26,17 @@ const EditableMap = ({
|
|
|
24
26
|
} = format;
|
|
25
27
|
const [center, setCenter] = React.useState(presets?.center || FRANCE_CENTER);
|
|
26
28
|
const [zoom, setZoom] = React.useState(presets?.zoom ?? DEFAULT_ZOOM);
|
|
27
|
-
const [markers, setMarkers] = React.useState(presets?.markers
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
const [markers, setMarkers] = React.useState(presets?.markers || []);
|
|
30
|
+
|
|
31
|
+
const refreshSize = () => {
|
|
30
32
|
ref.current.invalidateSize();
|
|
31
|
-
}
|
|
33
|
+
};
|
|
34
|
+
|
|
32
35
|
React.useEffect(() => {
|
|
33
36
|
if (isInDialog) {
|
|
34
37
|
window.refreshDialogMapSize = refreshSize;
|
|
35
38
|
}
|
|
36
|
-
}, [isInDialog
|
|
39
|
+
}, [isInDialog]);
|
|
37
40
|
React.useEffect(() => {
|
|
38
41
|
if (cmsMode === "editing") {
|
|
39
42
|
const newPresets = {
|
|
@@ -44,27 +47,30 @@ const EditableMap = ({
|
|
|
44
47
|
element.setAttribute("data-presets", JSON.stringify(newPresets));
|
|
45
48
|
}
|
|
46
49
|
}, [center, cmsMode, element, markers, zoom]);
|
|
47
|
-
const map = React.useMemo(() => _jsxs(MapContainer, {
|
|
48
|
-
ref: ref,
|
|
49
|
-
center: center,
|
|
50
|
-
zoom: zoom,
|
|
51
|
-
scrollWheelZoom: isInDialog,
|
|
52
|
-
className: css.map,
|
|
53
|
-
attributionControl: false,
|
|
54
|
-
children: [_jsx(TileLayer, {
|
|
55
|
-
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
56
|
-
}), _jsx(Markers, {
|
|
57
|
-
mapRef: ref,
|
|
58
|
-
markers: markers,
|
|
59
|
-
setMarkers: setMarkers,
|
|
60
|
-
setZoom: setZoom,
|
|
61
|
-
setCenter: setCenter
|
|
62
|
-
})]
|
|
63
|
-
}), [markers, center, zoom]);
|
|
64
50
|
return _jsxs("div", {
|
|
65
51
|
className: css.container,
|
|
66
52
|
"data-cms-remove": "",
|
|
67
|
-
children: [
|
|
53
|
+
children: [_jsxs(MapContainer, {
|
|
54
|
+
ref: ref,
|
|
55
|
+
center: center,
|
|
56
|
+
zoom: zoom,
|
|
57
|
+
scrollWheelZoom: isInDialog,
|
|
58
|
+
className: css.map,
|
|
59
|
+
attributionControl: false,
|
|
60
|
+
children: [_jsx(TileLayer, {
|
|
61
|
+
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
62
|
+
}), _jsx(MapEvents, {
|
|
63
|
+
mapRef: ref,
|
|
64
|
+
markers: markers,
|
|
65
|
+
setMarkers: setMarkers,
|
|
66
|
+
setZoom: setZoom,
|
|
67
|
+
setCenter: setCenter
|
|
68
|
+
}), _jsx(Markers, {
|
|
69
|
+
markers: markers,
|
|
70
|
+
setMarkers: setMarkers,
|
|
71
|
+
iconSet: iconSet
|
|
72
|
+
})]
|
|
73
|
+
}), cmsMode === "editing" && _jsx(Helper, {})]
|
|
68
74
|
});
|
|
69
75
|
};
|
|
70
76
|
|
|
@@ -8,10 +8,11 @@ import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
|
|
9
9
|
const IconPicker = ({
|
|
10
10
|
selectedIcon,
|
|
11
|
-
callback
|
|
11
|
+
callback,
|
|
12
|
+
iconSet
|
|
12
13
|
}) => {
|
|
13
14
|
const [opened, setOpened] = React.useState(false);
|
|
14
|
-
const Icon = Icons[selectedIcon];
|
|
15
|
+
const Icon = Icons[iconSet][selectedIcon];
|
|
15
16
|
const keys = Object.keys(Icons);
|
|
16
17
|
|
|
17
18
|
const togglePicker = () => {
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
const Icon = ({
|
|
5
|
+
width = 24,
|
|
6
|
+
height = 24,
|
|
7
|
+
...props
|
|
8
|
+
}) => _jsx("svg", {
|
|
9
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
10
|
+
width: width,
|
|
11
|
+
height: height,
|
|
12
|
+
...props,
|
|
13
|
+
children: props.children
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const Location = props => _jsx(Icon, { ...props,
|
|
17
|
+
children: _jsx("path", {
|
|
18
|
+
d: "M12 12q.825 0 1.413-.588Q14 10.825 14 10t-.587-1.413Q12.825 8 12 8q-.825 0-1.412.587Q10 9.175 10 10q0 .825.588 1.412Q11.175 12 12 12Zm0 9.625q-.2 0-.4-.075t-.35-.2Q7.6 18.125 5.8 15.363 4 12.6 4 10.2q0-3.75 2.413-5.975Q8.825 2 12 2t5.587 2.225Q20 6.45 20 10.2q0 2.4-1.8 5.163-1.8 2.762-5.45 5.987-.15.125-.35.2-.2.075-.4.075Z"
|
|
19
|
+
})
|
|
20
|
+
});
|
|
@@ -6,7 +6,9 @@ const Map = dynamic(() => import("./editable-map"), {
|
|
|
6
6
|
ssr: false
|
|
7
7
|
});
|
|
8
8
|
|
|
9
|
-
const EditableMap = (
|
|
9
|
+
const EditableMap = ({
|
|
10
|
+
iconSet = "esf"
|
|
11
|
+
}) => {
|
|
10
12
|
const [formats, setFormats] = React.useState([]);
|
|
11
13
|
const [refreshKey, setRefreshKey] = React.useState(0);
|
|
12
14
|
|
|
@@ -38,7 +40,8 @@ const EditableMap = () => {
|
|
|
38
40
|
}, [refreshKey]);
|
|
39
41
|
if (!formats.length) return null;
|
|
40
42
|
return formats.map(format => ReactDOM.createPortal(_jsx(Map, {
|
|
41
|
-
format: format
|
|
43
|
+
format: format,
|
|
44
|
+
iconSet: iconSet
|
|
42
45
|
}), format.element));
|
|
43
46
|
};
|
|
44
47
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useMapEvents } from "react-leaflet";
|
|
2
|
+
import { useUbloContext } from "ublo/with-ublo";
|
|
3
|
+
const DEFAULT_MARKER_DATA = {
|
|
4
|
+
icon: "Location",
|
|
5
|
+
title: "Nouveau point d'intérêt",
|
|
6
|
+
description: "",
|
|
7
|
+
url: "",
|
|
8
|
+
label: ""
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const MapEvents = ({
|
|
12
|
+
mapRef,
|
|
13
|
+
markers,
|
|
14
|
+
setMarkers,
|
|
15
|
+
setCenter,
|
|
16
|
+
setZoom
|
|
17
|
+
}) => {
|
|
18
|
+
const {
|
|
19
|
+
cmsMode
|
|
20
|
+
} = useUbloContext();
|
|
21
|
+
const ids = markers.map(m => m.id);
|
|
22
|
+
const newId = ids.length ? Math.max(...ids) + 1 : 1;
|
|
23
|
+
|
|
24
|
+
const addMarker = e => {
|
|
25
|
+
const hasAnOpenedPopup = Boolean(mapRef.current?.getContainer().querySelector(".leaflet-popup"));
|
|
26
|
+
if (cmsMode !== "editing" || hasAnOpenedPopup) return;
|
|
27
|
+
setMarkers([...markers, {
|
|
28
|
+
id: newId,
|
|
29
|
+
...DEFAULT_MARKER_DATA,
|
|
30
|
+
position: e.latlng
|
|
31
|
+
}]);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
useMapEvents({
|
|
35
|
+
dragend(e) {
|
|
36
|
+
setCenter(e.target.getCenter());
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
zoomend(e) {
|
|
40
|
+
setZoom(e.target.getZoom());
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
click(e) {
|
|
44
|
+
addMarker(e);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
});
|
|
48
|
+
return null;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default MapEvents;
|
|
@@ -1,71 +1,33 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as ReactDOM from "react-dom/server";
|
|
3
3
|
import * as L from "leaflet";
|
|
4
|
-
import { Marker, Popup, Tooltip
|
|
4
|
+
import { Marker, Popup, Tooltip } from "react-leaflet";
|
|
5
5
|
import { useUbloContext } from "ublo/with-ublo";
|
|
6
|
-
import Button from "dt-design-system/es/button";
|
|
7
6
|
import EditForm from "./edit-form";
|
|
8
7
|
import * as Icons from "./icons";
|
|
9
8
|
import css from "./markers.module.css";
|
|
9
|
+
import PopupData from "./popup-data";
|
|
10
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
11
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
-
const DEFAULT_MARKER_DATA = {
|
|
13
|
-
icon: "Location",
|
|
14
|
-
title: "Nouveau point d'intérêt",
|
|
15
|
-
description: "",
|
|
16
|
-
url: "",
|
|
17
|
-
label: ""
|
|
18
|
-
};
|
|
19
12
|
|
|
20
13
|
const Markers = ({
|
|
21
|
-
mapRef,
|
|
22
14
|
markers,
|
|
23
15
|
setMarkers,
|
|
24
|
-
|
|
25
|
-
setZoom
|
|
16
|
+
iconSet
|
|
26
17
|
}) => {
|
|
27
18
|
const {
|
|
28
19
|
cmsMode
|
|
29
20
|
} = useUbloContext();
|
|
30
|
-
const
|
|
31
|
-
const newId = ids.length ? Math.max(...ids) + 1 : 1;
|
|
32
|
-
|
|
33
|
-
const addMarker = e => {
|
|
34
|
-
const hasAnOpenedPopup = Boolean(mapRef.current?.getContainer().querySelector(".leaflet-popup"));
|
|
35
|
-
if (cmsMode !== "editing" || hasAnOpenedPopup) return;
|
|
36
|
-
setMarkers([...markers, {
|
|
37
|
-
id: newId,
|
|
38
|
-
...DEFAULT_MARKER_DATA,
|
|
39
|
-
position: e.latlng
|
|
40
|
-
}]);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
useMapEvents({
|
|
44
|
-
dragend(e) {
|
|
45
|
-
setCenter(e.target.getCenter());
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
zoomend(e) {
|
|
49
|
-
setZoom(e.target.getZoom());
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
click(e) {
|
|
53
|
-
addMarker(e);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
});
|
|
21
|
+
const isEditing = cmsMode === "editing";
|
|
57
22
|
return markers.map(marker => {
|
|
58
23
|
const popupRef = React.createRef();
|
|
59
24
|
const {
|
|
60
25
|
id,
|
|
61
26
|
icon,
|
|
62
27
|
title,
|
|
63
|
-
description,
|
|
64
|
-
url,
|
|
65
|
-
label,
|
|
66
28
|
position
|
|
67
29
|
} = marker;
|
|
68
|
-
const Icon = Icons[icon];
|
|
30
|
+
const Icon = Icons[iconSet][icon];
|
|
69
31
|
|
|
70
32
|
const updatePosition = e => {
|
|
71
33
|
setMarkers(currents => {
|
|
@@ -81,9 +43,8 @@ const Markers = ({
|
|
|
81
43
|
});
|
|
82
44
|
};
|
|
83
45
|
|
|
84
|
-
const formatedDescription = description.replace(/\n/g, "<br />");
|
|
85
46
|
return _jsxs(Marker, {
|
|
86
|
-
draggable:
|
|
47
|
+
draggable: isEditing,
|
|
87
48
|
eventHandlers: {
|
|
88
49
|
dragend(e) {
|
|
89
50
|
updatePosition(e);
|
|
@@ -95,31 +56,18 @@ const Markers = ({
|
|
|
95
56
|
className: css.markerIcon,
|
|
96
57
|
html: ReactDOM.renderToString(_jsx(Icon, {}))
|
|
97
58
|
}),
|
|
98
|
-
children: [
|
|
59
|
+
children: [!isEditing && _jsx(Tooltip, {
|
|
99
60
|
sticky: true,
|
|
100
61
|
children: title
|
|
101
62
|
}), _jsx(Popup, {
|
|
102
63
|
ref: popupRef,
|
|
103
|
-
children:
|
|
64
|
+
children: isEditing ? _jsx(EditForm, {
|
|
104
65
|
popupRef: popupRef,
|
|
105
66
|
marker: marker,
|
|
106
|
-
setMarkers: setMarkers
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
className: css.title,
|
|
111
|
-
children: title
|
|
112
|
-
}), formatedDescription && _jsx("div", {
|
|
113
|
-
className: css.description,
|
|
114
|
-
dangerouslySetInnerHTML: {
|
|
115
|
-
__html: formatedDescription
|
|
116
|
-
}
|
|
117
|
-
}), url?.trim() && _jsx(Button, {
|
|
118
|
-
tag: "a",
|
|
119
|
-
href: url.trim(),
|
|
120
|
-
className: css.link,
|
|
121
|
-
children: label || "En savoir plus"
|
|
122
|
-
})]
|
|
67
|
+
setMarkers: setMarkers,
|
|
68
|
+
iconSet: iconSet
|
|
69
|
+
}) : _jsx(PopupData, {
|
|
70
|
+
marker: marker
|
|
123
71
|
})
|
|
124
72
|
})]
|
|
125
73
|
}, id);
|
|
@@ -4,31 +4,3 @@
|
|
|
4
4
|
fill: var(--ds-secondary, var(--ds-blue-400, #4177f6));
|
|
5
5
|
transform: translate(-35%, -65%);
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
.data {
|
|
9
|
-
max-width: 280px;
|
|
10
|
-
max-height: 280px;
|
|
11
|
-
display: flex;
|
|
12
|
-
flex-direction: column;
|
|
13
|
-
gap: 6px;
|
|
14
|
-
font-family: var(--ds-sans-serif-font, "Open Sans", sans-serif);
|
|
15
|
-
overflow: auto;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.title {
|
|
19
|
-
position: sticky;
|
|
20
|
-
top: 0;
|
|
21
|
-
padding: 4px 0;
|
|
22
|
-
font-size: 17px;
|
|
23
|
-
font-weight: 700;
|
|
24
|
-
background-color: var(--ds-grey-000, #fff);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.description {
|
|
28
|
-
font-size: 15px;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.link {
|
|
32
|
-
margin-top: 6px;
|
|
33
|
-
color: var(--ds-grey-000, #fff) !important;
|
|
34
|
-
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Button from "dt-design-system/es/button";
|
|
3
|
+
import css from "./popup-data.module.css";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
const PopupData = ({
|
|
8
|
+
marker
|
|
9
|
+
}) => {
|
|
10
|
+
const {
|
|
11
|
+
title,
|
|
12
|
+
description,
|
|
13
|
+
url,
|
|
14
|
+
label
|
|
15
|
+
} = marker;
|
|
16
|
+
const formatedDescription = description.replace(/\n/g, "<br />");
|
|
17
|
+
return _jsxs("div", {
|
|
18
|
+
className: css.data,
|
|
19
|
+
children: [_jsx("div", {
|
|
20
|
+
className: css.title,
|
|
21
|
+
children: title
|
|
22
|
+
}), formatedDescription && _jsx("div", {
|
|
23
|
+
className: css.description,
|
|
24
|
+
dangerouslySetInnerHTML: {
|
|
25
|
+
__html: formatedDescription
|
|
26
|
+
}
|
|
27
|
+
}), url?.trim() && _jsx(Button, {
|
|
28
|
+
tag: "a",
|
|
29
|
+
href: url.trim(),
|
|
30
|
+
className: css.link,
|
|
31
|
+
children: label || "En savoir plus"
|
|
32
|
+
})]
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default PopupData;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.data {
|
|
2
|
+
max-width: 280px;
|
|
3
|
+
max-height: 280px;
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
gap: 6px;
|
|
7
|
+
font-family: var(--ds-sans-serif-font, "Open Sans", sans-serif);
|
|
8
|
+
overflow: auto;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.title {
|
|
12
|
+
position: sticky;
|
|
13
|
+
top: 0;
|
|
14
|
+
padding: 4px 0;
|
|
15
|
+
font-size: 17px;
|
|
16
|
+
font-weight: 700;
|
|
17
|
+
background-color: var(--ds-grey-000, #fff);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.description {
|
|
21
|
+
font-size: 15px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.link {
|
|
25
|
+
margin-top: 6px;
|
|
26
|
+
color: var(--ds-grey-000, #fff) !important;
|
|
27
|
+
}
|