import React from 'react'; import Box from '@mui/material/Box'; import type { SxProps, Theme } from '@mui/material/styles'; // ─── Types ────────────────────────────────────────────────────────────────── /** Props for the FA ClusterMarker atom */ export interface ClusterMarkerProps { /** Number of providers in this cluster */ count: number; /** True if any provider in the cluster is verified — drives the promoted palette */ hasVerified?: boolean; /** Click handler — opens the cluster popup */ onClick?: (e: React.MouseEvent) => void; /** MUI sx prop for the root element */ sx?: SxProps; } // ─── Constants ────────────────────────────────────────────────────────────── const NUB_SIZE = 'var(--fa-map-pin-nub-size)'; const BADGE_SIZE = 36; // ─── Colour sets — matches MapPin ─────────────────────────────────────────── const colours = { verified: { bg: 'var(--fa-color-brand-700)', text: 'var(--fa-color-white)', border: 'var(--fa-color-brand-700)', nub: 'var(--fa-color-brand-700)', }, unverified: { bg: 'var(--fa-color-neutral-100)', text: 'var(--fa-color-neutral-800)', border: 'var(--fa-color-neutral-300)', nub: 'var(--fa-color-neutral-100)', }, } as const; // ─── Component ────────────────────────────────────────────────────────────── /** * Cluster map marker for the FA design system. * * Circular pill with a count, representing N provider pins grouped at the * same screen location. Sibling to `MapPin` — same palette language (verified * promoted, unverified neutral), same nub treatment, same shadow. * * `hasVerified` drives the palette: if *any* provider in the cluster is * verified, the cluster adopts the promoted (brand-700) palette. All-unverified * clusters use the neutral palette. * * Designed for use as the `render`-ed output of `@googlemaps/markerclusterer`. * Pure CSS + SVG — no canvas. role="button" + keyboard + focus ring. * * Usage: * ```tsx * * * ``` */ export const ClusterMarker = React.forwardRef( ({ count, hasVerified = false, onClick, sx }, ref) => { const palette = hasVerified ? colours.verified : colours.unverified; const handleKeyDown = (e: React.KeyboardEvent) => { if ((e.key === 'Enter' || e.key === ' ') && onClick) { e.preventDefault(); onClick(e as unknown as React.MouseEvent); } }; const label = `${count} providers in this area`; return ( .ClusterMarker-badge': { outline: '2px solid var(--fa-color-interactive-focus)', outlineOffset: '2px', }, }, }, ...(Array.isArray(sx) ? sx : [sx]), ]} > {/* Circular badge */} {count} {/* Nub — same SVG pattern as MapPin for visual continuity */} ); }, ); ClusterMarker.displayName = 'ClusterMarker'; export default ClusterMarker;