Map
mapcn-anonimous071/mapFreeComponent
A MapLibre-powered map component with markers, popups, tooltips, routes, and controls.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/anonimous071/mapcn/main/public/maps/map.jsonSource
1"use client";23import MapLibreGL, { type PopupOptions, type MarkerOptions } from "maplibre-gl";4import "maplibre-gl/dist/maplibre-gl.css";5import { useTheme } from "next-themes";6import {7 createContext,8 forwardRef,9 useCallback,10 useContext,11 useEffect,12 useId,13 useImperativeHandle,14 useMemo,15 useRef,16 useState,17 type ReactNode,18} from "react";19import { createPortal } from "react-dom";20import { X, Minus, Plus, Locate, Maximize, Loader2 } from "lucide-react";2122import { cn } from "@/lib/utils";2324type MapContextValue = {25 map: MapLibreGL.Map | null;26 isLoaded: boolean;27};2829const MapContext = createContext<MapContextValue | null>(null);3031function useMap() {32 const context = useContext(MapContext);33 if (!context) {34 throw new Error("useMap must be used within a Map component");35 }36 return context;37}3839const defaultStyles = {40 dark: "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json",41 light: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",42};4344type MapStyleOption = string | MapLibreGL.StyleSpecification;4546type MapProps = {47 children?: ReactNode;48 /** Custom map styles for light and dark themes. Overrides the default Carto styles. */49 styles?: {50 light?: MapStyleOption;51 dark?: MapStyleOption;52 };53 /** Map projection type. Use `{ type: "globe" }` for 3D globe view. */54 projection?: MapLibreGL.ProjectionSpecification;55} & Omit<MapLibreGL.MapOptions, "container" | "style">;5657type MapRef = MapLibreGL.Map;5859const DefaultLoader = () => (60 <div className="absolute inset-0 flex items-center justify-center">61 <div className="flex gap-1">62 <span className="size-1.5 rounded-full bg-muted-foreground/60 animate-pulse" />63 <span className="size-1.5 rounded-full bg-muted-foreground/60 animate-pulse [animation-delay:150ms]" />64 <span className="size-1.5 rounded-full bg-muted-foreground/60 animate-pulse [animation-delay:300ms]" />65 </div>66 </div>67);6869const Map = forwardRef<MapRef, MapProps>(function Map(70 { children, styles, projection, ...props },71 ref72) {73 const containerRef = useRef<HTMLDivElement>(null);74 const [mapInstance, setMapInstance] = useState<MapLibreGL.Map | null>(null);75 const [isLoaded, setIsLoaded] = useState(false);76 const [isStyleLoaded, setIsStyleLoaded] = useState(false);77 const { resolvedTheme } = useTheme();78 const currentStyleRef = useRef<MapStyleOption | null>(null);79 const styleTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);8081// … truncated
What it pulls in
npm packages
