import React, { useState, useRef, forwardRef, ReactNode } from 'react'; import { View, Text, TouchableOpacity, StyleSheet, Dimensions, PixelRatio } from 'react-native'; import { useTheme } from './themes'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; const BORDER_RADIUS = 30; const PADDINGS = 8; const ICON_MARGIN = 7; const cStyles = StyleSheet.create({ root: { alignSelf: 'center', height: '6.3%', minHeight: 44, }, rootAbsolute: { position: 'absolute', }, rootInline: {}, rootPre: { position: 'absolute', bottom: -1000, }, rootPost: { borderRadius: BORDER_RADIUS, flexDirection: 'row', overflow: 'hidden', }, }); interface FContainerProps { children: ReactNode | ReactNode[]; inline?: boolean; } export const FContainer = forwardRef((props, ref) => { const [newWidth, setNewWidth] = useState(undefined); const layoutCalculated = useRef(false); const insets = useSafeAreaInsets(); const bottomInsets = { bottom: insets.bottom }; const onLayout = (event: { nativeEvent: { layout: { width: number } } }) => { if (layoutCalculated.current) return; const maxWidth = Dimensions.get('window').width - BORDER_RADIUS - 20; const { width } = event.nativeEvent.layout; const withPaddings = Math.ceil(width + PADDINGS * 2); const len = React.Children.toArray(props.children).filter(Boolean).length; let newW = withPaddings * len > maxWidth ? Math.floor(maxWidth / len) : withPaddings; if (len === 1 && newW < 90) newW = 90; setNewWidth(newW); layoutCalculated.current = true; }; return ( {newWidth ? React.Children.toArray(props.children) .filter(Boolean) .map((child, index, array) => { if (typeof child === 'string') { return ( {child} ); } return React.cloneElement(child as React.ReactElement, { width: newWidth, key: index, first: index === 0, last: index === array.length - 1, }); }) : props.children} ); }); const buttonFontSize = PixelRatio.roundToNearestPixel(Dimensions.get('window').width / 26) > 22 ? 22 : PixelRatio.roundToNearestPixel(Dimensions.get('window').width / 26); const bStyles = StyleSheet.create({ root: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', overflow: 'hidden', }, icon: { alignItems: 'center', }, text: { fontSize: buttonFontSize, fontWeight: '600', marginLeft: ICON_MARGIN, backgroundColor: 'transparent', }, }); interface FButtonProps { text: string; icon: ReactNode; width?: number; first?: boolean; last?: boolean; disabled?: boolean; } export const FButton = ({ text, icon, width, first, last, ...props }: FButtonProps) => { const { colors } = useTheme(); const bStylesHook = StyleSheet.create({ root: { backgroundColor: colors.buttonBackgroundColor, }, text: { color: colors.buttonAlternativeTextColor, }, textDisabled: { color: colors.formBorder, }, }); const style: Record = {}; if (width) { const paddingLeft = first ? BORDER_RADIUS / 2 : PADDINGS; const paddingRight = last ? BORDER_RADIUS / 2 : PADDINGS; style.paddingRight = paddingRight; style.paddingLeft = paddingLeft; style.width = width + paddingRight + paddingLeft; } return ( {icon} {text} ); };