All files / web/src/arcade-games/know-your-world/components RegionListPanel.tsx

100% Statements 95/95
100% Branches 18/18
100% Functions 4/4
100% Lines 95/95

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 961x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 143x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 12x 12x 12x 12x 12x 12x 12x 11x 1x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 143x 12x 12x 12x 12x 12x  
'use client'
 
import { memo } from 'react'
import { css } from '@styled/css'
 
interface RegionListItemProps {
  name: string
  onHover?: (name: string | null) => void
  isDark?: boolean
}
 
/**
 * Individual region list item with hover interaction.
 * Memoized to prevent unnecessary re-renders when list is large.
 */
const RegionListItem = memo(function RegionListItem({
  name,
  onHover,
  isDark = false,
}: RegionListItemProps) {
  return (
    <div
      onMouseEnter={() => onHover?.(name)}
      onMouseLeave={() => onHover?.(null)}
      className={css({
        px: '2',
        py: '1',
        fontSize: 'xs',
        color: isDark ? 'gray.300' : 'gray.600',
        cursor: onHover ? 'pointer' : 'default',
        rounded: 'md',
        overflowWrap: 'break-word',
        _hover: {
          bg: isDark ? 'gray.700' : 'gray.200',
          color: isDark ? 'gray.100' : 'gray.900',
        },
      })}
    >
      {name}
    </div>
  )
})
 
interface RegionListPanelProps {
  /** List of region names to display */
  regions: string[]
  /** Callback when hovering over a region name (for map preview) */
  onRegionHover?: (name: string | null) => void
  /** Maximum height of the scrollable list */
  maxHeight?: string
  /** Dark mode styling */
  isDark?: boolean
  /** Sort regions alphabetically (default: true) */
  sortAlphabetically?: boolean
}
 
/**
 * Scrollable panel displaying a list of region names.
 * Used in DrillDownMapSelector for displaying selected regions on desktop.
 */
export function RegionListPanel({
  regions,
  onRegionHover,
  maxHeight = '200px',
  isDark = false,
  sortAlphabetically = true,
}: RegionListPanelProps) {
  const displayRegions = sortAlphabetically
    ? [...regions].sort((a, b) => a.localeCompare(b))
    : regions
 
  return (
    <div
      data-element="region-list-panel"
      className={css({
        display: 'flex',
        flexDirection: 'column',
        maxHeight,
        overflow: 'hidden',
      })}
    >
      {/* Scrollable list */}
      <div
        className={css({
          overflowY: 'auto',
          flex: 1,
        })}
      >
        {displayRegions.map((name) => (
          <RegionListItem key={name} name={name} onHover={onRegionHover} isDark={isDark} />
        ))}
      </div>
    </div>
  )
}