59 lines
1.4 KiB
TypeScript
59 lines
1.4 KiB
TypeScript
import type { ReactElement } from 'react';
|
|
import { Pressable, StyleSheet } from 'react-native';
|
|
import * as Haptics from 'expo-haptics';
|
|
import { useTheme } from '@/theme';
|
|
import { Icon } from './Icon';
|
|
import type { IconName } from './Icon';
|
|
|
|
interface Props {
|
|
name: IconName;
|
|
onPress: () => void;
|
|
size?: number;
|
|
color?: string;
|
|
accent?: boolean;
|
|
haptic?: boolean;
|
|
accessibilityLabel: string;
|
|
}
|
|
|
|
// 44pt touch target icon button (iOS min), optional accent fill + haptic tick.
|
|
export const IconButton = ({
|
|
name,
|
|
onPress,
|
|
size = 22,
|
|
color,
|
|
accent = false,
|
|
haptic = false,
|
|
accessibilityLabel,
|
|
}: Props): ReactElement => {
|
|
const { colors } = useTheme();
|
|
return (
|
|
<Pressable
|
|
accessibilityRole="button"
|
|
accessibilityLabel={accessibilityLabel}
|
|
hitSlop={8}
|
|
onPress={() => {
|
|
if (haptic) {
|
|
void Haptics.selectionAsync();
|
|
}
|
|
onPress();
|
|
}}
|
|
style={({ pressed }) => [
|
|
styles.button,
|
|
accent && { backgroundColor: colors.accent },
|
|
pressed && { opacity: 0.6 },
|
|
]}
|
|
>
|
|
<Icon name={name} size={size} color={color ?? (accent ? colors.onAccent : colors.textMuted)} />
|
|
</Pressable>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
button: {
|
|
width: 44,
|
|
height: 44,
|
|
borderRadius: 22,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
});
|