All files / src/components NfpaDiamond.tsx

100% Statements 53/53
100% Branches 7/7
100% Functions 1/1
100% Lines 53/53

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 871x                               1x                         1x 1x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x   12x           12x  
import { NFPA_COLORS } from '@/constants/hazards';
 
/** Props for {@link NfpaDiamond}. */
interface NfpaDiamondProps {
  /** Health rating (0-4). */
  health?: string;
  /** Flammability rating (0-4). */
  fire?: string;
  /** Instability rating (0-4). */
  reactivity?: string;
  /** Special notice, e.g. `W` or `OX`. */
  special?: string;
  /** Rendered edge length in px. */
  size?: number;
}
 
/**
 * An NFPA 704 "fire diamond": blue health (left), red flammability (top), yellow instability
 * (right) and white special notice (bottom).
 * @component
 * @category Components
 * @group Chemical Info
 * @param props - See {@link NfpaDiamondProps}.
 * @returns The SVG diamond.
 * @example
 * ```tsx
 * <NfpaDiamond health="1" fire="3" reactivity="0" />
 * ```
 * @source
 */
export function NfpaDiamond({ health, fire, reactivity, special, size = 120 }: NfpaDiamondProps) {
  const label = `NFPA 704: health ${health ?? '?'}, fire ${fire ?? '?'}, reactivity ${reactivity ?? '?'}${special ? `, ${special}` : ''}`;
  const quadrants = [
    {
      points: '50,2 74,26 50,50 26,26',
      fill: NFPA_COLORS.fire,
      text: fire,
      x: 50,
      y: 31,
      ink: '#fff',
    },
    {
      points: '2,50 26,26 50,50 26,74',
      fill: NFPA_COLORS.health,
      text: health,
      x: 26,
      y: 55,
      ink: '#fff',
    },
    {
      points: '98,50 74,26 50,50 74,74',
      fill: NFPA_COLORS.reactivity,
      text: reactivity,
      x: 74,
      y: 55,
      ink: '#000',
    },
    {
      points: '50,98 74,74 50,50 26,74',
      fill: NFPA_COLORS.special,
      text: special,
      x: 50,
      y: 79,
      ink: '#000',
    },
  ];
  return (
    <svg width={size} height={size} viewBox="0 0 100 100" role="img" aria-label={label}>
      {quadrants.map((quadrant) => (
        <g key={quadrant.points}>
          <polygon points={quadrant.points} fill={quadrant.fill} stroke="#000" strokeWidth="1.5" />
          <text
            x={quadrant.x}
            y={quadrant.y}
            textAnchor="middle"
            fontSize="16"
            fontWeight="700"
            fill={quadrant.ink}
          >
            {quadrant.text ?? ''}
          </text>
        </g>
      ))}
    </svg>
  );
}