Download frontend/src/components/RangeMap.jsx from mg643/chirp: direct link, hf CLI and curl.
- Browser
- Download file 2.19 kB
-
https://huggingface.co/spaces/mg643/chirp/resolve/main/frontend/src/components/RangeMap.jsx
- Command line
-
hf download hf://spaces/mg643/chirp/frontend/src/components/RangeMap.jsx
-
curl -L -o RangeMap.jsx https://huggingface.co/spaces/mg643/chirp/resolve/main/frontend/src/components/RangeMap.jsx
2.19 kB
| /** | |
| * src/components/RangeMap.jsx | |
| * Renders a Leaflet map with a range circle centered on the species' known habitat. | |
| */ | |
| import React, { useEffect, useState } from 'react' | |
| import { motion } from 'framer-motion' | |
| import styles from './RangeMap.module.css' | |
| export default function RangeMap({ range, commonName, color }) { | |
| const [ready, setReady] = useState(false) | |
| const [MapContainer, setMapContainer] = useState(null) | |
| const [TileLayer, setTileLayer] = useState(null) | |
| const [Circle, setCircle] = useState(null) | |
| const [Popup, setPopup] = useState(null) | |
| useEffect(() => { | |
| import('react-leaflet').then(rl => { | |
| setMapContainer(() => rl.MapContainer) | |
| setTileLayer(() => rl.TileLayer) | |
| setCircle(() => rl.Circle) | |
| setPopup(() => rl.Popup) | |
| setReady(true) | |
| }) | |
| }, []) | |
| if (!range) return null | |
| return ( | |
| <motion.div | |
| className={styles.wrapper} | |
| initial={{ opacity: 0, y: 12 }} | |
| animate={{ opacity: 1, y: 0 }} | |
| transition={{ duration: 0.5, delay: 0.2 }} | |
| > | |
| <p className={styles.label}>Range Map</p> | |
| <div className={styles.mapContainer}> | |
| {ready && MapContainer ? ( | |
| <MapContainer | |
| center={range.center} | |
| zoom={3} | |
| scrollWheelZoom={false} | |
| style={{ height: '100%', width: '100%' }} | |
| zoomControl={false} | |
| > | |
| <TileLayer | |
| attribution="" | |
| url="https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png" | |
| /> | |
| <Circle | |
| center={range.center} | |
| radius={800000} | |
| pathOptions={{ | |
| color: color ?? '#9a749a', | |
| fillColor: color ?? '#9a749a', | |
| fillOpacity: 0.18, | |
| weight: 1.5, | |
| }} | |
| > | |
| <Popup>{commonName} — approximate range</Popup> | |
| </Circle> | |
| </MapContainer> | |
| ) : ( | |
| <div className={styles.mapPlaceholder}>Loading map…</div> | |
| )} | |
| </div> | |
| <p className={styles.rangeDesc}>{range.description}</p> | |
| </motion.div> | |
| ) | |
| } | |