All files / components/screens/combat/components/controls CombatControlsPanel.tsx

100% Statements 4/4
100% Branches 12/12
100% Functions 2/2
100% Lines 4/4

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                                                                          1x       6x   6x                                                                                               25x                          
/**
 * CombatControlsPanel - Displays controls guide and combat messages log
 *
 * Shows keyboard/touch controls on the left and scrolling combat log on the right.
 * Positioned at the bottom of the combat screen above the back button.
 *
 * Refactored to use useKoreanTheme for consistent theming.
 *
 * @module components/combat/components/CombatControlsPanel
 * @category Combat UI
 * @korean 전투컨트롤패널
 */
 
import React from "react";
import { useKoreanTheme } from "../../../../shared/base/useKoreanTheme";
import { hexToRgbaString } from "../../../../../utils/colorUtils";
 
export interface CombatControlsPanelProps {
  /** Combat message log (most recent messages) */
  readonly combatMessages: readonly string[];
  /** Whether to use mobile-optimized sizing */
  readonly isMobile: boolean;
}
 
/**
 * CombatControlsPanel - Controls guide and combat log display
 * 
 * Uses useKoreanTheme for consistent styling.
 *
 * @example
 * ```tsx
 * <CombatControlsPanel
 *   combatMessages={combatState.combatMessages}
 *   isMobile={false}
 * />
 * ```
 */
export const CombatControlsPanel: React.FC<CombatControlsPanelProps> = ({
  combatMessages,
  isMobile,
}) => {
  const theme = useKoreanTheme({ variant: "primary", size: "sm", isMobile });
  
  return (
    <div
      data-testid="combat-controls-panel"
      style={{
        position: "absolute",
        bottom: isMobile ? "90px" : "100px",
        left: isMobile ? "5px" : "15px",
        right: isMobile ? "5px" : "15px",
        display: "flex",
        justifyContent: "space-between",
        pointerEvents: "auto",
        zIndex: 50,
      }}
    >
      {/* Controls Guide */}
      <div
        data-testid="combat-controls-guide"
        style={{
          width: isMobile ? "45%" : "400px",
          background: "rgba(10, 10, 15, 0.8)",
          border: `2px solid ${hexToRgbaString(theme.colors.PRIMARY_CYAN, 1)}`,
          borderRadius: "8px",
          padding: "10px",
          color: hexToRgbaString(theme.colors.PRIMARY_CYAN, 1),
          fontFamily: theme.fontFamily.KOREAN,
        }}
      >
        <div style={{ fontSize: isMobile ? "10px" : "12px" }}>
          조작법 | Controls: A/D - Attack/Defend | 1-8 - Stances
        </div>
      </div>
 
      {/* Combat Message Log */}
      <div
        data-testid="combat-message-log"
        style={{
          width: isMobile ? "45%" : "400px",
          background: "rgba(10, 10, 15, 0.8)",
          border: `2px solid ${hexToRgbaString(theme.colors.PRIMARY_CYAN, 1)}`,
          borderRadius: "8px",
          padding: "10px",
          color: hexToRgbaString(theme.colors.PRIMARY_CYAN, 1),
          fontFamily: theme.fontFamily.KOREAN,
          maxHeight: "140px",
          overflow: "auto",
        }}
      >
        {combatMessages.slice(-5).map((msg, idx) => (
          <div
            key={`msg-${idx}`}
            style={{ fontSize: "12px", marginBottom: "4px" }}
          >
            {msg}
          </div>
        ))}
      </div>
    </div>
  );
};
 
export default CombatControlsPanel;