UNPKG

barikoi-map-widget

Version:

A customizable map widget built with React, designed for seamless integration with Barikoi's map services.

468 lines (462 loc) 16.4 kB
// src/components/BarikoiAutocomplete.tsx import { useEffect, useRef, useState as useState2 } from "react"; // src/contexts/BarikoiMapProvider.tsx import { createContext, useState, useContext, useMemo } from "react"; import { jsx } from "react/jsx-runtime"; var BarikoiMapContext = createContext(void 0); var BarikoiMapProvider = ({ children }) => { const [searchedPlace, setSearchedPlace] = useState(""); const [selectedPlace, setSelectedPlace] = useState(null); const [suggestions, setSuggestions] = useState([]); const [isAutocompleteLoading, setIsAutocompleteLoading] = useState(false); const [zoomLevel, setZoomLevel] = useState(10); const [centerPoint, setCenterPoint] = useState({ lat: 23.8103, lng: 90.4125 }); const [markerData, setMarkerData] = useState([]); const contextValue = useMemo(() => ({ autocomplete: { searchedPlace, setSearchedPlace, selectedPlace, setSelectedPlace, suggestions, setSuggestions, isAutocompleteLoading, setIsAutocompleteLoading }, map: { zoomLevel, setZoomLevel, centerPoint, setCenterPoint, markerData, setMarkerData } }), [searchedPlace, setSearchedPlace, selectedPlace, setSelectedPlace, suggestions, setSuggestions, isAutocompleteLoading, setIsAutocompleteLoading, zoomLevel, setZoomLevel, centerPoint, setCenterPoint, markerData, setMarkerData]); return /* @__PURE__ */ jsx( BarikoiMapContext.Provider, { value: contextValue, children } ); }; var useBarikoiMapContext = () => { const context = useContext(BarikoiMapContext); if (!context) { throw new Error("useBarikoiMap must be used within a BarikoiMapProvider"); } return context; }; // src/contexts/hooks/useAutocomplete.ts var useAutocomplete = () => { return useBarikoiMapContext().autocomplete; }; // src/components/BarikoiAutocomplete.tsx import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime"; var MarkerSVG = () => { return /* @__PURE__ */ jsx2("div", { style: { display: "inline-block" }, children: /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", fill: "none", viewBox: "0 0 36 44", children: [ /* @__PURE__ */ jsx2( "path", { stroke: "black", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M18 42c2-10 16-11.163 16-24 0-8.837-7.163-16-16-16S2 9.163 2 18c0 12.837 14 14 16 24z" } ), /* @__PURE__ */ jsx2( "path", { stroke: "black", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M18 24a6 6 0 100-12 6 6 0 000 12z" } ) ] }) }); }; var defaultStyles = { container: { width: "400px", position: "relative", fontFamily: "Arial, sans-serif" }, input: { width: "100%", padding: "10px 30px 10px 10px", fontSize: "14px", border: "1px solid #ccc", borderRadius: "4px", boxSizing: "border-box", position: "relative" }, dropdown: { position: "absolute", top: "100%", left: 0, overflowY: "auto", border: "1px solid #ccc", borderRadius: "4px", zIndex: 1e3, boxShadow: "0 4px 8px rgba(0, 0, 0, 0.1)", transform: "translateY(-10px)", transition: "opacity 0.3s ease-in-out, transform 0.3s ease-in-out", display: "none" }, dropdownVisible: { display: "block", // Show when visible transform: "translateY(0)" }, dropdownItem: { padding: "10px", cursor: "pointer", borderBottom: "1px solid #f0f0f0", transition: "background-color 0.2s ease-in-out", minHeight: "20px" }, dropdownItemHover: { backgroundColor: "#f5f5f5" }, dropdownFooter: { position: "sticky", bottom: 0, left: 0, backgroundColor: "#fff", padding: "10px", fontSize: "10px", color: "#adbabd", borderTop: "1px solidrgb(128, 128, 128)" }, noResult: { padding: "10px", color: "#999" }, clearButton: { position: "absolute", top: "10px", right: "10px", border: "none", backgroundColor: "transparent", cursor: "pointer", fontSize: "16px", color: "#999" } }; var BarikoiAutocomplete = ({ apiKey, className = {} }) => { const { searchedPlace, setSearchedPlace, selectedPlace, setSelectedPlace, suggestions, setSuggestions, isAutocompleteLoading, setIsAutocompleteLoading } = useAutocomplete(); const debounceRef = useRef(null); const [isDropdownVisible, setIsDropdownVisible] = useState2(false); useEffect(() => { const inputElement = document.querySelector('input[type="text"]'); const handleFocus = () => { if (suggestions.length > 0) { setIsDropdownVisible(true); } }; const handleBlur = () => { setTimeout(() => setIsDropdownVisible(false), 200); }; if (inputElement) { inputElement.addEventListener("focus", handleFocus); inputElement.addEventListener("blur", handleBlur); } return () => { if (inputElement) { inputElement.removeEventListener("focus", handleFocus); inputElement.removeEventListener("blur", handleBlur); } }; }, [suggestions]); useEffect(() => { if (!searchedPlace.trim()) { setSuggestions([]); setIsDropdownVisible(false); return; } if (searchedPlace === selectedPlace?.name) { setIsDropdownVisible(false); return; } setIsAutocompleteLoading(true); if (debounceRef.current) { clearTimeout(debounceRef.current); } debounceRef.current = setTimeout(async () => { try { const response = await fetch( `https://barikoi.xyz/v2/api/search/autocomplete/place?api_key=${apiKey}&q=${searchedPlace}` ); const { places } = await response.json(); const newSuggestions = places?.map((place, index) => ({ name: place?.address || "Unknown", ...place })) || []; setSuggestions(newSuggestions); if (newSuggestions.length > 0) { setIsDropdownVisible(true); } } catch (error) { console.error("Error fetching autocomplete data:", error); setSuggestions([]); } finally { setIsAutocompleteLoading(false); } }, 300); }, [searchedPlace, selectedPlace, apiKey]); const handleChange = (e) => { setSearchedPlace(e.target.value); }; const handleSelect = (item) => { setSearchedPlace(item.name); setSelectedPlace(item); setIsDropdownVisible(false); }; const handleClear = () => { setSearchedPlace(""); setSelectedPlace(null); setSuggestions([]); setIsDropdownVisible(false); }; const renderSuggestions = () => { if (isAutocompleteLoading) { return /* @__PURE__ */ jsx2( "div", { style: defaultStyles.noResult, className: className.noResult || "", children: "Searching..." } ); } if (suggestions.length === 0) { return /* @__PURE__ */ jsx2( "div", { style: defaultStyles.noResult, className: className.noResult || "", children: "No results found" } ); } return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx2( "div", { style: { // maxHeight: 'calc(600px - 40px)', // Adjust height to account for footer overflowY: "auto" }, children: suggestions.map((item) => /* @__PURE__ */ jsx2( "div", { style: defaultStyles.dropdownItem, className: className.dropdownItem || "", onMouseEnter: (e) => e.currentTarget.style.backgroundColor = defaultStyles.dropdownItemHover.backgroundColor, onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent", onClick: () => handleSelect(item), children: /* @__PURE__ */ jsxs( "div", { style: { display: "grid", gridTemplateColumns: "auto 1fr", alignItems: "center", minHeight: "40px" }, children: [ /* @__PURE__ */ jsx2( "div", { style: { display: "flex", justifyContent: "center", marginRight: 2 }, children: /* @__PURE__ */ jsx2(MarkerSVG, {}) } ), /* @__PURE__ */ jsx2("div", { children: item.name }) ] } ) }, item.id )) } ), /* @__PURE__ */ jsxs( "div", { style: defaultStyles.dropdownFooter, className: className.dropdownFooter || "", children: [ "Powered by", " ", /* @__PURE__ */ jsx2( "a", { href: "https://barikoi.com", target: "_blank", rel: "noopener noreferrer", style: { color: "#00A66B", textDecoration: "none" }, children: "Barikoi" } ) ] } ) ] }); }; return /* @__PURE__ */ jsxs("div", { style: defaultStyles.container, className: className.container || "", children: [ /* @__PURE__ */ jsx2( "input", { type: "text", value: searchedPlace, onChange: handleChange, placeholder: "Search Address", style: defaultStyles.input, className: className.input || "" } ), searchedPlace && /* @__PURE__ */ jsx2( "button", { type: "button", style: defaultStyles.clearButton, className: className.clearButton || "", onClick: handleClear, children: "X" } ), /* @__PURE__ */ jsx2( "div", { style: { ...defaultStyles.dropdown, ...isDropdownVisible ? defaultStyles.dropdownVisible : {} }, className: className.dropdown || "", children: renderSuggestions() } ) ] }); }; var BarikoiAutocomplete_default = BarikoiAutocomplete; // src/components/BarikoiMap.tsx import { useEffect as useEffect2, useRef as useRef2 } from "react"; import { Map, Marker, FullscreenControl, GeolocateControl, NavigationControl, ScaleControl } from "react-bkoi-gl"; // src/contexts/hooks/useMap.ts var useMap = () => { return useBarikoiMapContext().map; }; // src/components/BarikoiMap.tsx import "react-bkoi-gl/styles"; import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime"; var defaultStyles2 = { container: { minWidth: "500px", minHeight: "500px", overflow: "hidden" } }; var BarikoiMap = ({ apiKey, initialViewState, controls, mapStyle, className = {} }) => { const { centerPoint } = useMap(); const mapStyleUrl = `https://map.barikoi.com/styles/${mapStyle ?? "osm-liberty"}/style.json?key=${apiKey}`; const mapRef = useRef2(null); const _initialViewState = { longitude: 90.36402, latitude: 23.823731, minZoom: 4, maxZoom: 30, zoom: 13, bearing: 0, pitch: 0, antialias: true, ...initialViewState }; useEffect2(() => { if (centerPoint?.lng && centerPoint?.lat) { mapRef?.current?.flyTo({ center: [centerPoint.lng, centerPoint.lat], essential: true }); } }, [centerPoint]); return /* @__PURE__ */ jsx3( "div", { style: defaultStyles2.container, className: className.container || "", children: /* @__PURE__ */ jsxs2( Map, { ref: mapRef, mapStyle: mapStyleUrl, style: { width: "100%", height: "100%" }, initialViewState: _initialViewState, doubleClickZoom: false, dragRotate: false, attributionControl: true, children: [ controls?.geolocate?.enabled && /* @__PURE__ */ jsx3(GeolocateControl, { position: controls?.geolocate?.position ?? "top-right" }), controls?.fullscreen?.enabled && /* @__PURE__ */ jsx3(FullscreenControl, { position: controls?.fullscreen?.position ?? "top-right" }), controls?.navigation?.enabled && /* @__PURE__ */ jsx3(NavigationControl, { position: controls?.navigation?.position ?? "top-right" }), controls?.scale?.enabled && /* @__PURE__ */ jsx3(ScaleControl, { position: controls?.scale?.position ?? "bottom-right" }), centerPoint?.lng && centerPoint?.lat && controls?.marker?.enabled && /* @__PURE__ */ jsx3( Marker, { longitude: centerPoint.lng, latitude: centerPoint.lat, anchor: "bottom", children: /* @__PURE__ */ jsx3("img", { width: 50, height: 50, src: controls?.marker?.url ?? "https://maps.barikoi.com/images/icon.png", alt: "marker" }) } ), /* @__PURE__ */ jsx3( "div", { className: "barikoi-logo", style: { width: "90px", height: "20px", position: "absolute", left: 10, bottom: 8, backgroundSize: "contain", backgroundRepeat: "no-repeat", zIndex: 99999, backgroundImage: `url('data:image/png;base64,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')` } } ) ] } ) } ); }; var BarikoiMap_default = BarikoiMap; export { BarikoiAutocomplete_default as BarikoiAutocomplete, BarikoiMap_default as BarikoiMap, BarikoiMapProvider, useAutocomplete, useBarikoiMapContext, useMap }; //# sourceMappingURL=index.mjs.map