MyCuppa

Map

Embeddable map component with Google Maps, Mapbox, or Apple Maps

Platforms:
webiosandroid
Version 1.0.0

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:

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