Skip to content
NewYour data: charts, lists and meters that take your records
<GeoSessions />ReactAccess & securityFree

Active sessions

The places an account is signed in, as a list with a dot map. Signing out other sessions sends a wave from this device that removes them nearest first.

View as Markdown
<GeoSessions />

Trypress Sign out other sessions, then confirm.

Your data

Pass your sessions as sessions (or defaultSessions) and sign them out in onRevoke. Without them the component shows six invented demo sessions. See Your data.

Playground

Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.

Loading <GeoSessions />
Props
confirmlive
titlelive
React
<GeoSessions confirm title="Active sessions" />

Installation

pnpm dlx shadcn@latest add @lumesec/geo-sessions
First timeRegister the @lumesec registry once, or install by URL+

Adds @lumesec to your components.json:

pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json

Or skip the setup and install by URL:

npx shadcn@latest add https://elements.lumesec.ai/r/geo-sessions.json

Usage

geo-sessions-example.tsx
import { GeoSessions, type Session } from "@/components/lumesec/geo-sessions";

export function Example({ sessions, revoke }: { sessions: Session[]; revoke: (ids: readonly string[]) => void }) {
  return <GeoSessions defaultSessions={sessions} onRevoke={revoke} />;
}

Behaviour

The places an account is signed in, as a list with a compact map above it. Each row shows the device type, the city and when it was last active; pointing at a row pulses its point and draws a line from this device to it.

Sign out other sessions sends a wave across the map from this device. As it reaches each session, the point breaks up into sparks and its row collapses at the same moment, nearest first.

API reference

Props

Also accepts every prop of <div> (React.ComponentProps<"div">), spread onto the root element.

sessionsTypereadonly Session[]

Sessions (controlled): { id, device, label, city, lat?, lon?, lastActive, current?, approximate? }. device is laptop, desktop, phone, tablet or terminal; lastActive is epoch ms, an ISO date-time or a Date. Use with onSessionsChange. An empty array shows "No active sessions".

defaultSessionsTypereadonly Session[]Default6 demo sessions

Sessions when uncontrolled. Without sessions and defaultSessions the component shows six invented sessions.

onSessionsChangeType(sessions: readonly Session[]) => void

Called with the remaining sessions after a sign-out, once the rows have collapsed.

onRevokeType(ids: readonly string[]) => void

Called with the ids that were signed out, at the same moment as onSessionsChange. Not called for the demo sessions.

confirmTypebooleanDefaulttrue

Requires a second click within 4 seconds to sign out all other sessions. A single row's Sign out never asks.

nowTypenumber

Reference time in epoch ms for the relative times. Gives the same text on the server and the client. Without it a clock starts after mount and refreshes every 30 seconds.

localeTypestringDefault"en-US"

BCP 47 locale of the relative times and dates.

titleTypeReact.ReactNodeDefault"Active sessions"

Header text.

Ref

ref points at the root HTMLDivElement.

Keyboard

KeysAction
TabMoves through the rows' Sign out buttons and the footer button. A focused row previews its session on the map.
ArrowDown / ArrowUpMoves focus to the next or previous row's Sign out button.
Home / EndMoves focus to the first or last row's Sign out button.
Enter / SpaceOn a row: signs out that session. On the footer: arms it, and a second press within 4 seconds signs out all other sessions.
EscapeDisarms the footer button.

Accessibility

  • The sessions are a list labelled "Sessions". Each row is text (label, city, relative time) and a native button whose accessible name names the session, such as "Sign out Office desktop, Berlin".
  • The armed footer button's accessible name follows the rolled label ("Confirm sign-out"), and it is described by "Press again within 4 seconds to confirm".
  • With no other sessions left, the footer button reads "No other sessions" and is aria-disabled, so it keeps focus after a sign-out.
  • After a sign-out, focus moves to the next row's button, or to the footer button.
  • A polite live region announces the result, such as "5 sessions signed out".
  • Collapsing rows are inert and hidden from assistive technology. The map and its canvases are aria-hidden; the list carries the same data.
  • Reduced motion: there is no wave, implode or sparks and no first reveal of the land: rows are removed at once, the count and the labels change without rolling, the preview line appears without drawing on and the point does not pulse. The confirm fuse still burns down, without flicker.

Theming

Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.

This component reads --lumesec, --lumesec-glint, --lumesec-shine, --destructive, --card, --card-foreground, --muted, --muted-foreground, --foreground and --border.

Notes

  • The map is an Equal Earth strip cropped to 50° S to 72° N, drawn from the embedded world data with no map tiles. A session outside that band sits on the nearest edge. Sessions without lat and lon have no point; during a sweep they go after the front has crossed the map.
  • Sign out other sessions starts a front at this device (the session with current), or at the middle of the map when there is none. It travels at 420 px per second; each session's row collapses on the frame the front reaches its point, and sessions at the same place go together.
  • Before mount, rows with your data show absolute dates in UTC, such as "Oct 3, 14:20 UTC". Pass now for relative times in the server markup.
  • With controlled sessions, signed-out rows stay hidden until you pass a new array. Keep the old array while your request runs; a new array that still contains a session brings its row back.

Was this page helpful?