import React from 'react'; import { Pressable, type ViewStyle } from 'react-native'; import type { TabProps } from '../../../../types/tabs'; import { View } from '../../../layout/public'; import { useTheme } from '../../../theme/runtime'; import { Text } from '../../../typography/public'; import { useTabRegistration } from '../../composition/useTabRegistration'; import { useTabsContext } from '../../composition/useTabsContext'; /*** Renders one accessible selectable tab inside a Tabs context. */ export function Tab({ value, children, disabled = false, interactionPolicy = 'enabled', testID, trailing, }: TabProps) { const { theme } = useTheme(); const { activeValue, getPanelId, getTabId, setActiveValue, setFocusedValue, variant } = useTabsContext(); const pressableRef = useTabRegistration({ disabled, value }); const selected = activeValue === value; const passive = interactionPolicy === 'passive'; const onPress = passive || disabled ? undefined : () => setActiveValue(value); return ( setFocusedValue(undefined)} onFocus={() => setFocusedValue(value)} onPress={onPress} ref={pressableRef} testID={testID} > {renderTabContent(children, trailing, selected)} ); } /*** Renders the canonical tab label with optional trailing content. */ function renderTabContent( children: React.ReactNode, trailing: React.ReactNode, selected: boolean, ): React.ReactNode { const label = ( {children} ); if (trailing === undefined) return label; return ( {label} {trailing} ); } /*** Resolves active and disabled visual state without inline JSX styles. */ function resolveTabStyle({ activeBackground, borderColor, disabled, radius, selected, variant, }: { activeBackground: string; borderColor: string; disabled: boolean; radius: number; selected: boolean; variant: 'line' | 'attached'; }): ViewStyle { if (variant === 'attached') { return { backgroundColor: selected ? activeBackground : 'transparent', borderTopLeftRadius: selected ? radius : 0, borderTopRightRadius: selected ? radius : 0, opacity: disabled ? 0.64 : 1, }; } return { borderBottomColor: borderColor, borderBottomWidth: 2, opacity: disabled ? 0.64 : 1 }; }