Map Polygon
terrae/polygonFreeComponent
Geographic polygon with customizable fill and stroke styling.
Install it
npx shadcn@latest add https://www.terrae.dev/polygon.jsonSource
1"use client"23import type mapboxgl from "mapbox-gl"45import { useEffect, useId, useRef } from "react"6import { useMap } from "./hooks"7import type { MapPath } from "./types"89type MapPolygonProps = {10 coordinates: MapPath11 fillColor?: string12 fillOpacity?: number13 strokeColor?: string14 strokeWidth?: number15 strokeOpacity?: number16 dashArray?: [number, number]17}1819const DEFAULT_FILL_COLOR = "#3b82f6"20const DEFAULT_FILL_OPACITY = 0.421const DEFAULT_STROKE_COLOR = "#3b82f6"22const DEFAULT_STROKE_WIDTH = 223const DEFAULT_STROKE_OPACITY = 12425const getClosedCoordinates = (coords: MapPath): MapPath => {26 if (coords.length < 3) {27 return coords28 }2930 const first = coords[0]31 const last = coords[coords.length - 1]3233 if (first[0] === last[0] && first[1] === last[1]) {34 return coords35 }3637 return [...coords, first]38}3940export const MapPolygon = ({41 coordinates,42 fillColor = DEFAULT_FILL_COLOR,43 fillOpacity = DEFAULT_FILL_OPACITY,44 strokeColor = DEFAULT_STROKE_COLOR,45 strokeWidth = DEFAULT_STROKE_WIDTH,46 strokeOpacity = DEFAULT_STROKE_OPACITY,47 dashArray,48}: MapPolygonProps) => {49 const { map, isLoaded } = useMap()50 const id = useId()51 const sourceId = `polygon-source-${id}`52 const fillLayerId = `polygon-fill-layer-${id}`53 const strokeLayerId = `polygon-stroke-layer-${id}`54 const initializedRef = useRef(false)5556 const coordinatesRef = useRef(coordinates)57 const fillColorRef = useRef(fillColor)58 const fillOpacityRef = useRef(fillOpacity)59 const strokeColorRef = useRef(strokeColor)60 const strokeWidthRef = useRef(strokeWidth)61 const strokeOpacityRef = useRef(strokeOpacity)62 const dashArrayRef = useRef(dashArray)6364 coordinatesRef.current = coordinates65 fillColorRef.current = fillColor66 fillOpacityRef.current = fillOpacity67 strokeColorRef.current = strokeColor68 strokeWidthRef.current = strokeWidth69 strokeOpacityRef.current = strokeOpacity70 dashArrayRef.current = dashArray7172 useEffect(() => {73 if (!map) {74 return75 }7677 const addLayers = (mapInstance: mapboxgl.Map) => {78 if (mapInstance.getSource(sourceId)) {79 return80 }8182 const closedCoordinates = getClosedCoordinates(coordinatesRef.current)8384 mapInstance.addSource(sourceId, {85 type: "geojson",86 data: {87 type: "Feature",88 properties: {},89 geometry: {90 type: "Polygon",91 coordinates: [closedCoordinates],92 },93 },94 })9596// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from terrae
All 40 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Map Animated Circleanimated-circle | terrae | Components | Free | 1 dep | |
| Map Animated Footprintanimated-footprint | terrae | Components | Free | 2 deps | |
| Map Animated Polygonanimated-polygon | terrae | Components | Free | 1 dep | |
| Map Animated Pulseanimated-pulse | terrae | Components | Free | 1 dep | |
| Map Arc Animatedarc-animated | terrae | Components | Free | 1 dep | |
| Map Blur Areablur-area | terrae | Components | Free | 1 dep | |
| Map Camera Followcamera-follow | terrae | Components | Free | 1 dep | |
| Map Choroplethchoropleth | terrae | Components | Free | 1 dep |
