/* * 기본 버튼 — 48px 터치 타깃(design.md §1-3), radius 4(sm). * variant: primary(브랜드 블루) · ai(보라) · outline · success · danger · ghost. */ import React from 'react'; import { ActivityIndicator, Pressable, StyleSheet, Text, View, type StyleProp, type ViewStyle, } from 'react-native'; import { colors, radius, touch, type } from '../theme'; type Variant = 'primary' | 'ai' | 'outline' | 'success' | 'danger' | 'ghost'; interface Props { label: string; onPress?: () => void; variant?: Variant; disabled?: boolean; loading?: boolean; style?: StyleProp; icon?: React.ReactNode; } const bg: Record = { primary: colors.primary600, ai: colors.aiAccent, outline: 'transparent', success: colors.success, danger: colors.error, ghost: 'transparent', }; const fg: Record = { primary: colors.white, ai: colors.white, outline: colors.primary600, success: colors.white, danger: colors.white, ghost: colors.neutral700, }; export function Button({ label, onPress, variant = 'primary', disabled, loading, style, icon, }: Props) { const isDisabled = disabled || loading; return ( [ styles.base, { backgroundColor: bg[variant], borderColor: variant === 'outline' ? colors.primary600 : 'transparent', borderWidth: variant === 'outline' ? 1 : 0, opacity: isDisabled ? 0.5 : pressed ? 0.85 : 1, }, style, ]} > {loading ? ( ) : ( {icon} {label} )} ); } const styles = StyleSheet.create({ base: { minHeight: touch.min, borderRadius: radius.sm, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 16, }, row: { flexDirection: 'row', alignItems: 'center', gap: 8 }, label: { fontSize: type.h3.fontSize, fontWeight: '600' }, });