BlockDex

Components

Registries

Free blocks

Method

BlockDex

Components

Registries

Free blocks

Method

Open API

BlockDex

Components

Registries

Free blocks

Method

Open API

Components/terrae/controls

Map Controls

terrae/controls
FreeComponent

Interactive map controls (zoom, fullscreen, etc).

Install it

npx shadcn@latest add https://www.terrae.dev/controls.json

Source

src/registry/map/controls.tsxwww.terrae.dev/controls.json
1"use client"
2
3import { useEffect, useRef, useState, type ReactNode } from "react"
4import { Minus, Plus, Locate, Maximize, Loader2 } from "lucide-react"
5import { cn } from "@/lib/utils"
6import { useMap } from "./hooks"
7
8type MapControlPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right"
9
10type MapControlsProps = {
11 children: ReactNode
12 position?: MapControlPosition
13 className?: string
14}
15
16type ControlButtonProps = {
17 onClick: () => void
18 label: string
19 children: ReactNode
20 disabled?: boolean
21}
22
23type MapGeolocateProps = {
24 onLocate?: (coords: GeolocationCoordinates) => void
25}
26
27type GeolocationCoordinates = {
28 longitude: number
29 latitude: number
30}
31
32const DEFAULT_POSITION: MapControlPosition = "bottom-right"
33const ZOOM_STEP = 1
34const ZOOM_DURATION = 300
35const GEOLOCATE_ZOOM = 14
36const GEOLOCATE_DURATION = 1500
37
38const POSITION_CLASSES: Record<MapControlPosition, string> = {
39 "top-left": "top-2 left-2",
40 "top-right": "top-2 right-2",
41 "bottom-left": "bottom-2 left-2",
42 "bottom-right": "bottom-10 right-2",
43}
44const DEFAULT_DISABLED = false
45const DEFAULT_GEOLOCATE_PROPS: MapGeolocateProps = {}
46
47const ControlGroup = ({ children }: { children: ReactNode }) => {
48 return (
49 <div className="flex flex-col rounded-md border border-border bg-background shadow-sm overflow-hidden [&>button:not(:last-child)]:border-b [&>button:not(:last-child)]:border-border">
50 {children}
51 </div>
52 )
53}
54
55const ControlButton = ({ onClick, label, children, disabled = DEFAULT_DISABLED }: ControlButtonProps) => {
56 return (
57 <button
58 onClick={onClick}
59 aria-label={label}
60 type="button"
61 className={cn(
62 "flex items-center justify-center size-10 md:size-8 hover:bg-accent dark:hover:bg-accent/40 transition-colors",
63 disabled && "opacity-50 pointer-events-none cursor-not-allowed"
64 )}
65 disabled={disabled}
66 >
67 {children}
68 </button>
69 )
70}
71
72export const MapControls = ({ children, position = DEFAULT_POSITION, className }: MapControlsProps) => {
73 const { isLoaded } = useMap()
74
75 if (!isLoaded) {
76 return null
77 }
78
79 return (
80 <div className={cn("absolute z-10 flex flex-col gap-1.5", POSITION_CLASSES[position], className)}>{children}</div>
81 )
82}
83
84export const MapZoom = () => {
85 const { map } = useMap()
86
87 const handleZoomIn = () => {
88 map?.zoomTo(map.getZoom() + ZOOM_STEP, { duration: ZOOM_DURATION })
89 }
90
91 const handleZoomOut = () => {
92// … truncated

What it pulls in

npm packages

  • mapbox-gl
  • lucide-react

Other registry items

  • https://www.terrae.dev/map.json

Files it writes

  • src/registry/map/controls.tsx

Facts

Registry
terrae
Type
registry:ui
Access
Free
Files written
1
Licence
MIT
First indexed
2026-08-02
Last confirmed
today

Go to the source

www.terrae.dev alamenai/terrae on GitHub Raw registry item This item as JSON

More from terrae

All 40 items
Same registry, same kind — the ones you would have found next
ComponentRegistryKindAccessInstallsCommand
Map Animated Circleanimated-circleterraeComponentsFree1 dep
Map Animated Footprintanimated-footprintterraeComponentsFree2 deps
Map Animated Polygonanimated-polygonterraeComponentsFree1 dep
Map Animated Pulseanimated-pulseterraeComponentsFree1 dep
Map Arc Animatedarc-animatedterraeComponentsFree1 dep
Map Blur Areablur-areaterraeComponentsFree1 dep
Map Camera Followcamera-followterraeComponentsFree1 dep
Map ChoroplethchoroplethterraeComponentsFree1 dep
BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex