or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

addons.mdadvanced.mdcore-components.mddrawing.mdhocs.mdindex.mdlayers.mdplaces.mdshapes.mdvisualization.md

addons.mddocs/

0

# Addon Extensions

1

2

Third-party addon components that extend Google Maps functionality with enhanced features like marker clustering, custom info boxes, and labeled markers. These components require additional dependencies.

3

4

## Capabilities

5

6

### InfoBox

7

8

Enhanced info window component with advanced styling and positioning options. Requires the `google-maps-infobox` package.

9

10

```javascript { .api }

11

/**

12

* Enhanced info window with advanced styling options

13

* Requires: npm install google-maps-infobox

14

*/

15

class InfoBox extends Component<InfoBoxProps> {}

16

17

interface InfoBoxProps {

18

// Default props

19

defaultOptions?: InfoBoxOptions;

20

defaultPosition?: google.maps.LatLng;

21

defaultVisible?: boolean;

22

defaultZIndex?: number;

23

24

// Controlled props

25

options?: InfoBoxOptions;

26

position?: google.maps.LatLng;

27

visible?: boolean;

28

zIndex?: number;

29

30

// Event handlers

31

onCloseClick?(): void;

32

onContentChanged?(): void;

33

onDomReady?(): void;

34

onPositionChanged?(): void;

35

onZindexChanged?(): void;

36

}

37

```

38

39

**Usage Example:**

40

41

```javascript

42

import InfoBox from "react-google-maps/lib/components/addons/InfoBox";

43

44

<GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>

45

<Marker position={{ lat: 37.7749, lng: -122.4194 }} />

46

47

<InfoBox

48

position={{ lat: 37.7749, lng: -122.4194 }}

49

options={{

50

content: `

51

<div style="background: white; padding: 12px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.2);">

52

<h3 style="margin: 0 0 8px 0;">San Francisco</h3>

53

<p style="margin: 0;">The City by the Bay</p>

54

</div>

55

`,

56

disableAutoPan: false,

57

maxWidth: 0,

58

pixelOffset: { width: -140, height: 0 },

59

zIndex: null,

60

boxStyle: {

61

background: "url('tipbox.gif') no-repeat",

62

opacity: 0.75,

63

width: "280px"

64

},

65

closeBoxMargin: "10px 2px 2px 2px",

66

closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",

67

infoBoxClearance: { width: 50, height: 200 }

68

}}

69

onCloseClick={() => {

70

console.log("InfoBox closed");

71

}}

72

/>

73

</GoogleMap>

74

```

75

76

### MarkerClusterer

77

78

Component for clustering markers when they are close together at low zoom levels. Requires the `marker-clusterer-plus` package.

79

80

```javascript { .api }

81

/**

82

* Marker clustering component for managing large numbers of markers

83

* Requires: npm install marker-clusterer-plus

84

*/

85

class MarkerClusterer extends Component<MarkerClustererProps> {}

86

87

interface MarkerClustererProps {

88

// Default clustering options

89

defaultAverageCenter?: boolean;

90

defaultBatchSizeIE?: number;

91

defaultBatchSize?: number;

92

defaultCalculator?: Calculator;

93

defaultClusterClass?: string;

94

defaultEnableRetinaIcons?: boolean;

95

defaultGridSize?: number;

96

defaultIgnoreHidden?: boolean;

97

defaultImageExtension?: string;

98

defaultImagePath?: string;

99

defaultImageSizes?: number[];

100

defaultMaxZoom?: number;

101

defaultMinimumClusterSize?: number;

102

defaultStyles?: ClusterIconStyle[];

103

defaultTitle?: string;

104

defaultZoomOnClick?: boolean;

105

106

// Controlled clustering options

107

averageCenter?: boolean;

108

batchSizeIE?: number;

109

batchSize?: number;

110

calculator?: Calculator;

111

clusterClass?: string;

112

enableRetinaIcons?: boolean;

113

gridSize?: number;

114

ignoreHidden?: boolean;

115

imageExtension?: string;

116

imagePath?: string;

117

imageSizes?: number[];

118

maxZoom?: number;

119

minimumClusterSize?: number;

120

styles?: ClusterIconStyle[];

121

title?: string;

122

zoomOnClick?: boolean;

123

124

// Event handlers

125

onClick?(cluster: Cluster): void;

126

onClusteringBegin?(mc: MarkerClusterer): void;

127

onClusteringEnd?(mc: MarkerClusterer): void;

128

onMouseOut?(c: Cluster): void;

129

onMouseOver?(c: Cluster): void;

130

}

131

```

132

133

**Usage Example:**

134

135

```javascript

136

import MarkerClusterer from "react-google-maps/lib/components/addons/MarkerClusterer";

137

138

const ClusteredMarkers = () => {

139

const [markers] = useState([

140

{ lat: 37.7749, lng: -122.4194, id: 1 },

141

{ lat: 37.7849, lng: -122.4094, id: 2 },

142

{ lat: 37.7649, lng: -122.4294, id: 3 },

143

// ... many more markers

144

]);

145

146

return (

147

<GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>

148

<MarkerClusterer

149

averageCenter={true}

150

enableRetinaIcons={true}

151

gridSize={60}

152

maxZoom={15}

153

minimumClusterSize={2}

154

styles={[

155

{

156

textColor: 'white',

157

url: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m1.png',

158

height: 53,

159

width: 53

160

},

161

{

162

textColor: 'white',

163

url: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m2.png',

164

height: 56,

165

width: 56

166

},

167

{

168

textColor: 'white',

169

url: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m3.png',

170

height: 66,

171

width: 66

172

}

173

]}

174

onClick={(cluster) => {

175

console.log(`Cluster clicked with ${cluster.getMarkers().length} markers`);

176

}}

177

onClusteringEnd={(markerClusterer) => {

178

console.log(`Clustering complete: ${markerClusterer.getClusters().length} clusters`);

179

}}

180

>

181

{markers.map((marker) => (

182

<Marker

183

key={marker.id}

184

position={{ lat: marker.lat, lng: marker.lng }}

185

title={`Marker ${marker.id}`}

186

/>

187

))}

188

</MarkerClusterer>

189

</GoogleMap>

190

);

191

};

192

```

193

194

### MarkerWithLabel

195

196

Enhanced marker component with custom label styling. Requires the `markerwithlabel` package and extends the standard Marker props.

197

198

```javascript { .api }

199

/**

200

* Marker with custom label styling

201

* Requires: npm install markerwithlabel

202

* Extends MarkerProps with additional label properties

203

*/

204

class MarkerWithLabel extends Component<MarkerProps> {}

205

206

// Extends MarkerProps with these additional properties:

207

interface MarkerLabelProps extends MarkerProps {

208

/** Custom label class for styling */

209

labelClass?: string;

210

/** Anchor point for the label */

211

labelAnchor?: google.maps.Point;

212

/** Text content of the label */

213

labelContent?: string;

214

/** Inline styles for the label */

215

labelStyle?: CSSStyleDeclaration;

216

/** Callback when marker with label functionality is ready */

217

markerWithLabel?(): void;

218

}

219

```

220

221

**Usage Example:**

222

223

```javascript

224

import MarkerWithLabel from "react-google-maps/lib/components/addons/MarkerWithLabel";

225

226

<GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>

227

<MarkerWithLabel

228

position={{ lat: 37.7749, lng: -122.4194 }}

229

labelAnchor={new google.maps.Point(0, 0)}

230

labelContent="San Francisco"

231

labelStyle={{

232

backgroundColor: "yellow",

233

fontSize: "14px",

234

padding: "4px",

235

borderRadius: "4px",

236

border: "1px solid #333"

237

}}

238

icon={{

239

url: "https://maps.google.com/mapfiles/ms/icons/blue-dot.png"

240

}}

241

onClick={() => {

242

console.log("Labeled marker clicked");

243

}}

244

/>

245

246

<MarkerWithLabel

247

position={{ lat: 37.7649, lng: -122.4294 }}

248

labelContent="Custom Location"

249

labelClass="custom-label"

250

labelAnchor={new google.maps.Point(30, 0)}

251

icon={{

252

url: "https://maps.google.com/mapfiles/ms/icons/red-dot.png"

253

}}

254

/>

255

</GoogleMap>

256

```

257

258

## Addon Installation and Setup

259

260

### Installing Dependencies

261

262

Each addon requires its corresponding npm package:

263

264

```bash

265

# For InfoBox

266

npm install google-maps-infobox

267

268

# For MarkerClusterer

269

npm install marker-clusterer-plus

270

271

# For MarkerWithLabel

272

npm install markerwithlabel

273

274

# Install all addons

275

npm install google-maps-infobox marker-clusterer-plus markerwithlabel

276

```

277

278

### Importing Addon Components

279

280

Addon components must be imported directly from their specific paths:

281

282

```javascript

283

// Correct imports for addons

284

import InfoBox from "react-google-maps/lib/components/addons/InfoBox";

285

import MarkerClusterer from "react-google-maps/lib/components/addons/MarkerClusterer";

286

import MarkerWithLabel from "react-google-maps/lib/components/addons/MarkerWithLabel";

287

288

// These will NOT work - addons are not in main exports

289

import { InfoBox, MarkerClusterer, MarkerWithLabel } from "react-google-maps"; // ❌

290

```

291

292

## Advanced Addon Patterns

293

294

### Combining Clustering with Custom InfoBox

295

296

```javascript

297

const AdvancedMarkerMap = () => {

298

const [selectedMarker, setSelectedMarker] = useState(null);

299

const [markers] = useState(/* large array of markers */);

300

301

return (

302

<GoogleMap defaultZoom={10} defaultCenter={{ lat: 37.7749, lng: -122.4194 }}>

303

<MarkerClusterer

304

onClick={(cluster) => {

305

// Zoom into cluster

306

const bounds = new google.maps.LatLngBounds();

307

cluster.getMarkers().forEach(marker => {

308

bounds.extend(marker.getPosition());

309

});

310

map.fitBounds(bounds);

311

}}

312

>

313

{markers.map((marker) => (

314

<Marker

315

key={marker.id}

316

position={marker.position}

317

onClick={() => setSelectedMarker(marker)}

318

/>

319

))}

320

</MarkerClusterer>

321

322

{selectedMarker && (

323

<InfoBox

324

position={selectedMarker.position}

325

options={{

326

content: `

327

<div class="custom-infobox">

328

<h3>${selectedMarker.title}</h3>

329

<p>${selectedMarker.description}</p>

330

<button onclick="closeInfoBox()">Close</button>

331

</div>

332

`

333

}}

334

onCloseClick={() => setSelectedMarker(null)}

335

/>

336

)}

337

</GoogleMap>

338

);

339

};

340

```

341

342

### Custom Cluster Styling

343

344

```javascript

345

const customClusterStyles = [

346

{

347

textColor: 'white',

348

textSize: 11,

349

url: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(`

350

<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40">

351

<circle cx="20" cy="20" r="18" fill="#ff6b6b" stroke="#fff" stroke-width="2"/>

352

</svg>

353

`),

354

height: 40,

355

width: 40

356

},

357

{

358

textColor: 'white',

359

textSize: 12,

360

url: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(`

361

<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">

362

<circle cx="25" cy="25" r="23" fill="#4ecdc4" stroke="#fff" stroke-width="2"/>

363

</svg>

364

`),

365

height: 50,

366

width: 50

367

}

368

];

369

370

<MarkerClusterer

371

styles={customClusterStyles}

372

calculator={(markers, numStyles) => {

373

const count = markers.length;

374

let index = 0;

375

if (count > 10) index = 1;

376

if (count > 100) index = 2;

377

return { text: count, index: index };

378

}}

379

>

380

{/* markers */}

381

</MarkerClusterer>

382

```