A canvas globe of land dots that turns slowly, can be dragged to rotate, and can mark places with glowing dots. Still when off-screen, paused or for reduced motion.
Optional, and kept apart.
Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.
import { Globe } from "@rdloom/react";
export default function GlobeBasicExample() {
return (
<div className="flex w-full justify-center">
<div className="w-full max-w-xs">
<Globe label="Globe" description="A slowly turning globe of dots showing the continents. Drag to turn it." />
</div>
</div>
);
}Installation
npx rdloom add globeCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.
It also adds rdloom-motion.css next to your tokens and imports it from the tokens file, once: no setup, and no inline styles. The plain components you already use are untouched.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/globe.jsonWorks, but without upgrade tracking, and you import the motion CSS yourself.
Usage
import { Globe } from "@rdloom/react";
<div className="flex w-full justify-center">
<div className="w-full max-w-xs">
<Globe label="Globe" description="A slowly turning globe of dots showing the continents. Drag to turn it." />
</div>
</div>Markers
import { Globe, type WorldMarker } from "@rdloom/react";
const offices: WorldMarker[] = [
{ lat: 51.5, lng: -0.1, label: "London office" },
{ lat: 40.7, lng: -74, label: "New York office" },
{ lat: 1.35, lng: 103.8, label: "Singapore office" },
{ lat: -33.9, lng: 151.2, label: "Sydney office" },
];
export default function GlobeMarkersExample() {
return (
<div className="flex w-full justify-center">
<div className="w-full max-w-xs">
<Globe
label="Our offices"
description="A globe with a glowing dot at each of our four offices."
markers={offices}
markerColor="var(--rd-color-action-primary)"
speed={1.5}
/>
</div>
</div>
);
}Still
import { useState } from "react";
import { Button, Globe } from "@rdloom/react";
export default function GlobeStillExample() {
const [paused, setPaused] = useState(false);
return (
<div className="flex w-full flex-col items-center gap-3">
<div className="w-full max-w-xs">
<Globe label="Globe" description="A globe of dots that can be held still." isPaused={paused} />
</div>
<Button variant="secondary" onPress={() => setPaused((p) => !p)}>
{paused ? "Turn the globe" : "Hold the globe still"}
</Button>
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
labelAccessible name of the whole graphic. | string | "Globe" |
descriptionA sentence for screen readers that says what the graphic shows. It is visually hidden. | string | none |
markersPlaces to mark as { lat, lng, label }. Each one is also listed, with its label, for screen readers. | WorldMarker[] | none |
speedRotation speed as a multiplier: 1 is one turn a minute, 0 does not turn. | number | 1 |
dotColorColour of the land dots, any CSS colour. Defaults to the muted text colour. | string | none |
markerColorColour of the markers, any CSS colour. Defaults to the primary action colour. | string | none |
isPausedStops the movement and shows one still frame. | boolean | false |
Accessibility
Role group, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
Not interactive.
Screen readers announce
- The canvas is hidden from assistive technology
- The label, description and a list of the markers are read as text
What your code must do
- The canvas is decoration and aria-hidden; the root is a labelled group with a visually hidden description and a real list of the places
- Stands still for visitors who ask for less motion (prefers-reduced-motion), inside an rdm-still container and with isPaused; one still frame is drawn
- Moving for more than five seconds, so it can be paused with isPaused or the rdm-still container (WCAG 2.2.2)
- Does not flash: nothing changes more than three times in a second (WCAG 2.3.1)
- Paused while off-screen, and its animation frame is cancelled when it unmounts
- Hidden in forced-colors (high contrast) mode, where the place list is still there for assistive technology
- Drag with a pointer turns the globe; nothing depends on it, because the places are in the list
Guidelines
Use it when
- A hero or about section showing where a team or customers are
- A decorative graphic that carries a few named places
Avoid it when
- Showing exact geography or navigation
- Data that must be read from the map alone
Don't
- Putting the only copy of important information on the globe without the list
- Dozens of glowing markers
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-text-muted--rd-color-action-primary