You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@baremaps.apache.org by le...@apache.org on 2023/07/04 09:35:14 UTC
[incubator-baremaps-site] 02/03: Add map style select
This is an automated email from the ASF dual-hosted git repository.
leonardcs pushed a commit to branch feature/styles
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps-site.git
commit 56bdb3653309b9b41f2ca592f6965652337fb2f6
Author: Leonard <le...@gmail.com>
AuthorDate: Tue Jul 4 10:47:10 2023 +0200
Add map style select
---
src/components/GeocoderSearch/style.module.css | 2 +-
src/components/MapStyleSelect/index.tsx | 43 ++++++++++++++++++++++
src/components/MapStyleSelect/style.module.css | 45 +++++++++++++++++++++++
src/components/map/index.tsx | 22 +++++++++--
src/components/map/mapStyles.ts | 51 ++++++++++++++++++++++++++
src/components/map/style.module.css | 7 +++-
src/pages/index.mdx | 2 +-
7 files changed, 165 insertions(+), 7 deletions(-)
diff --git a/src/components/GeocoderSearch/style.module.css b/src/components/GeocoderSearch/style.module.css
index a519823..9a757e9 100644
--- a/src/components/GeocoderSearch/style.module.css
+++ b/src/components/GeocoderSearch/style.module.css
@@ -6,7 +6,7 @@
/* Responsive width for small screens */
@media screen and (max-width: 768px) {
.ctrl-container {
- width: 85%;
+ width: 70%;
}
}
diff --git a/src/components/MapStyleSelect/index.tsx b/src/components/MapStyleSelect/index.tsx
new file mode 100644
index 0000000..1c59044
--- /dev/null
+++ b/src/components/MapStyleSelect/index.tsx
@@ -0,0 +1,43 @@
+import cn from 'clsx';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faFillDrip } from '@fortawesome/free-solid-svg-icons';
+import { MapStyle } from '../map/mapStyles';
+import styles from './style.module.css';
+
+interface MapStyleSelectProps {
+ map: maplibregl.Map;
+ mapStyles: MapStyle[];
+}
+
+export const MapStyleSelect: React.FC<MapStyleSelectProps> = ({
+ map,
+ mapStyles
+}) => {
+ return (
+ <div className={cn(styles['ctrl-container'], 'maplibregl-ctrl-top-left')}>
+ <div
+ className={cn(
+ styles['select-container'],
+ 'maplibregl-ctrl maplibregl-ctrl-group'
+ )}
+ >
+ <FontAwesomeIcon icon={faFillDrip} className={styles.icon} />
+ <select
+ className={styles['style-select']}
+ onChange={e => {
+ const style = mapStyles.find(style => style.name === e.target.value);
+ if (style) {
+ map.setStyle(style.styleUrl);
+ }
+ }}
+ >
+ {mapStyles.map(style => (
+ <option key={style.name} value={style.name}>
+ {style.name}
+ </option>
+ ))}
+ </select>
+ </div>
+ </div>
+ );
+};
diff --git a/src/components/MapStyleSelect/style.module.css b/src/components/MapStyleSelect/style.module.css
new file mode 100644
index 0000000..63aece0
--- /dev/null
+++ b/src/components/MapStyleSelect/style.module.css
@@ -0,0 +1,45 @@
+.ctrl-container {
+ left: 465px;
+ color: black;
+}
+
+/* Responsive width for small screens */
+@media screen and (max-width: 768px) {
+ .ctrl-container {
+ left: 72%;
+ }
+}
+
+.icon {
+ padding: 0 10px;
+}
+
+.select-container {
+ width: 100%;
+ height: 29px;
+ display: flex;
+ align-items: center;
+}
+
+.style-select {
+ appearance: none;
+ border: none;
+ background-color: white;
+ outline: none;
+ box-shadow: none;
+ padding-right: 20px;
+
+ background-image: linear-gradient(45deg, transparent 50%, gray 50%),
+ linear-gradient(135deg, gray 50%, transparent 50%);
+ background-position: calc(100% - 5px) calc(50% + 2px), 100% calc(50% + 2px);
+ background-size: 5px 5px, 5px 5px;
+ background-repeat: no-repeat;
+}
+
+.theme-select:focus {
+ background-image: linear-gradient(135deg, transparent 50%, gray 50%),
+ linear-gradient(45deg, gray 50%, transparent 50%);
+ background-position: calc(100% - 5px) 50%, 100% 50%;
+ background-size: 5px 5px, 5px 5px;
+ background-repeat: no-repeat;
+}
diff --git a/src/components/map/index.tsx b/src/components/map/index.tsx
index 054731f..3b9ca55 100644
--- a/src/components/map/index.tsx
+++ b/src/components/map/index.tsx
@@ -1,10 +1,13 @@
import React, { useRef, useEffect, useState } from 'react';
+import cn from 'clsx';
import maplibregl from 'maplibre-gl';
import MaplibreInspect from '@/lib/maplibre/dist/maplibre-gl-inspect/maplibre-gl-inspect';
import MaplibreTileBoundaries from '@/lib/maplibre/dist/maplibre-gl-tile-boundaries/maplibre-gl-tile-boundaries';
import styles from './style.module.css';
import { GeocoderSearch } from '../GeocoderSearch';
+import { STYLES } from './mapStyles';
+import { MapStyleSelect } from '../MapStyleSelect';
interface MapProps {
longitude?: number;
@@ -25,6 +28,10 @@ interface MapProps {
getControls?: () => maplibregl.IControl[];
geocoder?: boolean;
ipToLoc?: boolean;
+ styleSelect?: boolean;
+ /** Map CSS styles */
+ rounded?: boolean;
+ style?: React.CSSProperties;
}
export const getDefaultControls = (): maplibregl.IControl[] => [
@@ -55,7 +62,10 @@ export default function Map({
mapOptions = {} as maplibregl.MapOptions,
getControls = getDefaultControls,
geocoder = true,
- ipToLoc = true
+ ipToLoc = true,
+ styleSelect = false,
+ rounded = true,
+ style = {}
}: MapProps) {
const mapContainer = useRef(null);
const [map, setMap] = useState(null);
@@ -97,17 +107,23 @@ export default function Map({
setMap(newMap);
};
- initMap();
+ if (!map) {
+ initMap();
+ }
}, []);
return (
- <div className={styles.wrap}>
+ <div
+ className={cn(styles.wrap, rounded ? styles.rounded : '')}
+ style={style}
+ >
{geocoder && (
<GeocoderSearch
url="https://demo.baremaps.com/api/geocoder"
map={map}
/>
)}
+ {styleSelect && <MapStyleSelect map={map} mapStyles={STYLES} />}
<div ref={mapContainer} className={styles.map} />
</div>
);
diff --git a/src/components/map/mapStyles.ts b/src/components/map/mapStyles.ts
new file mode 100644
index 0000000..81a42be
--- /dev/null
+++ b/src/components/map/mapStyles.ts
@@ -0,0 +1,51 @@
+export interface MapStyle {
+ name: string;
+ styleUrl: string;
+}
+
+export const STYLES: MapStyle[] = [
+ {
+ name: 'Default',
+ styleUrl: '/mapStyles/default.json'
+ },
+ {
+ name: 'Light',
+ styleUrl: '/mapStyles/light.json'
+ },
+ {
+ name: 'Dark',
+ styleUrl: '/mapStyles/dark.json'
+ },
+ {
+ name: 'Achromatomaly',
+ styleUrl: '/mapStyles/achromatomaly.json'
+ },
+ {
+ name: 'Achromatopsia',
+ styleUrl: '/mapStyles/achromatopsia.json'
+ },
+ {
+ name: 'Deuteranomaly',
+ styleUrl: '/mapStyles/deuteranomaly.json'
+ },
+ {
+ name: 'Deuteranopia',
+ styleUrl: '/mapStyles/deuteranopia.json'
+ },
+ {
+ name: 'Protanomaly',
+ styleUrl: '/mapStyles/protanomaly.json'
+ },
+ {
+ name: 'Protanopia',
+ styleUrl: '/mapStyles/protanopia.json'
+ },
+ {
+ name: 'Tritanomaly',
+ styleUrl: '/mapStyles/tritanomaly.json'
+ },
+ {
+ name: 'Tritanopia',
+ styleUrl: '/mapStyles/tritanopia.json'
+ }
+];
diff --git a/src/components/map/style.module.css b/src/components/map/style.module.css
index 509f84c..2267eb7 100644
--- a/src/components/map/style.module.css
+++ b/src/components/map/style.module.css
@@ -8,11 +8,14 @@
.map {
position: absolute;
color: black;
- border: solid 1px lightgray;
- border-radius: 0.75rem;
width: 100%;
height: 100%;
overflow: hidden;
+}
+
+.rounded {
+ border: solid 1px lightgray;
+ border-radius: 0.75rem;
/* this fixes the overflow:hidden for canvas - corresponds to 1 black pixel */
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
diff --git a/src/pages/index.mdx b/src/pages/index.mdx
index 542b2aa..f0a322a 100644
--- a/src/pages/index.mdx
+++ b/src/pages/index.mdx
@@ -34,7 +34,7 @@ import { IconTitle } from '@/components/titles/IconTitle';
<div className="content-container">
<Features>
<Feature index={0} plain large style={{ height: 600 }}>
- <Map />
+ <Map styleSelect />
</Feature>
<Feature index={0}>
<IconTitle icon={faListCheck}>