Map Markers
- Needs review
- RTL
Many markers from data on a MapView, clustered automatically: nearby markers merge into MapMarkerCluster
buttons (with category segments) that zoom in when pressed. Only markers on screen are rendered, and they are
reached with Tab in items order, so the map follows the list beside it.
import { MapMarkers } from "@nexera-ui/react";- 2
- examples
- 8
- props
- 0
- live controls
- 1
- platform
- 0
- WCAG criteria
- 2
- blocks use it
Try every prop. Copy the code.
Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.
import { MapMarkers } from "@nexera-ui/react";
<MapMarkers />Examples 1
The same examples as Storybook, rendered live. Open Code to copy one.
Without clustering
cluster={false} shows every marker, for small sets where each one matters.
import { MapMarkerPerson, MapMarkers } from "@nexera-ui/react";
interface Person {
id: string;
name: string;
status: MapMarkerWorkStatus;
lngLat: readonly [number, number];
}
const STATUSES: MapMarkerWorkStatus[] = ["working", "remote", "on-leave", "offline"];
const PEOPLE: Person[] = Array.from({ length: 120 }, (_, i) => ({
id: `p${String(i)}`,
name: `Person ${String(i + 1)}`,
status: STATUSES[i % 4] ?? "working",
lngLat: [-0.15 + ((i * 41) % 90) / 1000, 51.495 + ((i * 59) % 40) / 1000],
}));
<MapMarkers
items={PEOPLE.slice(0, 12)}
getId={(p: Person) => p.id}
getLngLat={(p: Person) => p.lngLat}
getCategory={(p: Person) => p.status}
categories={STATUSES}
clusterLabel={(n: number) => `${String(n)} people`}
renderMarker={(p: Person, { isSelected }: { isSelected: boolean }) => (
<MapMarkerPerson name={p.name} workStatus={p.status} isSelected={isSelected} />
)}
/>;
Props 8
8 props shown
items*Nexerareadonly T[]The data: people, places, assets.
getId*Nexera(item: T) => stringA stable, unique id per item (used by MapView selectedId).
getLngLat*Nexera(item: T) => LngLatThe item's position as [lng, lat]. Items without a valid one are skipped (named in the console in development).
renderMarker*Nexera(item: T, state: { isSelected: boolean; }) => ReactNodeThe marker for one item, for example a MapMarkerPerson.
getCategoryNexera(item: T) => stringThe item's category, counted per cluster for MapMarkerCluster's segments (with categories).
categoriesNexerareadonly string[]Categories in segment order.
clusterLabelNexera(count: number) => stringThe accessible name of a cluster. Translate it.
clusterNexeraboolean | { radius?: number; maxZoom?: number; }Merge nearby markers into clusters.
* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.
Accessible by default.
Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.
This component relies on the shared primitives' accessibility tests; no criteria are tagged to it directly yet.
Fits any width.
Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.
Styling hooks
Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.
<MapMarkers className="shadow-sm" />Used in blocks
Related components
- AccordionItemOne collapsible section of an FAQ or settings page.
- AreaChartA stacked area chart: layers piled up over time with the title, range switch, actions and legend of the card.
- AvailabilityRowOne person's availability across a window of the day: an avatar with initials and the name, and a timeline with the busy periods drawn as bars.
- AvatarA person or organisation shown as a photo, initials or an icon.
- AvatarGroupA row of overlapping avatars with a "+N" chip for the rest.
- AvatarLabelAn avatar with a name and an optional subtitle beside it, for a person in a list, a header or a mention.
- BadgeShort status or category label: `Tone` x `Variant` x `Size`, with an optional dot, leading icon and remove button.
- BadgeGroupA pill that pairs a small badge with a short message, for an announcement or a status line.