@classic-homes/theme-mcp 0.1.20 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2022 -10
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +114 -1
- package/dist/index.js +2022 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -17365,6 +17365,2017 @@ interface SankeyData {
|
|
|
17365
17365
|
}));
|
|
17366
17366
|
}
|
|
17367
17367
|
|
|
17368
|
+
// src/data/maps-catalog.json
|
|
17369
|
+
var maps_catalog_default = {
|
|
17370
|
+
version: "0.4.0",
|
|
17371
|
+
packageName: "@classic-homes/maps-core",
|
|
17372
|
+
description: "Core utilities, types, and themes for Classic Theme MapLibre GL components",
|
|
17373
|
+
subpackages: {
|
|
17374
|
+
main: {
|
|
17375
|
+
importPath: "@classic-homes/maps-core",
|
|
17376
|
+
description: "Main entry point with all exports (themes, types, utilities)",
|
|
17377
|
+
modules: {
|
|
17378
|
+
theme: {
|
|
17379
|
+
description: "MapLibre GL theme generation from design tokens",
|
|
17380
|
+
functions: [
|
|
17381
|
+
{
|
|
17382
|
+
name: "generateLightTheme",
|
|
17383
|
+
signature: "() => MapTheme",
|
|
17384
|
+
description: "Generate light theme configuration from design tokens"
|
|
17385
|
+
},
|
|
17386
|
+
{
|
|
17387
|
+
name: "generateDarkTheme",
|
|
17388
|
+
signature: "() => MapTheme",
|
|
17389
|
+
description: "Generate dark theme configuration from design tokens"
|
|
17390
|
+
},
|
|
17391
|
+
{
|
|
17392
|
+
name: "lightTheme",
|
|
17393
|
+
signature: "MapTheme",
|
|
17394
|
+
description: "Pre-generated light theme object (singleton)"
|
|
17395
|
+
},
|
|
17396
|
+
{
|
|
17397
|
+
name: "darkTheme",
|
|
17398
|
+
signature: "MapTheme",
|
|
17399
|
+
description: "Pre-generated dark theme object (singleton)"
|
|
17400
|
+
},
|
|
17401
|
+
{
|
|
17402
|
+
name: "lightBasicStyle",
|
|
17403
|
+
signature: "StyleSpecification",
|
|
17404
|
+
description: "Pre-generated light MapLibre style using OSM raster tiles"
|
|
17405
|
+
},
|
|
17406
|
+
{
|
|
17407
|
+
name: "darkBasicStyle",
|
|
17408
|
+
signature: "StyleSpecification",
|
|
17409
|
+
description: "Pre-generated dark MapLibre style using OSM raster tiles"
|
|
17410
|
+
},
|
|
17411
|
+
{
|
|
17412
|
+
name: "THEME_LIGHT",
|
|
17413
|
+
signature: "'classic-light'",
|
|
17414
|
+
description: "Theme name constant for light theme"
|
|
17415
|
+
},
|
|
17416
|
+
{
|
|
17417
|
+
name: "THEME_DARK",
|
|
17418
|
+
signature: "'classic-dark'",
|
|
17419
|
+
description: "Theme name constant for dark theme"
|
|
17420
|
+
},
|
|
17421
|
+
{
|
|
17422
|
+
name: "generateLightColors",
|
|
17423
|
+
signature: "() => MapThemeColors",
|
|
17424
|
+
description: "Generate light theme colors from design tokens"
|
|
17425
|
+
},
|
|
17426
|
+
{
|
|
17427
|
+
name: "generateDarkColors",
|
|
17428
|
+
signature: "() => MapThemeColors",
|
|
17429
|
+
description: "Generate dark theme colors from design tokens"
|
|
17430
|
+
},
|
|
17431
|
+
{
|
|
17432
|
+
name: "generateLightDataColors",
|
|
17433
|
+
signature: "() => MapDataColors",
|
|
17434
|
+
description: "Generate light theme data visualization colors"
|
|
17435
|
+
},
|
|
17436
|
+
{
|
|
17437
|
+
name: "generateDarkDataColors",
|
|
17438
|
+
signature: "() => MapDataColors",
|
|
17439
|
+
description: "Generate dark theme data visualization colors"
|
|
17440
|
+
},
|
|
17441
|
+
{
|
|
17442
|
+
name: "getTypography",
|
|
17443
|
+
signature: "() => { fontFamily: string; sizes: Record<string, number> }",
|
|
17444
|
+
description: "Get typography settings from design tokens"
|
|
17445
|
+
},
|
|
17446
|
+
{
|
|
17447
|
+
name: "getTheme",
|
|
17448
|
+
signature: "(mode: 'light' | 'dark') => MapTheme",
|
|
17449
|
+
description: "Get a theme by mode name"
|
|
17450
|
+
},
|
|
17451
|
+
{
|
|
17452
|
+
name: "generateBasicStyle",
|
|
17453
|
+
signature: "(theme: MapTheme) => StyleSpecification",
|
|
17454
|
+
description: "Generate a basic OSM raster tile style for a theme"
|
|
17455
|
+
},
|
|
17456
|
+
{
|
|
17457
|
+
name: "generateVectorStyle",
|
|
17458
|
+
signature: "(theme: MapTheme, options?: { tileUrl?: string }) => StyleSpecification",
|
|
17459
|
+
description: "Generate a vector tile style for a theme"
|
|
17460
|
+
},
|
|
17461
|
+
{
|
|
17462
|
+
name: "getBasicStyle",
|
|
17463
|
+
signature: "(mode: 'light' | 'dark') => StyleSpecification",
|
|
17464
|
+
description: "Get a basic raster style by mode name"
|
|
17465
|
+
}
|
|
17466
|
+
]
|
|
17467
|
+
},
|
|
17468
|
+
format: {
|
|
17469
|
+
description: "Formatting utilities for map coordinates and measurements",
|
|
17470
|
+
functions: [
|
|
17471
|
+
{
|
|
17472
|
+
name: "formatCoordinates",
|
|
17473
|
+
signature: "(coordinates: LngLat, precision?: number, format?: 'decimal' | 'dms' | 'dd') => string",
|
|
17474
|
+
description: "Format coordinates for display (decimal, DMS, or DD format)",
|
|
17475
|
+
example: "formatCoordinates([-122.4194, 37.7749]) // '-122.419400, 37.774900'"
|
|
17476
|
+
},
|
|
17477
|
+
{
|
|
17478
|
+
name: "decimalToDMS",
|
|
17479
|
+
signature: "(decimal: number, type: 'lat' | 'lng') => string",
|
|
17480
|
+
description: "Convert decimal degrees to DMS (degrees, minutes, seconds) format",
|
|
17481
|
+
example: `decimalToDMS(37.7749, 'lat') // '37\xB0 46' 29.6" N'`
|
|
17482
|
+
},
|
|
17483
|
+
{
|
|
17484
|
+
name: "formatDistance",
|
|
17485
|
+
signature: "(meters: number, unit?: 'metric' | 'imperial') => string",
|
|
17486
|
+
description: "Format distance in meters/kilometers or feet/miles",
|
|
17487
|
+
example: "formatDistance(1500) // '1.5 km'"
|
|
17488
|
+
},
|
|
17489
|
+
{
|
|
17490
|
+
name: "formatArea",
|
|
17491
|
+
signature: "(sqMeters: number, unit?: 'metric' | 'imperial') => string",
|
|
17492
|
+
description: "Format area in square meters/kilometers or acres",
|
|
17493
|
+
example: "formatArea(10000) // '1.00 ha'"
|
|
17494
|
+
},
|
|
17495
|
+
{
|
|
17496
|
+
name: "formatBounds",
|
|
17497
|
+
signature: "(bounds: MapBounds | BoundsArray) => string",
|
|
17498
|
+
description: "Format map bounds as readable string"
|
|
17499
|
+
},
|
|
17500
|
+
{
|
|
17501
|
+
name: "formatZoom",
|
|
17502
|
+
signature: "(zoom: number) => string",
|
|
17503
|
+
description: "Format zoom level for display",
|
|
17504
|
+
example: "formatZoom(12.5) // 'Zoom: 12.5'"
|
|
17505
|
+
},
|
|
17506
|
+
{
|
|
17507
|
+
name: "formatBearing",
|
|
17508
|
+
signature: "(bearing: number) => string",
|
|
17509
|
+
description: "Format bearing/rotation as degrees with cardinal direction",
|
|
17510
|
+
example: "formatBearing(45) // '45\xB0 NE'"
|
|
17511
|
+
},
|
|
17512
|
+
{
|
|
17513
|
+
name: "formatPitch",
|
|
17514
|
+
signature: "(pitch: number) => string",
|
|
17515
|
+
description: "Format pitch/tilt for display",
|
|
17516
|
+
example: "formatPitch(60) // '60\xB0 tilt'"
|
|
17517
|
+
},
|
|
17518
|
+
{
|
|
17519
|
+
name: "formatScale",
|
|
17520
|
+
signature: "(scale: number) => string",
|
|
17521
|
+
description: "Format a scale ratio for display",
|
|
17522
|
+
example: "formatScale(50000) // '1:50K'"
|
|
17523
|
+
},
|
|
17524
|
+
{
|
|
17525
|
+
name: "zoomToScale",
|
|
17526
|
+
signature: "(zoom: number, latitude?: number) => number",
|
|
17527
|
+
description: "Approximate the scale ratio from zoom level (varies by latitude)"
|
|
17528
|
+
},
|
|
17529
|
+
{
|
|
17530
|
+
name: "formatPropertyValue",
|
|
17531
|
+
signature: "(value: unknown) => string",
|
|
17532
|
+
description: "Format a property value for display in popups (handles numbers, booleans, arrays)"
|
|
17533
|
+
},
|
|
17534
|
+
{
|
|
17535
|
+
name: "formatFeatureProperties",
|
|
17536
|
+
signature: "(properties: Record<string, unknown>, options?: { exclude?: string[]; include?: string[]; labelMap?: Record<string, string> }) => string",
|
|
17537
|
+
description: "Create a popup content string from feature properties with optional filtering and label mapping"
|
|
17538
|
+
},
|
|
17539
|
+
{
|
|
17540
|
+
name: "formatLabel",
|
|
17541
|
+
signature: "(key: string) => string",
|
|
17542
|
+
description: "Format a property key as a human-readable label (handles snake_case and camelCase)"
|
|
17543
|
+
}
|
|
17544
|
+
]
|
|
17545
|
+
},
|
|
17546
|
+
accessibility: {
|
|
17547
|
+
description: "Accessibility utilities for screen readers",
|
|
17548
|
+
functions: [
|
|
17549
|
+
{
|
|
17550
|
+
name: "KEYBOARD_CONTROLS",
|
|
17551
|
+
signature: "Record<string, Record<string, string>>",
|
|
17552
|
+
description: "Keyboard shortcut documentation object for map interactions (pan, zoom, rotate, pitch, reset)"
|
|
17553
|
+
},
|
|
17554
|
+
{
|
|
17555
|
+
name: "generateKeyboardControlsDescription",
|
|
17556
|
+
signature: "() => string",
|
|
17557
|
+
description: "Generate a text description of keyboard controls for screen readers"
|
|
17558
|
+
},
|
|
17559
|
+
{
|
|
17560
|
+
name: "generateMapDescription",
|
|
17561
|
+
signature: "(title: string, options?: { center?: LngLat; zoom?: number; featureCount?: number; markerCount?: number; layerTypes?: string[] }) => string",
|
|
17562
|
+
description: "Generate accessible description for a map"
|
|
17563
|
+
},
|
|
17564
|
+
{
|
|
17565
|
+
name: "generateFeatureCollectionDescription",
|
|
17566
|
+
signature: "(title: string, data: GeoJSONFeatureCollection) => string",
|
|
17567
|
+
description: "Generate accessible description for GeoJSON features (counts and geometry types)"
|
|
17568
|
+
},
|
|
17569
|
+
{
|
|
17570
|
+
name: "generateMarkersDescription",
|
|
17571
|
+
signature: "(title: string, markers: MarkerData[]) => string",
|
|
17572
|
+
description: "Generate accessible description for markers (count and first few labels)"
|
|
17573
|
+
},
|
|
17574
|
+
{
|
|
17575
|
+
name: "generateFeatureTable",
|
|
17576
|
+
signature: "(features: GeoJSONFeatureCollection, propertyKeys: string[]) => string",
|
|
17577
|
+
description: "Generate a hidden data table (HTML) for screen readers with sr-only class"
|
|
17578
|
+
},
|
|
17579
|
+
{
|
|
17580
|
+
name: "generateMarkerList",
|
|
17581
|
+
signature: "(markers: MarkerData[]) => string",
|
|
17582
|
+
description: "Generate a hidden marker list (HTML) for screen readers with sr-only class"
|
|
17583
|
+
},
|
|
17584
|
+
{
|
|
17585
|
+
name: "generateMoveAnnouncement",
|
|
17586
|
+
signature: "(center: LngLat, zoom: number, action: 'pan' | 'zoom' | 'move') => string",
|
|
17587
|
+
description: "Generate live region announcement for map navigation changes"
|
|
17588
|
+
}
|
|
17589
|
+
]
|
|
17590
|
+
},
|
|
17591
|
+
styles: {
|
|
17592
|
+
description: "Styling utilities for map layers",
|
|
17593
|
+
functions: [
|
|
17594
|
+
{
|
|
17595
|
+
name: "createFillStyle",
|
|
17596
|
+
signature: "(options: { color: ColorExpression; opacity?: NumberExpression; outlineColor?: ColorExpression }) => { paint: Record<string, unknown> }",
|
|
17597
|
+
description: "Create a solid polygon/fill style object for MapLibre layers"
|
|
17598
|
+
},
|
|
17599
|
+
{
|
|
17600
|
+
name: "createLineStyle",
|
|
17601
|
+
signature: "(options: { color: ColorExpression; width: NumberExpression; opacity?: NumberExpression; dashArray?: number[]; cap?: 'butt' | 'round' | 'square'; join?: 'bevel' | 'round' | 'miter' }) => { paint: Record<string, unknown>; layout: Record<string, unknown> }",
|
|
17602
|
+
description: "Create a line style object with paint and layout properties"
|
|
17603
|
+
},
|
|
17604
|
+
{
|
|
17605
|
+
name: "createCircleStyle",
|
|
17606
|
+
signature: "(options: { radius: NumberExpression; color: ColorExpression; opacity?: NumberExpression; strokeWidth?: NumberExpression; strokeColor?: ColorExpression; blur?: number }) => { paint: Record<string, unknown> }",
|
|
17607
|
+
description: "Create a circle/point style object for MapLibre layers"
|
|
17608
|
+
},
|
|
17609
|
+
{
|
|
17610
|
+
name: "createExtrusionStyle",
|
|
17611
|
+
signature: "(options: { height: NumberExpression; baseHeight?: NumberExpression; color: ColorExpression; opacity?: number; verticalGradient?: boolean }) => { paint: Record<string, unknown> }",
|
|
17612
|
+
description: "Create a 3D extrusion style object for building layers"
|
|
17613
|
+
},
|
|
17614
|
+
{
|
|
17615
|
+
name: "createHeatmapStyle",
|
|
17616
|
+
signature: "(options: { weight?: NumberExpression; intensity?: NumberExpression; radius?: NumberExpression; opacity?: NumberExpression; colorRamp?: string[] }) => { paint: Record<string, unknown> }",
|
|
17617
|
+
description: "Create a heatmap style object with optional color ramp"
|
|
17618
|
+
},
|
|
17619
|
+
{
|
|
17620
|
+
name: "createHoverExpression",
|
|
17621
|
+
signature: "(baseValue: unknown, hoverValue: unknown, featureStateName?: string) => unknown[]",
|
|
17622
|
+
description: "Create MapLibre expression for hover state colors using feature-state"
|
|
17623
|
+
},
|
|
17624
|
+
{
|
|
17625
|
+
name: "createSelectionExpression",
|
|
17626
|
+
signature: "(baseValue: unknown, selectedValue: unknown, featureStateName?: string) => unknown[]",
|
|
17627
|
+
description: "Create MapLibre expression for selection state colors using feature-state"
|
|
17628
|
+
},
|
|
17629
|
+
{
|
|
17630
|
+
name: "createInteractiveExpression",
|
|
17631
|
+
signature: "(baseValue: unknown, hoverValue: unknown, selectedValue: unknown) => unknown[]",
|
|
17632
|
+
description: "Create combined hover and selection expression (selection takes priority)"
|
|
17633
|
+
},
|
|
17634
|
+
{
|
|
17635
|
+
name: "createCategoricalColorExpression",
|
|
17636
|
+
signature: "(property: string, colorMap: Record<string, string>, defaultColor: string) => unknown[]",
|
|
17637
|
+
description: "Create data-driven color expression based on a property value (match expression)"
|
|
17638
|
+
},
|
|
17639
|
+
{
|
|
17640
|
+
name: "createContinuousColorExpression",
|
|
17641
|
+
signature: "(property: string, stops: [number, string][], interpolation?: 'linear' | 'exponential' | ['cubic-bezier', number, number, number, number]) => unknown[]",
|
|
17642
|
+
description: "Create continuous color ramp expression for numeric properties"
|
|
17643
|
+
},
|
|
17644
|
+
{
|
|
17645
|
+
name: "createZoomExpression",
|
|
17646
|
+
signature: "(stops: [number, number][]) => unknown[]",
|
|
17647
|
+
description: "Create zoom-based interpolation expression for size/width values"
|
|
17648
|
+
},
|
|
17649
|
+
{
|
|
17650
|
+
name: "getHighlightStyle",
|
|
17651
|
+
signature: "(theme?: MapTheme) => { fill: Record<string, unknown>; line: Record<string, unknown>; circle: Record<string, unknown> }",
|
|
17652
|
+
description: "Get pre-configured highlight style properties for hover states"
|
|
17653
|
+
},
|
|
17654
|
+
{
|
|
17655
|
+
name: "getSelectionStyle",
|
|
17656
|
+
signature: "(theme?: MapTheme) => { fill: Record<string, unknown>; line: Record<string, unknown>; circle: Record<string, unknown> }",
|
|
17657
|
+
description: "Get pre-configured selection style properties with hover and selection states"
|
|
17658
|
+
}
|
|
17659
|
+
]
|
|
17660
|
+
},
|
|
17661
|
+
bounds: {
|
|
17662
|
+
description: "Bounds calculation utilities for GeoJSON data",
|
|
17663
|
+
functions: [
|
|
17664
|
+
{
|
|
17665
|
+
name: "calculateBounds",
|
|
17666
|
+
signature: "(geojson: GeoJSONFeatureCollection | GeoJSONFeature) => BoundsArray | null",
|
|
17667
|
+
description: "Calculate bounds from GeoJSON data, returns [[sw_lng, sw_lat], [ne_lng, ne_lat]] or null"
|
|
17668
|
+
},
|
|
17669
|
+
{
|
|
17670
|
+
name: "extendBounds",
|
|
17671
|
+
signature: "(bounds: BoundsArray, point: LngLat) => BoundsArray",
|
|
17672
|
+
description: "Extend existing bounds to include a new point"
|
|
17673
|
+
},
|
|
17674
|
+
{
|
|
17675
|
+
name: "combineBounds",
|
|
17676
|
+
signature: "(bounds1: BoundsArray, bounds2: BoundsArray) => BoundsArray",
|
|
17677
|
+
description: "Combine two bounds into one that encompasses both"
|
|
17678
|
+
},
|
|
17679
|
+
{
|
|
17680
|
+
name: "isValidBounds",
|
|
17681
|
+
signature: "(bounds: BoundsArray) => boolean",
|
|
17682
|
+
description: "Validate that bounds are properly formed and within valid ranges"
|
|
17683
|
+
}
|
|
17684
|
+
]
|
|
17685
|
+
},
|
|
17686
|
+
data: {
|
|
17687
|
+
description: "Data loading and validation utilities for GeoJSON",
|
|
17688
|
+
functions: [
|
|
17689
|
+
{
|
|
17690
|
+
name: "loadGeoJSON",
|
|
17691
|
+
signature: "(url: string, options?: LoadGeoJSONOptions) => Promise<LoadGeoJSONResult<T>>",
|
|
17692
|
+
description: "Load GeoJSON data from a URL with timeout support and optional validation"
|
|
17693
|
+
},
|
|
17694
|
+
{
|
|
17695
|
+
name: "validateGeoJSON",
|
|
17696
|
+
signature: "(data: unknown) => ValidationResult",
|
|
17697
|
+
description: "Validate GeoJSON structure, returns { valid, errors, featureCount, geometryTypes }"
|
|
17698
|
+
},
|
|
17699
|
+
{
|
|
17700
|
+
name: "calculateCentroid",
|
|
17701
|
+
signature: "(geojson: GeoJSONFeatureCollection | GeoJSONFeature) => [number, number] | null",
|
|
17702
|
+
description: "Calculate the centroid of GeoJSON data as [lng, lat]"
|
|
17703
|
+
},
|
|
17704
|
+
{
|
|
17705
|
+
name: "countFeaturesByType",
|
|
17706
|
+
signature: "(geojson: GeoJSONFeatureCollection) => Record<string, number>",
|
|
17707
|
+
description: "Count features by geometry type (Point, Polygon, etc.)"
|
|
17708
|
+
},
|
|
17709
|
+
{
|
|
17710
|
+
name: "filterByGeometryType",
|
|
17711
|
+
signature: "(geojson: GeoJSONFeatureCollection, types: string[]) => GeoJSONFeatureCollection",
|
|
17712
|
+
description: "Filter features by geometry type, returns new FeatureCollection"
|
|
17713
|
+
}
|
|
17714
|
+
]
|
|
17715
|
+
},
|
|
17716
|
+
positioning: {
|
|
17717
|
+
description: "Positioning utilities for map controls",
|
|
17718
|
+
functions: [
|
|
17719
|
+
{
|
|
17720
|
+
name: "BASE_OFFSET",
|
|
17721
|
+
signature: "8",
|
|
17722
|
+
description: "Base offset from map edge in pixels (matches Tailwind's -2)"
|
|
17723
|
+
},
|
|
17724
|
+
{
|
|
17725
|
+
name: "POSITION_CLASSES",
|
|
17726
|
+
signature: "Record<ControlPosition, string>",
|
|
17727
|
+
description: "Tailwind classes for each corner position (top-left, top-right, bottom-left, bottom-right)"
|
|
17728
|
+
},
|
|
17729
|
+
{
|
|
17730
|
+
name: "OFFSET_CLASSES",
|
|
17731
|
+
signature: "Record<ControlPosition, string>",
|
|
17732
|
+
description: "Horizontal offset classes when MapLibre controls are present at the same position"
|
|
17733
|
+
},
|
|
17734
|
+
{
|
|
17735
|
+
name: "computePositionClasses",
|
|
17736
|
+
signature: "(position: ControlPosition, hasControlsAtPosition: boolean) => string",
|
|
17737
|
+
description: "Compute position classes for a control, with optional offset for MapLibre controls"
|
|
17738
|
+
},
|
|
17739
|
+
{
|
|
17740
|
+
name: "computeVerticalOffsetStyle",
|
|
17741
|
+
signature: "(position: ControlPosition, customControlOffset: number, baseOffset?: number) => Record<string, string>",
|
|
17742
|
+
description: "Compute vertical offset style for stacking multiple custom controls"
|
|
17743
|
+
}
|
|
17744
|
+
]
|
|
17745
|
+
},
|
|
17746
|
+
cluster: {
|
|
17747
|
+
description: "Cluster utilities for MapLibre GL clustering",
|
|
17748
|
+
functions: [
|
|
17749
|
+
{
|
|
17750
|
+
name: "isClusterFeature",
|
|
17751
|
+
signature: "(feature: { properties?: Record<string, unknown> | null }) => boolean",
|
|
17752
|
+
description: "Type guard to check if a feature is a cluster (has cluster_id and point_count)"
|
|
17753
|
+
},
|
|
17754
|
+
{
|
|
17755
|
+
name: "getClusterExpansionZoom",
|
|
17756
|
+
signature: "(map: Map, sourceId: string, clusterId: number) => Promise<number>",
|
|
17757
|
+
description: "Get the zoom level needed to expand a cluster"
|
|
17758
|
+
},
|
|
17759
|
+
{
|
|
17760
|
+
name: "getClusterChildren",
|
|
17761
|
+
signature: "(map: Map, sourceId: string, clusterId: number) => Promise<GeoJSONFeature[]>",
|
|
17762
|
+
description: "Get the immediate children features of a cluster"
|
|
17763
|
+
},
|
|
17764
|
+
{
|
|
17765
|
+
name: "getClusterLeaves",
|
|
17766
|
+
signature: "(map: Map, sourceId: string, clusterId: number, limit?: number, offset?: number) => Promise<GeoJSONFeature[]>",
|
|
17767
|
+
description: "Get all leaf features (individual points) of a cluster"
|
|
17768
|
+
},
|
|
17769
|
+
{
|
|
17770
|
+
name: "expandCluster",
|
|
17771
|
+
signature: "(map: Map, sourceId: string, clusterId: number, center: LngLat, options?: ClusterExpandOptions) => Promise<void>",
|
|
17772
|
+
description: "Expand a cluster by zooming in to show its contents (main utility for click-to-expand)"
|
|
17773
|
+
},
|
|
17774
|
+
{
|
|
17775
|
+
name: "getClusterBounds",
|
|
17776
|
+
signature: "(map: Map, sourceId: string, clusterId: number, limit?: number) => Promise<BoundsArray>",
|
|
17777
|
+
description: "Calculate bounds that encompass all leaves of a cluster"
|
|
17778
|
+
},
|
|
17779
|
+
{
|
|
17780
|
+
name: "expandClusterToBounds",
|
|
17781
|
+
signature: "(map: Map, sourceId: string, clusterId: number, options?: ClusterExpandOptions) => Promise<void>",
|
|
17782
|
+
description: "Expand a cluster by fitting to the bounds of its leaves (alternative to expandCluster)"
|
|
17783
|
+
}
|
|
17784
|
+
]
|
|
17785
|
+
},
|
|
17786
|
+
lotStyles: {
|
|
17787
|
+
description: "Specialized style utilities for polygon lot visualizations",
|
|
17788
|
+
functions: [
|
|
17789
|
+
{
|
|
17790
|
+
name: "createLotFillStyle",
|
|
17791
|
+
signature: "(options: LotFillStyleOptions) => { paint: Record<string, unknown> }",
|
|
17792
|
+
description: "Create fill style for lot polygons with status-based coloring and hover/selection states"
|
|
17793
|
+
},
|
|
17794
|
+
{
|
|
17795
|
+
name: "createLotOutlineStyle",
|
|
17796
|
+
signature: "(options: LotOutlineStyleOptions) => { paint: Record<string, unknown>; layout: Record<string, unknown> }",
|
|
17797
|
+
description: "Create outline style for lot polygons with zoom-based width scaling"
|
|
17798
|
+
},
|
|
17799
|
+
{
|
|
17800
|
+
name: "createExtrusionHeightExpression",
|
|
17801
|
+
signature: "(options: ExtrusionHeightOptions) => unknown[]",
|
|
17802
|
+
description: "Create MapLibre expression for 3D lot extrusion heights based on property values"
|
|
17803
|
+
},
|
|
17804
|
+
{
|
|
17805
|
+
name: "createStatusColorExpression",
|
|
17806
|
+
signature: "(property: string, colorMap: Record<string, string>, defaultColor: string) => unknown[]",
|
|
17807
|
+
description: "Create data-driven color expression based on lot status property"
|
|
17808
|
+
},
|
|
17809
|
+
{
|
|
17810
|
+
name: "createInteractiveStatusColorExpression",
|
|
17811
|
+
signature: "(property: string, colorMap: Record<string, string>, hoverColor: string, selectedColor: string, defaultColor: string) => unknown[]",
|
|
17812
|
+
description: "Create combined status color expression with hover and selection states using feature-state"
|
|
17813
|
+
}
|
|
17814
|
+
]
|
|
17815
|
+
},
|
|
17816
|
+
lod: {
|
|
17817
|
+
description: "Level-of-Detail utilities for performance optimization with large datasets",
|
|
17818
|
+
functions: [
|
|
17819
|
+
{
|
|
17820
|
+
name: "groupFeaturesByProperty",
|
|
17821
|
+
signature: "(data: GeoJSONFeatureCollection, options: GroupFeaturesOptions) => FeatureGroup[]",
|
|
17822
|
+
description: "Group features by a property value for LOD aggregation"
|
|
17823
|
+
},
|
|
17824
|
+
{
|
|
17825
|
+
name: "generateConvexHull",
|
|
17826
|
+
signature: "(features: GeoJSONFeature[]) => GeoJSONFeature | null",
|
|
17827
|
+
description: "Generate a convex hull polygon from a set of features"
|
|
17828
|
+
},
|
|
17829
|
+
{
|
|
17830
|
+
name: "generateBoundingPolygon",
|
|
17831
|
+
signature: "(features: GeoJSONFeature[]) => GeoJSONFeature | null",
|
|
17832
|
+
description: "Generate a bounding box polygon from a set of features"
|
|
17833
|
+
},
|
|
17834
|
+
{
|
|
17835
|
+
name: "boundsToPolygon",
|
|
17836
|
+
signature: "(bounds: BoundsArray) => GeoJSONFeature",
|
|
17837
|
+
description: "Convert bounds array to a polygon feature"
|
|
17838
|
+
},
|
|
17839
|
+
{
|
|
17840
|
+
name: "generateLODData",
|
|
17841
|
+
signature: "(data: GeoJSONFeatureCollection, options: GenerateLODOptions) => LODData",
|
|
17842
|
+
description: "Generate multi-level LOD data with aggregated representations at different zoom levels"
|
|
17843
|
+
},
|
|
17844
|
+
{
|
|
17845
|
+
name: "calculateZoomThresholds",
|
|
17846
|
+
signature: "(featureCount: number, minZoom?: number, maxZoom?: number) => number[]",
|
|
17847
|
+
description: "Calculate optimal zoom thresholds based on feature count"
|
|
17848
|
+
},
|
|
17849
|
+
{
|
|
17850
|
+
name: "simplifyPolygon",
|
|
17851
|
+
signature: "(coordinates: number[][][], tolerance: number) => number[][][]",
|
|
17852
|
+
description: "Simplify polygon coordinates using Douglas-Peucker algorithm"
|
|
17853
|
+
},
|
|
17854
|
+
{
|
|
17855
|
+
name: "simplifyFeature",
|
|
17856
|
+
signature: "(feature: GeoJSONFeature, tolerance: number) => GeoJSONFeature",
|
|
17857
|
+
description: "Simplify a single feature's geometry"
|
|
17858
|
+
},
|
|
17859
|
+
{
|
|
17860
|
+
name: "simplifyFeatureCollection",
|
|
17861
|
+
signature: "(data: GeoJSONFeatureCollection, tolerance: number) => GeoJSONFeatureCollection",
|
|
17862
|
+
description: "Simplify all features in a collection"
|
|
17863
|
+
},
|
|
17864
|
+
{
|
|
17865
|
+
name: "simplifyFeatureCollectionWithStats",
|
|
17866
|
+
signature: "(data: GeoJSONFeatureCollection, tolerance: number) => { data: GeoJSONFeatureCollection; stats: SimplificationStats }",
|
|
17867
|
+
description: "Simplify collection and return statistics (point reduction, time)"
|
|
17868
|
+
},
|
|
17869
|
+
{
|
|
17870
|
+
name: "generateLODDataWithSimplification",
|
|
17871
|
+
signature: "(data: GeoJSONFeatureCollection, options: GenerateLODOptions & { simplificationThresholds?: SimplificationThreshold[] }) => LODDataWithSimplification",
|
|
17872
|
+
description: "Generate LOD data with automatic polygon simplification at each level"
|
|
17873
|
+
},
|
|
17874
|
+
{
|
|
17875
|
+
name: "getSimplifiedFeaturesForZoom",
|
|
17876
|
+
signature: "(lodData: LODDataWithSimplification, zoom: number) => GeoJSONFeatureCollection",
|
|
17877
|
+
description: "Get the appropriate simplified features for a given zoom level"
|
|
17878
|
+
},
|
|
17879
|
+
{
|
|
17880
|
+
name: "createDynamicLODManager",
|
|
17881
|
+
signature: "(data: GeoJSONFeatureCollection, options?: DynamicLODOptions) => DynamicLODState",
|
|
17882
|
+
description: "Create a manager for dynamic LOD switching based on zoom and performance"
|
|
17883
|
+
},
|
|
17884
|
+
{
|
|
17885
|
+
name: "getSimplificationToleranceForZoom",
|
|
17886
|
+
signature: "(zoom: number, thresholds?: SimplificationThreshold[]) => number",
|
|
17887
|
+
description: "Get appropriate simplification tolerance for a zoom level"
|
|
17888
|
+
},
|
|
17889
|
+
{
|
|
17890
|
+
name: "DEFAULT_SIMPLIFICATION_THRESHOLDS",
|
|
17891
|
+
signature: "SimplificationThreshold[]",
|
|
17892
|
+
description: "Default zoom-based simplification thresholds"
|
|
17893
|
+
}
|
|
17894
|
+
]
|
|
17895
|
+
},
|
|
17896
|
+
spatial: {
|
|
17897
|
+
description: "Spatial indexing utilities for efficient viewport queries on large datasets",
|
|
17898
|
+
functions: [
|
|
17899
|
+
{
|
|
17900
|
+
name: "buildSpatialIndex",
|
|
17901
|
+
signature: "(data: GeoJSONFeatureCollection, options?: BuildSpatialIndexOptions) => SpatialIndex",
|
|
17902
|
+
description: "Build a grid-based spatial index for fast viewport queries"
|
|
17903
|
+
},
|
|
17904
|
+
{
|
|
17905
|
+
name: "queryByBounds",
|
|
17906
|
+
signature: "(index: SpatialIndex, bounds: BoundsArray, options?: QuerySpatialIndexOptions) => GeoJSONFeatureCollection",
|
|
17907
|
+
description: "Query features within bounds from a spatial index"
|
|
17908
|
+
},
|
|
17909
|
+
{
|
|
17910
|
+
name: "queryByBoundsWithStats",
|
|
17911
|
+
signature: "(index: SpatialIndex, bounds: BoundsArray, options?: QuerySpatialIndexOptions) => { data: GeoJSONFeatureCollection; stats: QueryStats }",
|
|
17912
|
+
description: "Query features with performance statistics (cells checked, culled percentage)"
|
|
17913
|
+
},
|
|
17914
|
+
{
|
|
17915
|
+
name: "createViewportQuery",
|
|
17916
|
+
signature: "(index: SpatialIndex) => (bounds: BoundsArray) => GeoJSONFeatureCollection",
|
|
17917
|
+
description: "Create a reusable viewport query function"
|
|
17918
|
+
},
|
|
17919
|
+
{
|
|
17920
|
+
name: "createViewportManager",
|
|
17921
|
+
signature: "(data: GeoJSONFeatureCollection, options?: ViewportManagedDataOptions) => ViewportManagedResult",
|
|
17922
|
+
description: "Create a managed viewport system that automatically updates on map move"
|
|
17923
|
+
},
|
|
17924
|
+
{
|
|
17925
|
+
name: "buildRTreeIndex",
|
|
17926
|
+
signature: "(data: GeoJSONFeatureCollection, options?: BuildRTreeIndexOptions) => RTreeIndex",
|
|
17927
|
+
description: "Build an R-tree spatial index (better for clustered/overlapping data)"
|
|
17928
|
+
},
|
|
17929
|
+
{
|
|
17930
|
+
name: "queryRTreeByBounds",
|
|
17931
|
+
signature: "(index: RTreeIndex, bounds: BoundsArray, options?: QuerySpatialIndexOptions) => GeoJSONFeatureCollection",
|
|
17932
|
+
description: "Query features within bounds from an R-tree index"
|
|
17933
|
+
},
|
|
17934
|
+
{
|
|
17935
|
+
name: "queryRTreeByBoundsWithStats",
|
|
17936
|
+
signature: "(index: RTreeIndex, bounds: BoundsArray, options?: QuerySpatialIndexOptions) => { data: GeoJSONFeatureCollection; stats: RTreeQueryStats }",
|
|
17937
|
+
description: "Query R-tree with performance statistics"
|
|
17938
|
+
},
|
|
17939
|
+
{
|
|
17940
|
+
name: "createRTreeViewportManager",
|
|
17941
|
+
signature: "(data: GeoJSONFeatureCollection, options?: ViewportManagedDataOptions) => ViewportManagedResult",
|
|
17942
|
+
description: "Create a managed viewport system using R-tree index"
|
|
17943
|
+
},
|
|
17944
|
+
{
|
|
17945
|
+
name: "createPredictiveViewportManager",
|
|
17946
|
+
signature: "(data: GeoJSONFeatureCollection, options?: ViewportManagedDataOptions) => PredictiveViewportResult",
|
|
17947
|
+
description: "Create viewport manager with predictive pan loading to eliminate pop-in"
|
|
17948
|
+
},
|
|
17949
|
+
{
|
|
17950
|
+
name: "createIdleViewportManager",
|
|
17951
|
+
signature: "(data: GeoJSONFeatureCollection, options?: IdleViewportManagerOptions) => IdleViewportResult",
|
|
17952
|
+
description: "Create viewport manager that defers updates to idle time for smooth panning"
|
|
17953
|
+
}
|
|
17954
|
+
]
|
|
17955
|
+
},
|
|
17956
|
+
fingerprint: {
|
|
17957
|
+
description: "Fast O(1) GeoJSON equality checking via fingerprinting",
|
|
17958
|
+
functions: [
|
|
17959
|
+
{
|
|
17960
|
+
name: "createGeoJSONFingerprint",
|
|
17961
|
+
signature: "(data: GeoJSONFeatureCollection | GeoJSON.GeoJSON | string | null | undefined) => GeoJSONFingerprint",
|
|
17962
|
+
description: "Create a lightweight fingerprint for fast equality comparison without deep comparison"
|
|
17963
|
+
},
|
|
17964
|
+
{
|
|
17965
|
+
name: "fingerprintEqual",
|
|
17966
|
+
signature: "(a: GeoJSONFingerprint | null, b: GeoJSONFingerprint | null) => boolean",
|
|
17967
|
+
description: "Compare two fingerprints for equality"
|
|
17968
|
+
},
|
|
17969
|
+
{
|
|
17970
|
+
name: "geoJSONEqual",
|
|
17971
|
+
signature: "(a: GeoJSONFeatureCollection | null | undefined, b: GeoJSONFeatureCollection | null | undefined) => boolean",
|
|
17972
|
+
description: "Check if two GeoJSON collections are equal using fingerprinting"
|
|
17973
|
+
}
|
|
17974
|
+
]
|
|
17975
|
+
},
|
|
17976
|
+
equality: {
|
|
17977
|
+
description: "Deep equality and delta detection utilities for efficient updates",
|
|
17978
|
+
functions: [
|
|
17979
|
+
{
|
|
17980
|
+
name: "deepEqual",
|
|
17981
|
+
signature: "(a: unknown, b: unknown) => boolean",
|
|
17982
|
+
description: "Deep equality comparison optimized for MapLibre expressions and style objects"
|
|
17983
|
+
},
|
|
17984
|
+
{
|
|
17985
|
+
name: "paintPropsEqual",
|
|
17986
|
+
signature: "(a: PaintProps | undefined, b: PaintProps | undefined) => boolean",
|
|
17987
|
+
description: "Check if two paint property objects are equal"
|
|
17988
|
+
},
|
|
17989
|
+
{
|
|
17990
|
+
name: "getChangedPaintProps",
|
|
17991
|
+
signature: "(oldProps: PaintProps | undefined, newProps: PaintProps | undefined) => PaintPropsDiff",
|
|
17992
|
+
description: "Get only the changed paint properties (for efficient MapLibre updates)"
|
|
17993
|
+
},
|
|
17994
|
+
{
|
|
17995
|
+
name: "filterEqual",
|
|
17996
|
+
signature: "(a: FilterExpression | undefined, b: FilterExpression | undefined) => boolean",
|
|
17997
|
+
description: "Check if two filter expressions are equal"
|
|
17998
|
+
},
|
|
17999
|
+
{
|
|
18000
|
+
name: "serializeFilter",
|
|
18001
|
+
signature: "(filter: FilterExpression | undefined) => string",
|
|
18002
|
+
description: "Serialize a filter expression for comparison"
|
|
18003
|
+
}
|
|
18004
|
+
]
|
|
18005
|
+
}
|
|
18006
|
+
}
|
|
18007
|
+
},
|
|
18008
|
+
workers: {
|
|
18009
|
+
importPath: "@classic-homes/maps-core/workers",
|
|
18010
|
+
description: "Web Worker infrastructure for off-main-thread spatial processing",
|
|
18011
|
+
modules: {
|
|
18012
|
+
client: {
|
|
18013
|
+
description: "Client API for communicating with spatial workers",
|
|
18014
|
+
functions: [
|
|
18015
|
+
{
|
|
18016
|
+
name: "SpatialWorkerClient",
|
|
18017
|
+
signature: "class",
|
|
18018
|
+
description: "Client class for interacting with the spatial worker. Handles worker lifecycle, request tracking, and graceful degradation."
|
|
18019
|
+
},
|
|
18020
|
+
{
|
|
18021
|
+
name: "createSpatialWorkerClient",
|
|
18022
|
+
signature: "(options?: SpatialWorkerClientOptions) => SpatialWorkerClient",
|
|
18023
|
+
description: "Factory function to create a spatial worker client"
|
|
18024
|
+
}
|
|
18025
|
+
],
|
|
18026
|
+
example: "// Vite setup\nimport SpatialWorker from '@classic-homes/maps-core/workers/spatial.worker?worker';\nconst client = createSpatialWorkerClient({\n workerFactory: () => new SpatialWorker(),\n useRTree: true,\n});\n\nawait client.initialize(geojsonData);\nconst result = await client.query(viewportBounds);\nclient.terminate();"
|
|
18027
|
+
}
|
|
18028
|
+
}
|
|
18029
|
+
},
|
|
18030
|
+
theme: {
|
|
18031
|
+
importPath: "@classic-homes/maps-core/theme",
|
|
18032
|
+
description: "Theme exports only (for tree-shaking)"
|
|
18033
|
+
},
|
|
18034
|
+
types: {
|
|
18035
|
+
importPath: "@classic-homes/maps-core/types",
|
|
18036
|
+
description: "TypeScript type definitions only"
|
|
18037
|
+
}
|
|
18038
|
+
},
|
|
18039
|
+
types: {
|
|
18040
|
+
props: {
|
|
18041
|
+
description: "Component prop types",
|
|
18042
|
+
types: [
|
|
18043
|
+
{
|
|
18044
|
+
name: "BaseMapProps",
|
|
18045
|
+
description: "Base props shared by all map components",
|
|
18046
|
+
properties: [
|
|
18047
|
+
{ name: "title", type: "string", required: true, description: "Accessible title for the map (aria-label)" },
|
|
18048
|
+
{ name: "description", type: "string", required: false, description: "Optional description for screen readers" },
|
|
18049
|
+
{ name: "width", type: "number | string", required: false, description: "Map width (CSS value or pixels)" },
|
|
18050
|
+
{ name: "height", type: "number | string", required: false, description: "Map height (default: 400)" },
|
|
18051
|
+
{ name: "minHeight", type: "number", required: false, description: "Minimum height constraint" },
|
|
18052
|
+
{ name: "maxHeight", type: "number", required: false, description: "Maximum height constraint" },
|
|
18053
|
+
{ name: "loading", type: "boolean", required: false, description: "Show loading skeleton" },
|
|
18054
|
+
{ name: "error", type: "string | null", required: false, description: "Error message to display" },
|
|
18055
|
+
{ name: "emptyMessage", type: "string", required: false, description: "Message when no data/features" },
|
|
18056
|
+
{ name: "theme", type: "'light' | 'dark' | 'auto'", required: false, description: "Theme preference" },
|
|
18057
|
+
{ name: "animation", type: "boolean", required: false, description: "Enable animations (respects prefers-reduced-motion)" },
|
|
18058
|
+
{ name: "class", type: "string", required: false, description: "Custom CSS class" }
|
|
18059
|
+
]
|
|
18060
|
+
},
|
|
18061
|
+
{
|
|
18062
|
+
name: "MapProps",
|
|
18063
|
+
description: "Full map component props (extends BaseMapProps)",
|
|
18064
|
+
properties: [
|
|
18065
|
+
{ name: "style", type: "string | MapStyleSpec", required: false, description: "Map style URL or style spec object" },
|
|
18066
|
+
{ name: "center", type: "[number, number]", required: false, description: "Initial center [lng, lat]" },
|
|
18067
|
+
{ name: "zoom", type: "number", required: false, description: "Initial zoom level (0-24)" },
|
|
18068
|
+
{ name: "bearing", type: "number", required: false, description: "Initial bearing in degrees" },
|
|
18069
|
+
{ name: "pitch", type: "number", required: false, description: "Initial pitch/tilt in degrees" },
|
|
18070
|
+
{ name: "bounds", type: "[[number, number], [number, number]]", required: false, description: "Fit to bounds on load" },
|
|
18071
|
+
{ name: "boundsPadding", type: "number | { top, right, bottom, left }", required: false, description: "Padding when fitting to bounds" },
|
|
18072
|
+
{ name: "minZoom", type: "number", required: false, description: "Minimum zoom level" },
|
|
18073
|
+
{ name: "maxZoom", type: "number", required: false, description: "Maximum zoom level" },
|
|
18074
|
+
{ name: "maxBounds", type: "BoundsArray", required: false, description: "Maximum bounds the map can pan to" },
|
|
18075
|
+
{ name: "interactive", type: "boolean", required: false, description: "Enable map interactions" },
|
|
18076
|
+
{ name: "scrollZoom", type: "boolean", required: false, description: "Enable scroll zoom" },
|
|
18077
|
+
{ name: "dragPan", type: "boolean", required: false, description: "Enable drag pan" },
|
|
18078
|
+
{ name: "dragRotate", type: "boolean", required: false, description: "Enable drag rotate" },
|
|
18079
|
+
{ name: "doubleClickZoom", type: "boolean", required: false, description: "Enable double click zoom" },
|
|
18080
|
+
{ name: "touchZoomRotate", type: "boolean", required: false, description: "Enable touch zoom/rotate" },
|
|
18081
|
+
{ name: "keyboard", type: "boolean", required: false, description: "Enable keyboard navigation" },
|
|
18082
|
+
{ name: "navigationControl", type: "boolean", required: false, description: "Show navigation control" },
|
|
18083
|
+
{ name: "navigationControlPosition", type: "ControlPosition", required: false, description: "Navigation control position" },
|
|
18084
|
+
{ name: "scaleControl", type: "boolean", required: false, description: "Show scale control" },
|
|
18085
|
+
{ name: "scaleControlPosition", type: "ControlPosition", required: false, description: "Scale control position" },
|
|
18086
|
+
{ name: "fullscreenControl", type: "boolean", required: false, description: "Show fullscreen control" },
|
|
18087
|
+
{ name: "geolocateControl", type: "boolean", required: false, description: "Show geolocate control" },
|
|
18088
|
+
{ name: "onLoad", type: "(params: MapLoadEventParams) => void", required: false, description: "Callback when map loads" },
|
|
18089
|
+
{ name: "onClick", type: "(params: MapClickEventParams) => void", required: false, description: "Callback for map click" },
|
|
18090
|
+
{ name: "onMove", type: "(params: MapMoveEventParams) => void", required: false, description: "Callback for map move/pan" },
|
|
18091
|
+
{ name: "onZoom", type: "(params: MapMoveEventParams) => void", required: false, description: "Callback for zoom change" },
|
|
18092
|
+
{ name: "onError", type: "(params: MapErrorEventParams) => void", required: false, description: "Callback for map errors" }
|
|
18093
|
+
]
|
|
18094
|
+
},
|
|
18095
|
+
{
|
|
18096
|
+
name: "SourceProps",
|
|
18097
|
+
description: "Props for GeoJSON/vector/raster data sources",
|
|
18098
|
+
properties: [
|
|
18099
|
+
{ name: "id", type: "string", required: true, description: "Unique source ID" },
|
|
18100
|
+
{ name: "type", type: "'geojson' | 'vector' | 'raster' | 'raster-dem' | 'image' | 'video'", required: true, description: "Source type" },
|
|
18101
|
+
{ name: "data", type: "GeoJSONFeatureCollection | string", required: false, description: "Source data (for GeoJSON sources)" },
|
|
18102
|
+
{ name: "tiles", type: "string[]", required: false, description: "Tile URL template (for vector/raster)" },
|
|
18103
|
+
{ name: "url", type: "string", required: false, description: "TileJSON URL" },
|
|
18104
|
+
{ name: "tileSize", type: "number", required: false, description: "Tile size (default: 512)" },
|
|
18105
|
+
{ name: "attribution", type: "string", required: false, description: "Attribution text" },
|
|
18106
|
+
{ name: "cluster", type: "boolean | ClusterConfig", required: false, description: "Enable clustering (GeoJSON only)" },
|
|
18107
|
+
{ name: "clusterRadius", type: "number", required: false, description: "Cluster radius (GeoJSON only)" },
|
|
18108
|
+
{ name: "clusterMaxZoom", type: "number", required: false, description: "Max zoom for clustering" },
|
|
18109
|
+
{ name: "generateId", type: "boolean", required: false, description: "Generate feature IDs" },
|
|
18110
|
+
{ name: "fitBounds", type: "boolean", required: false, description: "Fit map to source bounds when loaded" },
|
|
18111
|
+
{ name: "fitBoundsPadding", type: "number | { top, right, bottom, left }", required: false, description: "Padding when fitting" },
|
|
18112
|
+
{ name: "fitBoundsMaxZoom", type: "number", required: false, description: "Max zoom when fitting" }
|
|
18113
|
+
]
|
|
18114
|
+
},
|
|
18115
|
+
{
|
|
18116
|
+
name: "MarkerProps",
|
|
18117
|
+
description: "Props for map markers. NOTE: DOM-based markers (maplibregl.Marker) are susceptible to CSS framework interference that can cause visual sliding during map pan/rotate operations. For production use cases requiring markers, consider using SymbolLayer instead, which renders on the GPU canvas and is immune to CSS interference.",
|
|
18118
|
+
properties: [
|
|
18119
|
+
{ name: "id", type: "string", required: false, description: "Unique marker ID" },
|
|
18120
|
+
{ name: "coordinates", type: "[number, number]", required: true, description: "Marker position [lng, lat]" },
|
|
18121
|
+
{ name: "color", type: "string", required: false, description: "Marker color" },
|
|
18122
|
+
{ name: "anchor", type: "'center' | 'top' | 'bottom' | 'left' | 'right' | ...", required: false, description: "Custom anchor point" },
|
|
18123
|
+
{ name: "offset", type: "[number, number]", required: false, description: "Offset from coordinates in pixels" },
|
|
18124
|
+
{ name: "rotation", type: "number", required: false, description: "Marker rotation angle" },
|
|
18125
|
+
{ name: "draggable", type: "boolean", required: false, description: "Enable dragging" },
|
|
18126
|
+
{ name: "scale", type: "number", required: false, description: "Marker scale" },
|
|
18127
|
+
{ name: "onClick", type: "(params: MarkerClickEventParams) => void", required: false, description: "Callback for marker click" },
|
|
18128
|
+
{ name: "onDrag", type: "(params: MarkerDragEventParams) => void", required: false, description: "Callback for marker drag" },
|
|
18129
|
+
{ name: "onDragEnd", type: "(params: MarkerDragEventParams) => void", required: false, description: "Callback when drag ends" }
|
|
18130
|
+
]
|
|
18131
|
+
},
|
|
18132
|
+
{
|
|
18133
|
+
name: "PopupProps",
|
|
18134
|
+
description: "Props for map popups",
|
|
18135
|
+
properties: [
|
|
18136
|
+
{ name: "coordinates", type: "[number, number]", required: true, description: "Popup position [lng, lat]" },
|
|
18137
|
+
{ name: "closeButton", type: "boolean", required: false, description: "Show close button (default: true)" },
|
|
18138
|
+
{ name: "closeOnClick", type: "boolean", required: false, description: "Close on click outside (default: true)" },
|
|
18139
|
+
{ name: "closeOnMove", type: "boolean", required: false, description: "Close when map moves" },
|
|
18140
|
+
{ name: "anchor", type: "'center' | 'top' | 'bottom' | 'left' | 'right' | ...", required: false, description: "Popup anchor" },
|
|
18141
|
+
{ name: "offset", type: "number | [number, number]", required: false, description: "Popup offset" },
|
|
18142
|
+
{ name: "maxWidth", type: "string", required: false, description: "Maximum width (default: '300px')" },
|
|
18143
|
+
{ name: "focusAfterOpen", type: "boolean", required: false, description: "Focus popup when opened" },
|
|
18144
|
+
{ name: "autoPan", type: "boolean", required: false, description: "Auto-pan to ensure popup is visible (default: true)" },
|
|
18145
|
+
{ name: "autoPanPadding", type: "number | { top, right, bottom, left }", required: false, description: "Padding around popup when auto-panning" },
|
|
18146
|
+
{ name: "onOpen", type: "(params: PopupEventParams) => void", required: false, description: "Callback when popup opens" },
|
|
18147
|
+
{ name: "onClose", type: "(params: PopupEventParams) => void", required: false, description: "Callback when popup closes" }
|
|
18148
|
+
]
|
|
18149
|
+
},
|
|
18150
|
+
{
|
|
18151
|
+
name: "BaseLayerProps",
|
|
18152
|
+
description: "Base props shared by all layer components",
|
|
18153
|
+
properties: [
|
|
18154
|
+
{ name: "id", type: "string", required: true, description: "Unique layer ID" },
|
|
18155
|
+
{ name: "source", type: "string", required: true, description: "Source ID this layer uses" },
|
|
18156
|
+
{ name: "sourceLayer", type: "string", required: false, description: "Source layer (for vector tile sources)" },
|
|
18157
|
+
{ name: "visible", type: "boolean", required: false, description: "Layer visibility" },
|
|
18158
|
+
{ name: "opacity", type: "number", required: false, description: "Layer opacity (0-1)" },
|
|
18159
|
+
{ name: "minZoom", type: "number", required: false, description: "Minimum zoom level" },
|
|
18160
|
+
{ name: "maxZoom", type: "number", required: false, description: "Maximum zoom level" },
|
|
18161
|
+
{ name: "filter", type: "unknown[]", required: false, description: "Filter expression for features" },
|
|
18162
|
+
{ name: "beforeId", type: "string", required: false, description: "Insert layer before another" },
|
|
18163
|
+
{ name: "onClick", type: "(params: FeatureClickEventParams) => void", required: false, description: "Callback for feature click" },
|
|
18164
|
+
{ name: "onHover", type: "(params: FeatureHoverEventParams) => void", required: false, description: "Callback for feature hover" }
|
|
18165
|
+
]
|
|
18166
|
+
},
|
|
18167
|
+
{
|
|
18168
|
+
name: "FillLayerProps",
|
|
18169
|
+
description: "Props for polygon fill layers (extends BaseLayerProps)",
|
|
18170
|
+
properties: [
|
|
18171
|
+
{ name: "fillColor", type: "string | Expression", required: false, description: "Fill color" },
|
|
18172
|
+
{ name: "fillOpacity", type: "number | Expression", required: false, description: "Fill opacity (0-1)" },
|
|
18173
|
+
{ name: "fillOutlineColor", type: "string | Expression", required: false, description: "Outline color" },
|
|
18174
|
+
{ name: "fillPattern", type: "string", required: false, description: "Fill pattern (sprite image name)" },
|
|
18175
|
+
{ name: "fillTranslate", type: "[number, number]", required: false, description: "Translate fill geometry" },
|
|
18176
|
+
{ name: "fillAntialias", type: "boolean", required: false, description: "Fill antialias" }
|
|
18177
|
+
]
|
|
18178
|
+
},
|
|
18179
|
+
{
|
|
18180
|
+
name: "LineLayerProps",
|
|
18181
|
+
description: "Props for line layers (extends BaseLayerProps)",
|
|
18182
|
+
properties: [
|
|
18183
|
+
{ name: "lineColor", type: "string | Expression", required: false, description: "Line color" },
|
|
18184
|
+
{ name: "lineWidth", type: "number | Expression", required: false, description: "Line width in pixels" },
|
|
18185
|
+
{ name: "lineOpacity", type: "number | Expression", required: false, description: "Line opacity (0-1)" },
|
|
18186
|
+
{ name: "lineCap", type: "'butt' | 'round' | 'square'", required: false, description: "Line cap style" },
|
|
18187
|
+
{ name: "lineJoin", type: "'bevel' | 'round' | 'miter'", required: false, description: "Line join style" },
|
|
18188
|
+
{ name: "lineDasharray", type: "number[]", required: false, description: "Dash pattern" },
|
|
18189
|
+
{ name: "lineGapWidth", type: "number", required: false, description: "Line gap width" },
|
|
18190
|
+
{ name: "lineOffset", type: "number", required: false, description: "Line offset" }
|
|
18191
|
+
]
|
|
18192
|
+
},
|
|
18193
|
+
{
|
|
18194
|
+
name: "CircleLayerProps",
|
|
18195
|
+
description: "Props for circle point layers (extends BaseLayerProps)",
|
|
18196
|
+
properties: [
|
|
18197
|
+
{ name: "circleRadius", type: "number | Expression", required: false, description: "Circle radius in pixels" },
|
|
18198
|
+
{ name: "circleColor", type: "string | Expression", required: false, description: "Circle color" },
|
|
18199
|
+
{ name: "circleOpacity", type: "number | Expression", required: false, description: "Circle opacity (0-1)" },
|
|
18200
|
+
{ name: "circleStrokeWidth", type: "number | Expression", required: false, description: "Stroke width" },
|
|
18201
|
+
{ name: "circleStrokeColor", type: "string | Expression", required: false, description: "Stroke color" },
|
|
18202
|
+
{ name: "circleBlur", type: "number", required: false, description: "Circle blur" },
|
|
18203
|
+
{ name: "circlePitchAlignment", type: "'map' | 'viewport'", required: false, description: "Pitch alignment" }
|
|
18204
|
+
]
|
|
18205
|
+
},
|
|
18206
|
+
{
|
|
18207
|
+
name: "SymbolLayerProps",
|
|
18208
|
+
description: "Props for symbol/label layers (extends BaseLayerProps)",
|
|
18209
|
+
properties: [
|
|
18210
|
+
{ name: "iconImage", type: "string | Expression", required: false, description: "Icon image name (from sprite)" },
|
|
18211
|
+
{ name: "iconSize", type: "number | Expression", required: false, description: "Icon size" },
|
|
18212
|
+
{ name: "iconRotate", type: "number | Expression", required: false, description: "Icon rotation angle" },
|
|
18213
|
+
{ name: "iconOffset", type: "[number, number]", required: false, description: "Icon offset" },
|
|
18214
|
+
{ name: "iconAnchor", type: "'center' | 'left' | 'right' | 'top' | 'bottom' | ...", required: false, description: "Icon anchor" },
|
|
18215
|
+
{ name: "iconAllowOverlap", type: "boolean", required: false, description: "Allow icon overlap" },
|
|
18216
|
+
{ name: "textField", type: "string | Expression", required: false, description: "Text field content" },
|
|
18217
|
+
{ name: "textFont", type: "string[]", required: false, description: "Text font stack" },
|
|
18218
|
+
{ name: "textSize", type: "number | Expression", required: false, description: "Text size" },
|
|
18219
|
+
{ name: "textColor", type: "string | Expression", required: false, description: "Text color" },
|
|
18220
|
+
{ name: "textHaloColor", type: "string", required: false, description: "Text halo color" },
|
|
18221
|
+
{ name: "textHaloWidth", type: "number", required: false, description: "Text halo width" },
|
|
18222
|
+
{ name: "textAnchor", type: "'center' | 'left' | 'right' | 'top' | 'bottom' | ...", required: false, description: "Text anchor" },
|
|
18223
|
+
{ name: "symbolPlacement", type: "'point' | 'line' | 'line-center'", required: false, description: "Symbol placement" }
|
|
18224
|
+
]
|
|
18225
|
+
},
|
|
18226
|
+
{
|
|
18227
|
+
name: "FillExtrusionLayerProps",
|
|
18228
|
+
description: "Props for 3D extrusion layers (extends BaseLayerProps)",
|
|
18229
|
+
properties: [
|
|
18230
|
+
{ name: "fillExtrusionHeight", type: "number | Expression", required: true, description: "Extrusion height in meters" },
|
|
18231
|
+
{ name: "fillExtrusionBase", type: "number | Expression", required: false, description: "Base height in meters" },
|
|
18232
|
+
{ name: "fillExtrusionColor", type: "string | Expression", required: false, description: "Extrusion color" },
|
|
18233
|
+
{ name: "fillExtrusionOpacity", type: "number", required: false, description: "Extrusion opacity (0-1)" },
|
|
18234
|
+
{ name: "fillExtrusionVerticalGradient", type: "boolean", required: false, description: "Enable vertical gradient" }
|
|
18235
|
+
]
|
|
18236
|
+
},
|
|
18237
|
+
{
|
|
18238
|
+
name: "HeatmapLayerProps",
|
|
18239
|
+
description: "Props for heatmap layers (extends BaseLayerProps)",
|
|
18240
|
+
properties: [
|
|
18241
|
+
{ name: "heatmapRadius", type: "number | Expression", required: false, description: "Heatmap radius in pixels" },
|
|
18242
|
+
{ name: "heatmapIntensity", type: "number | Expression", required: false, description: "Intensity multiplier" },
|
|
18243
|
+
{ name: "heatmapWeight", type: "number | Expression", required: false, description: "Weight per point" },
|
|
18244
|
+
{ name: "heatmapColor", type: "Expression", required: false, description: "Heatmap color ramp expression" },
|
|
18245
|
+
{ name: "heatmapOpacity", type: "number | Expression", required: false, description: "Heatmap opacity" }
|
|
18246
|
+
]
|
|
18247
|
+
},
|
|
18248
|
+
{
|
|
18249
|
+
name: "RasterLayerProps",
|
|
18250
|
+
description: "Props for raster/image layers (extends BaseLayerProps)",
|
|
18251
|
+
properties: [
|
|
18252
|
+
{ name: "rasterOpacity", type: "number", required: false, description: "Raster opacity (0-1)" },
|
|
18253
|
+
{ name: "rasterHueRotate", type: "number", required: false, description: "Hue rotation in degrees" },
|
|
18254
|
+
{ name: "rasterBrightnessMin", type: "number", required: false, description: "Minimum brightness (0-1)" },
|
|
18255
|
+
{ name: "rasterBrightnessMax", type: "number", required: false, description: "Maximum brightness (0-1)" },
|
|
18256
|
+
{ name: "rasterSaturation", type: "number", required: false, description: "Saturation adjustment (-1 to 1)" },
|
|
18257
|
+
{ name: "rasterContrast", type: "number", required: false, description: "Contrast adjustment (-1 to 1)" },
|
|
18258
|
+
{ name: "rasterResampling", type: "'linear' | 'nearest'", required: false, description: "Resampling method" },
|
|
18259
|
+
{ name: "rasterFadeDuration", type: "number", required: false, description: "Fade duration when tiles load (ms)" }
|
|
18260
|
+
]
|
|
18261
|
+
},
|
|
18262
|
+
{
|
|
18263
|
+
name: "LegendProps",
|
|
18264
|
+
description: "Props for map legend component",
|
|
18265
|
+
properties: [
|
|
18266
|
+
{ name: "title", type: "string", required: false, description: "Legend title" },
|
|
18267
|
+
{ name: "position", type: "ControlPosition", required: false, description: "Position on map" },
|
|
18268
|
+
{ name: "type", type: "'categorical' | 'gradient'", required: false, description: "Legend type" },
|
|
18269
|
+
{ name: "items", type: "LegendItem[]", required: false, description: "Items for categorical legends" },
|
|
18270
|
+
{ name: "gradient", type: "GradientStop[]", required: false, description: "Gradient stops for continuous legends" },
|
|
18271
|
+
{ name: "minLabel", type: "string", required: false, description: "Min value label for gradient" },
|
|
18272
|
+
{ name: "maxLabel", type: "string", required: false, description: "Max value label for gradient" },
|
|
18273
|
+
{ name: "collapsible", type: "boolean", required: false, description: "Whether legend is collapsible" },
|
|
18274
|
+
{ name: "collapsed", type: "boolean", required: false, description: "Whether initially collapsed" },
|
|
18275
|
+
{ name: "onItemClick", type: "(item: LegendItem, index: number) => void", required: false, description: "Callback for item click" }
|
|
18276
|
+
]
|
|
18277
|
+
},
|
|
18278
|
+
{
|
|
18279
|
+
name: "LegendGroupProps",
|
|
18280
|
+
description: "Props for accordion-style legend container",
|
|
18281
|
+
properties: [
|
|
18282
|
+
{ name: "legends", type: "LegendConfig[]", required: true, description: "Array of legend configurations" },
|
|
18283
|
+
{ name: "position", type: "ControlPosition", required: false, description: "Position on map" },
|
|
18284
|
+
{ name: "defaultExpanded", type: "string", required: false, description: "ID of initially expanded legend" },
|
|
18285
|
+
{ name: "expanded", type: "string | null", required: false, description: "Controlled expanded state" },
|
|
18286
|
+
{ name: "onExpandedChange", type: "(id: string | null) => void", required: false, description: "Callback when expanded changes" },
|
|
18287
|
+
{ name: "allowCollapseAll", type: "boolean", required: false, description: "Allow collapsing all (default: false)" }
|
|
18288
|
+
]
|
|
18289
|
+
},
|
|
18290
|
+
{
|
|
18291
|
+
name: "CoordinateDisplayProps",
|
|
18292
|
+
description: "Props for coordinate display control",
|
|
18293
|
+
properties: [
|
|
18294
|
+
{ name: "position", type: "ControlPosition", required: false, description: "Position on map" },
|
|
18295
|
+
{ name: "format", type: "'decimal' | 'dms' | 'dd'", required: false, description: "Coordinate format" },
|
|
18296
|
+
{ name: "precision", type: "number", required: false, description: "Decimal places" },
|
|
18297
|
+
{ name: "showZoom", type: "boolean", required: false, description: "Show zoom level" },
|
|
18298
|
+
{ name: "showBearing", type: "boolean", required: false, description: "Show bearing" }
|
|
18299
|
+
]
|
|
18300
|
+
},
|
|
18301
|
+
{
|
|
18302
|
+
name: "NavigationControlProps",
|
|
18303
|
+
description: "Props for navigation control",
|
|
18304
|
+
properties: [
|
|
18305
|
+
{ name: "position", type: "ControlPosition", required: false, description: "Position on map" },
|
|
18306
|
+
{ name: "showCompass", type: "boolean", required: false, description: "Show compass" },
|
|
18307
|
+
{ name: "showZoom", type: "boolean", required: false, description: "Show zoom buttons" },
|
|
18308
|
+
{ name: "visualizePitch", type: "boolean", required: false, description: "Visualize pitch with compass" }
|
|
18309
|
+
]
|
|
18310
|
+
},
|
|
18311
|
+
{
|
|
18312
|
+
name: "ScaleControlProps",
|
|
18313
|
+
description: "Props for scale control",
|
|
18314
|
+
properties: [
|
|
18315
|
+
{ name: "position", type: "ControlPosition", required: false, description: "Position on map" },
|
|
18316
|
+
{ name: "maxWidth", type: "number", required: false, description: "Maximum width of scale" },
|
|
18317
|
+
{ name: "unit", type: "'imperial' | 'metric' | 'nautical'", required: false, description: "Unit system" }
|
|
18318
|
+
]
|
|
18319
|
+
},
|
|
18320
|
+
{
|
|
18321
|
+
name: "GeolocateControlProps",
|
|
18322
|
+
description: "Props for geolocate control",
|
|
18323
|
+
properties: [
|
|
18324
|
+
{ name: "position", type: "ControlPosition", required: false, description: "Position on map" },
|
|
18325
|
+
{ name: "trackUserLocation", type: "boolean", required: false, description: "Track user location" },
|
|
18326
|
+
{ name: "showAccuracyCircle", type: "boolean", required: false, description: "Show accuracy circle" },
|
|
18327
|
+
{ name: "showUserHeading", type: "boolean", required: false, description: "Show user heading" }
|
|
18328
|
+
]
|
|
18329
|
+
}
|
|
18330
|
+
]
|
|
18331
|
+
},
|
|
18332
|
+
data: {
|
|
18333
|
+
description: "Data structure types",
|
|
18334
|
+
types: [
|
|
18335
|
+
{
|
|
18336
|
+
name: "LngLat",
|
|
18337
|
+
description: "Longitude/latitude coordinate pair as [lng, lat] tuple"
|
|
18338
|
+
},
|
|
18339
|
+
{
|
|
18340
|
+
name: "MapBounds",
|
|
18341
|
+
description: "Geographic bounding box with southwest and northeast corners",
|
|
18342
|
+
properties: [
|
|
18343
|
+
{ name: "southwest", type: "LngLat", required: true, description: "Southwest corner" },
|
|
18344
|
+
{ name: "northeast", type: "LngLat", required: true, description: "Northeast corner" }
|
|
18345
|
+
]
|
|
18346
|
+
},
|
|
18347
|
+
{
|
|
18348
|
+
name: "BoundsArray",
|
|
18349
|
+
description: "Bounding box as [[sw_lng, sw_lat], [ne_lng, ne_lat]]"
|
|
18350
|
+
},
|
|
18351
|
+
{
|
|
18352
|
+
name: "MapViewport",
|
|
18353
|
+
description: "Map viewport state (center, zoom, bearing, pitch)"
|
|
18354
|
+
},
|
|
18355
|
+
{
|
|
18356
|
+
name: "GeoJSONFeature",
|
|
18357
|
+
description: "GeoJSON Feature with typed properties"
|
|
18358
|
+
},
|
|
18359
|
+
{
|
|
18360
|
+
name: "GeoJSONFeatureCollection",
|
|
18361
|
+
description: "GeoJSON FeatureCollection with typed features"
|
|
18362
|
+
},
|
|
18363
|
+
{
|
|
18364
|
+
name: "GeoJSONGeometry",
|
|
18365
|
+
description: "Union of all GeoJSON geometry types"
|
|
18366
|
+
},
|
|
18367
|
+
{
|
|
18368
|
+
name: "MarkerData",
|
|
18369
|
+
description: "Data for map markers",
|
|
18370
|
+
properties: [
|
|
18371
|
+
{ name: "id", type: "string | number", required: true, description: "Unique identifier" },
|
|
18372
|
+
{ name: "coordinates", type: "LngLat", required: true, description: "Marker position" },
|
|
18373
|
+
{ name: "label", type: "string", required: false, description: "Display label" },
|
|
18374
|
+
{ name: "color", type: "string", required: false, description: "Marker color" }
|
|
18375
|
+
]
|
|
18376
|
+
},
|
|
18377
|
+
{
|
|
18378
|
+
name: "ClusterConfig",
|
|
18379
|
+
description: "Configuration for source clustering",
|
|
18380
|
+
properties: [
|
|
18381
|
+
{ name: "radius", type: "number", required: false, description: "Cluster radius in pixels" },
|
|
18382
|
+
{ name: "maxZoom", type: "number", required: false, description: "Max zoom for clustering" },
|
|
18383
|
+
{ name: "minPoints", type: "number", required: false, description: "Minimum points to form cluster" }
|
|
18384
|
+
]
|
|
18385
|
+
},
|
|
18386
|
+
{
|
|
18387
|
+
name: "ClusterFeatureProperties",
|
|
18388
|
+
description: "Properties automatically added to cluster features by MapLibre",
|
|
18389
|
+
properties: [
|
|
18390
|
+
{ name: "cluster_id", type: "number", required: true, description: "Unique cluster identifier" },
|
|
18391
|
+
{ name: "point_count", type: "number", required: true, description: "Number of points in cluster" },
|
|
18392
|
+
{ name: "point_count_abbreviated", type: "string", required: true, description: "Abbreviated count (e.g., '1.2k')" },
|
|
18393
|
+
{ name: "cluster", type: "true", required: true, description: "Whether this is a cluster" }
|
|
18394
|
+
]
|
|
18395
|
+
},
|
|
18396
|
+
{
|
|
18397
|
+
name: "LegendItem",
|
|
18398
|
+
description: "Item for categorical legends",
|
|
18399
|
+
properties: [
|
|
18400
|
+
{ name: "label", type: "string", required: true, description: "Item label" },
|
|
18401
|
+
{ name: "color", type: "string", required: true, description: "Item color" },
|
|
18402
|
+
{ name: "icon", type: "string", required: false, description: "Optional icon name" },
|
|
18403
|
+
{ name: "value", type: "string | number", required: false, description: "Optional value" },
|
|
18404
|
+
{ name: "active", type: "boolean", required: false, description: "Whether active/visible" }
|
|
18405
|
+
]
|
|
18406
|
+
},
|
|
18407
|
+
{
|
|
18408
|
+
name: "GradientStop",
|
|
18409
|
+
description: "Stop for gradient legends",
|
|
18410
|
+
properties: [
|
|
18411
|
+
{ name: "position", type: "number", required: true, description: "Position in gradient (0-1)" },
|
|
18412
|
+
{ name: "color", type: "string", required: true, description: "Color at position" },
|
|
18413
|
+
{ name: "label", type: "string", required: false, description: "Optional label" }
|
|
18414
|
+
]
|
|
18415
|
+
},
|
|
18416
|
+
{
|
|
18417
|
+
name: "ControlPosition",
|
|
18418
|
+
description: "Position for map controls: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'"
|
|
18419
|
+
},
|
|
18420
|
+
{
|
|
18421
|
+
name: "LoadGeoJSONOptions",
|
|
18422
|
+
description: "Options for loadGeoJSON function",
|
|
18423
|
+
properties: [
|
|
18424
|
+
{ name: "timeout", type: "number", required: false, description: "Request timeout in ms (default: 30000)" },
|
|
18425
|
+
{ name: "fetchOptions", type: "RequestInit", required: false, description: "Additional fetch options" },
|
|
18426
|
+
{ name: "validate", type: "boolean", required: false, description: "Validate structure after loading" }
|
|
18427
|
+
]
|
|
18428
|
+
},
|
|
18429
|
+
{
|
|
18430
|
+
name: "ValidationResult",
|
|
18431
|
+
description: "Result of GeoJSON validation",
|
|
18432
|
+
properties: [
|
|
18433
|
+
{ name: "valid", type: "boolean", required: true, description: "Whether valid" },
|
|
18434
|
+
{ name: "errors", type: "string[]", required: true, description: "List of errors" },
|
|
18435
|
+
{ name: "featureCount", type: "number", required: false, description: "Number of features" },
|
|
18436
|
+
{ name: "geometryTypes", type: "string[]", required: false, description: "Geometry types found" }
|
|
18437
|
+
]
|
|
18438
|
+
},
|
|
18439
|
+
{
|
|
18440
|
+
name: "ClusterExpandOptions",
|
|
18441
|
+
description: "Options for cluster expansion",
|
|
18442
|
+
properties: [
|
|
18443
|
+
{ name: "duration", type: "number", required: false, description: "Animation duration in ms (default: 500)" },
|
|
18444
|
+
{ name: "animate", type: "boolean", required: false, description: "Whether to animate (default: true)" },
|
|
18445
|
+
{ name: "padding", type: "number | { top, bottom, left, right }", required: false, description: "Padding around bounds" },
|
|
18446
|
+
{ name: "maxZoom", type: "number", required: false, description: "Maximum zoom level" }
|
|
18447
|
+
]
|
|
18448
|
+
},
|
|
18449
|
+
{
|
|
18450
|
+
name: "GeoJSONFingerprint",
|
|
18451
|
+
description: "Lightweight fingerprint for fast GeoJSON equality checking",
|
|
18452
|
+
properties: [
|
|
18453
|
+
{ name: "type", type: "string", required: true, description: "GeoJSON type (FeatureCollection, Feature, etc.)" },
|
|
18454
|
+
{ name: "featureCount", type: "number", required: true, description: "Number of features" },
|
|
18455
|
+
{ name: "firstFeatureId", type: "string | number | undefined", required: false, description: "ID of first feature" },
|
|
18456
|
+
{ name: "lastFeatureId", type: "string | number | undefined", required: false, description: "ID of last feature" },
|
|
18457
|
+
{ name: "geometryTypes", type: "Set<string>", required: true, description: "Set of geometry types present" }
|
|
18458
|
+
]
|
|
18459
|
+
},
|
|
18460
|
+
{
|
|
18461
|
+
name: "PaintProps",
|
|
18462
|
+
description: "MapLibre paint properties object (Record<string, unknown>)"
|
|
18463
|
+
},
|
|
18464
|
+
{
|
|
18465
|
+
name: "PaintPropsDiff",
|
|
18466
|
+
description: "Result of comparing two paint prop objects",
|
|
18467
|
+
properties: [
|
|
18468
|
+
{ name: "hasChanges", type: "boolean", required: true, description: "Whether any properties changed" },
|
|
18469
|
+
{ name: "changed", type: "Record<string, unknown>", required: true, description: "Properties that changed (key -> new value)" },
|
|
18470
|
+
{ name: "removed", type: "string[]", required: true, description: "Properties that were removed" }
|
|
18471
|
+
]
|
|
18472
|
+
},
|
|
18473
|
+
{
|
|
18474
|
+
name: "FilterExpression",
|
|
18475
|
+
description: "MapLibre filter expression (unknown[] | undefined)"
|
|
18476
|
+
},
|
|
18477
|
+
{
|
|
18478
|
+
name: "SpatialIndex",
|
|
18479
|
+
description: "Grid-based spatial index for viewport queries",
|
|
18480
|
+
properties: [
|
|
18481
|
+
{ name: "cells", type: "Map<string, GeoJSONFeature[]>", required: true, description: "Grid cells containing features" },
|
|
18482
|
+
{ name: "bounds", type: "BoundsArray", required: true, description: "Total bounds of indexed data" },
|
|
18483
|
+
{ name: "cellSize", type: "{ lng: number; lat: number }", required: true, description: "Size of each grid cell" },
|
|
18484
|
+
{ name: "featureCount", type: "number", required: true, description: "Total number of features indexed" }
|
|
18485
|
+
]
|
|
18486
|
+
},
|
|
18487
|
+
{
|
|
18488
|
+
name: "RTreeIndex",
|
|
18489
|
+
description: "R-tree spatial index (better for clustered data)",
|
|
18490
|
+
properties: [
|
|
18491
|
+
{ name: "tree", type: "RBush<RTreeItem>", required: true, description: "R-tree data structure" },
|
|
18492
|
+
{ name: "bounds", type: "BoundsArray", required: true, description: "Total bounds of indexed data" },
|
|
18493
|
+
{ name: "featureCount", type: "number", required: true, description: "Total number of features indexed" }
|
|
18494
|
+
]
|
|
18495
|
+
},
|
|
18496
|
+
{
|
|
18497
|
+
name: "QueryStats",
|
|
18498
|
+
description: "Statistics from a spatial query",
|
|
18499
|
+
properties: [
|
|
18500
|
+
{ name: "totalFeatures", type: "number", required: true, description: "Total features in index" },
|
|
18501
|
+
{ name: "visibleFeatures", type: "number", required: true, description: "Features in query result" },
|
|
18502
|
+
{ name: "culledPercent", type: "number", required: true, description: "Percentage of features culled" },
|
|
18503
|
+
{ name: "cellsChecked", type: "number", required: true, description: "Number of grid cells checked" },
|
|
18504
|
+
{ name: "totalCells", type: "number", required: true, description: "Total cells in grid" }
|
|
18505
|
+
]
|
|
18506
|
+
},
|
|
18507
|
+
{
|
|
18508
|
+
name: "PanVelocity",
|
|
18509
|
+
description: "Velocity vector for predictive panning",
|
|
18510
|
+
properties: [
|
|
18511
|
+
{ name: "lngPerSec", type: "number", required: true, description: "Longitude change per second" },
|
|
18512
|
+
{ name: "latPerSec", type: "number", required: true, description: "Latitude change per second" },
|
|
18513
|
+
{ name: "magnitude", type: "number", required: true, description: "Velocity magnitude" }
|
|
18514
|
+
]
|
|
18515
|
+
},
|
|
18516
|
+
{
|
|
18517
|
+
name: "LODData",
|
|
18518
|
+
description: "Level-of-Detail data structure",
|
|
18519
|
+
properties: [
|
|
18520
|
+
{ name: "levels", type: "Map<number, GeoJSONFeatureCollection>", required: true, description: "Data at each zoom level" },
|
|
18521
|
+
{ name: "zoomThresholds", type: "number[]", required: true, description: "Zoom level breakpoints" },
|
|
18522
|
+
{ name: "originalFeatureCount", type: "number", required: true, description: "Original feature count" }
|
|
18523
|
+
]
|
|
18524
|
+
},
|
|
18525
|
+
{
|
|
18526
|
+
name: "SimplificationStats",
|
|
18527
|
+
description: "Statistics from polygon simplification",
|
|
18528
|
+
properties: [
|
|
18529
|
+
{ name: "originalPoints", type: "number", required: true, description: "Original point count" },
|
|
18530
|
+
{ name: "simplifiedPoints", type: "number", required: true, description: "Point count after simplification" },
|
|
18531
|
+
{ name: "reductionPercent", type: "number", required: true, description: "Percentage of points removed" },
|
|
18532
|
+
{ name: "processingTimeMs", type: "number", required: true, description: "Time taken in milliseconds" }
|
|
18533
|
+
]
|
|
18534
|
+
},
|
|
18535
|
+
{
|
|
18536
|
+
name: "SpatialWorkerClientOptions",
|
|
18537
|
+
description: "Options for creating a SpatialWorkerClient",
|
|
18538
|
+
properties: [
|
|
18539
|
+
{ name: "requestTimeout", type: "number", required: false, description: "Timeout for requests in ms (default: 30000)" },
|
|
18540
|
+
{ name: "useRTree", type: "boolean", required: false, description: "Use R-tree (true) or grid index (false). Default: true" },
|
|
18541
|
+
{ name: "gridTargetCells", type: "number", required: false, description: "Target cells for grid index. Default: 1024" },
|
|
18542
|
+
{ name: "rtreeMaxEntries", type: "number", required: false, description: "Max entries per R-tree node. Default: 9" },
|
|
18543
|
+
{ name: "workerFactory", type: "() => Worker", required: false, description: "Factory function to create the worker" },
|
|
18544
|
+
{ name: "workerUrl", type: "string | URL", required: false, description: "URL to the worker script (alternative to workerFactory)" }
|
|
18545
|
+
]
|
|
18546
|
+
},
|
|
18547
|
+
{
|
|
18548
|
+
name: "WorkerQueryResult",
|
|
18549
|
+
description: "Result from a worker viewport query",
|
|
18550
|
+
properties: [
|
|
18551
|
+
{ name: "success", type: "boolean", required: true, description: "Whether query succeeded" },
|
|
18552
|
+
{ name: "data", type: "GeoJSONFeatureCollection", required: true, description: "Query results" },
|
|
18553
|
+
{ name: "stats", type: "QueryStats", required: true, description: "Query statistics" },
|
|
18554
|
+
{ name: "queryTimeMs", type: "number", required: true, description: "Time taken in milliseconds" },
|
|
18555
|
+
{ name: "error", type: "string", required: false, description: "Error message if failed" }
|
|
18556
|
+
]
|
|
18557
|
+
}
|
|
18558
|
+
]
|
|
18559
|
+
},
|
|
18560
|
+
events: {
|
|
18561
|
+
description: "Event types",
|
|
18562
|
+
types: [
|
|
18563
|
+
{
|
|
18564
|
+
name: "BaseMapEventParams",
|
|
18565
|
+
description: "Base event parameters shared across all map events",
|
|
18566
|
+
properties: [
|
|
18567
|
+
{ name: "type", type: "string", required: true, description: "Event type identifier" },
|
|
18568
|
+
{ name: "originalEvent", type: "MouseEvent | TouchEvent", required: false, description: "Original native event" }
|
|
18569
|
+
]
|
|
18570
|
+
},
|
|
18571
|
+
{
|
|
18572
|
+
name: "MapClickEventParams",
|
|
18573
|
+
description: "Parameters for map click events",
|
|
18574
|
+
properties: [
|
|
18575
|
+
{ name: "type", type: "'click' | 'dblclick' | 'contextmenu'", required: true, description: "Event type" },
|
|
18576
|
+
{ name: "lngLat", type: "LngLat", required: true, description: "Click location [lng, lat]" },
|
|
18577
|
+
{ name: "point", type: "[number, number]", required: true, description: "Screen pixel coordinates [x, y]" },
|
|
18578
|
+
{ name: "features", type: "GeoJSONFeature[]", required: false, description: "Features at click point" }
|
|
18579
|
+
]
|
|
18580
|
+
},
|
|
18581
|
+
{
|
|
18582
|
+
name: "MapHoverEventParams",
|
|
18583
|
+
description: "Parameters for mouse move/hover events",
|
|
18584
|
+
properties: [
|
|
18585
|
+
{ name: "type", type: "'mousemove' | 'mouseenter' | 'mouseleave'", required: true, description: "Event type" },
|
|
18586
|
+
{ name: "lngLat", type: "LngLat", required: true, description: "Cursor location [lng, lat]" },
|
|
18587
|
+
{ name: "point", type: "[number, number]", required: true, description: "Screen pixel coordinates [x, y]" },
|
|
18588
|
+
{ name: "features", type: "GeoJSONFeature[]", required: false, description: "Features at cursor location" }
|
|
18589
|
+
]
|
|
18590
|
+
},
|
|
18591
|
+
{
|
|
18592
|
+
name: "FeatureClickEventParams",
|
|
18593
|
+
description: "Parameters for feature click events",
|
|
18594
|
+
properties: [
|
|
18595
|
+
{ name: "type", type: "'click' | 'dblclick' | 'contextmenu'", required: true, description: "Event type" },
|
|
18596
|
+
{ name: "feature", type: "GeoJSONFeature", required: true, description: "Clicked feature" },
|
|
18597
|
+
{ name: "featureId", type: "string | number", required: false, description: "Feature ID" },
|
|
18598
|
+
{ name: "layerId", type: "string", required: true, description: "Layer ID" },
|
|
18599
|
+
{ name: "sourceId", type: "string", required: true, description: "Source ID" },
|
|
18600
|
+
{ name: "lngLat", type: "LngLat", required: true, description: "Click location" },
|
|
18601
|
+
{ name: "point", type: "[number, number]", required: true, description: "Screen coordinates" }
|
|
18602
|
+
]
|
|
18603
|
+
},
|
|
18604
|
+
{
|
|
18605
|
+
name: "FeatureHoverEventParams",
|
|
18606
|
+
description: "Parameters for feature hover events",
|
|
18607
|
+
properties: [
|
|
18608
|
+
{ name: "type", type: "'mouseenter' | 'mousemove' | 'mouseleave'", required: true, description: "Event type" },
|
|
18609
|
+
{ name: "feature", type: "GeoJSONFeature | null", required: true, description: "Hovered feature (null on leave)" },
|
|
18610
|
+
{ name: "featureId", type: "string | number", required: false, description: "Feature ID" },
|
|
18611
|
+
{ name: "layerId", type: "string", required: true, description: "Layer ID" },
|
|
18612
|
+
{ name: "sourceId", type: "string", required: true, description: "Source ID" },
|
|
18613
|
+
{ name: "lngLat", type: "LngLat", required: true, description: "Cursor location" }
|
|
18614
|
+
]
|
|
18615
|
+
},
|
|
18616
|
+
{
|
|
18617
|
+
name: "MarkerClickEventParams",
|
|
18618
|
+
description: "Parameters for marker click events",
|
|
18619
|
+
properties: [
|
|
18620
|
+
{ name: "type", type: "'click'", required: true, description: "Event type" },
|
|
18621
|
+
{ name: "markerId", type: "string", required: true, description: "Marker ID" },
|
|
18622
|
+
{ name: "lngLat", type: "LngLat", required: true, description: "Marker coordinates" },
|
|
18623
|
+
{ name: "properties", type: "Record<string, unknown>", required: false, description: "Marker properties" }
|
|
18624
|
+
]
|
|
18625
|
+
},
|
|
18626
|
+
{
|
|
18627
|
+
name: "MarkerDragEventParams",
|
|
18628
|
+
description: "Parameters for marker drag events",
|
|
18629
|
+
properties: [
|
|
18630
|
+
{ name: "type", type: "'dragstart' | 'drag' | 'dragend'", required: true, description: "Event type" },
|
|
18631
|
+
{ name: "markerId", type: "string", required: true, description: "Marker ID" },
|
|
18632
|
+
{ name: "lngLat", type: "LngLat", required: true, description: "Current coordinates" },
|
|
18633
|
+
{ name: "originalLngLat", type: "LngLat", required: false, description: "Original coordinates at drag start" }
|
|
18634
|
+
]
|
|
18635
|
+
},
|
|
18636
|
+
{
|
|
18637
|
+
name: "MapLoadEventParams",
|
|
18638
|
+
description: "Parameters for map load events",
|
|
18639
|
+
properties: [
|
|
18640
|
+
{ name: "type", type: "'load' | 'style.load' | 'idle'", required: true, description: "Event type" },
|
|
18641
|
+
{ name: "loaded", type: "boolean", required: true, description: "Whether fully loaded" }
|
|
18642
|
+
]
|
|
18643
|
+
},
|
|
18644
|
+
{
|
|
18645
|
+
name: "MapMoveEventParams",
|
|
18646
|
+
description: "Parameters for map move events",
|
|
18647
|
+
properties: [
|
|
18648
|
+
{ name: "type", type: "'move' | 'movestart' | 'moveend' | 'zoom' | ...", required: true, description: "Event type" },
|
|
18649
|
+
{ name: "center", type: "LngLat", required: true, description: "New center" },
|
|
18650
|
+
{ name: "zoom", type: "number", required: true, description: "New zoom level" },
|
|
18651
|
+
{ name: "bearing", type: "number", required: true, description: "New bearing" },
|
|
18652
|
+
{ name: "pitch", type: "number", required: true, description: "New pitch" },
|
|
18653
|
+
{ name: "isUserInteraction", type: "boolean", required: false, description: "Whether user-initiated" }
|
|
18654
|
+
]
|
|
18655
|
+
},
|
|
18656
|
+
{
|
|
18657
|
+
name: "PopupEventParams",
|
|
18658
|
+
description: "Parameters for popup events",
|
|
18659
|
+
properties: [
|
|
18660
|
+
{ name: "type", type: "'open' | 'close'", required: true, description: "Event type" },
|
|
18661
|
+
{ name: "lngLat", type: "LngLat", required: true, description: "Popup coordinates" }
|
|
18662
|
+
]
|
|
18663
|
+
},
|
|
18664
|
+
{
|
|
18665
|
+
name: "MapErrorEventParams",
|
|
18666
|
+
description: "Parameters for map error events",
|
|
18667
|
+
properties: [
|
|
18668
|
+
{ name: "type", type: "'error'", required: true, description: "Event type" },
|
|
18669
|
+
{ name: "message", type: "string", required: true, description: "Error message" },
|
|
18670
|
+
{ name: "source", type: "string", required: false, description: "Error source (tile, source, layer)" },
|
|
18671
|
+
{ name: "error", type: "Error", required: false, description: "Original error object" }
|
|
18672
|
+
]
|
|
18673
|
+
}
|
|
18674
|
+
]
|
|
18675
|
+
}
|
|
18676
|
+
},
|
|
18677
|
+
components: {
|
|
18678
|
+
react: {
|
|
18679
|
+
package: "@classic-homes/maps-react",
|
|
18680
|
+
components: [
|
|
18681
|
+
"Map",
|
|
18682
|
+
"MapContext",
|
|
18683
|
+
"MapContainer",
|
|
18684
|
+
"MapSkeleton",
|
|
18685
|
+
"MapError",
|
|
18686
|
+
"MapEmpty",
|
|
18687
|
+
"Source",
|
|
18688
|
+
"Marker",
|
|
18689
|
+
"Popup",
|
|
18690
|
+
"PopupCard",
|
|
18691
|
+
"PopupHeader",
|
|
18692
|
+
"PopupContent",
|
|
18693
|
+
"PopupFooter",
|
|
18694
|
+
"FillLayer",
|
|
18695
|
+
"LineLayer",
|
|
18696
|
+
"CircleLayer",
|
|
18697
|
+
"SymbolLayer",
|
|
18698
|
+
"FillExtrusionLayer",
|
|
18699
|
+
"HeatmapLayer",
|
|
18700
|
+
"RasterLayer",
|
|
18701
|
+
"Legend",
|
|
18702
|
+
"LegendGroup",
|
|
18703
|
+
"CoordinateDisplay",
|
|
18704
|
+
"DeckOverlay"
|
|
18705
|
+
],
|
|
18706
|
+
hooks: [
|
|
18707
|
+
{
|
|
18708
|
+
name: "useMap",
|
|
18709
|
+
signature: "() => MapContextValue",
|
|
18710
|
+
description: "Hook to access the MapLibre map instance and state from context. Must be used within a Map component.",
|
|
18711
|
+
returns: "{ map: MapLibreMap | null, loaded: boolean, controlOffsets?: ControlOffsets, registerControl?, unregisterControl?, getCustomControlOffset? }"
|
|
18712
|
+
},
|
|
18713
|
+
{
|
|
18714
|
+
name: "useMapInstance",
|
|
18715
|
+
signature: "() => MapLibreMap | null",
|
|
18716
|
+
description: "Hook to access the map instance only when loaded. Returns null if map is not yet available."
|
|
18717
|
+
},
|
|
18718
|
+
{
|
|
18719
|
+
name: "useMapTheme",
|
|
18720
|
+
signature: "(theme?: 'light' | 'dark' | 'auto') => { resolvedTheme: 'light' | 'dark', mapTheme: MapTheme, mapStyle: StyleSpecification }",
|
|
18721
|
+
description: "Hook to get the resolved theme based on preference and system settings. Handles 'auto' mode by detecting system dark mode."
|
|
18722
|
+
},
|
|
18723
|
+
{
|
|
18724
|
+
name: "useReducedMotion",
|
|
18725
|
+
signature: "() => boolean",
|
|
18726
|
+
description: "Hook to detect if user prefers reduced motion. Returns true if prefers-reduced-motion media query matches."
|
|
18727
|
+
},
|
|
18728
|
+
{
|
|
18729
|
+
name: "useLayer",
|
|
18730
|
+
signature: "(options: UseLayerOptions) => void",
|
|
18731
|
+
description: "Hook for adding custom layers to the map. Handles layer lifecycle (add/update/remove) automatically."
|
|
18732
|
+
}
|
|
18733
|
+
],
|
|
18734
|
+
context: {
|
|
18735
|
+
name: "MapContext",
|
|
18736
|
+
description: "React context for sharing map instance with child components",
|
|
18737
|
+
value: {
|
|
18738
|
+
map: "MapLibreMap | null - The MapLibre map instance",
|
|
18739
|
+
loaded: "boolean - Whether the map has loaded",
|
|
18740
|
+
controlOffsets: "Record<string, number> - Pixel offsets for custom controls",
|
|
18741
|
+
registerControl: "(id, position, height) => number - Register a custom control",
|
|
18742
|
+
unregisterControl: "(id, position) => void - Unregister a custom control",
|
|
18743
|
+
getCustomControlOffset: "(id, position) => number - Get vertical offset for a control"
|
|
18744
|
+
}
|
|
18745
|
+
}
|
|
18746
|
+
},
|
|
18747
|
+
svelte: {
|
|
18748
|
+
package: "@classic-homes/maps-svelte",
|
|
18749
|
+
components: [
|
|
18750
|
+
"Map",
|
|
18751
|
+
"MapContainer",
|
|
18752
|
+
"MapSkeleton",
|
|
18753
|
+
"MapError",
|
|
18754
|
+
"MapEmpty",
|
|
18755
|
+
"Source",
|
|
18756
|
+
"Marker",
|
|
18757
|
+
"Popup",
|
|
18758
|
+
"PopupCard",
|
|
18759
|
+
"PopupHeader",
|
|
18760
|
+
"PopupContent",
|
|
18761
|
+
"PopupFooter",
|
|
18762
|
+
"FillLayer",
|
|
18763
|
+
"LineLayer",
|
|
18764
|
+
"CircleLayer",
|
|
18765
|
+
"SymbolLayer",
|
|
18766
|
+
"FillExtrusionLayer",
|
|
18767
|
+
"HeatmapLayer",
|
|
18768
|
+
"RasterLayer",
|
|
18769
|
+
"Legend",
|
|
18770
|
+
"LegendGroup",
|
|
18771
|
+
"CoordinateDisplay",
|
|
18772
|
+
"DeckOverlay"
|
|
18773
|
+
],
|
|
18774
|
+
composables: [
|
|
18775
|
+
{
|
|
18776
|
+
name: "useMapContext",
|
|
18777
|
+
signature: "() => { map: Writable<Map | null>, loaded: Writable<boolean> }",
|
|
18778
|
+
description: "Get the map context from the parent Map component using Svelte context API"
|
|
18779
|
+
},
|
|
18780
|
+
{
|
|
18781
|
+
name: "useMapTheme",
|
|
18782
|
+
signature: "(theme?: 'light' | 'dark' | 'auto') => { resolvedTheme: 'light' | 'dark', mapTheme: MapTheme, mapStyle: StyleSpecification }",
|
|
18783
|
+
description: "Composable to get the resolved theme based on preference and system settings"
|
|
18784
|
+
},
|
|
18785
|
+
{
|
|
18786
|
+
name: "useReducedMotion",
|
|
18787
|
+
signature: "() => boolean",
|
|
18788
|
+
description: "Composable to detect if user prefers reduced motion"
|
|
18789
|
+
},
|
|
18790
|
+
{
|
|
18791
|
+
name: "useLayer",
|
|
18792
|
+
signature: "(options: UseLayerOptions) => void",
|
|
18793
|
+
description: "Composable for adding custom layers to the map with automatic lifecycle management"
|
|
18794
|
+
}
|
|
18795
|
+
]
|
|
18796
|
+
}
|
|
18797
|
+
},
|
|
18798
|
+
quickReference: {
|
|
18799
|
+
installation: "npm install @classic-homes/maps-svelte maplibre-gl\n# or\nnpm install @classic-homes/maps-react maplibre-gl",
|
|
18800
|
+
basicUsage: `import { Map, Source, CircleLayer, Marker, Popup } from '@classic-homes/maps-svelte';
|
|
18801
|
+
|
|
18802
|
+
<Map
|
|
18803
|
+
title="My Map"
|
|
18804
|
+
center={[-122.4, 37.8]}
|
|
18805
|
+
zoom={10}
|
|
18806
|
+
height={400}
|
|
18807
|
+
navigationControl
|
|
18808
|
+
>
|
|
18809
|
+
<Source id="points" data={geojson}>
|
|
18810
|
+
<CircleLayer id="points-layer" source="points" circleRadius={6} circleColor="#3ba4a7" />
|
|
18811
|
+
</Source>
|
|
18812
|
+
<Marker coordinates={[-122.4, 37.8]} color="red" />
|
|
18813
|
+
</Map>`,
|
|
18814
|
+
peerDependency: "maplibre-gl@^4.0.0 || ^5.0.0",
|
|
18815
|
+
optionalPeerDependencies: "@deck.gl/core, @deck.gl/layers, @deck.gl/mapbox (for DeckOverlay)",
|
|
18816
|
+
cssImportOrder: "/* In main CSS file - order matters */\n@import '@classic-homes/theme-styles';\n@import 'maplibre-gl/dist/maplibre-gl.css';\n@import '@classic-homes/maps-core/styles/controls.css';\n@import '@classic-homes/maps-core/styles/popup.css';\n\n@tailwind base;\n@tailwind components;\n@tailwind utilities;",
|
|
18817
|
+
tailwindConfig: "module.exports = {\n presets: [require('@classic-homes/theme-tailwind-preset')],\n content: [\n './src/**/*.{js,ts,jsx,tsx}',\n './node_modules/@classic-homes/maps-react/dist/**/*.{js,mjs}',\n ],\n};"
|
|
18818
|
+
},
|
|
18819
|
+
bestPractices: {
|
|
18820
|
+
description: "Recommended patterns for using the maps packages effectively",
|
|
18821
|
+
accessibility: {
|
|
18822
|
+
title: "Accessibility",
|
|
18823
|
+
guidelines: [
|
|
18824
|
+
"Always provide a descriptive `title` prop for the Map component - this becomes the aria-label",
|
|
18825
|
+
"Use `description` prop for additional context for screen readers",
|
|
18826
|
+
"The map supports full keyboard navigation: Arrow keys to pan, +/- to zoom, Shift+Arrow to rotate",
|
|
18827
|
+
"Use `generateMapDescription()` utility for dynamic accessible descriptions",
|
|
18828
|
+
"Markers and layers support `ariaLabel` for individual feature descriptions",
|
|
18829
|
+
"Consider providing a text alternative or data table for complex visualizations"
|
|
18830
|
+
]
|
|
18831
|
+
},
|
|
18832
|
+
performance: {
|
|
18833
|
+
title: "Performance",
|
|
18834
|
+
guidelines: [
|
|
18835
|
+
"Use clustering for large point datasets (>1000 points) via Source's `cluster` prop",
|
|
18836
|
+
"Set `generateId={true}` on Source when using feature state for hover/selection",
|
|
18837
|
+
"Use `minZoom` and `maxZoom` on layers to reduce rendering at unnecessary zoom levels",
|
|
18838
|
+
"Prefer GeoJSON data URLs over inline data for large datasets (enables caching)",
|
|
18839
|
+
"Use `loadGeoJSON()` utility for type-safe data loading with timeout handling",
|
|
18840
|
+
"Memoize GeoJSON data in React to prevent unnecessary re-renders",
|
|
18841
|
+
"For 100k+ features, use `buildSpatialIndex()` or `buildRTreeIndex()` for fast viewport culling",
|
|
18842
|
+
"Use `createGeoJSONFingerprint()` for O(1) equality checks instead of deep comparison",
|
|
18843
|
+
"Use `getChangedPaintProps()` to only update changed paint properties (minimizes MapLibre API calls)",
|
|
18844
|
+
"Consider `createIdleViewportManager()` for smooth panning with deferred updates",
|
|
18845
|
+
"Use `createPredictiveViewportManager()` to eliminate feature pop-in during panning",
|
|
18846
|
+
"For very large polygons, use LOD utilities with `simplifyPolygon()` for zoom-based simplification",
|
|
18847
|
+
"Use `SpatialWorkerClient` to move spatial indexing off the main thread for 100k+ features",
|
|
18848
|
+
"Set `hoverThrottleMs` on layers to throttle hover callbacks (feature-state updates remain immediate)"
|
|
18849
|
+
]
|
|
18850
|
+
},
|
|
18851
|
+
theming: {
|
|
18852
|
+
title: "Theming",
|
|
18853
|
+
guidelines: [
|
|
18854
|
+
"Use `theme='auto'` to automatically respect system dark/light preference",
|
|
18855
|
+
"All map UI elements (controls, popups, legends) inherit from design tokens",
|
|
18856
|
+
"Use `useMapTheme` hook to access resolved theme and style in custom components",
|
|
18857
|
+
"The `useReducedMotion` hook respects user's motion preferences for animations",
|
|
18858
|
+
"Custom layers can use theme colors via the `MapTheme` object from the hook"
|
|
18859
|
+
]
|
|
18860
|
+
},
|
|
18861
|
+
layerOrdering: {
|
|
18862
|
+
title: "Layer Ordering",
|
|
18863
|
+
guidelines: [
|
|
18864
|
+
"Layers render in the order they appear in JSX/template",
|
|
18865
|
+
"Use `beforeId` prop to insert layers at specific positions",
|
|
18866
|
+
"Common order: Fill layers -> Line layers -> Circle layers -> Symbol layers",
|
|
18867
|
+
"Place highlight/selection layers after base layers",
|
|
18868
|
+
"Use z-index style properties within layer types for fine control"
|
|
18869
|
+
]
|
|
18870
|
+
},
|
|
18871
|
+
eventHandling: {
|
|
18872
|
+
title: "Event Handling",
|
|
18873
|
+
guidelines: [
|
|
18874
|
+
"Use layer-level `onClick` and `onHover` for feature interactions (more efficient than map-level)",
|
|
18875
|
+
"Feature events include full feature properties and geometry",
|
|
18876
|
+
"Use `feature.id` for feature state operations (hover highlighting)",
|
|
18877
|
+
"Marker events include marker-specific data and coordinates",
|
|
18878
|
+
"Map events provide viewport info (center, zoom, bearing, pitch)"
|
|
18879
|
+
]
|
|
18880
|
+
},
|
|
18881
|
+
clustering: {
|
|
18882
|
+
title: "Clustering",
|
|
18883
|
+
guidelines: [
|
|
18884
|
+
"Enable via `<Source cluster={true}>` or with config: `cluster={{ radius: 50, maxZoom: 14 }}`",
|
|
18885
|
+
"Use `isClusterFeature()` type guard to check if a feature is a cluster",
|
|
18886
|
+
"Use `expandCluster()` to zoom into clusters on click",
|
|
18887
|
+
"Cluster features have `cluster_id`, `point_count`, and `point_count_abbreviated` properties",
|
|
18888
|
+
"Style clusters differently using data-driven expressions based on `point_count`"
|
|
18889
|
+
]
|
|
18890
|
+
},
|
|
18891
|
+
popups: {
|
|
18892
|
+
title: "Popups",
|
|
18893
|
+
guidelines: [
|
|
18894
|
+
"Use PopupCard with PopupHeader/PopupContent/PopupFooter for structured popups",
|
|
18895
|
+
"Set `closeOnClick={false}` if popup should persist until explicitly closed",
|
|
18896
|
+
"Use `autoPan={true}` (default) to ensure popup is visible when opened",
|
|
18897
|
+
"Popup content can be any React/Svelte component",
|
|
18898
|
+
"Consider `maxWidth` prop for content-heavy popups"
|
|
18899
|
+
]
|
|
18900
|
+
},
|
|
18901
|
+
markers: {
|
|
18902
|
+
title: "Markers",
|
|
18903
|
+
guidelines: [
|
|
18904
|
+
"DOM-based Marker components use maplibregl.Marker which renders in the DOM",
|
|
18905
|
+
"DOM markers are susceptible to CSS framework interference (e.g., Tailwind) that can cause visual sliding during pan/rotate",
|
|
18906
|
+
"For production use with many markers or when CSS conflicts occur, prefer SymbolLayer which renders on the GPU canvas",
|
|
18907
|
+
"SymbolLayer is immune to CSS interference and generally performs better at scale",
|
|
18908
|
+
"Use Marker component only for simple cases or when you need custom HTML content that can't be achieved with icons",
|
|
18909
|
+
"If using DOM markers, the component applies CSS protection but this may not fully prevent sliding in all CSS environments"
|
|
18910
|
+
]
|
|
18911
|
+
},
|
|
18912
|
+
dynamicData: {
|
|
18913
|
+
title: "Dynamic Data Loading",
|
|
18914
|
+
description: "Patterns for loading and updating map data dynamically (async fetching, user interactions, etc.)",
|
|
18915
|
+
guidelines: [
|
|
18916
|
+
"For dynamic marker-like points, use Source + CircleLayer/SymbolLayer instead of individual Marker components",
|
|
18917
|
+
"When Source data prop changes, the component automatically calls source.setData() to update layers efficiently",
|
|
18918
|
+
"Convert your data array to GeoJSON FeatureCollection format using useMemo/derived to avoid unnecessary re-renders",
|
|
18919
|
+
"Layers automatically re-render when their source data changes - no need to recreate layers",
|
|
18920
|
+
"Use generateId prop on Source to enable feature state (hover effects, selection)",
|
|
18921
|
+
"For popups with SymbolLayer, use onClick handler to get feature coordinates and properties",
|
|
18922
|
+
"This approach is more performant than DOM markers: single GPU draw call vs O(n) DOM operations",
|
|
18923
|
+
"DOM Markers also support dynamic loading - they appear immediately when added after map initialization"
|
|
18924
|
+
],
|
|
18925
|
+
recommendedPattern: {
|
|
18926
|
+
name: "Dynamic SymbolLayer with Popup",
|
|
18927
|
+
description: "Recommended pattern for dynamic points with popups - GPU-based, efficient, and immune to CSS conflicts",
|
|
18928
|
+
react: `const [points, setPoints] = useState([]);
|
|
18929
|
+
|
|
18930
|
+
const geojson = useMemo(() => ({
|
|
18931
|
+
type: 'FeatureCollection',
|
|
18932
|
+
features: points.map(p => ({
|
|
18933
|
+
type: 'Feature',
|
|
18934
|
+
properties: { name: p.name, id: p.id },
|
|
18935
|
+
geometry: { type: 'Point', coordinates: p.coordinates }
|
|
18936
|
+
}))
|
|
18937
|
+
}), [points]);
|
|
18938
|
+
|
|
18939
|
+
const [selected, setSelected] = useState(null);
|
|
18940
|
+
|
|
18941
|
+
return (
|
|
18942
|
+
<Map title="Dynamic Points">
|
|
18943
|
+
<Source id="points" type="geojson" data={geojson} generateId>
|
|
18944
|
+
<CircleLayer
|
|
18945
|
+
id="circles"
|
|
18946
|
+
source="points"
|
|
18947
|
+
circleRadius={10}
|
|
18948
|
+
circleColor="#3ba4a7"
|
|
18949
|
+
onClick={(e) => setSelected({ ...e.feature.properties, coordinates: e.lngLat })}
|
|
18950
|
+
onHover={() => {}}
|
|
18951
|
+
/>
|
|
18952
|
+
<SymbolLayer
|
|
18953
|
+
id="labels"
|
|
18954
|
+
source="points"
|
|
18955
|
+
textField={['get', 'name']}
|
|
18956
|
+
textOffset={[0, 1.5]}
|
|
18957
|
+
/>
|
|
18958
|
+
</Source>
|
|
18959
|
+
{selected && (
|
|
18960
|
+
<Popup coordinates={selected.coordinates} onClose={() => setSelected(null)} closeButton>
|
|
18961
|
+
<PopupCard>
|
|
18962
|
+
<PopupHeader title={selected.name} />
|
|
18963
|
+
</PopupCard>
|
|
18964
|
+
</Popup>
|
|
18965
|
+
)}
|
|
18966
|
+
</Map>
|
|
18967
|
+
);`,
|
|
18968
|
+
svelte: `<script>
|
|
18969
|
+
let points = $state([]);
|
|
18970
|
+
let selected = $state(null);
|
|
18971
|
+
|
|
18972
|
+
const geojson = $derived({
|
|
18973
|
+
type: 'FeatureCollection',
|
|
18974
|
+
features: points.map(p => ({
|
|
18975
|
+
type: 'Feature',
|
|
18976
|
+
properties: { name: p.name, id: p.id },
|
|
18977
|
+
geometry: { type: 'Point', coordinates: p.coordinates }
|
|
18978
|
+
}))
|
|
18979
|
+
});
|
|
18980
|
+
</script>
|
|
18981
|
+
|
|
18982
|
+
<Map title="Dynamic Points">
|
|
18983
|
+
<Source id="points" type="geojson" data={geojson} generateId>
|
|
18984
|
+
<CircleLayer
|
|
18985
|
+
id="circles"
|
|
18986
|
+
source="points"
|
|
18987
|
+
circleRadius={10}
|
|
18988
|
+
circleColor="#3ba4a7"
|
|
18989
|
+
onClick={(e) => selected = { ...e.feature.properties, coordinates: e.lngLat }}
|
|
18990
|
+
onHover={() => {}}
|
|
18991
|
+
/>
|
|
18992
|
+
<SymbolLayer id="labels" source="points" textField={['get', 'name']} textOffset={[0, 1.5]} />
|
|
18993
|
+
</Source>
|
|
18994
|
+
{#if selected}
|
|
18995
|
+
<Popup coordinates={selected.coordinates} onClose={() => selected = null} closeButton>
|
|
18996
|
+
<PopupCard><PopupHeader title={selected.name} /></PopupCard>
|
|
18997
|
+
</Popup>
|
|
18998
|
+
{/if}
|
|
18999
|
+
</Map>`
|
|
19000
|
+
},
|
|
19001
|
+
comparisonTable: {
|
|
19002
|
+
description: "Comparison of dynamic data approaches",
|
|
19003
|
+
approaches: [
|
|
19004
|
+
{
|
|
19005
|
+
name: "Source + SymbolLayer (Recommended)",
|
|
19006
|
+
updateMechanism: "source.setData() on existing source",
|
|
19007
|
+
performance: "Single GPU draw call",
|
|
19008
|
+
cssImmunity: "Yes - rendered on canvas",
|
|
19009
|
+
useCase: "Most marker-like use cases, especially with many points"
|
|
19010
|
+
},
|
|
19011
|
+
{
|
|
19012
|
+
name: "DOM Markers",
|
|
19013
|
+
updateMechanism: "Create/destroy marker instances",
|
|
19014
|
+
performance: "O(n) DOM operations",
|
|
19015
|
+
cssImmunity: "No - CSS protection applied but not guaranteed",
|
|
19016
|
+
useCase: "Custom HTML content that can't be achieved with icons"
|
|
19017
|
+
}
|
|
19018
|
+
]
|
|
19019
|
+
}
|
|
19020
|
+
},
|
|
19021
|
+
mapboxMigration: {
|
|
19022
|
+
title: "Migrating from Mapbox GL",
|
|
19023
|
+
differences: [
|
|
19024
|
+
"No access token required (MapLibre is open source)",
|
|
19025
|
+
"Use `theme='light'` or `theme='dark'` instead of Mapbox style URLs",
|
|
19026
|
+
"Replace `mapboxgl.accessToken = 'pk...'` with nothing",
|
|
19027
|
+
"Replace `mapbox://styles/*` with theme prop or custom style URL",
|
|
19028
|
+
"Replace imperative `map.addLayer()` with declarative `<CircleLayer />` components",
|
|
19029
|
+
"Replace `map.on('click', layer, fn)` with `<Layer onClick={fn} />`"
|
|
19030
|
+
],
|
|
19031
|
+
exampleMigration: `// Before (Mapbox)
|
|
19032
|
+
import mapboxgl from 'mapbox-gl';
|
|
19033
|
+
mapboxgl.accessToken = 'pk.xxx';
|
|
19034
|
+
const map = new mapboxgl.Map({ container, style: 'mapbox://styles/...' });
|
|
19035
|
+
map.on('load', () => {
|
|
19036
|
+
map.addSource('data', { type: 'geojson', data });
|
|
19037
|
+
map.addLayer({ id: 'points', type: 'circle', source: 'data' });
|
|
19038
|
+
});
|
|
19039
|
+
|
|
19040
|
+
// After (Classic Theme)
|
|
19041
|
+
import { Map, Source, CircleLayer } from '@classic-homes/maps-react';
|
|
19042
|
+
|
|
19043
|
+
<Map title="Properties" center={[-122.4, 37.8]} zoom={12}>
|
|
19044
|
+
<Source id="data" type="geojson" data={geojson}>
|
|
19045
|
+
<CircleLayer id="points" source="data" circleRadius={8} onClick={handleClick} />
|
|
19046
|
+
</Source>
|
|
19047
|
+
</Map>`
|
|
19048
|
+
}
|
|
19049
|
+
},
|
|
19050
|
+
themeTypes: {
|
|
19051
|
+
description: "Theme-related TypeScript types",
|
|
19052
|
+
types: [
|
|
19053
|
+
{
|
|
19054
|
+
name: "MapTheme",
|
|
19055
|
+
description: "Complete theme configuration for maps",
|
|
19056
|
+
properties: [
|
|
19057
|
+
{ name: "name", type: "string", required: true, description: "Theme identifier ('classic-light' or 'classic-dark')" },
|
|
19058
|
+
{ name: "colors", type: "MapThemeColors", required: true, description: "UI and base colors" },
|
|
19059
|
+
{ name: "dataColors", type: "MapDataColors", required: true, description: "Data visualization colors" },
|
|
19060
|
+
{ name: "typography", type: "{ fontFamily: string; sizes: Record<string, number> }", required: true, description: "Typography settings" }
|
|
19061
|
+
]
|
|
19062
|
+
},
|
|
19063
|
+
{
|
|
19064
|
+
name: "MapThemeColors",
|
|
19065
|
+
description: "Theme colors for map UI elements",
|
|
19066
|
+
properties: [
|
|
19067
|
+
{ name: "background", type: "string", required: true, description: "Map background color" },
|
|
19068
|
+
{ name: "text", type: "string", required: true, description: "Primary text color" },
|
|
19069
|
+
{ name: "textMuted", type: "string", required: true, description: "Muted text color" },
|
|
19070
|
+
{ name: "border", type: "string", required: true, description: "Border color" },
|
|
19071
|
+
{ name: "water", type: "string", required: true, description: "Water feature color" },
|
|
19072
|
+
{ name: "land", type: "string", required: true, description: "Land/terrain color" },
|
|
19073
|
+
{ name: "road", type: "string", required: true, description: "Road color" },
|
|
19074
|
+
{ name: "building", type: "string", required: true, description: "Building color" },
|
|
19075
|
+
{ name: "park", type: "string", required: true, description: "Park/green space color" }
|
|
19076
|
+
]
|
|
19077
|
+
},
|
|
19078
|
+
{
|
|
19079
|
+
name: "MapDataColors",
|
|
19080
|
+
description: "Colors for data visualization layers (5 colors for series)",
|
|
19081
|
+
properties: [
|
|
19082
|
+
{ name: "primary", type: "string", required: true, description: "Primary data color (chart-1)" },
|
|
19083
|
+
{ name: "secondary", type: "string", required: true, description: "Secondary data color (chart-2)" },
|
|
19084
|
+
{ name: "tertiary", type: "string", required: true, description: "Tertiary data color (chart-3)" },
|
|
19085
|
+
{ name: "quaternary", type: "string", required: true, description: "Quaternary data color (chart-4)" },
|
|
19086
|
+
{ name: "quinary", type: "string", required: true, description: "Quinary data color (chart-5)" },
|
|
19087
|
+
{ name: "highlight", type: "string", required: true, description: "Highlight/hover color" },
|
|
19088
|
+
{ name: "selection", type: "string", required: true, description: "Selection color" }
|
|
19089
|
+
]
|
|
19090
|
+
},
|
|
19091
|
+
{
|
|
19092
|
+
name: "MapStyleSpec",
|
|
19093
|
+
description: "MapLibre style specification (StyleSpecification from maplibre-gl)"
|
|
19094
|
+
},
|
|
19095
|
+
{
|
|
19096
|
+
name: "ColorExpression",
|
|
19097
|
+
description: "MapLibre expression that evaluates to a color (string | Expression)"
|
|
19098
|
+
},
|
|
19099
|
+
{
|
|
19100
|
+
name: "NumberExpression",
|
|
19101
|
+
description: "MapLibre expression that evaluates to a number (number | Expression)"
|
|
19102
|
+
}
|
|
19103
|
+
]
|
|
19104
|
+
}
|
|
19105
|
+
};
|
|
19106
|
+
|
|
19107
|
+
// src/resources/maps.ts
|
|
19108
|
+
var catalog5 = maps_catalog_default;
|
|
19109
|
+
function registerMapsResources(server) {
|
|
19110
|
+
server.resource("Maps Core Package", "maps://all", async (uri) => ({
|
|
19111
|
+
contents: [
|
|
19112
|
+
{
|
|
19113
|
+
uri: uri.href,
|
|
19114
|
+
mimeType: "application/json",
|
|
19115
|
+
text: JSON.stringify(catalog5, null, 2)
|
|
19116
|
+
}
|
|
19117
|
+
]
|
|
19118
|
+
}));
|
|
19119
|
+
server.resource("Maps Theme", "maps://theme", async (uri) => ({
|
|
19120
|
+
contents: [
|
|
19121
|
+
{
|
|
19122
|
+
uri: uri.href,
|
|
19123
|
+
mimeType: "application/json",
|
|
19124
|
+
text: JSON.stringify(
|
|
19125
|
+
{
|
|
19126
|
+
importPath: catalog5.subpackages.theme.importPath,
|
|
19127
|
+
description: catalog5.subpackages.theme.description,
|
|
19128
|
+
functions: catalog5.subpackages.main.modules?.theme.functions
|
|
19129
|
+
},
|
|
19130
|
+
null,
|
|
19131
|
+
2
|
|
19132
|
+
)
|
|
19133
|
+
}
|
|
19134
|
+
]
|
|
19135
|
+
}));
|
|
19136
|
+
server.resource("Maps Types", "maps://types", async (uri) => ({
|
|
19137
|
+
contents: [
|
|
19138
|
+
{
|
|
19139
|
+
uri: uri.href,
|
|
19140
|
+
mimeType: "application/json",
|
|
19141
|
+
text: JSON.stringify(
|
|
19142
|
+
{
|
|
19143
|
+
importPath: catalog5.subpackages.types.importPath,
|
|
19144
|
+
description: "TypeScript types exported from @classic-homes/maps-core",
|
|
19145
|
+
props: catalog5.types.props,
|
|
19146
|
+
data: catalog5.types.data,
|
|
19147
|
+
events: catalog5.types.events
|
|
19148
|
+
},
|
|
19149
|
+
null,
|
|
19150
|
+
2
|
|
19151
|
+
)
|
|
19152
|
+
}
|
|
19153
|
+
]
|
|
19154
|
+
}));
|
|
19155
|
+
server.resource("Maps Utilities", "maps://utils", async (uri) => ({
|
|
19156
|
+
contents: [
|
|
19157
|
+
{
|
|
19158
|
+
uri: uri.href,
|
|
19159
|
+
mimeType: "application/json",
|
|
19160
|
+
text: JSON.stringify(
|
|
19161
|
+
{
|
|
19162
|
+
importPath: catalog5.subpackages.main.importPath,
|
|
19163
|
+
description: "Utility functions for formatting, accessibility, and styling",
|
|
19164
|
+
format: catalog5.subpackages.main.modules?.format,
|
|
19165
|
+
accessibility: catalog5.subpackages.main.modules?.accessibility,
|
|
19166
|
+
styles: catalog5.subpackages.main.modules?.styles
|
|
19167
|
+
},
|
|
19168
|
+
null,
|
|
19169
|
+
2
|
|
19170
|
+
)
|
|
19171
|
+
}
|
|
19172
|
+
]
|
|
19173
|
+
}));
|
|
19174
|
+
server.resource("Maps Components", "maps://components", async (uri) => ({
|
|
19175
|
+
contents: [
|
|
19176
|
+
{
|
|
19177
|
+
uri: uri.href,
|
|
19178
|
+
mimeType: "application/json",
|
|
19179
|
+
text: JSON.stringify(catalog5.components, null, 2)
|
|
19180
|
+
}
|
|
19181
|
+
]
|
|
19182
|
+
}));
|
|
19183
|
+
server.resource("Maps Quick Reference", "maps://quick-reference", async (uri) => ({
|
|
19184
|
+
contents: [
|
|
19185
|
+
{
|
|
19186
|
+
uri: uri.href,
|
|
19187
|
+
mimeType: "text/markdown",
|
|
19188
|
+
text: `# Maps Core Quick Reference
|
|
19189
|
+
|
|
19190
|
+
## Installation
|
|
19191
|
+
|
|
19192
|
+
\`\`\`bash
|
|
19193
|
+
${catalog5.quickReference.installation}
|
|
19194
|
+
\`\`\`
|
|
19195
|
+
|
|
19196
|
+
## Basic Usage
|
|
19197
|
+
|
|
19198
|
+
\`\`\`typescript
|
|
19199
|
+
${catalog5.quickReference.basicUsage}
|
|
19200
|
+
\`\`\`
|
|
19201
|
+
|
|
19202
|
+
## Peer Dependency
|
|
19203
|
+
|
|
19204
|
+
\`${catalog5.quickReference.peerDependency}\`
|
|
19205
|
+
|
|
19206
|
+
## Optional Peer Dependencies (for Deck.gl)
|
|
19207
|
+
|
|
19208
|
+
\`${catalog5.quickReference.optionalPeerDependencies}\`
|
|
19209
|
+
|
|
19210
|
+
## Available Components
|
|
19211
|
+
|
|
19212
|
+
**React:** \`@classic-homes/maps-react\`
|
|
19213
|
+
- ${catalog5.components.react.components.join(", ")}
|
|
19214
|
+
|
|
19215
|
+
**Svelte:** \`@classic-homes/maps-svelte\`
|
|
19216
|
+
- ${catalog5.components.svelte.components.join(", ")}
|
|
19217
|
+
|
|
19218
|
+
## Theme Exports
|
|
19219
|
+
|
|
19220
|
+
- \`generateLightTheme()\` - Generate light theme from tokens
|
|
19221
|
+
- \`generateDarkTheme()\` - Generate dark theme from tokens
|
|
19222
|
+
- \`lightTheme\` - Pre-generated light theme
|
|
19223
|
+
- \`darkTheme\` - Pre-generated dark theme
|
|
19224
|
+
- \`lightBasicStyle\` - Pre-generated light MapLibre style
|
|
19225
|
+
- \`darkBasicStyle\` - Pre-generated dark MapLibre style
|
|
19226
|
+
- \`THEME_LIGHT\` - Constant: 'classic-light'
|
|
19227
|
+
- \`THEME_DARK\` - Constant: 'classic-dark'
|
|
19228
|
+
|
|
19229
|
+
## Layer Types
|
|
19230
|
+
|
|
19231
|
+
- **FillLayer** - Polygon fills (choropleth, areas)
|
|
19232
|
+
- **LineLayer** - Lines (routes, borders)
|
|
19233
|
+
- **CircleLayer** - Point circles
|
|
19234
|
+
- **SymbolLayer** - Icons and text labels
|
|
19235
|
+
- **FillExtrusionLayer** - 3D building extrusions
|
|
19236
|
+
- **HeatmapLayer** - Point density visualization
|
|
19237
|
+
- **DeckOverlay** - Deck.gl integration for advanced WebGL
|
|
19238
|
+
|
|
19239
|
+
## Formatting Utilities
|
|
19240
|
+
|
|
19241
|
+
- \`formatCoordinates(coordinates, precision?, format?)\` - Format coordinates (decimal, DMS, or DD)
|
|
19242
|
+
- \`formatDistance(meters, unit?)\` - Format distance (metric or imperial)
|
|
19243
|
+
- \`formatArea(sqMeters, unit?)\` - Format area (metric or imperial)
|
|
19244
|
+
- \`formatBounds(bounds)\` - Format bounding box
|
|
19245
|
+
|
|
19246
|
+
## Accessibility Utilities
|
|
19247
|
+
|
|
19248
|
+
- \`generateMapDescription(title, options?)\` - Accessible map description
|
|
19249
|
+
- \`generateFeatureCollectionDescription(collection, name?)\` - Describe features
|
|
19250
|
+
- \`KEYBOARD_CONTROLS\` - Keyboard shortcut descriptions
|
|
19251
|
+
|
|
19252
|
+
## Styling Utilities
|
|
19253
|
+
|
|
19254
|
+
- \`createHoverExpression(baseColor, hoverColor)\` - Hover state expression
|
|
19255
|
+
- \`createSelectionExpression(baseColor, selectedColor)\` - Selection expression
|
|
19256
|
+
- \`getHighlightStyle(theme)\` - Highlight style properties
|
|
19257
|
+
- \`getSelectionStyle(theme)\` - Selection style properties
|
|
19258
|
+
|
|
19259
|
+
## React Hooks
|
|
19260
|
+
|
|
19261
|
+
- \`useMap()\` - Access map instance and state from context
|
|
19262
|
+
- \`useMapInstance()\` - Get map instance when loaded (returns null otherwise)
|
|
19263
|
+
- \`useMapTheme(theme?)\` - Get resolved theme, map theme object, and style
|
|
19264
|
+
- \`useReducedMotion()\` - Detect user's motion preference
|
|
19265
|
+
- \`useLayer(options)\` - Add custom layers with automatic lifecycle
|
|
19266
|
+
|
|
19267
|
+
## CSS Import Order
|
|
19268
|
+
|
|
19269
|
+
\`\`\`css
|
|
19270
|
+
@import '@classic-homes/theme-styles';
|
|
19271
|
+
@import 'maplibre-gl/dist/maplibre-gl.css';
|
|
19272
|
+
@import '@classic-homes/maps-core/styles/controls.css';
|
|
19273
|
+
@import '@classic-homes/maps-core/styles/popup.css';
|
|
19274
|
+
|
|
19275
|
+
@tailwind base;
|
|
19276
|
+
@tailwind components;
|
|
19277
|
+
@tailwind utilities;
|
|
19278
|
+
\`\`\`
|
|
19279
|
+
`
|
|
19280
|
+
}
|
|
19281
|
+
]
|
|
19282
|
+
}));
|
|
19283
|
+
server.resource("Maps Props Types", "maps://props", async (uri) => ({
|
|
19284
|
+
contents: [
|
|
19285
|
+
{
|
|
19286
|
+
uri: uri.href,
|
|
19287
|
+
mimeType: "application/json",
|
|
19288
|
+
text: JSON.stringify(catalog5.types.props, null, 2)
|
|
19289
|
+
}
|
|
19290
|
+
]
|
|
19291
|
+
}));
|
|
19292
|
+
server.resource("Maps Data Types", "maps://data", async (uri) => ({
|
|
19293
|
+
contents: [
|
|
19294
|
+
{
|
|
19295
|
+
uri: uri.href,
|
|
19296
|
+
mimeType: "application/json",
|
|
19297
|
+
text: JSON.stringify(catalog5.types.data, null, 2)
|
|
19298
|
+
}
|
|
19299
|
+
]
|
|
19300
|
+
}));
|
|
19301
|
+
server.resource("Maps Event Types", "maps://events", async (uri) => ({
|
|
19302
|
+
contents: [
|
|
19303
|
+
{
|
|
19304
|
+
uri: uri.href,
|
|
19305
|
+
mimeType: "application/json",
|
|
19306
|
+
text: JSON.stringify(catalog5.types.events, null, 2)
|
|
19307
|
+
}
|
|
19308
|
+
]
|
|
19309
|
+
}));
|
|
19310
|
+
server.resource("Maps React Hooks", "maps://hooks", async (uri) => ({
|
|
19311
|
+
contents: [
|
|
19312
|
+
{
|
|
19313
|
+
uri: uri.href,
|
|
19314
|
+
mimeType: "application/json",
|
|
19315
|
+
text: JSON.stringify(
|
|
19316
|
+
{
|
|
19317
|
+
package: catalog5.components.react.package,
|
|
19318
|
+
hooks: catalog5.components.react.hooks,
|
|
19319
|
+
context: catalog5.components.react.context
|
|
19320
|
+
},
|
|
19321
|
+
null,
|
|
19322
|
+
2
|
|
19323
|
+
)
|
|
19324
|
+
}
|
|
19325
|
+
]
|
|
19326
|
+
}));
|
|
19327
|
+
server.resource("Maps Best Practices", "maps://best-practices", async (uri) => ({
|
|
19328
|
+
contents: [
|
|
19329
|
+
{
|
|
19330
|
+
uri: uri.href,
|
|
19331
|
+
mimeType: "application/json",
|
|
19332
|
+
text: JSON.stringify(catalog5.bestPractices, null, 2)
|
|
19333
|
+
}
|
|
19334
|
+
]
|
|
19335
|
+
}));
|
|
19336
|
+
server.resource("Maps Theme Types", "maps://theme-types", async (uri) => ({
|
|
19337
|
+
contents: [
|
|
19338
|
+
{
|
|
19339
|
+
uri: uri.href,
|
|
19340
|
+
mimeType: "application/json",
|
|
19341
|
+
text: JSON.stringify(catalog5.themeTypes, null, 2)
|
|
19342
|
+
}
|
|
19343
|
+
]
|
|
19344
|
+
}));
|
|
19345
|
+
server.resource("Maps Migration Guide", "maps://migration", async (uri) => ({
|
|
19346
|
+
contents: [
|
|
19347
|
+
{
|
|
19348
|
+
uri: uri.href,
|
|
19349
|
+
mimeType: "text/markdown",
|
|
19350
|
+
text: `# Migrating from Mapbox GL to Classic Theme Maps
|
|
19351
|
+
|
|
19352
|
+
## Key Differences
|
|
19353
|
+
|
|
19354
|
+
${catalog5.bestPractices?.mapboxMigration.differences?.map((d) => `- ${d}`).join("\n")}
|
|
19355
|
+
|
|
19356
|
+
## Example Migration
|
|
19357
|
+
|
|
19358
|
+
\`\`\`typescript
|
|
19359
|
+
${catalog5.bestPractices?.mapboxMigration.exampleMigration}
|
|
19360
|
+
\`\`\`
|
|
19361
|
+
|
|
19362
|
+
## CSS Setup
|
|
19363
|
+
|
|
19364
|
+
\`\`\`css
|
|
19365
|
+
${catalog5.quickReference.cssImportOrder}
|
|
19366
|
+
\`\`\`
|
|
19367
|
+
|
|
19368
|
+
## Tailwind Configuration
|
|
19369
|
+
|
|
19370
|
+
\`\`\`javascript
|
|
19371
|
+
${catalog5.quickReference.tailwindConfig}
|
|
19372
|
+
\`\`\`
|
|
19373
|
+
`
|
|
19374
|
+
}
|
|
19375
|
+
]
|
|
19376
|
+
}));
|
|
19377
|
+
}
|
|
19378
|
+
|
|
17368
19379
|
// src/resources/index.ts
|
|
17369
19380
|
function registerResources(server) {
|
|
17370
19381
|
registerComponentResources(server);
|
|
@@ -17376,11 +19387,12 @@ function registerResources(server) {
|
|
|
17376
19387
|
registerNotificationsResources(server);
|
|
17377
19388
|
registerDocsResources(server);
|
|
17378
19389
|
registerChartsResources(server);
|
|
19390
|
+
registerMapsResources(server);
|
|
17379
19391
|
}
|
|
17380
19392
|
|
|
17381
19393
|
// src/tools/searchComponents.ts
|
|
17382
19394
|
import { z } from "zod";
|
|
17383
|
-
var
|
|
19395
|
+
var catalog6 = component_catalog_default;
|
|
17384
19396
|
var SearchComponentsSchema = z.object({
|
|
17385
19397
|
query: z.string().describe("Search query (component name, description, or functionality)"),
|
|
17386
19398
|
category: z.enum([
|
|
@@ -17406,7 +19418,7 @@ function registerSearchComponentsTool(server) {
|
|
|
17406
19418
|
const queryLower = query.toLowerCase().trim();
|
|
17407
19419
|
const isListAll = queryLower === "*" || queryLower === "all" || queryLower === "" || queryLower === "list" || queryLower === "list all";
|
|
17408
19420
|
const queryWords = queryLower.split(/\s+/).filter((word) => word.length > 0);
|
|
17409
|
-
const results =
|
|
19421
|
+
const results = catalog6.components.filter((component) => {
|
|
17410
19422
|
if (category && component.category !== category) {
|
|
17411
19423
|
return false;
|
|
17412
19424
|
}
|
|
@@ -17473,7 +19485,7 @@ function registerSearchComponentsTool(server) {
|
|
|
17473
19485
|
|
|
17474
19486
|
// src/tools/getComponentProps.ts
|
|
17475
19487
|
import { z as z2 } from "zod";
|
|
17476
|
-
var
|
|
19488
|
+
var catalog7 = component_catalog_default;
|
|
17477
19489
|
var GetComponentPropsSchema = z2.object({
|
|
17478
19490
|
componentName: z2.string().describe('Name of the component (e.g., "Button", "DashboardLayout")'),
|
|
17479
19491
|
includeExamples: z2.boolean().default(true).describe("Whether to include usage examples")
|
|
@@ -17485,11 +19497,11 @@ function registerGetComponentPropsTool(server) {
|
|
|
17485
19497
|
GetComponentPropsSchema.shape,
|
|
17486
19498
|
async (params) => {
|
|
17487
19499
|
const { componentName, includeExamples } = GetComponentPropsSchema.parse(params);
|
|
17488
|
-
const component =
|
|
19500
|
+
const component = catalog7.components.find(
|
|
17489
19501
|
(c) => c.name.toLowerCase() === componentName.toLowerCase()
|
|
17490
19502
|
);
|
|
17491
19503
|
if (!component) {
|
|
17492
|
-
const suggestions =
|
|
19504
|
+
const suggestions = catalog7.components.filter((c) => c.name.toLowerCase().includes(componentName.toLowerCase().slice(0, 3))).slice(0, 5).map((c) => c.name);
|
|
17493
19505
|
return {
|
|
17494
19506
|
content: [
|
|
17495
19507
|
{
|
|
@@ -17634,7 +19646,7 @@ function registerSuggestPatternTool(server) {
|
|
|
17634
19646
|
|
|
17635
19647
|
// src/tools/validateUsage.ts
|
|
17636
19648
|
import { z as z4 } from "zod";
|
|
17637
|
-
var
|
|
19649
|
+
var catalog8 = component_catalog_default;
|
|
17638
19650
|
var ValidateUsageSchema = z4.object({
|
|
17639
19651
|
componentName: z4.string().describe("Name of the component being used"),
|
|
17640
19652
|
props: z4.record(z4.unknown()).describe("Props being passed to the component"),
|
|
@@ -17647,7 +19659,7 @@ function registerValidateUsageTool(server) {
|
|
|
17647
19659
|
ValidateUsageSchema.shape,
|
|
17648
19660
|
async (params) => {
|
|
17649
19661
|
const { componentName, props, context } = ValidateUsageSchema.parse(params);
|
|
17650
|
-
const component =
|
|
19662
|
+
const component = catalog8.components.find(
|
|
17651
19663
|
(c) => c.name.toLowerCase() === componentName.toLowerCase()
|
|
17652
19664
|
);
|
|
17653
19665
|
if (!component) {
|
|
@@ -17960,7 +19972,7 @@ Example for ${pageType}Layout:
|
|
|
17960
19972
|
|
|
17961
19973
|
// src/prompts/componentUsage.ts
|
|
17962
19974
|
import { z as z7 } from "zod";
|
|
17963
|
-
var
|
|
19975
|
+
var catalog9 = component_catalog_default;
|
|
17964
19976
|
var ComponentUsageSchema = z7.object({
|
|
17965
19977
|
componentName: z7.string().describe("Name of the component (e.g., Button, Card, Select)"),
|
|
17966
19978
|
variant: z7.string().optional().describe("Desired variant (optional)"),
|
|
@@ -17976,7 +19988,7 @@ function registerComponentUsagePrompt(server) {
|
|
|
17976
19988
|
const componentName = parsed.componentName || "Button";
|
|
17977
19989
|
const variant = parsed.variant || "";
|
|
17978
19990
|
const useCase = parsed.useCase || "";
|
|
17979
|
-
const component =
|
|
19991
|
+
const component = catalog9.components.find(
|
|
17980
19992
|
(c) => c.name.toLowerCase() === componentName.toLowerCase()
|
|
17981
19993
|
);
|
|
17982
19994
|
let componentInfo = "";
|
|
@@ -17998,7 +20010,7 @@ ${component.examples.map((e) => `### ${e.title}
|
|
|
17998
20010
|
${e.code}
|
|
17999
20011
|
\`\`\``).join("\n\n")}`;
|
|
18000
20012
|
} else {
|
|
18001
|
-
componentInfo = `Component "${componentName}" not found in catalog. Available components: ${
|
|
20013
|
+
componentInfo = `Component "${componentName}" not found in catalog. Available components: ${catalog9.components.map((c) => c.name).join(", ")}`;
|
|
18002
20014
|
}
|
|
18003
20015
|
return {
|
|
18004
20016
|
messages: [
|