Dotted World Map
A stylised dotted-continent world drawn in inline SVG, with labelled city pins and no tile server.
3 frameworksIntermediate
Dotted map pins that open a small details popover on click, one at a time.
<!-- Static snapshot with one popover open. In a framework, toggle it from the pin's aria-expanded. -->
<div class="relative w-full overflow-hidden rounded-2xl border border-gray-200 bg-gray-50 dark:border-gray-800 dark:bg-gray-950">
<div class="relative aspect-[16/10] w-full">
<svg aria-hidden="true" class="absolute inset-0 h-full w-full text-gray-300 dark:text-gray-700" preserveAspectRatio="xMidYMid slice">
<defs>
<pattern id="pin-dots" width="14" height="14" patternUnits="userSpaceOnUse">
<circle cx="2" cy="2" r="1.4" fill="currentColor" />
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#pin-dots)" />
</svg>
<div class="absolute" style="left:40%;top:45%">
<button type="button" aria-expanded="true" aria-label="The Roastery" class="flex h-10 w-10 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500">
<span class="h-3.5 w-3.5 rounded-full bg-blue-600 ring-4 ring-blue-500/25 dark:bg-blue-400"></span>
</button>
<div role="dialog" aria-label="The Roastery" class="absolute bottom-full left-1/2 z-10 mb-2 w-48 -translate-x-1/2 rounded-lg border border-gray-200 bg-white p-3 text-left shadow-lg dark:border-gray-800 dark:bg-gray-900">
<p class="text-sm font-semibold text-gray-900 dark:text-gray-100">The Roastery</p>
<p class="mt-0.5 text-xs text-gray-600 dark:text-gray-400">Open until 6pm · 0.4 km away</p>
</div>
</div>
</div>
</div>| Prop | Type | Default | Description |
|---|---|---|---|
places | Place[] | - | Places |
className | string | - | Additional classes merged onto the root element. |
Supply `places` as `{ id, label, detail, x, y }`. Each pin is a button with `aria-expanded`; clicking toggles its popover, Escape closes it, and opening one closes the rest so only a single card shows at a time.