Files
MikrotikManager/components/flag.tsx
T
2026-05-03 11:16:07 +07:00

67 lines
2.0 KiB
TypeScript

/**
* Flag — renders a country flag image from an ISO 3166-1 alpha-2 code.
* Images served from flagcdn.com (free, no auth required).
*/
const COUNTRY_NAMES: Record<string, string> = {
RU: "Россия",
DE: "Германия",
NL: "Нидерланды",
SG: "Сингапур",
US: "США",
GB: "Великобритания",
FR: "Франция",
FI: "Финляндия",
SE: "Швеция",
PL: "Польша",
UA: "Украина",
TR: "Турция",
JP: "Япония",
HK: "Гонконг",
}
/** Country name in Russian (fallback to code) */
export function countryName(code: string): string {
return COUNTRY_NAMES[code.toUpperCase()] ?? code
}
interface FlagProps {
code: string
/** px size — width of the flag image (height auto-scales 3:2 ratio) */
size?: number
className?: string
}
// flagcdn.com supports only these widths
const CDN_SIZES = [20, 40, 80, 160, 320, 640, 1280, 2560]
function nearestCdnSize(px: number): number {
return CDN_SIZES.find(s => s >= px) ?? CDN_SIZES[CDN_SIZES.length - 1]
}
/**
* Renders a flag <img> for a given ISO 3166-1 alpha-2 country code.
* Source: https://flagcdn.com — free CDN, no API key needed.
*/
export function Flag({ code, size = 20, className }: FlagProps) {
if (!code) return null
const lower = code.toLowerCase()
const name = countryName(code.toUpperCase())
const cdnSrc = nearestCdnSize(size)
const cdnSrc2x = nearestCdnSize(size * 2)
return (
// Внешний CDN (динамический URL) — next/image без remotePatterns не подходит
// eslint-disable-next-line @next/next/no-img-element -- flagcdn.com, размеры задаём явно
<img
src={`https://flagcdn.com/w${cdnSrc}/${lower}.png`}
srcSet={`https://flagcdn.com/w${cdnSrc2x}/${lower}.png 2x`}
width={size}
height={Math.round(size * 0.75)}
alt={name}
title={name}
className={className}
style={{ display: "inline-block", verticalAlign: "middle", borderRadius: 2 }}
/>
)
}