All files / components/screens/controls/components ControlCategoryTabsOverlayHtml.tsx

100% Statements 17/17
100% Branches 18/18
100% Functions 7/7
100% Lines 15/15

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                                                                      2x         60x   60x                   60x                           60x     180x   180x                         180x       26x     5x 4x 4x       4x 3x 3x                        
/**
 * ControlCategoryTabs - Tab navigation for control categories
 * 
 * Allows switching between Combat, Movement, and System control views
 * Uses BaseButtonOverlayHtml for consistent styling
 * 
 * @module components/screens/controls/components
 */
 
import React, { useMemo } from "react";
import { hexToRgbaString } from "../../../../utils/colorUtils";
import { useKoreanTheme } from "../../../shared/base/useKoreanTheme";
import { CONTROL_CATEGORIES } from "../constants/ControlsConstants";
 
export interface ControlCategoryTabsProps {
  readonly selectedTab: 'combat' | 'movement' | 'system';
  readonly onTabChange: (tab: 'combat' | 'movement' | 'system') => void;
  readonly isMobile: boolean;
}
 
/**
 * ControlCategoryTabs Component
 * 
 * Displays tabs for switching between control categories.
 * Uses Korean theming and responsive sizing.
 * 
 * @example
 * ```tsx
 * <ControlCategoryTabs
 *   selectedTab="combat"
 *   onTabChange={(tab) => setSelectedTab(tab)}
 *   isMobile={false}
 * />
 * ```
 */
export const ControlCategoryTabs: React.FC<ControlCategoryTabsProps> = ({
  selectedTab,
  onTabChange,
  isMobile,
}) => {
  const theme = useKoreanTheme({ variant: 'primary', size: 'md', isMobile });
 
  const tabStyle = useMemo(() => ({
    display: 'flex',
    flexDirection: 'row' as const,
    gap: isMobile ? '8px' : '12px',
    justifyContent: 'center',
    alignItems: 'center',
    padding: isMobile ? '10px' : '15px',
    flexWrap: 'wrap' as const,
  }), [isMobile]);
 
  const buttonBaseStyle = useMemo(() => ({
    padding: isMobile ? '8px 16px' : '12px 24px',
    borderRadius: '8px',
    border: `2px solid ${hexToRgbaString(theme.colors.UI_BORDER, 0.6)}`,
    cursor: 'pointer',
    transition: 'all 0.2s ease',
    fontFamily: 'inherit',
    fontSize: isMobile ? '14px' : '16px',
    fontWeight: 'bold' as const,
    display: 'flex',
    alignItems: 'center',
    gap: '8px',
  }), [isMobile, theme]);
 
  return (
    <div style={tabStyle} data-testid="control-category-tabs">
      {CONTROL_CATEGORIES.map((category) => {
        const isSelected = selectedTab === category.id;
        
        const buttonStyle = {
          ...buttonBaseStyle,
          background: isSelected
            ? hexToRgbaString(category.color, 0.3)
            : hexToRgbaString(theme.colors.UI_BACKGROUND_DARK, 0.8),
          borderColor: isSelected
            ? hexToRgbaString(category.color, 1)
            : hexToRgbaString(theme.colors.UI_BORDER, 0.6),
          color: isSelected
            ? `#${category.color.toString(16).padStart(6, '0')}`
            : `#${theme.colors.TEXT_SECONDARY.toString(16).padStart(6, '0')}`,
        };
 
        return (
          <button
            key={category.id}
            style={buttonStyle}
            onClick={() => onTabChange(category.id as 'combat' | 'movement' | 'system')}
            data-testid={`tab-${category.id}`}
            onMouseEnter={(e) => {
              if (!isSelected) {
                e.currentTarget.style.background = hexToRgbaString(category.color, 0.1);
                e.currentTarget.style.borderColor = hexToRgbaString(category.color, 0.8);
              }
            }}
            onMouseLeave={(e) => {
              if (!isSelected) {
                e.currentTarget.style.background = hexToRgbaString(theme.colors.UI_BACKGROUND_DARK, 0.8);
                e.currentTarget.style.borderColor = hexToRgbaString(theme.colors.UI_BORDER, 0.6);
              }
            }}
          >
            <span role="img" aria-label={category.english}>{category.icon}</span>
            <span>{category.korean} | {category.english}</span>
          </button>
        );
      })}
    </div>
  );
};