Map
An embeddable map component that supports Google Maps, Mapbox, and Apple Maps with a unified API across all platforms.
Features
- Multi-provider Support: Google Maps (Web/Android), Apple Maps (iOS), Mapbox (all platforms)
- Markers & Annotations: Add custom markers with icons and info windows
- Geolocation: User location tracking and centering
- Clustering: Automatic marker clustering for large datasets
- Custom Styling: Brand-specific map themes
- Gestures: Pan, zoom, rotate with platform-native feel
- Offline Support: Pre-cached map tiles for offline use
Installation
pnpm add @mycuppa/map
Platform-Specific Setup
iOS:
# Add to your Podfile
pod 'GoogleMaps'
# Or for Apple Maps (included by default)
Android:
// Add to build.gradle
dependencies {
implementation 'com.google.android.gms:play-services-maps:18.2.0'
}
Web:
// Add script to your HTML
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
Basic Usage
import { Map, Marker } from '@mycuppa/map'
export function LocationMap() {
return (
<Map
initialCenter={{ lat: 37.7749, lng: -122.4194 }}
initialZoom={12}
style={{ width: '100%', height: 400 }}
>
<Marker
position={{ lat: 37.7749, lng: -122.4194 }}
title="San Francisco"
description="Golden Gate Bridge"
/>
</Map>
)
}
With User Location
import { Map, useUserLocation } from '@mycuppa/map'
export function MyLocationMap() {
const { location, loading, error } = useUserLocation()
if (loading) return <div>Loading map...</div>
if (error) return <div>Error: {error.message}</div>
return (
<Map
initialCenter={location}
initialZoom={15}
showUserLocation
followUserLocation
>
<Marker
position={location}
icon="user-location"
/>
</Map>
)
}
Multiple Markers with Clustering
import { Map, Marker, MarkerClusterer } from '@mycuppa/map'
const locations = [
{ id: 1, lat: 37.7749, lng: -122.4194, name: 'SF Office' },
{ id: 2, lat: 37.7849, lng: -122.4094, name: 'SF Store 1' },
{ id: 3, lat: 37.7649, lng: -122.4294, name: 'SF Store 2' },
// ... more locations
]
export function StoreLocator() {
return (
<Map initialCenter={{ lat: 37.7749, lng: -122.4194 }} initialZoom={12}>
<MarkerClusterer>
{locations.map(location => (
<Marker
key={location.id}
position={{ lat: location.lat, lng: location.lng }}
title={location.name}
onClick={() => console.log('Clicked:', location.name)}
/>
))}
</MarkerClusterer>
</Map>
)
}
Custom Styling
import { Map, MapTheme } from '@mycuppa/map'
const customTheme: MapTheme = {
palette: {
water: '#1a73e8',
land: '#f5f5f5',
roads: '#ffffff',
},
styles: [
{
featureType: 'poi',
stylers: [{ visibility: 'off' }],
},
],
}
export function BrandedMap() {
return (
<Map
initialCenter={{ lat: 37.7749, lng: -122.4194 }}
theme={customTheme}
/>
)
}
Props
Map
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| initialCenter | { lat: number, lng: number } | Required | Initial map center |
| initialZoom | number | 10 | Initial zoom level (0-20) |
| provider | 'google' \| 'mapbox' \| 'apple' | Auto-detected | Map provider |
| showUserLocation | boolean | false | Show user location marker |
| followUserLocation | boolean | false | Center map on user location |
| theme | MapTheme | - | Custom map styling |
| onRegionChange | (region) => void | - | Called when map region changes |
| style | CSSProperties \| ViewStyle | - | Container styles |
Marker
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| position | { lat: number, lng: number } | Required | Marker position |
| title | string | - | Marker title |
| description | string | - | Marker description |
| icon | string \| ImageSource | - | Custom marker icon |
| onClick | () => void | - | Click handler |
API Keys
Get your API keys:
- Google Maps: Google Cloud Console
- Mapbox: Mapbox Account
- Apple Maps: Included with iOS SDK
Platform Notes
iOS
- Uses Apple Maps by default for native feel
- Google Maps available via
provider="google" - Requires location permissions in Info.plist
Android
- Uses Google Maps by default
- Requires API key in AndroidManifest.xml
- Automatic marker clustering supported
Web
- Defaults to Google Maps
- Mapbox available for custom styling
- Responsive and touch-optimized
Related
- Geolocation Hook - Track user location
- Contact Form - Use with location picker
- Store Locator Screen - Complete store finder