Um modelo de componentes composíveis — GeoMap fornece o container, e todo o resto é composto como filhos.
BrownieJS utiliza um modelo de componentes composíveis. GeoMap fornece o container do mapa com renderização de tiles. TileLayer, Marker, MarkerCluster, Popup, Circle, Route e Geolocation são compostos como filhos.
npm install @brownie-js/reactimport { GeoMap, TileLayer, Marker } from '@brownie-js/react';
function MyMap() {
return (
<div style={{ width: '100%', height: 400 }}>
<GeoMap center={[-46.63, -23.55]} zoom={10} mapLabel="My map">
<TileLayer />
<Marker coordinates={[-46.63, -23.55]} ariaLabel="Sao Paulo" />
</GeoMap>
</div>
);
}GeoMap fornece o container do mapa e contexto. TileLayer renderiza tiles OSM. Marker, Route e Geolocation são compostos como filhos.
BrownieJS usa a ordem [longitude, latitude] — o padrão GeoJSON — em todas as props de coordenadas (center, coordinates, bounds). Isso é o oposto do Leaflet, que usa [lat, lng].
// Leaflet (lat, lng):
center={[-23.55, -46.63]}
// BrownieJS (lon, lat) — GeoJSON:
center={[-46.63, -23.55]}Migrando do Leaflet? Inverta suas coordenadas: o [lat, lng] do Leaflet vira [lng, lat] no BrownieJS.
O componente raiz do mapa. Fornece um mapa baseado em tiles com centro e zoom configuráveis, dimensionamento automático via ResizeObserver, navegação com zoom e pan, e contexto para todos os componentes filhos. Expõe um handle imperativo via ref com flyTo(), fitBounds(), getZoom(), getCenter() e getBounds().
import { GeoMap, TileLayer, Marker } from '@brownie-js/react';
function InteractiveMap() {
return (
<div style={{ width: '100%', height: 500 }}>
<GeoMap
center={[-46.63, -23.55]}
zoom={10}
minZoom={3}
maxZoom={18}
onZoomChange={(zoom) => console.log('Zoom:', zoom)}
mapLabel="Interactive map"
>
<TileLayer />
<Marker coordinates={[-46.63, -23.55]} ariaLabel="Sao Paulo" />
</GeoMap>
</div>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| center | [number, number] | [0, 0] | Centro do mapa como [longitude, latitude]. |
| zoom | number | 2 | Nível de zoom inicial. |
| children | ReactNode | — | Componentes filhos (TileLayer, Marker, Route, etc.). |
| className | string | — | Nome de classe CSS para o container do mapa. |
| style | CSSProperties | — | Estilos CSS para o container do mapa. |
| mapLabel | string | "Interactive map" | Label acessível para o container do mapa. |
| minZoom | number | 1 | Nível mínimo de zoom. |
| maxZoom | number | 19 | Nível máximo de zoom. |
| bounds | { sw: [number, number]; ne: [number, number] } | — | Bounds iniciais para ajustar o mapa. |
| width | number | — | Largura fixa em pixels (auto-dimensiona se omitido). |
| height | number | — | Altura fixa em pixels (auto-dimensiona se omitido). |
| onClick | (event: { latlng: [number, number]; pixel: [number, number]; originalEvent: MouseEvent }) => void | — | Chamado quando o mapa é clicado. |
| onZoomChange | (zoom: number) => void | — | Dispara durante o zoom com o nível atual. |
| onMoveEnd | (state: { center: [number, number]; zoom: number; bounds: { sw: [number, number]; ne: [number, number] } }) => void | — | Dispara quando uma interação de zoom ou pan termina. |
| showAttribution | boolean | true | Exibe a atribuição do provedor de tiles. Padrão: true. |
| isLoading | boolean | false | Quando true, exibe o placeholder de carregamento no lugar do mapa. Use enquanto dados assíncronos (marcadores, rotas, etc.) estão sendo buscados. |
| loader | ReactNode | <Loader /> | Componente de carregamento customizado exibido quando isLoading é true. Padrão: componente <Loader /> embutido. |
| interactiveZoom | boolean | true | Habilita o zoom via scroll, gesto de pinça e duplo clique. Defina como false para bloquear o nível de zoom mantendo o pan. Padrão: true. |
| onError | (error: Error, info: React.ErrorInfo) => void | — | Chamado quando um erro é lançado dentro do mapa. Recebe (error: Error, info: React.ErrorInfo). Use para conectar serviços de monitoramento de erros como Sentry ou Datadog. |
GeoMap aceita uma ref que expõe métodos para controle programático — útil quando você precisa navegar no mapa de fora da árvore de componentes (ex: botão "usar minha localização").
import { useRef } from 'react';
import { GeoMap, TileLayer, GeoMapHandle } from '@brownie-js/react';
function MapWithControls() {
const mapRef = useRef<GeoMapHandle>(null);
return (
<div style={{ width: '100%', height: 500 }}>
<GeoMap ref={mapRef} center={[-46.63, -23.55]} zoom={10} mapLabel="Map">
<TileLayer />
</GeoMap>
<button onClick={() => mapRef.current?.flyTo([-43.17, -22.91], 12)}>
Rio de Janeiro
</button>
<button onClick={() =>
mapRef.current?.flyTo({ center: [-46.63, -23.55], zoom: 14, duration: 600 })
}>
São Paulo (slow)
</button>
<button onClick={() =>
mapRef.current?.fitBounds({ sw: [-46.8, -23.7], ne: [-46.4, -23.4] })
}>
Fit region
</button>
</div>
);
}flyTo(options: FlyToOptions): void
flyTo(center: [number, number], zoom?: number): void
fitBounds(bounds: { sw: [number, number]; ne: [number, number] }, padding?: number): void
getZoom(): number
getCenter(): [number, number]
getBounds(): { sw: [number, number]; ne: [number, number] }flyTo() anima até a posição alvo usando RequestAnimationFrame. Aceita duration opcional (padrão 300ms) e função de easing. Respeita prefers-reduced-motion: se o usuário tiver redução de movimento ativada, o mapa pula instantaneamente.
Renderiza uma grade de tiles a partir de um template de URL (ex: OpenStreetMap). Deve ser colocado dentro de GeoMap.
import { GeoMap, TileLayer } from '@brownie-js/react';
function MapWithTiles() {
return (
<div style={{ width: '100%', height: 400 }}>
<GeoMap center={[-46.63, -23.55]} zoom={10} mapLabel="Tile map">
<TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />
</GeoMap>
</div>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| url | string | "https://tile.openstreetmap.org/{z}/{x}/{y}.png" | Template de URL do tile com placeholders {x}, {y}, {z}. |
| opacity | number | 1 | Opacidade da camada (0–1). |
| zIndex | number | — | CSS z-index para ordenação de camadas. |
Renderiza um marcador em uma coordenada geográfica. Suporta conteúdo SVG personalizado, arrastar e soltar, handlers de clique e tooltips.
import { GeoMap, TileLayer, Marker } from '@brownie-js/react';
function MapWithMarkers() {
return (
<GeoMap center={[-43.17, -22.91]} zoom={12} mapLabel="Map with markers">
<TileLayer />
<Marker
coordinates={[-43.17, -22.91]}
color="#d4850c"
size={10}
onClick={(event, data) => console.log('Clicked marker')}
ariaLabel="Rio de Janeiro"
/>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| coordinates | [number, number] | — | Coordenadas geográficas [longitude, latitude] (convenção GeoJSON). |
| color | string | '#d4850c' | Cor de preenchimento do marcador. |
| size | number | 8 | Diâmetro do marcador em pixels. |
| icon | ReactNode | — | ReactNode personalizado para substituir o ícone padrão do marcador. |
| anchor | "center" | "bottom" | "center" | Ponto de ancoragem do marcador. |
| draggable | boolean | false | Se o marcador pode ser arrastado. |
| opacity | number | — | Opacidade do marcador (0–1). |
| children | ReactNode | — | Conteúdo SVG personalizado. Substitui o círculo padrão quando fornecido. |
| onClick | (event: MouseEvent, data?: Record<string, unknown>) => void | — | Chamado quando o marcador é clicado. |
| onMouseEnter | (event: MouseEvent) => void | — | Chamado quando o mouse entra no marcador. |
| onMouseLeave | (event: MouseEvent) => void | — | Chamado quando o mouse sai do marcador. |
| onDragEnd | (coordinates: [number, number], data?: Record<string, unknown>) => void | — | Chamado quando o arraste completa com novas coordenadas geográficas. |
| data | Record<string, unknown> | — | Dados arbitrários para associar ao marcador. |
| animated | boolean | false | Ativar animação de entrada (fade-in + deslize) quando o marcador é montado. |
| ariaLabel | string | — | Nome acessível para o marcador. |
Agrupa marcadores próximos em clusters usando um algoritmo baseado em grid. Re-agrupa automaticamente ao mudar o zoom.
import { GeoMap, TileLayer, Marker } from '@brownie-js/react';
import { MarkerCluster } from '@brownie-js/react/cluster';
function ClusteredMap() {
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Clustered markers">
<TileLayer />
<MarkerCluster radius={60} maxZoom={16}>
<Marker coordinates={[-46.63, -23.55]} ariaLabel="Point A" />
<Marker coordinates={[-46.64, -23.56]} ariaLabel="Point B" />
<Marker coordinates={[-46.62, -23.54]} ariaLabel="Point C" />
</MarkerCluster>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| radius | number | 60 | Tamanho da célula do grid de cluster em pixels. |
| maxZoom | number | 16 | Nível de zoom acima do qual marcadores não são agrupados. |
| renderCluster | (cluster: ClusterData) => ReactNode | — | Função de renderização personalizada para marcadores de cluster. |
| onClick | (cluster: ClusterData) => void | — | Chamado quando um cluster é clicado. |
| animated | boolean | false | Ativar animações de transição suaves quando clusters se fundem ou dividem. |
| categoryKey | string | — | Chave de dados usada para agrupar marcadores em categorias dentro dos clusters. |
| categoryColors | Record<string, string> | — | Mapa de valores de categoria para cores na renderização de clusters multicategoria. |
| children | ReactNode | — | Componentes Marker para agrupar. |
Um overlay HTML posicionado em coordenadas geográficas. Pode ser usado sozinho ou como filho de Marker.
import { GeoMap, TileLayer, Marker, Popup } from '@brownie-js/react';
import { useState } from 'react';
function MapWithPopup() {
const [selected, setSelected] = useState(false);
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Map with popup">
<TileLayer />
<Marker
coordinates={[-46.63, -23.55]}
onClick={() => setSelected(true)}
ariaLabel="Sao Paulo"
>
{selected && (
<Popup offset={[0, -10]} onClose={() => setSelected(false)}>
<div>Hello from Sao Paulo!</div>
</Popup>
)}
</Marker>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| coordinates | [number, number] | — | Posição geográfica [longitude, latitude]. Herdada do Marker pai se omitida. |
| offset | [number, number] | — | Deslocamento em pixels [x, y] da posição de ancoragem. |
| closeOnClick | boolean | — | Se clicar no mapa fecha o popup. |
| onClose | () => void | — | Chamado quando o popup é fechado. |
| className | string | — | Classe CSS para o container do popup. |
| style | CSSProperties | — | Estilos inline para o container do popup. |
| image | { src: string; alt: string; height?: number } | — | Imagem hero opcional exibida acima do conteúdo do popup. |
| children | ReactNode | — | Conteúdo do popup. |
Renderiza um círculo SVG no mapa com um centro geográfico e raio em metros.
import { GeoMap, TileLayer, Circle } from '@brownie-js/react';
function MapWithCircle() {
return (
<GeoMap center={[-46.63, -23.55]} zoom={13} mapLabel="Map with circle">
<TileLayer />
<Circle
center={[-46.63, -23.55]}
radius={2000}
color="#7c8b6f"
fillColor="rgba(124,139,111,0.15)"
ariaLabel="Search area"
/>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| center | [number, number] | — | Coordenadas do centro [longitude, latitude]. |
| radius | number | — | Raio em metros. |
| color | string | — | Cor do contorno. |
| fillColor | string | — | Cor de preenchimento. |
| strokeWidth | number | — | Largura do contorno em pixels. |
| dashArray | string | — | SVG stroke-dasharray para bordas tracejadas. |
| opacity | number | — | Opacidade geral (0–1). |
| onClick | (event: MouseEvent) => void | — | Chamado quando o círculo é clicado. |
| ariaLabel | string | — | Nome acessível para o círculo. |
Um overlay leve que exibe conteúdo em uma posição em pixels. Tipicamente usado com eventos de mouse em marcadores ou rotas.
import { GeoMap, TileLayer, Marker, Tooltip } from '@brownie-js/react';
import { useState } from 'react';
function MapWithTooltip() {
const [tip, setTip] = useState<{ x: number; y: number } | null>(null);
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Map with tooltip">
<TileLayer />
<Marker
coordinates={[-46.63, -23.55]}
onMouseEnter={(e) => setTip({ x: e.clientX, y: e.clientY })}
onMouseLeave={() => setTip(null)}
ariaLabel="Sao Paulo"
/>
{tip && <Tooltip x={tip.x} y={tip.y} content="Sao Paulo" />}
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| x | number | — | Posição horizontal em pixels. |
| y | number | — | Posição vertical em pixels. |
| content | ReactNode | — | Conteúdo do tooltip. |
| className | string | — | Classe CSS para o container do tooltip. |
| style | CSSProperties | — | Estilos inline para o container do tooltip. |
Desenha um path SVG ao longo de uma série de coordenadas geográficas. Suporta estilização de traços personalizada, linhas tracejadas, integração com roteamento OSRM e tooltips.
import { GeoMap, TileLayer } from '@brownie-js/react';
import { Route } from '@brownie-js/react/route';
function MapWithRoute() {
const waypoints: [number, number][] = [
[-43.17, -22.91], // Rio de Janeiro
[-46.63, -23.55], // Sao Paulo
];
return (
<GeoMap center={[-44.9, -23.2]} zoom={8} mapLabel="Route map">
<TileLayer />
<Route
coordinates={waypoints}
color="#d4850c"
strokeWidth={3}
routing={true}
onRouteLoaded={(data) => console.log(`${data.distance}m`)}
/>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| coordinates | [number, number][] | — | Array de coordenadas geográficas [longitude, latitude] definindo a rota. |
| color | string | '#d4850c' | Cor do traço. |
| strokeWidth | number | 2 | Largura do traço em pixels. |
| dashArray | string | — | SVG stroke-dasharray para linhas tracejadas (ex: "5,5"). |
| routing | boolean | false | Ativar roteamento OSRM. |
| routingUrl | string | — | URL personalizada do endpoint OSRM. |
| onClick | (event: MouseEvent) => void | — | Chamado quando o path da rota é clicado. |
| onMouseEnter | (event: MouseEvent) => void | — | Chamado quando o mouse entra no path da rota. |
| onMouseLeave | (event: MouseEvent) => void | — | Chamado quando o mouse sai do path da rota. |
| onRouteLoaded | (data: { distance: number; duration: number; geometry: [number, number][] }) => void | — | Chamado quando os dados da rota OSRM carregam. |
| animated | boolean | false | Ativar animação de trilha de formigas ao longo do path da rota. |
| animationSpeed | number | 2 | Duração de um ciclo de animação em segundos. |
| ariaLabel | string | — | Nome acessível para a rota. |
Acessa a API de Geolocalização do navegador para rastrear a posição do usuário. Pode monitorar continuamente mudanças de posição com precisão e timeout configuráveis.
import { GeoMap, TileLayer } from '@brownie-js/react';
import { Geolocation } from '@brownie-js/react/geo';
function LiveLocationMap() {
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Live location map">
<TileLayer />
<Geolocation
watch={true}
enableHighAccuracy={true}
onError={(err) => console.warn(err.message)}
/>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| watch | boolean | true | Se deve monitorar continuamente a posição. |
| enableHighAccuracy | boolean | true | Ativar modo de alta precisão. |
| timeout | number | 10000 | Timeout em milissegundos. |
| maximumAge | number | 0 | Idade máxima da posição em cache em milissegundos. |
| onError | (error: GeolocationPositionError) => void | — | Chamado quando ocorre um erro de geolocalização. |
Posiciona controles filhos em um canto do mapa. Use com controles integrados (ZoomControl, ScaleBar) ou qualquer conteúdo personalizado.
import { GeoMap, TileLayer, MapControl } from '@brownie-js/react';
import { ZoomControl, ScaleBar } from '@brownie-js/react/controls';
function MapWithControls() {
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Map with controls">
<TileLayer />
<MapControl position="top-right">
<ZoomControl />
</MapControl>
<MapControl position="bottom-left">
<ScaleBar />
</MapControl>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| position | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-right' | Posição do canto: 'top-left', 'top-right', 'bottom-left' ou 'bottom-right'. |
| children | ReactNode | — | Conteúdo do controle a ser renderizado no canto do mapa. |
| className | string | — | Classe CSS para o container do controle. |
| style | CSSProperties | — | Estilos inline para o container do controle. |
Uma camada de overlay SVG personalizada. Fornece uma render prop project() que converte coordenadas geográficas em posições de pixel, permitindo desenhar formas SVG arbitrárias no mapa.
import { GeoMap, TileLayer, SVGLayer } from '@brownie-js/react';
function MapWithSVGOverlay() {
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Map with SVG layer">
<TileLayer />
<SVGLayer>
{({ project }) => {
const [x, y] = project(-46.63, -23.55);
return <circle cx={x} cy={y} r={20} fill="rgba(255,0,0,0.3)" />;
}}
</SVGLayer>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| children | (ctx: { project }) => ReactNode | — | Função de renderização recebendo { project } para conversão de coordenadas para pixels. |
| className | string | — | Classe CSS para o container SVG. |
| style | CSSProperties | — | Estilos inline para o container SVG. |
Uma camada de overlay HTML personalizada. Fornece uma render prop project() que converte coordenadas geográficas em posições de pixel, permitindo renderizar elementos HTML arbitrários no mapa.
import { GeoMap, TileLayer, HTMLLayer } from '@brownie-js/react';
function MapWithHTMLOverlay() {
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Map with HTML layer">
<TileLayer />
<HTMLLayer>
{({ project }) => {
const [x, y] = project(-46.63, -23.55);
return (
<div style={{ position: 'absolute', left: x, top: y, transform: 'translate(-50%, -50%)' }}>
Custom HTML content
</div>
);
}}
</HTMLLayer>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| children | (ctx: { project }) => ReactNode | — | Função de renderização recebendo { project } para conversão de coordenadas para pixels. |
| className | string | — | Classe CSS para o container HTML. |
| style | CSSProperties | — | Estilos inline para o container HTML. |
Um componente placeholder de mapa exibido enquanto dados assíncronos carregam. Usado automaticamente pelo GeoMap quando isLoading é true, e também pode ser usado de forma independente — por exemplo, antes de um componente de mapa carregado de forma lazy.
import { GeoMap, TileLayer, Loader } from '@brownie-js/react';
import { useState, useEffect } from 'react';
function MapWithLoader() {
const [markers, setMarkers] = useState([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetchMarkers().then((data) => {
setMarkers(data);
setIsLoading(false);
});
}, []);
return (
<div style={{ width: '100%', height: 400 }}>
<GeoMap center={[-46.63, -23.55]} zoom={10} isLoading={isLoading}>
<TileLayer />
{markers.map((m) => (
<Marker key={m.id} coordinates={m.coordinates} />
))}
</GeoMap>
</div>
);
}
// Standalone usage (e.g., before a lazy-loaded map)
function MapSkeleton() {
return (
<div style={{ width: '100%', height: 400 }}>
<Loader ariaLabel="Loading map data..." />
</div>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| ariaLabel | string | "Loading map" | Rótulo acessível para a região de carregamento. Anunciado por leitores de tela. Padrão: "Loading map". |
| className | string | — | Classe CSS aplicada ao contêiner do loader. |
| style | CSSProperties | — | Estilos CSS inline aplicados ao contêiner do loader. Mesclado com os estilos de layout padrão. |
Retorna o contexto do mapa incluindo estado do viewport, funções de projeção e o método flyTo() para navegação programática. Deve ser usado dentro de GeoMap.
import { useMap } from '@brownie-js/react';
// Programmatic navigation
function NavigationButton() {
const { flyTo } = useMap();
return (
<button onClick={() => flyTo([-46.63, -23.55], 12)}>
Go to São Paulo
</button>
);
}
// With full options
function NavigationButtonAnimated() {
const { flyTo } = useMap();
return (
<button onClick={() => flyTo({ center: [-46.63, -23.55], zoom: 14, duration: 600 })}>
Fly (slow)
</button>
);
}
// Projection utilities
function CustomOverlay() {
const { center, zoom, project } = useMap();
const [x, y] = project(center[0], center[1]);
return <div style={{ position: 'absolute', left: x, top: y }}>Zoom: {zoom}</div>;
}Returns: MapContextValue com project(), invert(), flyTo(), center, zoom, width, height.
Encapsula a API de Geolocalização do navegador. Retorna a posição do usuário, estado de carregamento e erros. Por padrão monitora continuamente via watchPosition().
import { useGeolocation } from '@brownie-js/react/geo';
function LocationInfo() {
const { position, loading, error } = useGeolocation({ watch: true });
if (loading) return <p>Locating...</p>;
if (error) return <p>Error: {error.message}</p>;
if (!position) return null;
return <p>Lat: {position.latitude}, Lng: {position.longitude}</p>;
}Returns: { position: { latitude, longitude, accuracy } | null, error, loading }
Busca geometria de roteamento rodoviário de uma API compatível com OSRM. Com cache em memória e limpeza via AbortController.
import { useOsrmRoute } from '@brownie-js/react/route';
function RouteInfo() {
const waypoints: [number, number][] = [
[-43.17, -22.91],
[-46.63, -23.55],
];
const { data, loading } = useOsrmRoute(waypoints, true);
if (loading) return <p>Calculating route...</p>;
if (!data) return null;
return <p>Distance: {(data.distance / 1000).toFixed(1)} km</p>;
}Signature: useOsrmRoute(waypoints, enabled, routingUrl?)
Returns: { data: { coordinates, distance, duration } | null, loading, error }
Chama a API de geocodificação reversa Nominatim (OpenStreetMap) para resolver coordenadas em um endereço.
import { useReverseGeocode } from '@brownie-js/react/geo';
function AddressDisplay() {
const { data, loading } = useReverseGeocode(-23.55, -46.63);
if (loading) return <p>Looking up address...</p>;
if (!data) return null;
return <p>{data.displayName}</p>;
}Signature: useReverseGeocode(lat, lng)
Returns: { data: { road, suburb, city, state, country, postcode, displayName } | null, loading, error }
Hooks headless fornecem a lógica e estado para componentes de mapa sem renderizar nenhuma UI. Use-os para construir componentes totalmente personalizados com sua própria marcação e estilização.
Gerencia o posicionamento, auto-flip e estado de visibilidade do popup. Retorna style e props para espalhar no seu elemento de popup personalizado.
import { usePopup } from '@brownie-js/react';
function CustomPopup({ coordinates, onClose }) {
const { style, isFlipped, props, popupRef } = usePopup({
coordinates,
offset: [0, -10],
onClose,
});
return (
<div ref={popupRef} style={style} {...props}>
<p>Custom popup content</p>
{isFlipped && <span>Flipped!</span>}
</div>
);
}Signature: usePopup(options)
Returns: { style, isVisible, isFlipped, close, props, popupRef }
Gerencia o posicionamento do tooltip relativo a uma coordenada em pixels. Retorna style e props para o seu elemento de tooltip personalizado.
import { useTooltip } from '@brownie-js/react';
function CustomTooltip({ x, y, content }) {
const { style, props } = useTooltip({ x, y });
return (
<div style={style} {...props}>
{content}
</div>
);
}Signature: useTooltip(options)
Returns: { style, props }
Gerencia posicionamento do marcador, estado de arraste e culling de viewport. Retorna style, handlers e estado para o seu elemento de marcador personalizado.
import { useMarker } from '@brownie-js/react';
function CustomMarker({ coordinates }) {
const { style, isOutOfView, isDragging, handlers, props } = useMarker({
coordinates,
draggable: true,
});
if (isOutOfView) return null;
return (
<div style={style} {...handlers} {...props}>
{isDragging ? 'Dragging...' : 'My Marker'}
</div>
);
}Signature: useMarker(options)
Returns: { style, isOutOfView, isDragging, handlers, props }
Calcula o centro em pixels e o raio para um círculo geográfico. Retorna props SVG e estilo do container para o seu elemento de círculo personalizado.
import { useCircle } from '@brownie-js/react';
function CustomCircle({ center, radius }) {
const { center: pixelCenter, radiusPx, svgProps, containerStyle } = useCircle({
center,
radius,
});
return (
<svg style={containerStyle} {...svgProps}>
<circle cx={pixelCenter[0]} cy={pixelCenter[1]} r={radiusPx} fill="rgba(0,0,255,0.2)" />
</svg>
);
}Signature: useCircle(options)
Returns: { center, radiusPx, svgProps, containerStyle }
Calcula os dados do path SVG para uma rota e opcionalmente busca roteamento OSRM. Retorna dados do path e estado de carregamento para o seu elemento de rota personalizado.
import { useRouteLayer } from '@brownie-js/react/route';
function CustomRoute({ coordinates }) {
const { pathD, svgProps, containerStyle, isLoading } = useRouteLayer({
coordinates,
routing: true,
});
if (isLoading) return null;
return (
<svg style={containerStyle} {...svgProps}>
<path d={pathD} stroke="blue" strokeWidth={3} fill="none" />
</svg>
);
}Signature: useRouteLayer(options)
Returns: { pathD, svgProps, containerStyle, isLoading, routeData }
Rastreia a posição GPS do usuário e calcula coordenadas em pixels para o ponto e anel de precisão. Retorna dados de posição e estado para o seu elemento de geolocalização personalizado.
import { useGeolocationDot } from '@brownie-js/react/geo';
function CustomGeolocation() {
const { dotCenter, accuracyRadiusPx, containerStyle, loading } = useGeolocationDot({
watch: true,
});
if (loading || !dotCenter) return null;
return (
<svg style={containerStyle}>
<circle cx={dotCenter[0]} cy={dotCenter[1]} r={accuracyRadiusPx} fill="rgba(0,100,255,0.15)" />
<circle cx={dotCenter[0]} cy={dotCenter[1]} r={6} fill="#0064ff" />
</svg>
);
}Signature: useGeolocationDot(options)
Returns: { position, dotCenter, accuracyRadiusPx, containerStyle, error, loading }
Fornece funções de projeção e dimensões do mapa para construir camadas personalizadas. Um wrapper de conveniência sobre useMap() otimizado para renderização de camadas.
import { useMapLayer } from '@brownie-js/react';
function CustomLayer() {
const { project, width, height, zoom } = useMapLayer();
const [x, y] = project(-46.63, -23.55);
return (
<svg style={{ position: 'absolute', width, height, pointerEvents: 'none' }}>
<circle cx={x} cy={y} r={10} fill="red" />
<text x={x + 14} y={y + 4}>Zoom: {zoom}</text>
</svg>
);
}Signature: useMapLayer()
Returns: { project, invert, width, height, zoom, center }
O componente Circle do BrownieJS usa raio geográfico em metros — ele escala com o zoom. Para um ponto de tamanho fixo em pixels que não escala com o zoom (equivalente ao CircleMarker do Leaflet), use useMapLayer com um SVG circle de r fixo em pixels:
import { useMapLayer } from '@brownie-js/react';
// Fixed pixel-size dot — does NOT scale with zoom (Leaflet's CircleMarker equivalent)
function ApproxLocationDot({ coordinates }: { coordinates: [number, number] }) {
const { project, width, height } = useMapLayer();
const [x, y] = project(coordinates[0], coordinates[1]);
return (
<svg style={{ position: 'absolute', width, height, pointerEvents: 'none' }}>
<circle cx={x} cy={y} r={10} fill="orange" opacity={0.7} />
</svg>
);
}
// For a geographic area that DOES scale with zoom, use <Circle radius={meters} /> instead.Todos os componentes BrownieJS suportam personalização visual via CSS custom properties (variáveis). Você pode defini-las globalmente no container do mapa ou usar MapThemeProvider para uma API amigável ao React.
Defina qualquer variável --bm-* em um elemento pai para tematizar todos os componentes BrownieJS dentro dele. Variáveis disponíveis: --bm-popup-bg, --bm-popup-color, --bm-popup-radius, --bm-popup-shadow, --bm-tooltip-bg, --bm-tooltip-color, --bm-tooltip-border, --bm-tooltip-radius, --bm-tooltip-shadow, --bm-marker-color, --bm-circle-color, --bm-circle-fill, --bm-route-color, --bm-geolocation-color, --bm-attribution-bg, --bm-focus-ring, --bm-control-bg, --bm-control-color, --bm-control-shadow, --bm-control-radius, --bm-control-padding, --bm-control-gap.
/* Set CSS custom properties on any parent element */
.my-map {
--bm-popup-bg: #1a1a1a;
--bm-popup-color: #ffffff;
--bm-popup-radius: 12px;
--bm-tooltip-bg: #333;
--bm-tooltip-color: #fff;
--bm-marker-color: #e74c3c;
--bm-route-color: #3498db;
--bm-circle-color: #2ecc71;
--bm-focus-ring: #9b59b6;
--bm-control-bg: #1a1a1a;
--bm-control-color: #ffffff;
}Um componente React que converte um objeto de tema em CSS custom properties. Importe de @brownie-js/react/theme. Aceita chaves em camelCase que mapeiam para variáveis --bm-* (ex: popupBg se torna --bm-popup-bg).
import { MapThemeProvider } from '@brownie-js/react/theme';
import { GeoMap, TileLayer, Marker, Popup } from '@brownie-js/react';
function DarkMap() {
return (
<MapThemeProvider
theme={{
popupBg: '#1a1a1a',
popupColor: '#fff',
popupRadius: '12px',
markerColor: '#e74c3c',
controlBg: '#1a1a1a',
controlColor: '#fff',
}}
>
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Dark themed map">
<TileLayer />
<Marker coordinates={[-46.63, -23.55]} ariaLabel="Sao Paulo" />
</GeoMap>
</MapThemeProvider>
);
}Controles de mapa prontos para uso importados de @brownie-js/react/controls. Use-os dentro de MapControl para posicioná-los no mapa.
Fornece botões de zoom in (+) e zoom out (-) com acessibilidade por teclado.
import { GeoMap, TileLayer, MapControl } from '@brownie-js/react';
import { ZoomControl } from '@brownie-js/react/controls';
function MapWithZoom() {
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Map with zoom control">
<TileLayer />
<MapControl position="top-right">
<ZoomControl />
</MapControl>
</GeoMap>
);
}Exibe uma barra de escala de distância que atualiza com o nível de zoom atual. Suporta unidades métricas e imperiais.
import { GeoMap, TileLayer, MapControl } from '@brownie-js/react';
import { ScaleBar } from '@brownie-js/react/controls';
function MapWithScale() {
return (
<GeoMap center={[-46.63, -23.55]} zoom={12} mapLabel="Map with scale bar">
<TileLayer />
<MapControl position="bottom-left">
<ScaleBar unit="metric" maxWidth={150} />
</MapControl>
</GeoMap>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
| maxWidth | number | 100 | Largura máxima da barra de escala em pixels. |
| unit | 'metric' | 'imperial' | 'metric' | Sistema de unidades: 'metric' ou 'imperial'. |