Skip to content
Template Empire
Browse components

Office Pulse Map

A free React office locations section with semantic contact cards and a decorative SVG network map.

Find us worldwide

A local team, wherever work takes you.

Meet the people closest to your next launch. Every studio shares one operating rhythm, with local context built into the way we work.

Customise

0.24
2.4s
14
0.08s
24px

Code

<ContactOfficePulseMap
  title="A local team, wherever work takes you."
  offices={offices}
  routes={routes}
/>

Office Pulse Map is a free contact section and React office locations section for Next.js, React and Tailwind. It pairs an accessible list of office addresses with a dependency-free SVG map, so visitors can find every location without relying on the visual network.

Scoped GSAP draws valid routes once, retargets the selected office from its current state and runs one restrained pulse only while the section and browser tab are visible. Reduced motion keeps the map settled, selection immediate and every address fully available.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/contact-office-pulse-map

Usage

import { ContactOfficePulseMap } from "@/components/contact-office-pulse-map";

const offices = [
  {
    id: "london",
    city: "London",
    country: "United Kingdom",
    address: "16 St John's Lane, London EC1M 4BS",
    timezone: "GMT / BST",
    href: "https://www.google.com/maps/search/?api=1&query=London",
    x: 48,
    y: 31,
  },
  {
    id: "singapore",
    city: "Singapore",
    country: "Singapore",
    address: "71 Robinson Road, Singapore 068895",
    timezone: "SGT",
    href: "https://www.google.com/maps/search/?api=1&query=Singapore",
    x: 77,
    y: 66,
  },
];

const routes = [
  { id: "london-singapore", fromId: "london", toId: "singapore" },
];

export default function Page() {
  return (
    <ContactOfficePulseMap
      title="Talk to a team in your time zone."
      description="Choose an office to see where our network is focused."
      offices={offices}
      routes={routes}
    />
  );
}

Props

PropTypeDefaultDescription
eyebrowstring"Find us worldwide"Introductory label above the section heading.
titlestringrequiredSection heading rendered as an h2.
descriptionstringundefinedOptional supporting copy below the heading.
offices{ id; city; country; address; timezone?; href?; x; y }[]requiredTwo to eight offices with stable IDs, complete contact details and map coordinates clamped from 0 through 100.
routes{ id: string; fromId: string; toId: string }[][]Stable relationships between office IDs. Missing endpoints, duplicate IDs and self-routes are ignored.
activeIdstringundefinedActive office ID in controlled mode.
defaultActiveIdstringfirst office IDInitial active office ID in uncontrolled mode.
onActiveChange(id: string) => voidundefinedCalled after a valid office selection.
layout"map-left" | "map-right""map-left"Desktop composition. Narrow screens always place semantic office content before the decorative map.
mapArcHeightnumber0.24Route curvature as a fraction of endpoint distance, clamped from 0.08 through 0.48.
pulseDurationnumber2.4Seconds between active-marker pulses, clamped from 1.2 through 6.
markerSizenumber14Marker diameter in SVG coordinate units, clamped from 10 through 24.
routeStaggernumber0.08Seconds between route draws, clamped from 0 through 0.18.
radiusnumber24Map-panel radius in CSS pixels, clamped from 8 through 36.
classNamestringundefinedAdditional classes merged onto the section root.

Customisation

Office Pulse Map exposes Tier 3 tokens for its surface, land, grid, routes and markers. Effect props control composition, geometry and timing while office names, addresses, links, coordinates and relationships remain authored data:

<ContactOfficePulseMap
  className="office-network"
  title="A studio close to every launch."
  offices={offices}
  routes={routes}
  layout="map-right"
  mapArcHeight={0.32}
  markerSize={18}
  radius={30}
/>

.office-network {
  --office-map-surface: var(--background);
  --office-map-land: var(--muted);
  --office-map-grid: var(--border);
  --office-map-route: var(--ring);
  --office-map-marker: var(--primary);
}

Frequently asked questions

Is Office Pulse Map free for commercial use?
Yes. Office Pulse Map is MIT licensed, so you can use it in personal and commercial projects without attribution.
Is this React office locations section accessible?
Yes. Offices are an actual list with native selection buttons, pressed state, visible selected text, address elements and real address links. The SVG map is decorative and hidden from assistive technology, so no contact information depends on colour, animation or map interpretation. Reduced motion creates no trigger or pulse.
How does the office pulse affect performance?
The route entrance runs once and only the decorative path offset, marker transforms and opacity are animated. One observer and one visibility listener pause the single active pulse while the section is fully offscreen or the browser tab is hidden, and scoped GSAP cleanup removes every animation and listener on unmount.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with contact, team and conversion sections designed as one system.Explore Template Empire templates