kintex/mobile/components/LanguageSelector.tsx

69 lines
2.3 KiB
TypeScript

/*
* 언어 선택기 — ko/en/zh/ja 세그먼트. more/profile 등 설정 영역에서 재사용.
* 현재 언어 강조 + 선택 시 지속(AsyncStorage `kintex_lang`) + 전 화면 즉시 갱신(react-i18next).
*/
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Pressable, StyleSheet, Text, View } from 'react-native';
import { useLanguage } from '../context/LanguageContext';
import type { Lang } from '../lib/i18n/types';
import { colors, radius, spacing, touch, type } from '../theme';
import { Card } from './Card';
export function LanguageSelector() {
const { t } = useTranslation();
const { lang, supported, setLanguage } = useLanguage();
return (
<Card>
<Text style={styles.title}>{t('lang.title')}</Text>
<Text style={styles.subtitle}>{t('lang.subtitle')}</Text>
<View style={styles.segment}>
{supported.map((code: Lang) => {
const on = lang === code;
return (
<Pressable
key={code}
accessibilityRole="button"
accessibilityState={{ selected: on }}
accessibilityLabel={t(`lang.${code}` as const)}
style={[styles.segBtn, on && styles.segBtnOn]}
onPress={() => {
if (!on) void setLanguage(code);
}}
>
<Text style={[styles.segText, on && styles.segTextOn]} numberOfLines={1}>
{t(`lang.${code}` as const)}
</Text>
</Pressable>
);
})}
</View>
</Card>
);
}
const styles = StyleSheet.create({
title: { color: colors.neutral900, fontSize: type.h3.fontSize, fontWeight: '700' },
subtitle: { color: colors.neutral500, fontSize: type.caption.fontSize, marginTop: 4, marginBottom: spacing.sm },
segment: {
flexDirection: 'row',
backgroundColor: colors.neutral050,
borderWidth: 1,
borderColor: colors.neutral200,
borderRadius: radius.md,
padding: 4,
gap: 4,
},
segBtn: {
flex: 1,
minHeight: touch.min,
alignItems: 'center',
justifyContent: 'center',
borderRadius: radius.sm,
},
segBtnOn: { backgroundColor: colors.primary600 },
segText: { fontSize: type.caption.fontSize, fontWeight: '700', color: colors.neutral700 },
segTextOn: { color: colors.white },
});