mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
basic locate control
This commit is contained in:
parent
6d53d0d3f8
commit
b52ae474cd
6
package-lock.json
generated
6
package-lock.json
generated
@ -14,6 +14,7 @@
|
||||
"@types/offscreencanvas": "^2019.7.1",
|
||||
"axios": "^1.6.5",
|
||||
"leaflet": "^1.9.4",
|
||||
"leaflet.locatecontrol": "^0.79.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-image-crop": "^10.1.8",
|
||||
@ -2904,6 +2905,11 @@
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
|
||||
},
|
||||
"node_modules/leaflet.locatecontrol": {
|
||||
"version": "0.79.0",
|
||||
"resolved": "https://registry.npmjs.org/leaflet.locatecontrol/-/leaflet.locatecontrol-0.79.0.tgz",
|
||||
"integrity": "sha512-h64QIHFkypYdr90lkSfjKvPvvk8/b8UnP3m9WuoWdp5p2AaCWC0T1NVwyuj4rd5U4fBW3tQt4ppmZ2LceHMIDg=="
|
||||
},
|
||||
"node_modules/leaflet.markercluster": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz",
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
"@types/offscreencanvas": "^2019.7.1",
|
||||
"axios": "^1.6.5",
|
||||
"leaflet": "^1.9.4",
|
||||
"leaflet.locatecontrol": "^0.79.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-image-crop": "^10.1.8",
|
||||
|
||||
53
src/Components/Map/Subcomponents/Controls/LocateControl.tsx
Normal file
53
src/Components/Map/Subcomponents/Controls/LocateControl.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import * as React from 'react'
|
||||
import * as L from 'leaflet'
|
||||
import { useMap } from 'react-leaflet'
|
||||
import 'leaflet.locatecontrol'
|
||||
|
||||
import 'leaflet.locatecontrol/dist/L.Control.Locate.css'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
// Converts leaflet.locatecontrol to a React Component
|
||||
export const LocateControl = () => {
|
||||
|
||||
const map = useMap();
|
||||
|
||||
// prevent react18 from calling useEffect twice
|
||||
const init = useRef(false)
|
||||
|
||||
|
||||
const [lc, setLc] = useState<any>(null);
|
||||
const [active, setActive] = useState<boolean>(false);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!init.current) {
|
||||
//@ts-ignore
|
||||
setLc(L.control.locate().addTo(map));
|
||||
init.current = true;
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (<>
|
||||
<div className="tw-card tw-w-14 tw-bg-base-100 tw-shadow-xl tw-items-center tw-justify-center">
|
||||
|
||||
<div className="tw-card-body hover:tw-bg-slate-300 tw-card tw-p-2 tw-h-10 tw-w-10 tw-transition-all tw-duration-300 hover:tw-cursor-pointer" onClick={() => {
|
||||
if (active) {
|
||||
lc.stop();
|
||||
setActive(false);
|
||||
}
|
||||
else {
|
||||
lc.start();
|
||||
setActive(true);
|
||||
}
|
||||
|
||||
}}>
|
||||
<svg fill="currentColor" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" className='tw-mt-1 tw-p-[1px]'>
|
||||
<path d="M30 14.75h-2.824c-0.608-5.219-4.707-9.318-9.874-9.921l-0.053-0.005v-2.824c0-0.69-0.56-1.25-1.25-1.25s-1.25 0.56-1.25 1.25v0 2.824c-5.219 0.608-9.318 4.707-9.921 9.874l-0.005 0.053h-2.824c-0.69 0-1.25 0.56-1.25 1.25s0.56 1.25 1.25 1.25v0h2.824c0.608 5.219 4.707 9.318 9.874 9.921l0.053 0.005v2.824c0 0.69 0.56 1.25 1.25 1.25s1.25-0.56 1.25-1.25v0-2.824c5.219-0.608 9.318-4.707 9.921-9.874l0.005-0.053h2.824c0.69 0 1.25-0.56 1.25-1.25s-0.56-1.25-1.25-1.25v0zM17.25 24.624v-2.624c0-0.69-0.56-1.25-1.25-1.25s-1.25 0.56-1.25 1.25v0 2.624c-3.821-0.57-6.803-3.553-7.368-7.326l-0.006-0.048h2.624c0.69 0 1.25-0.56 1.25-1.25s-0.56-1.25-1.25-1.25v0h-2.624c0.57-3.821 3.553-6.804 7.326-7.368l0.048-0.006v2.624c0 0.69 0.56 1.25 1.25 1.25s1.25-0.56 1.25-1.25v0-2.624c3.821 0.57 6.803 3.553 7.368 7.326l0.006 0.048h-2.624c-0.69 0-1.25 0.56-1.25 1.25s0.56 1.25 1.25 1.25v0h2.624c-0.571 3.821-3.553 6.803-7.326 7.368l-0.048 0.006z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div></>)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import { useTags } from '../../hooks/useTags';
|
||||
import { useItems } from '../../hooks/useItems';
|
||||
import { useLeafletRefs } from '../../hooks/useLeafletRefs';
|
||||
import { getValue } from '../../../../Utils/GetValue';
|
||||
import { LocateControl } from './LocateControl';
|
||||
|
||||
|
||||
|
||||
@ -58,16 +59,19 @@ export const SearchControl = ({ clusterRef }) => {
|
||||
return (<>
|
||||
{!(windowDimensions.height < 500) &&
|
||||
<div className='tw-w-[calc(100vw-2rem)] tw-max-w-[22rem] '>
|
||||
<input type="text" placeholder="search ..." autoComplete="off" value={value} className="tw-input tw-input-bordered tw-w-full tw-shadow-xl tw-rounded-lg"
|
||||
ref={searchInput}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
onFocus={() => setHideSuggestions(false)}
|
||||
onBlur={async () => {
|
||||
setTimeout(() => {
|
||||
setHideSuggestions(true);
|
||||
}, 200);
|
||||
}} />
|
||||
{value.length > 0 && <button className="tw-btn tw-btn-sm tw-btn-circle tw-absolute tw-right-2 tw-top-2" onClick={() => setValue("")}>✕</button>}
|
||||
<div className='flex tw-flex-row'>
|
||||
<input type="text" placeholder="search ..." autoComplete="off" value={value} className="tw-input tw-input-bordered tw-w-full tw-shadow-xl tw-rounded-lg tw-mr-2"
|
||||
ref={searchInput}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
onFocus={() => setHideSuggestions(false)}
|
||||
onBlur={async () => {
|
||||
setTimeout(() => {
|
||||
setHideSuggestions(true);
|
||||
}, 200);
|
||||
}} />
|
||||
<LocateControl />
|
||||
</div>
|
||||
{value.length > 0 && <button className="tw-btn tw-btn-sm tw-btn-circle tw-absolute tw-right-16 tw-top-2" onClick={() => setValue("")}>✕</button>}
|
||||
{hideSuggestions || Array.from(geoResults).length == 0 && itemsResults.length == 0 && tagsResults.length == 0 || value.length == 0 ? "" :
|
||||
<div className='tw-card tw-card-body tw-bg-base-100 tw-p-4 tw-mt-2 tw-shadow-xl'>
|
||||
{tagsResults.length > 0 &&
|
||||
@ -110,7 +114,7 @@ export const SearchControl = ({ clusterRef }) => {
|
||||
{Array.from(geoResults).length > 0 && (itemsResults.length > 0 || tagsResults.length > 0) && <hr className='tw-opacity-50'></hr>}
|
||||
{Array.from(geoResults).map((geo) => (
|
||||
<div className='tw-flex tw-flex-row' key={Math.random()}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="tw-text-current tw-mr-2 tw-mt-0 tw-w-5">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="tw-text-current tw-mr-2 tw-mt-0 tw-w-4">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
|
||||
</svg>
|
||||
|
||||
|
||||
@ -20,6 +20,10 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leaflet-control-locate {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leaflet-data-marker {
|
||||
|
||||
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAQCAYAAACcN8ZaAAAB3klEQVR42s3U4UdDURzG8czMXJnJ1Vwzc6VJZjaZJdlMlpQsKdmUFNOUspRSSqUolfQfr+fF98Vx5mwv9qbDx7LdznnO7/7Omej3+/+Ga0QMUYkhbvBgmhzCQxwxibIGrGEF8CQhU+LLtKQkQNqScUgjxRxTBIxbgfgD/BgnhM8kM5KTeclLQYqGkkMRBckzR8ic/mAgd5BAZplsUaqyIg2sDtHg2brUZJk5SmwopErJUWE8SpmTMhNvya60Zd/SNrR4bkeaskG4uiwRZk6yrJEYFibGAxn+scECHTmTnuVCzvmty3PHciB7bGKN6lQkzysPqIrHmpFhYbKUtckC1/Ioz4ZHuZdbuSLYiRxRpSZVWXZVxAzC0R4Ik5SQsu6w8yd5l2/5kg95I9SdXMoZQfYIUjeqEUrgOkXGPeN4TYRhxy8E+ZUf+eS7B7miIoeybVSjKDnm8u3+gH3pDTYwu1igATvs/pXqvBKiR4i2bNJfi1ZfUAnjgrOG8wY2quNzBKuU/ZS+uSFEl5O0xRGuUIlZCcw7xG5QPkeHYUSNV5WXGou2sC3rBC0LjenqCXGO0WEiTJa0Lr4KixdHBrDGuGGiRqCUpFk8pGIpQtCU7p4YPwxYxEMCk1aAMQZh8Ac8PfbIzYPJOwAAAABJRU5ErkJggg==') no-repeat;
|
||||
|
||||
@ -20,6 +20,7 @@ import { QuestControl } from "./Subcomponents/Controls/QuestControl";
|
||||
import { Control } from "./Subcomponents/Controls/Control";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { TagsControl } from "./Subcomponents/Controls/TagsControl";
|
||||
import { LocateControl } from "./Subcomponents/Controls/LocateControl";
|
||||
|
||||
|
||||
export interface MapEventListenerProps {
|
||||
@ -40,6 +41,7 @@ function UtopiaMap({
|
||||
children }
|
||||
: UtopiaMapProps) {
|
||||
|
||||
|
||||
let meta = document.getElementsByTagName('meta')
|
||||
const [metaTags, setMetaTags] = useState<HTMLCollectionOf<HTMLMetaElement>>(meta);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user