Components
Loading preview...
A MapLibre-powered map component with theme-aware basemaps, controlled viewport state, and custom style switching.
npx shadcn@latest add https://21st.dev/r/mapcn/mapcn-map"use client";
import { useState } from "react";
import { Map, type MapViewport } from "@/components/ui/mapcn-map";
export default function ControlledMapDemo() {
const [viewport, setViewport] = useState<MapViewport>({
center: [-74.006, 40.7128],
zoom: 8,
bearing: 0,
pitch: 0,
});
return (
<div className="flex min-h-screen w-full items-center justify-center overflow-hidden bg-background p-8">
<div className="relative h-[420px] w-full max-w-4xl overflow-hidden rounded-lg border bg-background shadow-sm">
<Map viewport={viewport} onViewportChange={setViewport} />
<div className="absolute top-2 left-2 z-10 flex flex-wrap gap-x-3 gap-y-1 rounded border bg-background/80 px-2 py-1.5 font-mono text-xs backdrop-blur">
<span>
<span className="text-muted-foreground">lng:</span>{" "}
{viewport.center[0].toFixed(3)}
</span>
<span>
<span className="text-muted-foreground">lat:</span>{" "}
{viewport.center[1].toFixed(3)}
</span>
<span>
<span className="text-muted-foreground">zoom:</span>{" "}
{viewport.zoom.toFixed(1)}
</span>
<span>
<span className="text-muted-foreground">bearing:</span>{" "}
{viewport.bearing.toFixed(1)}°
</span>
<span>
<span className="text-muted-foreground">pitch:</span>{" "}
{viewport.pitch.toFixed(1)}°
</span>
</div>
</div>
</div>
);
}
export { ControlledMapDemo };