import React, { useState } from 'react'; import { StyleProp, StyleSheet, ViewStyle, TouchableHighlight, View, } from 'react-native'; import type { Theme, AnyValue } from '../../types'; import { withTheme } from '../../core/theming'; import { padding, margin, blockSizes, buildBorderStyles, } from '../../styles/styles'; import { Border } from '../../styles/styleElements'; import { Text, Panel } from '../..'; type TabsProps = { children?: React.ReactNode; onChange?: (value: AnyValue) => void; stretch?: boolean; style?: StyleProp; theme: Theme; value: AnyValue; }; const Tabs = ({ children, onChange, stretch = false, style, theme, value, ...rest }: TabsProps) => { const childrenWithProps = React.Children.map(children, child => { if (!React.isValidElement(child)) { return null; } const tabProps = { //@ts-ignore selected: child.props.value === value, onPress: onChange, stretch, }; return React.cloneElement(child, tabProps); }); return ( {childrenWithProps} ); }; type TabBodyProps = { children?: React.ReactNode; style?: StyleProp; theme: Theme; }; const Body = ({ children, style, ...rest }: TabBodyProps) => { return ( {children} ); }; type TabProps = { children?: React.ReactNode; onPress?: (value: AnyValue) => void; selected?: boolean; stretch?: boolean; style?: StyleProp; theme: Theme; value: AnyValue; }; const Tab = ({ children, onPress = () => {}, selected, stretch, style, theme, value, ...rest }: TabProps) => { const [isPressed, setIsPressed] = useState(false); const borderStyles = buildBorderStyles(theme); return ( onPress(value)} onHideUnderlay={() => setIsPressed(false)} onShowUnderlay={() => setIsPressed(true)} underlayColor='none' style={[ styles.tab, { zIndex: selected ? 1 : 0 }, stretch ? { flexGrow: 1 } : { width: 'auto' }, selected ? margin(0, -8) : margin(0, 0), style, ]} accessibilityRole='tab' accessibilityState={{ selected, }} {...rest} > {children} {isPressed && ( )} ); }; const styles = StyleSheet.create({ tabs: { display: 'flex', flexDirection: 'row', alignItems: 'flex-end', paddingHorizontal: 8, zIndex: 1, bottom: -2, }, body: { display: 'flex', padding: 16, }, tab: { alignSelf: 'flex-end', }, tabContent: { justifyContent: 'center', width: 'auto', }, tabBodyBorder: { height: 4, position: 'absolute', left: 4, right: 4, bottom: -2, borderTopWidth: 2, }, mask: { height: 4, position: 'absolute', left: 4, right: 4, bottom: -2, }, focusOutline: { position: 'absolute', left: 6, top: 6, bottom: 4, right: 6, }, }); const TabWithTheme = withTheme(Tab); const BodyWithTheme = withTheme(Body); Tabs.Tab = TabWithTheme; Tabs.Body = BodyWithTheme; export default withTheme(Tabs);