/** * DT Button Component * * A themed button following the Dangerous Things design language * with SVG-based beveled corners. */ import {StyleSheet, View, ViewStyle, StyleProp, Pressable} from 'react-native'; import {Text} from 'react-native-paper'; import Svg, {Path} from 'react-native-svg'; import {DTColors} from '../theme/colors'; import {type DTVariant, getVariantColor} from '../utils/variantColors'; import {buildButtonBevelPath} from '../utils/bevelPaths'; import {useComponentLayout} from '../utils/useComponentLayout'; import {useState} from 'react'; interface DTButtonProps { /** * Button content/label */ children: React.ReactNode; /** * Visual variant of the button * @default 'normal' */ variant?: DTVariant; /** * Button display mode * - 'outlined': Border with transparent background (default) * - 'contained': Filled background * @default 'outlined' */ mode?: 'outlined' | 'contained'; /** * Custom color (overrides variant) */ color?: string; /** * Press handler */ onPress?: () => void; /** * Whether button is disabled */ disabled?: boolean; /** * Additional styles for container */ style?: StyleProp; /** * Border width * @default 2 */ borderWidth?: number; /** * Bevel size in pixels * @default 8 */ bevelSize?: number; } /** * DT-styled Button component with SVG beveled corners * * @example * * Scan NFC Tag * * * @example * * View Results * */ export function DTButton({ children, variant = 'normal', mode = 'outlined', color, onPress, disabled = false, style, borderWidth = 2, bevelSize = 8, }: DTButtonProps) { const {dimensions, onLayout, hasDimensions} = useComponentLayout(); const [pressed, setPressed] = useState(false); const accentColor = getVariantColor(variant, color); const isContained = mode === 'contained'; const bgColor = isContained ? accentColor : 'transparent'; const textColor = isContained ? DTColors.dark : accentColor; const {width, height} = dimensions; const opacity = disabled ? 0.5 : pressed ? 0.7 : 1; return ( setPressed(true)} onPressOut={() => setPressed(false)} style={[{opacity}, style]}> {hasDimensions && ( )} {typeof children === 'string' ? ( {children} ) : ( children )} ); } const styles = StyleSheet.create({ container: { position: 'relative', minHeight: 44, }, content: { position: 'relative', zIndex: 1, paddingVertical: 12, paddingHorizontal: 24, alignItems: 'center', justifyContent: 'center', }, label: { fontWeight: '600', letterSpacing: 1, textTransform: 'uppercase', }, });