import { type LinkProps, useLinkProps, useTheme, } from '@react-navigation/native'; import Color from 'color'; import * as React from 'react'; import { Platform, StyleSheet } from 'react-native'; import { PlatformPressable, type Props as PlatformPressableProps, } from './PlatformPressable'; import { Text } from './Text'; type ButtonBaseProps = Omit & { variant?: 'plain' | 'tinted' | 'filled'; color?: string; children: string | string[]; }; type ButtonLinkProps = LinkProps & Omit; const BUTTON_RADIUS = 40; export function Button( props: ButtonLinkProps ): React.JSX.Element; export function Button(props: ButtonBaseProps): React.JSX.Element; export function Button( props: ButtonBaseProps | ButtonLinkProps ) { if ('screen' in props || 'action' in props) { // @ts-expect-error: This is already type-checked by the prop types return ; } else { return ; } } function ButtonLink({ screen, params, action, href, ...rest }: ButtonLinkProps) { // @ts-expect-error: This is already type-checked by the prop types const props = useLinkProps({ screen, params, action, href }); return ; } function ButtonBase({ variant = 'tinted', color: customColor, android_ripple, style, children, ...rest }: ButtonBaseProps) { const { colors, fonts } = useTheme(); const color = customColor ?? colors.primary; let backgroundColor; let textColor; switch (variant) { case 'plain': backgroundColor = 'transparent'; textColor = color; break; case 'tinted': backgroundColor = Color(color).fade(0.85).string(); textColor = color; break; case 'filled': backgroundColor = color; textColor = Color(color).isDark() ? 'white' : Color(color).darken(0.71).string(); break; } return ( {children} ); } const styles = StyleSheet.create({ button: { paddingHorizontal: 24, paddingVertical: 10, borderRadius: BUTTON_RADIUS, borderCurve: 'continuous', }, text: { fontSize: 14, lineHeight: 20, letterSpacing: 0.1, textAlign: 'center', }, });