Extras
Map
BitMap is a provider-pluggable interactive map. The same API drives markers, vector shapes, GeoJSON layers and tile overlays across seven backends - Leaflet, MapLibre GL, Mapbox GL, OpenLayers, ArcGIS, Azure Maps and CesiumJS - with two-way bound camera and marker collections on top. It also supplies what the backends leave out, uniformly: marker clustering, popups whose content is live Blazor markup, container auto-resizing, cooperative gestures, a keyboard and screen-reader story, geodesic distance and bounding-box arithmetic, and explicit loading, failure and unsupported states.
Notes
To use this component, install the
Bit.BlazorUI.Extras(opens in a new tab)
nuget package.
BitMap<TMapProvider> is generic - choose a provider class as the type argument and pass a configured instance via Provider.
Providers: BitLeafletMapProvider, BitMapLibreMapProvider, BitMapboxMapProvider,
BitOpenLayersMapProvider, BitArcGisMapProvider, BitAzureMapsMapProvider, BitCesiumMapProvider.
Mapbox, Azure Maps, and ArcGIS (for non-OSM basemaps) require an API key on the provider instance.
The provider is compared by reference, so mutating an instance you already passed in does not push anything to the
map - assign a new instance to apply changed options. Everything else is imperative: hold a @ref and
wait for OnReady before calling a map method.
For anything this component does not model, AdditionalOptions on the provider is passed straight through
to the underlying library's map constructor and merged last, so it also overrides what the component does model.
Leaflet, MapLibre and Mapbox honour it; the rest split their configuration across several objects with no single
place to put it.
Usage
Every example is live. Open its code to see exactly what produced the component running underneath.
Basic
The map fills its container, so give that container a height - a map inside a parent with no height of its own collapses to nothing.
Markers
PopupHtml renders raw HTML and PopupText is escaped for you - pass anything
user-supplied through the latter. Set Alt on every marker: it becomes the accessible name, and
without one a screen reader reads a row of indistinguishable "marker" entries.
Wait for
OnReady before calling any map method; until then the underlying map does not exist yet and
the call throws. SyncMarkers replaces the whole set in a single interop call, which is worth reaching
for over a loop of AddMarker on a Blazor Server circuit.
Seed markers are added on OnReady. Try the buttons.
Vectors
BitMapVectorPathStyle covers stroke colour, width, opacity, dash pattern and offset, line cap and
join, and the fill. Note Fill = false is not the same as a zero fill opacity: an invisible fill is
still rendered and still swallows clicks. Clicking a shape raises OnVectorClick with the layer id,
the kind of geometry, and where the click landed.
Click Redraw to draw shapes, then click a shape.
GeoJSON
Clicking a feature raises
OnGeoJsonFeatureClick with that feature's properties as a
JsonElement, so you can read whatever fields your data actually carries without modelling them
up front. Treat those properties as untrusted: they are data, and rendering them as HTML is how a GeoJSON
document turns into a script injection.
Click 'Load GeoJSON', then click a feature.
Custom tiles
Provider instance - any XYZ template with
{z}, {x} and {y} placeholders is accepted, plus the optional
{s} subdomain.
Set
TileAttribution to whatever the tile source requires. This is a licence term, not decoration:
OpenStreetMap-derived tiles must credit "© OpenStreetMap contributors" visibly, and the public
tile.openstreetmap.org server is explicitly not for production traffic.
Events
OnClick and OnDoubleClick report where the pointer landed, and only when the click did
not hit a marker or a vector layer - those raise their own events instead.
OnViewChanged fires after a pan or zoom settles. Every provider coalesces the burst of move and zoom
events a single drag produces into one notification per idle window, because each one is an interop round-trip -
a SignalR message per event under Blazor Server. GetView reads the same snapshot on demand.
OnContextMenu reports a right-click (or a long press on touch) with the coordinate under the
pointer - the usual way to offer "add a marker here". The browser's own menu still opens unless the provider
sets SuppressBrowserContextMenu; only suppress it when you put a menu of your own in its place,
because taking it away costs the user "open in new tab", "copy image" and their assistive-technology equivalents.
Pan/zoom or click the map.
Advanced
ScrollWheelZoom, Dragging,
DoubleClickZoom, BoxZoom, KeyboardNavigation), the scale bar, and
MaxBounds to keep the user inside a region. Changing any of them means assigning a new provider
instance - the parameter is compared by reference.
On top of the basemap,
AddTileOverlay stacks a second XYZ source with its own opacity and stacking
order, which is how weather radar, labels or a heat layer are usually delivered.
Marker tooltips appear on hover - and on keyboard focus, since a marker is a tab stop - on Leaflet, MapLibre, Mapbox, OpenLayers and Azure Maps; ArcGIS and Cesium have no equivalent and use
Title instead. ZIndexOffset is Leaflet-only. Each type's reference notes which
backend honours what, because a parameter silently ignored by the provider you happen to be using is
worse than one that is not there.
Toggle options or use the buttons.
Navigation
ZoomIn/ZoomOut step by whole zoom levels,
SetZoom jumps to an absolute one, PanBy shifts the view by a pixel offset,
and PanTo recentres on a coordinate without touching the zoom the user chose.
The pan buttons are not just a convenience. WCAG 2.2 requires a single-pointer alternative to dragging (SC 2.5.7), so a map that can only be panned by dragging fails an audit -
PanBy is what you
build that alternative from.
FlyTo animates the move. When the visitor has asked their system for reduced motion,
RespectReducedMotion (on by default) turns that flight into an instant jump to the same place;
pass essential: true for a move whose motion is what carries the meaning.
Locate asks the browser for the visitor's position - the browser shows its own permission
prompt, and a refusal comes back as null rather than an exception.
Use the buttons to drive the camera from code.
Accessibility
AriaLabel, and described by
KeyboardInstructions - which assistive tech reads and sighted keyboard users see the moment
the map takes focus. EscapeToExit (on by default) lets Escape return focus to the page, so a
focused map is never a keyboard trap.
AnnounceViewChanges reports the new centre and zoom through a polite live region, throttled by
ViewAnnouncementThrottle so a drag cannot flood the screen reader. Supply
ViewAnnouncementFormatter to announce a place name instead of a pair of decimals - far more
useful to someone who cannot see the map.
CooperativeGestures stops the map swallowing the page scroll: a bare wheel scrolls the page
and shows a hint, ctrl (⌘ on macOS) + wheel zooms, and on touch one finger scrolls while two fingers pan.
Turn it on for any map embedded in a longer page.
None of that reaches the markers themselves, though: a map is a picture, and its pins are drawn rather than written.
MarkerListMode renders the same markers as a table - name, coordinates, and a
button that brings each one into view and raises the same OnMarkerClick a mouse user gets.
ScreenReaderOnly leaves the map looking untouched while making that table reachable;
Visible shows it to everyone, which is often the better answer for a store locator. It is
also what survives being printed.
| Name | Latitude | Longitude | Show on map |
|---|
Loading and lifecycle
LoadState distinguishes the four things that can happen on the way to a rendered map -
Idle, Loading, Ready, Failed, and
Unsupported for a browser that cannot give a WebGL-backed provider a context at all.
OnLoadStateChanged reports every transition; LoadingTemplate,
ErrorTemplate and UnsupportedTemplate replace the built-in messages.
AutoResize (on by default) watches the container and re-measures the map itself, which also
covers the classic case of a map inside a collapsed panel that would otherwise render grey forever - drag
the resize handle below to see it. LazyLoad defers creating the map until it scrolls into
view, so a map below the fold does not compete with the page's first paint.
Data binding
@bind-Center and @bind-Zoom make the camera ordinary Blazor state: assigning
either moves the map, and panning or zooming writes the new value straight back into your field. The
component diffs the two directions against the map's last reported viewport, so echoing a value the map
itself produced does not move it again.
Markers takes the whole set as a collection instead of a sequence of imperative calls.
BitMapMarker is a record, so the component compares the incoming markers by value against
what is already rendered and touches only the ones that changed - which matters beyond speed, because
re-adding a marker closes its open popup and drops its keyboard focus. When most of the set changed it
replaces everything in one batched call instead.
Markers are keyboard-reachable by default: Tab moves between them and Enter or Space opens the popup. Set
Focusable="false" on decorative pins, and give every meaningful one an Alt
so it announces as a place rather than as "marker".
Clustering
Clustering and nearby markers collapse into a bubble showing how many they stand for;
clicking one zooms to fit its members. The map below carries 500 markers - drawn
individually they are unreadable, and each one is its own DOM node and its own keyboard tab stop.
The grouping runs inside BitMap, in screen space, above whichever provider is active - so it behaves the same on all seven backends instead of needing a Leaflet plugin here and a GeoJSON source there. Screen space rather than degrees matters: a fixed distance in degrees covers far less ground near the poles, so a degree-based radius over-clusters at high latitudes.
RadiusPixels sets how aggressively markers merge, MaxZoom the level at which
they all separate again, and CullOffscreen (on by default) keeps markers outside the
viewport from reaching the provider at all - that is most of the performance win.
OnClusterClick fires instead of OnMarkerClick, because a bubble is not one of
your markers - and it reports the count either way, so turning ZoomOnClick off to handle
the click yourself still tells you how big the bubble was. A bubble is a keyboard-reachable marker with
a name of its own, so that name is translatable too: AriaLabelFormat sets it, with
{0} standing for the count.
Click a bubble to zoom into it, or a single pin for its own click event.
Layer control
SetLayerVisible and SetTileOverlayVisible toggle something off the map while
keeping its definition, so switching it back on needs no re-declaration - and a provider swap brings it
back in whatever state you left it. Prefer this to a zero opacity: an invisible layer is still drawn and
still hit-tested, so it goes on swallowing clicks meant for what is underneath.
SetLayerStyle restyles a shape without restating its geometry, and
SetTileOverlayOpacity blends a raster overlay against the basemap - the usual way weather
or heat data is layered over a street map. A tile overlay also takes a
MinZoom/MaxZoom window, so a source that only publishes some zooms does not
answer with a grid of 404s, and Subdomains for sources that shard tiles across hostnames.
ClearTileOverlays takes them all off at once, the counterpart of
ClearMarkers and ClearVectorLayers.
RequestFullscreen takes the map's own container fullscreen rather than the page, so your
overlay content and controls go with it. Call it from a real click: browsers only honour the request
inside the short activation window a gesture opens. OnFullscreenChanged reports the state
either way, including when the user leaves with Escape.
Toggle the area and the overlay, or restyle the area in place.
Popup content
MarkerPopupTemplate makes a popup's content ordinary Blazor markup instead of an HTML string.
That is worth preferring over PopupHtml for two reasons. Blazor escapes what it renders, so a
popup built from data you do not control cannot become an injection point - the whole class of bug that a
raw-HTML popup puts on you. And the content is live: components, event handlers, bindings and validation
all work inside it, where an HTML string is inert. Click a marker below and use the button in its popup.
The popup is rendered by BitMap and pinned to its marker, so it looks and behaves the same on all seven backends rather than inheriting each vendor's. It is a
role="dialog" named after its marker;
opening it moves keyboard focus inside, Escape closes it and hands focus back to the map, and a click
elsewhere on the map or the popup's own close button dismisses it. It follows its marker when the
marker moves, and closes itself if that marker leaves the map.
The mechanics are worth knowing if you build something similar: the popup's DOM stays exactly where Blazor put it and only its
transform is driven from JavaScript, recomputed per animation frame.
Handing that DOM to the mapping library's own popup would move it out of the container Blazor patches by
position, and the next render of that region would corrupt or throw.
Click a marker, then use the button inside its popup.
MapLibre GL
The library is fetched from a CDN on first render, so it needs a
script-src entry and a WebGL-capable
browser; without one the component shows its unsupported state rather than a blank canvas.
OpenLayers
'unsafe-eval' in your CSP. No token required; it defaults to OpenStreetMap
raster tiles.
OpenLayers is the backend to reach for when the work is GIS-shaped rather than map-shaped: it is the only one here with first-class support for arbitrary projections and a wide format library.
Mapbox GL (token required)
mapbox:// styles.
To get started:
- Create a free account at mapbox.com(opens in a new tab)
- Copy your default public token from the Access Tokens(opens in a new tab) page
- Pass it to
BitMapboxMapProvider.AccessToken
Security: only ship a public token (
pk.*) to the browser, never a secret token (sk.*).
Public tokens are visible to anyone using your site, so restrict each token to your production domains via the
URL allowlist on the Access Tokens(opens in a new tab) page,
set a billing cap, and use a separate token per environment so you can rotate or revoke without downtime.
For stricter scenarios, mint a short-lived token from a server endpoint or proxy tile requests through your backend.
ArcGIS Maps SDK
osm basemap works without an API key.
Security: if you supply an API key for non-OSM basemaps, configure HTTP referrer restrictions on the key in the ArcGIS Developer dashboard(opens in a new tab) so it can only be used from your own domains, and scope it to the minimum required services.
Azure Maps (subscription key required)
To get started:
- Create an Azure Maps account in the Azure Portal(opens in a new tab)
- Navigate to your Maps account → Authentication → Shared Key Authentication
- Copy the Primary Key and pass it to
BitAzureMapsMapProvider.SubscriptionKey
Security: shipping a shared subscription key to the browser is fine for demos but not recommended for production. For production, prefer Microsoft Entra ID or SAS token authentication: a backend mints a short-lived token and the client uses that instead of the primary key. If you must use a subscription key, restrict allowed origins on the Maps account and set usage alerts so a leaked key cannot quietly drain your quota.
CesiumJS 3D globe
Security: if you provide a Cesium ion token, create a dedicated token in the Cesium ion dashboard(opens in a new tab), grant only the asset access it needs, and add your production domains to the token's allowed URLs list so a copied token cannot be used from other origins.
Marker icons
IconUrl replaces the default pin with an image of your own, sized by
IconWidth and IconHeight. The icons below are inline SVG data URIs, so
they cost no extra request and can be recoloured from the same C# that builds the marker.
IconAnchorX and IconAnchorY say which pixel of the image sits on the
coordinate, measured from its top-left corner. They default to the bottom centre, which is where a
pin's tip is - so an icon that is a disc rather than a pin renders half a diameter too high until
you anchor it at its own centre. Toggle it below: the ring marks the true coordinate, and only the
centre-anchored disc actually sits on it.
Getting this right matters beyond neatness. An unanchored icon is off by its own height, which at street zoom is most of a city block - enough to put a delivery pin on the wrong side of the road.
Geographic helpers
BitMapLatLng and BitMapLatLngBounds carry the arithmetic that map work
keeps needing, so it does not have to be rewritten - badly - in every app.
DistanceTo measures the great-circle distance in metres, Offset travels a
distance along a bearing, and ToBounds turns a radius into the box that frames it.
Click anywhere on the map to drop a probe and see all three.
BitMapLatLngBounds answers the questions a viewport raises:
FromMarkers and FromCoordinates build the smallest box around a set,
Contains and Intersects test it, Extend grows it to take in
one more place, and Pad leaves breathing room in map units rather than pixels. Boxes
that cross the antimeridian are handled the short way round, which is where a hand-rolled min/max
quietly produces a box wrapping the wrong way across the globe.
FitBounds takes both a pixel padding and a maxZoom ceiling - without the
ceiling, framing a box around a single place drops you to street level.
PanTo moves the centre while keeping the current zoom, and Project
reports where a coordinate currently sits inside the container in CSS pixels, which is what you
position an overlay of your own from.
Click the map to drop a probe.
Style & Class
Style and Class land on the map's root element. The root is
position:relative and fills its container, so this is also where you set the map's height -
a map inside a parent with no height of its own collapses to nothing.
RTL
Dir="BitDir.Rtl" for right-to-left pages. The map canvas itself is direction-neutral -
what flips is the component's own chrome: the keyboard-instructions panel, the cooperative-gestures hint,
and any content you place in ChildContent.
API
Every parameter, public member, sub-class and enum this component exposes.
BitMap parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| TMapProvider | Type (generic) | The map provider type. One of: BitLeafletMapProvider, BitMapLibreMapProvider, BitMapboxMapProvider, BitOpenLayersMapProvider, BitArcGisMapProvider, BitAzureMapsMapProvider, BitCesiumMapProvider. | |
| Provider | TMapProvider? | null | Provider configuration instance (center, zoom, tokens, etc.). When null a default instance is created. |
| Center | BitMapLatLng? | null | Two-way bindable centre. Assigning it moves the map, and panning the map writes the new centre back. Leave it unset to let the provider's Center own the camera. |
| Zoom | double? | null | Two-way bindable zoom level. Behaves like Center: assigning it zooms the map, and zooming the map writes the new level back. |
| Markers | IEnumerable<BitMapMarker>? | null | The markers the map should show, as a collection instead of imperative calls. Markers compare by value, so only the ones that actually changed are sent; a wholesale change is replaced in one batched call. This parameter owns the marker set - mixing it with AddMarker/RemoveMarker means the next collection change reconciles those away. |
| ChildContent | RenderFragment? | null | Optional content rendered above the map canvas. |
| Clustering | BitMapClustering? | null | Groups nearby markers into a bubble showing how many they stand for, and expands it on click. The grouping runs inside BitMap in screen space, so it behaves identically on all seven backends. While it is on, the markers you add are the source set and BitMap decides what the provider actually draws. |
| OnClusterClick | EventCallback<BitMapClusterClickArgs> | Fires when the user clicks a cluster bubble, instead of OnMarkerClick - a cluster is not one of your markers. | |
| MarkerPopupTemplate | RenderFragment<BitMapMarker>? | null | Content of the popup that opens when a marker is clicked, as live Blazor markup rather than an HTML string - so it is escaped automatically, and components, event handlers and bindings work inside it. Rendered by BitMap and pinned to its marker, so it behaves the same on all seven backends. |
| PopupLabel | string | Marker details | Accessible name of the popup when its marker has neither an Alt nor a Title. |
| PopupCloseLabel | string | Close | Accessible name of the popup's close button. |
| OnPopupOpened | EventCallback<BitMapMarker> | Fires when a MarkerPopupTemplate popup opens, with the marker it belongs to. | |
| OnPopupClosed | EventCallback | Fires when a MarkerPopupTemplate popup closes. | |
| MarkerListMode | BitMapMarkerListMode | BitMapMarkerListMode.None | Renders a text alternative to the markers - a table of names and coordinates whose rows bring their marker into view. A map is a picture, so its markers are unreachable to a screen reader no matter how well the canvas is labelled; ScreenReaderOnly leaves the map looking unchanged while making the same data reachable. |
| MarkerListTemplate | RenderFragment<IReadOnlyList<BitMapMarker>>? | null | Replaces the built-in marker table. Receives the markers in no guaranteed order. |
| MarkerListCaption | string | Map markers | Caption of the built-in marker table. Say what the markers are, not that they are markers. |
| MarkerListZoom | double? | 15 | Zoom applied when a marker-list row brings its marker into view. Null keeps the current zoom. |
| ReplayStateOnProviderSwap | bool | false | When true, imperatively-added markers, vector layers, and tile overlays are replayed after a destructive provider swap (different JsObjectName). |
| OnReady | EventCallback | Fires after the map is ready for imperative calls. Fires once on initial mount, and fires again after a destructive provider swap each time the new provider becomes ready. | |
| OnClick | EventCallback<BitMapLatLng> | Fires when the user clicks the map canvas. | |
| OnDoubleClick | EventCallback<BitMapLatLng> | Fires when the user double-clicks the map. | |
| OnContextMenu | EventCallback<BitMapLatLng> | Fires when the user right-clicks (or long-presses on touch) the map, with the coordinate under the pointer. The browser's own menu still opens unless the provider sets SuppressBrowserContextMenu. | |
| OnViewChanged | EventCallback<BitMapViewState> | Fires whenever the map view changes. | |
| OnMarkerClick | EventCallback<string> | Fires when the user clicks a marker (argument is the marker id). | |
| OnMarkerDragEnd | EventCallback<BitMapMarkerDragEndArgs> | Fires when a draggable marker is dropped. | |
| OnVectorClick | EventCallback<BitMapVectorClickArgs> | Fires when the user clicks a vector layer. | |
| OnGeoJsonFeatureClick | EventCallback<BitMapGeoJsonFeatureClickArgs> | Fires when the user clicks a GeoJSON feature. | |
| AutoResize | bool | true | Keeps the map sized to its container through a ResizeObserver. Also recovers the classic case of a map created inside a hidden tab, which would otherwise stay grey after the tab is shown. |
| LazyLoad | bool | false | Defers creating the map until its container scrolls into view, so a map below the fold doesn't compete with the page's first paint. LoadState stays Idle while it waits. |
| LazyLoadRootMargin | string | 200px | How far outside the viewport the container may be and still count as visible for LazyLoad. Any margin syntax IntersectionObserver accepts. |
| CooperativeGestures | bool | false | Requires ctrl/⌘ + wheel to zoom and two fingers to pan, so an embedded map doesn't swallow the page scroll. A blocked gesture shows a short hint instead. |
| CooperativeGesturesWheelHint | string | Use ctrl + scroll to zoom the map | Hint shown when a bare wheel gesture is blocked by CooperativeGestures. |
| CooperativeGesturesTouchHint | string | Use two fingers to move the map | Hint shown when a one-finger drag is blocked by CooperativeGestures. |
| EscapeToExit | bool | true | Moves focus out of the map canvas on Escape. A focused map consumes the arrow keys, so without a way out it is a keyboard trap (WCAG 2.1.2). |
| KeyboardInstructions | string | Use the arrow keys to pan the map, plus and minus to zoom, and Escape to leave the map. | Description of the keyboard model. Associated with the canvas via aria-describedby, and shown on screen while the map has keyboard focus. |
| AnnounceViewChanges | bool | false | Announces the new centre and zoom through a polite live region after a pan or zoom, throttled by ViewAnnouncementThrottle. |
| ViewAnnouncementFormatter | Func<BitMapViewState, string>? | null | Builds the announcement text. Supply one to announce a place name instead of coordinates - far more useful than a pair of decimals. |
| ViewAnnouncementThrottle | TimeSpan | 00:00:02 | Minimum interval between two view announcements, so a drag can't flood the screen reader. |
| RespectReducedMotion | bool | true | Turns FlyTo and an animated SetView into an instant jump when the visitor prefers reduced motion. Both methods take an essential argument to opt a specific move back into animating. |
| ShowLoading | bool | true | Shows the built-in loading indicator while the provider's assets and map instance are being created. |
| LoadingTemplate | RenderFragment? | null | Replaces the built-in loading indicator. |
| ErrorTemplate | RenderFragment<Exception?>? | null | Replaces the built-in failure message. Receives the exception behind the failure, when one was captured. |
| UnsupportedTemplate | RenderFragment? | null | Replaces the built-in message shown when the browser cannot give a WebGL-backed provider a context. |
| LoadingLabel | string | Loading map… | Text of the built-in loading indicator. |
| ErrorLabel | string | The map could not be loaded. | Text of the built-in failure message. |
| UnsupportedLabel | string | This browser cannot display the map (WebGL is unavailable). | Text of the built-in unsupported-browser message. |
| OnLoadStateChanged | EventCallback<BitMapLoadState> | Fires on every LoadState transition (Idle, Loading, Ready, Failed, Unsupported). | |
| OnRenderContextLost | EventCallback | Fires when the browser drops the WebGL context the map renders into. Browsers cap how many contexts may be live at once, and the oldest is dropped silently - without this the map just turns black. | |
| OnRenderContextRestored | EventCallback | Fires when a lost WebGL context is restored. | |
| OnFullscreenChanged | EventCallback<bool> | Fires when the map enters or leaves fullscreen, including when the user leaves it with Escape or the browser's own control. | |
| OnInteropError | EventCallback<BitMapInteropErrorArgs> | Fires when an interop call into the underlying provider fails. Lets consumers surface errors that the component would otherwise swallow to prevent circuit-breaking exceptions. |
BitMap public members
| Name | Type | Default value | Description |
|---|---|---|---|
| IsReady | bool | false | True after the map is ready for interop calls. |
| LoadState | BitMapLoadState | BitMapLoadState.Idle | Where the map is in its lifecycle: Idle, Loading, Ready, Failed, or Unsupported. |
| LoadError | Exception? | null | The exception behind a Failed LoadState, when one was captured. |
| MarkerIds | IReadOnlyCollection<string> | Ids of the markers currently on the map, in no guaranteed order. Read from the component's own snapshot, so it costs no interop round-trip. | |
| OpenPopupMarker | BitMapMarker? | null | The marker whose MarkerPopupTemplate popup is open, or null when none is. |
| OpenPopup | Func<string, ValueTask> | Opens the MarkerPopupTemplate popup for a marker. Does nothing when no template is set - use OpenMarkerPopup for the provider's own popup. | |
| ClosePopup | Func<ValueTask> | Closes the MarkerPopupTemplate popup, if one is open. | |
| OrderedMarkers | IReadOnlyList<BitMapMarker> | The markers currently on the map, in no guaranteed order. Costs no interop round-trip. | |
| LayerIds | IReadOnlyCollection<string> | Ids of the vector layers currently on the map, in no guaranteed order. Costs no interop round-trip. | |
| TileOverlayIds | IReadOnlyCollection<string> | Ids of the tile overlays currently on the map, in no guaranteed order. Costs no interop round-trip. | |
| GetView | Func<ValueTask<BitMapViewState>> | Returns a snapshot of the current viewport. | |
| SetView | Func<BitMapLatLng, double?, bool, bool, ValueTask> | Pan and optionally zoom to the given center (center, zoom, animate, essential). Animation is skipped under a reduced-motion preference unless the move is marked essential. | |
| FlyTo | Func<BitMapLatLng, double?, bool, ValueTask> | Animated pan/zoom to the given center (center, zoom, essential). Becomes an instant jump under a reduced-motion preference unless marked essential. | |
| SetZoom | Func<double, bool, bool, ValueTask> | Set an absolute zoom level, keeping the current centre. | |
| ZoomIn | Func<double, bool, bool, ValueTask> | Zoom in by a number of levels (default 1) around the current centre. | |
| ZoomOut | Func<double, bool, bool, ValueTask> | Zoom out by a number of levels (default 1) around the current centre. | |
| ZoomBy | Func<double, bool, bool, ValueTask> | Change the zoom by a relative number of levels. Negative values zoom out. | |
| PanBy | Func<double, double, bool, bool, ValueTask> | Pan by a pixel offset. This is what pan buttons are built from, and shipping those matters: WCAG 2.2 SC 2.5.7 requires a single-pointer alternative to dragging the map. | |
| Locate | Func<BitMapGeolocationOptions?, ValueTask<BitMapGeolocationResult?>> | Asks the browser for the visitor's position and, unless turned off, pans there. Returns null when the browser denies the permission prompt or times out. | |
| PanTo | Func<BitMapLatLng, bool, bool, ValueTask> | Move the centre while keeping the current zoom. | |
| Project | Func<BitMapLatLng, ValueTask<BitMapPoint?>> | Where a coordinate currently sits inside the map container, in CSS pixels from its top-left corner. Null when it is not on screen. Only valid for the viewport it was read at. | |
| FitBounds | Func<BitMapLatLngBounds, int, double, ValueTask> | Fit the view to the given bounding box, with a pixel padding and a maxZoom ceiling (default 18) so framing a box around a single place does not drop to street level. | |
| FitBoundsToMarkers | Func<int, double, ValueTask> | Fit the view to include every marker currently drawn, with the same padding and maxZoom ceiling as FitBounds. | |
| InvalidateSize | Func<ValueTask> | Recalculate map size after a container resize. | |
| AddMarker | Func<BitMapMarker, ValueTask> | Add a marker to the map. | |
| RemoveMarker | Func<string, ValueTask> | Remove a marker by id. | |
| ClearMarkers | Func<ValueTask> | Remove all markers. | |
| SetMarkerPosition | Func<string, BitMapLatLng, ValueTask> | Move a marker to a new position. | |
| OpenMarkerPopup | Func<string, ValueTask> | Open a marker's popup. | |
| SyncMarkers | Func<IEnumerable<BitMapMarker>, ValueTask> | Replace all markers in one batch. | |
| AddPolyline | Func<string, IReadOnlyList<BitMapLatLng>, BitMapVectorPathStyle?, ValueTask> | Add a polyline. | |
| AddPolygon | Func<string, IReadOnlyList<BitMapLatLng>, BitMapVectorPathStyle?, ValueTask> | Add a polygon. | |
| AddCircle | Func<string, BitMapLatLng, double, BitMapVectorPathStyle?, ValueTask> | Add a circle (radius in meters). | |
| AddRectangle | Func<string, BitMapLatLngBounds, BitMapVectorPathStyle?, ValueTask> | Add a rectangle. | |
| AddGeoJson | Func<string, string, BitMapVectorPathStyle?, ValueTask> | Add a GeoJSON layer. | |
| RemoveLayer | Func<string, ValueTask> | Remove a vector layer by id. | |
| ClearVectorLayers | Func<ValueTask> | Remove all vector layers. | |
| AddTileOverlay | Func<BitMapTileOverlay, ValueTask> | Add a tile overlay above the base map. | |
| IsFullscreen | bool | false | Whether the map is currently displayed fullscreen. |
| RequestFullscreen | Func<ValueTask<bool>> | Takes the map's container fullscreen - not the page - so overlay content and custom controls go with it. Call it from a user gesture: browsers only honour the request inside the short activation window a click opens. Returns whether the browser granted it. | |
| ExitFullscreen | Func<ValueTask<bool>> | Leaves fullscreen, if this map is the element currently displayed fullscreen. | |
| ToggleFullscreen | Func<ValueTask<bool>> | Enters fullscreen, or leaves it if the map is already fullscreen. | |
| SetLayerVisible | Func<string, bool, ValueTask> | Shows or hides a vector layer while keeping its definition. Unlike a zero opacity, a hidden layer stops hit-testing rather than swallowing clicks meant for what is underneath it. | |
| IsLayerVisible | Func<string, bool> | Whether a vector layer is currently drawn. Unknown ids report false. | |
| SetLayerStyle | Func<string, BitMapVectorPathStyle?, ValueTask> | Restyles an existing vector layer, keeping its geometry. A hidden layer keeps the new style for when it is shown again. | |
| SetTileOverlayVisible | Func<string, bool, ValueTask> | Shows or hides a tile overlay while keeping its definition. | |
| IsTileOverlayVisible | Func<string, bool> | Whether a tile overlay is currently drawn. Unknown ids report false. | |
| SetTileOverlayOpacity | Func<string, double, ValueTask> | Changes a tile overlay's opacity, which is how a raster overlay is blended against the basemap underneath it. | |
| ClearTileOverlays | Func<ValueTask> | Remove every tile overlay, leaving the base map alone. | |
| RemoveTileOverlay | Func<string, ValueTask> | Remove a tile overlay by id. |
BitComponentBase parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| AriaLabel | string? | null | Gets or sets the accessible label for the component, used by assistive technologies. |
| Class | string? | null | Gets or sets the CSS class name(s) to apply to the rendered element. |
| Dir | BitDir? | null | Gets or sets the text directionality for the component's content. |
| ForceAnimation | bool | false | Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested. |
| HtmlAttributes | Dictionary<string, object> | new Dictionary<string, object>() | Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. |
| Id | string? | null | Gets or sets the unique identifier for the component's root element. |
| IsEnabled | bool | true | Gets or sets a value indicating whether the component is enabled and can respond to user interaction. |
| Style | string? | null | Gets or sets the CSS style string to apply to the rendered element. |
| TabIndex | string? | null | Gets or sets the tab order index for the component when navigating with the keyboard. |
| Visibility | BitVisibility | BitVisibility.Visible | Gets or sets the visibility state (visible, hidden, or collapsed) of the component. |
BitComponentBase public members
| Name | Type | Default value | Description |
|---|---|---|---|
| UniqueId | Guid | Guid.NewGuid() | Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed. |
| RootElement | ElementReference | Gets the reference to the root HTML element associated with this component. |
BitVisibility enum
| Name | Value | Description |
|---|---|---|
| Visible | 0 | The content of the component is visible. |
| Hidden | 1 | The content of the component is hidden, but the space it takes on the page remains (visibility:hidden). |
| Collapsed | 2 | The component is hidden (display:none). |
BitDir enum
| Name | Value | Description |
|---|---|---|
| Ltr | 0 | Ltr (left to right) is to be used for languages that are written from the left to the right (like English). |
| Rtl | 1 | Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic). |
| Auto | 2 | Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element. |
Feedback
Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.