126 lines
3.3 KiB
TypeScript
126 lines
3.3 KiB
TypeScript
/**
|
|
* PlatformIcon — 플랫폼 식별자 (string variant) 로 lucide line icon 을 반환.
|
|
*
|
|
* 입력은 'youtube', 'YouTube', 'naver-blog', '네이버 블로그' 같이 다양한 형태가
|
|
* 들어올 수 있어 normalize 후 부분 일치까지 시도합니다. 매칭 실패 시 Globe.
|
|
*/
|
|
import {
|
|
Globe,
|
|
Instagram,
|
|
Youtube,
|
|
Facebook,
|
|
Music,
|
|
FileText,
|
|
Heart,
|
|
MapPin,
|
|
Search,
|
|
type LucideIcon,
|
|
} from 'lucide-react';
|
|
|
|
export type PlatformVariant =
|
|
| 'website'
|
|
| 'instagram'
|
|
| 'youtube'
|
|
| 'facebook'
|
|
| 'tiktok'
|
|
| 'naverPlace'
|
|
| 'naverBlog'
|
|
| 'naver'
|
|
| 'gangnamUnni'
|
|
| 'blog';
|
|
|
|
export const PLATFORM_ICONS: Record<PlatformVariant, LucideIcon> = {
|
|
website: Globe,
|
|
instagram: Instagram,
|
|
youtube: Youtube,
|
|
facebook: Facebook,
|
|
tiktok: Music,
|
|
naverPlace: MapPin,
|
|
naverBlog: FileText,
|
|
naver: Search,
|
|
gangnamUnni: Heart,
|
|
blog: FileText,
|
|
};
|
|
|
|
export const PLATFORM_COLORS: Record<PlatformVariant, string> = {
|
|
website: '#6C5CE7',
|
|
instagram: '#833AB4',
|
|
youtube: '#FF3D3D',
|
|
facebook: '#1877F2',
|
|
tiktok: '#0A1128',
|
|
naverPlace: '#03C75A',
|
|
naverBlog: '#03C75A',
|
|
naver: '#03C75A',
|
|
gangnamUnni: '#FF6B8A',
|
|
blog: '#03C75A',
|
|
};
|
|
|
|
/** 별칭 → canonical key. lowercase / 한글 / 공백·하이픈 변형을 흡수. */
|
|
const ALIAS: Record<string, PlatformVariant> = {
|
|
website: 'website',
|
|
homepage: 'website',
|
|
web: 'website',
|
|
site: 'website',
|
|
홈페이지: 'website',
|
|
instagram: 'instagram',
|
|
ig: 'instagram',
|
|
인스타: 'instagram',
|
|
인스타그램: 'instagram',
|
|
youtube: 'youtube',
|
|
yt: 'youtube',
|
|
유튜브: 'youtube',
|
|
facebook: 'facebook',
|
|
fb: 'facebook',
|
|
페이스북: 'facebook',
|
|
tiktok: 'tiktok',
|
|
틱톡: 'tiktok',
|
|
naverplace: 'naverPlace',
|
|
네이버플레이스: 'naverPlace',
|
|
네이버플레이스지도: 'naverPlace',
|
|
place: 'naverPlace',
|
|
naverblog: 'naverBlog',
|
|
네이버블로그: 'naverBlog',
|
|
naver: 'naver',
|
|
네이버: 'naver',
|
|
blog: 'blog',
|
|
블로그: 'blog',
|
|
gangnamunni: 'gangnamUnni',
|
|
강남언니: 'gangnamUnni',
|
|
};
|
|
|
|
/** 자유 문자열 → PlatformVariant. 못 찾으면 undefined. */
|
|
export function resolvePlatformVariant(raw: string | null | undefined): PlatformVariant | undefined {
|
|
if (!raw) return undefined;
|
|
const norm = raw.toLowerCase().replace(/[\s\-_]+/g, '');
|
|
if (norm in ALIAS) return ALIAS[norm];
|
|
// 부분 일치 (예: "naver blog" → "naverblog" → naverBlog)
|
|
for (const key of Object.keys(ALIAS)) {
|
|
if (norm.includes(key)) return ALIAS[key];
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
interface PlatformIconProps {
|
|
/** 플랫폼 식별 문자열. 'youtube' / 'Instagram' / '네이버 블로그' 등 자유 형식 */
|
|
variant: string | null | undefined;
|
|
size?: number;
|
|
className?: string;
|
|
/** 색상을 자동으로 플랫폼 컬러로 채울지 (false 면 현재 텍스트 색 상속) */
|
|
colored?: boolean;
|
|
/** 매칭 실패 시 사용할 fallback icon. 기본 Globe. */
|
|
fallback?: LucideIcon;
|
|
}
|
|
|
|
export function PlatformIcon({
|
|
variant,
|
|
size = 16,
|
|
className,
|
|
colored = false,
|
|
fallback = Globe,
|
|
}: PlatformIconProps) {
|
|
const key = resolvePlatformVariant(variant);
|
|
const Icon = key ? PLATFORM_ICONS[key] : fallback;
|
|
const color = colored && key ? PLATFORM_COLORS[key] : undefined;
|
|
return <Icon size={size} className={className} style={color ? { color } : undefined} />;
|
|
}
|