import { Globe, List } from 'lucide-react'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; // Cross-feature reuse: CountryMap and getCountryName are leaf modules from the // Analytics page (src/dashboard). BreakdownPanel is a feature surface so this // direct import is intentional — avoids duplicating the SVG choropleth. import CountryMap from '../../../dashboard/components/CountryMap'; import { getCountryName } from '../../../dashboard/data/countries'; import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'; import type { DataState } from '@/types/component-states'; interface CountryTileBodyProps { byCountry: Record; } // Renders the map or list view depending on the toggle. // Exported so BreakdownPanel can inline the StatTile wiring externally. export function CountryTileBody( { byCountry }: CountryTileBodyProps ) { const [ view, setView ] = React.useState<'map' | 'list'>( 'map' ); const containerRef = React.useRef( null ); const [ width, setWidth ] = React.useState( 0 ); React.useEffect( () => { const el = containerRef.current; if ( ! el ) { return; } const update = () => setWidth( el.offsetWidth ); update(); const observer = new ResizeObserver( update ); observer.observe( el ); return () => observer.disconnect(); }, [] ); // Top-10 countries sorted descending, shaped for HostList items. const items = React.useMemo( () => Object.entries( byCountry ) .map( ( [ code, value ] ) => ( { key: code, value, label: getCountryName( code ), } ) ) .sort( ( a, b ) => b.value - a.value ) .slice( 0, 10 ), [ byCountry ] ); return (
{ /* Toggle sits at the top of the body area */ }
v && setView( v as 'map' | 'list' ) } >
{ view === 'map' ? (
{ width > 0 && ( ) }
) : ( // Reuses the same HostList from index.tsx — passed in as a render prop // so we don't duplicate the animated list implementation. ) }
); } // Minimal list render matching HostList's visual silhouette (h-8 bar, bg-brand/15, // label left-2, value right). No motion — CountryTile is a secondary view. function CountryList( { items }: { items: { key: string; value: number; label: string }[] } ) { const max = Math.max( 1, ...items.map( i => i.value ) ); return ( ); } // Derived state helper — same signature as deriveListState in index.tsx. export function deriveCountryState( base: 'loading' | 'loaded' | 'empty' | 'error', count: number ): DataState { if ( base === 'error' || base === 'loading' ) { return base; } return count > 0 ? 'loaded' : 'empty'; }