All files / components/shared/ui HUDSection.tsx

100% Statements 8/8
100% Branches 30/30
100% Functions 1/1
100% Lines 8/8

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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146                                                                                                                                      1x                       24x             24x 24x     24x       24x       24x       24x                                                                                      
/**
 * HUDSection - Reusable HUD section with Korean theming
 * 
 * Provides consistent section styling for grouped HUD elements.
 * Includes optional bilingual title support and Korean cyberpunk theming.
 * 
 * Features:
 * - Korean-English bilingual titles
 * - Primary/Secondary variant styling
 * - Responsive sizing
 * - Consistent borders and backgrounds
 * 
 * @module components/shared/ui
 * @korean HUD섹션 - 한국 테마를 가진 재사용 가능한 HUD 섹션
 */
 
import React from 'react';
import { hexToRgbaString } from '../../../utils/colorUtils';
import { useKoreanTheme } from '../base/useKoreanTheme';
 
/**
 * Props for HUDSection component
 */
export interface HUDSectionProps {
  /** English title (optional) */
  readonly title?: string;
  /** Korean title (optional) */
  readonly titleKorean?: string;
  /** Child elements */
  readonly children: React.ReactNode;
  /** Visual variant (primary or secondary) */
  readonly variant?: 'primary' | 'secondary';
  /** Internal padding in pixels */
  readonly padding?: number;
  /** Gap between items in pixels */
  readonly gap?: number;
  /** Additional CSS styles */
  readonly style?: React.CSSProperties;
  /** Test ID for testing */
  readonly dataTestId?: string;
  /** Whether mobile layout is active */
  readonly isMobile?: boolean;
  /** Whether to enable pointer events */
  readonly pointerEvents?: boolean;
}
 
/**
 * HUDSection Component
 * 
 * Reusable section container for HUD elements with Korean theming.
 * Displays optional bilingual title and wraps content with styled borders
 * and backgrounds.
 * 
 * @example
 * ```tsx
 * <HUDSection
 *   title="Statistics"
 *   titleKorean="통계"
 *   variant="primary"
 *   padding={12}
 *   dataTestId="stats-section"
 * >
 *   <StatDisplay label="Hits" value={42} />
 *   <StatDisplay label="Combos" value={12} />
 * </HUDSection>
 * ```
 */
export const HUDSection: React.FC<HUDSectionProps> = ({
  title,
  titleKorean,
  children,
  variant = 'primary',
  padding = 12,
  gap = 8,
  style = {},
  dataTestId,
  isMobile = false,
  pointerEvents = true,
}) => {
  const theme = useKoreanTheme({
    variant,
    size: 'md',
    isMobile,
  });
 
  // Calculate responsive font size
  const fontSize = isMobile ? 11 : 12;
  const titleFontSize = isMobile ? 12 : 14;
 
  // Determine border and background colors based on variant
  const borderColor = variant === 'primary'
    ? hexToRgbaString(theme.colors.PRIMARY_CYAN, 0.5)
    : hexToRgbaString(theme.colors.ACCENT_GOLD, 0.5);
  
  const backgroundColor = variant === 'primary'
    ? hexToRgbaString(theme.colors.UI_BACKGROUND_DARK, 0.8)
    : hexToRgbaString(theme.colors.UI_BACKGROUND_MEDIUM, 0.8);
 
  const titleColor = variant === 'primary'
    ? hexToRgbaString(theme.colors.ACCENT_GOLD, 1)
    : hexToRgbaString(theme.colors.PRIMARY_CYAN, 1);
 
  return (
    <div
      style={{
        background: backgroundColor,
        border: `2px solid ${borderColor}`,
        borderRadius: '8px',
        padding: `${padding}px`,
        display: 'flex',
        flexDirection: 'column',
        gap: `${gap}px`,
        pointerEvents: pointerEvents ? 'auto' : 'none',
        ...style,
      }}
      data-testid={dataTestId}
    >
      {/* Bilingual Title */}
      {(title ?? titleKorean) && (
        <div
          style={{
            fontSize: `${titleFontSize}px`,
            fontWeight: 'bold',
            color: titleColor,
            fontFamily: theme.koreanTypography.fontFamily,
            lineHeight: theme.koreanTypography.lineHeight,
            display: 'flex',
            alignItems: 'center',
            gap: '6px',
          }}
          data-testid={dataTestId ? `${dataTestId}-title` : undefined}
        >
          {titleKorean && <span>{titleKorean}</span>}
          {titleKorean && title && <span style={{ color: hexToRgbaString(theme.colors.TEXT_SECONDARY, 0.7) }}>|</span>}
          {title && <span style={{ fontSize: `${fontSize}px` }}>{title}</span>}
        </div>
      )}
      
      {/* Content */}
      {children}
    </div>
  );
};
 
export default HUDSection;