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' },
});