Hooks

useDocyrusMapView

Map backed by a Docyrus data source. Detects the location field and builds markers from logos, icons or the default pin, with clustering, a viewport filter, basemaps and drag-to-move with reverse geocoding.

iOSAndroidExpo Go

Installation

pnpm dlx @docyrus/cli add @docyrus/rn-hooks-use-docyrus-map-view
Required Packages(5 packages)
pnpm add @docyrus/api-client @docyrus/app-utils @tanstack/react-query react-native-maps expo-location (optional)

This is a port of the web hook with the same signature. It builds on useDocyrusDataGrid for the saved views, toolbar, filters and search, then requests only the columns the map needs.

The rendering is rewritten for native. DocyrusMapView draws everything on the compound Map, which uses react-native-maps. It includes:

  • clustered markers showing a logo, a Docyrus icon or the default pin
  • callouts
  • drag-to-move
  • zoom and locate controls
  • a basemap switcher
  • a "Search this area" pill

The web names DocyrusLeafletMapView and DocyrusGoogleMapView are exported as aliases. DocyrusGoogleMapView forces the Google provider.

Usage

import { useDocyrusClient } from '@docyrus/signin/react-native';

import {
  DocyrusMapView,
  useDocyrusMapView
} from '@/hooks/docyrus-native/use-docyrus-map-view';

export function OrganizationsMap() {
  const client = useDocyrusClient();

  const mapView = useDocyrusMapView({
    client: client!,
    appSlug: 'base',
    dataSourceSlug: 'organization',
    locationFieldSlug: 'map_location',
    titleFieldSlug: 'name',
    descriptionFieldSlugs: ['address', 'city', 'status'],
    markerImageFieldSlug: 'company_logo',
    markerIconFieldSlug: 'company_icon',
    enableViewportFilter: true,
    viewportFilterMode: 'manual',
    enableMarkerDrag: true,
    basemaps: ['street', 'satellite', 'hybrid', 'terrain'],
    googleMapsApiKey: process.env.EXPO_PUBLIC_GOOGLE_MAPS_API_KEY,
    persistState: true
  });

  return (
    <>
      {mapView.toolbar}
      <DocyrusMapView
        className="h-[480px]"
        markers={mapView.markers}
        allMarkersCount={mapView.allMarkers.length}
        center={mapView.center}
        bounds={mapView.bounds}
        defaultZoom={mapView.defaultZoom}
        focusedZoom={mapView.focusedZoom}
        fitBoundsPadding={mapView.fitBoundsPadding}
        selectedMarkerId={mapView.selectedMarkerId}
        onSelectMarker={mapView.setSelectedMarkerId}
        onViewportChange={mapView.setViewportBounds}
        isViewportStale={mapView.isViewportStale}
        onSearchThisArea={mapView.searchThisArea}
        draggableMarkers={mapView.enableMarkerDrag}
        onMarkerMove={mapView.handleMarkerMove}
        basemaps={mapView.availableBasemaps}
        activeBasemap={mapView.activeBasemap}
        onBasemapChange={mapView.setActiveBasemap}
        onMapClick={mapView.onMapClick} />
    </>
  );
}

API Reference

Options (UseDocyrusMapViewOptions<TData>)

Extends every useDocyrusDataGrid option except data, enableItemsQuery, showSelectColumn and enableRowMarkers.

PropTypeDefaultDescription
clientRestApiClient—Authenticated Docyrus API client (required)
appSlugstring—App slug (required)
dataSourceSlugstring—Data source slug (required)
dataTData[]—Pre-loaded rows. When set, the items query is skipped
collectionDocyrusDataGridCollection<TData>—Custom list adapter
locationFieldSlugstringfirst field-locationSelectLocation field
titleFieldSlugstringname, title, … or the first text fieldMarker title field
descriptionFieldSlugsstring[]description, details, address, city, …Fields for the callout description
markerImageFieldSlugstring—Image / file field used as the marker image
markerIconFieldSlugstringfield-icon / iconDocyrus icon field
markerIconColorFieldSlugstring—Icon color field (hex, rgb() or a Tailwind token)
markerIconColorstring—Icon color when the color field is empty
markerPriority'image' | 'icon''image'Which one to show when a record has both
enableViewportFilterbooleanfalseLimits markers / mappedItems to the viewport
viewportFilterMode'auto' | 'manual''auto'manual waits for searchThisArea()
enableMarkerDragbooleanfalseMakes markers draggable (long-press, then drag)
onMarkerMove(marker, newPosition) => void | Promise<void>PATCH locationReplaces the default PATCH
markerTemplatestring—{{field_slug}} template for the callout text
getMarker(item, context) => DocyrusMapMarker<TData> | null—Replaces the built-in marker builder
defaultCenterDocyrusMapPoint{ lat: 39.9334, lng: 32.8597 }Center when there are no markers
defaultZoomnumber6Zoom when there are no markers
focusedZoomnumber14Zoom for a single marker
fitBoundsPaddingnumber48Padding in px for the one-time fit to all markers
autoSelectSingleMarkerbooleantrueSelects the marker automatically when there is only one
googleMapsApiKeystring | null—Enables Google reverse geocoding. There is no env fallback on native
onMapClick(position: DocyrusMapPoint) => void—Called on a tap on the map, then again with address once it resolves
basemapsArray<DocyrusBasemapId | DocyrusBasemapDefinition> | false—Basemaps in the picker. Omit to hide the picker
defaultBasemapstringfirst entryInitial basemap
enableGroupMenu / enableRowHeightMenu / enableDisplayMenubooleanfalseGrid toolbar menus
staleTimenumber30000React Query stale time in ms
onReload() => void—Called after a toolbar reload
persistStateboolean | { storage?: 'session' | 'local'; key?: string }—Saves the grid's view parameters and the basemap (…:map) for each saved view

Result (UseDocyrusMapViewResult<TData>)

KeyTypeDescription
markers / allMarkersDocyrusMapMarker<TData>[]Markers after / before the viewport filter
items / mappedItems / unmappedItemsTData[]All records / records with a location / records without one
counts{ total, mapped, unmapped }Record counts
viewportBounds / setViewportBoundsDocyrusMapBounds | null / setterLast settled bounds. Wire the setter to onViewportChange
isViewportStalebooleanManual mode: the map has moved since the last search
searchThisArea / clearViewportFilter() => voidApplies / clears the viewport filter
enableMarkerDrag / handleMarkerMoveboolean / (marker, pos) => Promise<void>Drag-to-move
availableBasemaps / activeBasemap / setActiveBasemap—Basemap state
locationField / titleField / descriptionFieldsDataSourceFieldResolved fields
hasLocationFieldbooleanWhether a location field was found
requestedColumns / resolvedListParams—Query payload
center / bounds / defaultZoom / focusedZoom / fitBoundsPadding—Camera inputs for DocyrusMapView
selectedMarkerId / selectedMarker / setSelectedMarkerId / selectMarker / clearSelectedMarker—Selection
googleMapsApiKeystring | nullThe resolved key
onMapClick(position) => void | undefinedPassed through from options
isLoading / error / reload—Loading, error and reload
table / toolbar / views / fields / dataSource / activeViewId / setActiveViewId—Passed through from useDocyrusDataGrid

DocyrusMapView props

PropTypeDefaultDescription
markersDocyrusMapMarker<TData>[]—Markers to render (required)
centerDocyrusMapPoint—Initial center (required)
boundsDocyrusMapBounds | null—The map fits these bounds once, the first time they are available
defaultZoomnumber6Initial zoom without bounds
focusedZoomnumber14Zoom used for a single point
fitBoundsPaddingnumber48Fit padding in px
selectedMarkerIdstring | null—Highlighted marker
onSelectMarker(id | null) => void—Called on a marker press, and with null when the map is tapped
onMapClick(position) => void—Called on a tap on empty map, then again with address
renderPopup(marker) => ReactNode—Custom callout content
onEditMarker(marker) => void—Called when the callout is pressed
onViewportChange(bounds) => void—Called when the map settles
draggableMarkersboolean—Makes markers draggable
onMarkerMove(marker, position) => void | Promise<void>—Called when a marker is dropped
allMarkersCountnumber—Keeps the map mounted when the viewport has no markers
basemaps / activeBasemap / onBasemapChange——Layers control; shown when there are 2 or more basemaps
renderMarkerIcon(marker, isSelected) => ReactNode—Custom marker view
emptyStateReactNodet('ui.mapView.emptyMarkers')Shown when there is no data
classNamestringh-[420px]Container classes. Give it a height
provider'default' | 'google''default'Map provider (native-only)
isViewportStale / onSearchThisAreaboolean / () => void—"Search this area" pill (native-only)
enableClusteringbooleantrueClusters nearby markers (native-only)
showZoomControl / showLocateControlbooleantrueMap controls (native-only)
googleMapsApiKeystring | null—Reverse-geocoding key for onMapClick (native-only)

DocyrusGoogleMapView also accepts apiKey, defaultMapType ('roadmap' | 'satellite' | 'hybrid' | 'terrain') and getMarkerIcon(marker, isSelected) => string | { url, size } | null.

Helpers

  • reverseGeocode(lat, lng, apiKey?) returns Promise<string | null>. It tries the optional expo-location peer first, then the Google Geocoding REST API when a key is given, then OpenStreetMap Nominatim. It never throws.
  • getExpoLocationModule() returns the optional expo-location module, or null.
  • DEFAULT_DOCYRUS_BASEMAPS holds the built-in street / satellite / hybrid / terrain definitions.

Native deltas

  • There is ONE DocyrusMapView on react-native-maps instead of the web Leaflet and Google Maps views. Both web names are exported as aliases.
  • DocyrusBasemapDefinition adds mapType ('standard' | 'satellite' | 'hybrid' | 'terrain'). The Leaflet tile fields are optional and ignored.
  • DocyrusMapMarker adds icon (the raw Docyrus icon id), which is rendered with DocyrusIcon.
  • The map fits to the markers only once, like web, so refetches and drags never move the user's viewport. The viewport is not persisted.
  • expo-location is an optional peer. Without it, reverse geocoding uses Google REST (with a key) or Nominatim.

Translation Keys

KeyFallback
ui.mapView.emptyMarkersNo mapped records yet.
ui.mapView.searchThisAreaSearch this area
ui.mapView.tapToEditTap to edit

Type Exports

TypeDescription
UseDocyrusMapViewOptions<TData> / UseDocyrusMapViewResult<TData>Hook options and result
DocyrusMapMarker<TData> / DocyrusMapMarkerBuilderContext<TData> / DocyrusMapMarkerIconMarker types
DocyrusMapPoint / DocyrusMapBounds / DocyrusLocationValue / DocyrusNormalizedLocationGeometry types
DocyrusBasemapId / DocyrusBasemapDefinition / DocyrusGoogleMapType / DocyrusMapProviderBasemap types
DocyrusMapViewProps<TData> / DocyrusGoogleMapViewProps<TData>View props

On this page