import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { useTheme } from '../theme'; import { Touchable } from './Touchable'; /** 键值:数字/小数点/加减走 numpadExpression;today/done 由宿主处理。 */ export type KeyboardKey = string; interface NumpadKeyboardProps { onKey: (key: KeyboardKey) => void; todayLabel: string; doneLabel: string; /** 退格键无障碍标签(i18n)。 */ backspaceLabel: string; } const ROWS: KeyboardKey[][] = [ ['1', '2', '3', 'today'], ['4', '5', '6', '+'], ['7', '8', '9', '-'], ['.', '0', 'backspace', 'done'], ]; /** 内嵌数字键盘(4×4):金额优先,+/- 连续计算,「今天」快速设日期。带有按压微缩放与变色触控反馈。 */ export function NumpadKeyboard({ onKey, todayLabel, doneLabel, backspaceLabel }: NumpadKeyboardProps) { const { theme } = useTheme(); const renderKey = (key: KeyboardKey) => { if (key === 'done') { return ( onKey(key)} disableRipple style={({ pressed }) => [ styles.key, styles.doneKey, { backgroundColor: pressed ? theme.colors.accentDark : theme.colors.accent, borderRadius: theme.radii.lg, }, ]} accessibilityRole="button" accessibilityLabel={doneLabel} > {doneLabel} ); } if (key === 'backspace') { return ( onKey(key)} disableRipple style={({ pressed }) => [ styles.key, pressed && { backgroundColor: theme.colors.bgTertiary }, ]} accessibilityRole="button" accessibilityLabel={backspaceLabel} > ); } if (key === 'today') { return ( onKey(key)} disableRipple style={({ pressed }) => [ styles.key, pressed && { backgroundColor: theme.colors.bgTertiary }, ]} accessibilityRole="button" accessibilityLabel={todayLabel} > {todayLabel} ); } if (key === '+' || key === '-') { return ( onKey(key)} disableRipple style={({ pressed }) => [ styles.key, pressed && { backgroundColor: theme.colors.bgTertiary }, ]} accessibilityRole="button" accessibilityLabel={key} > {key === '+' ? '+' : '-'} ); } return ( onKey(key)} disableRipple style={({ pressed }) => [ styles.key, pressed && { backgroundColor: theme.colors.bgTertiary }, ]} accessibilityRole="button" accessibilityLabel={key} > {key} ); }; return ( {ROWS.map((row, i) => ( {row.map(renderKey)} ))} ); } const styles = StyleSheet.create({ grid: { gap: 2 }, row: { flexDirection: 'row' }, key: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingVertical: 14, borderRadius: 8 }, digitText: { fontSize: 22, fontWeight: '600', fontVariant: ['tabular-nums'] }, opText: { fontSize: 16, fontWeight: '600' }, doneKey: { margin: 4 }, doneText: { fontSize: 15, fontWeight: '700' }, });