import React, { useCallback, useMemo, useRef } from 'react'; import { TouchableOpacity, View } from 'react-native'; import { usePaywallContext } from '../../context/PaywallContext'; import { applyStyles, parseColor, parseSize, childSpacingStyle, shadowStyles, focusedStyleOverrides } from '../../utils/styles'; import { handleAction } from '../../utils/actionHandler'; import { TemplateRenderer } from '../TemplateRenderer'; import type { TComponent } from '@namiml/sdk-core'; import { FocusedStyleProvider, useFocusableState, useFocusEnabled, useRegisterPreferredFocus } from '../../context/FocusContext'; import { useTVPreferredFocus } from '../../utils/tvFocus'; interface Props { component: any; scaleFactor: number; onClose?: () => void; parentDirection?: string; } export const NamiToggleButton: React.FC = ({ component, scaleFactor, onClose, parentDirection }) => { const ctx = usePaywallContext(); const focusEnabled = useFocusEnabled(); const touchableRef = useRef(null); const { isFocused, onFocus, onBlur } = useFocusableState( Boolean(component.focused), focusEnabled, ); useTVPreferredFocus( touchableRef, focusEnabled && Boolean(component.focused), ); useRegisterPreferredFocus( touchableRef.current, focusEnabled && Boolean(component.focused), ); const formId = component.formId ?? component.id ?? ''; const mode = component.mode ?? 'toggle'; const currentValue = ctx.state.formStates?.[formId]; const isActive = mode === 'radio' ? currentValue === component.value : !!currentValue; const onPress = useCallback(() => { const functionName = component.onTap?.function; if (!functionName) return; handleAction({ onTap: { function: functionName, parameters: { ...(component.onTap?.parameters ?? {}), formId, value: mode === 'radio' ? component.value : undefined, }, }, ctx, onClose, }); }, [formId, mode, component.value, ctx, component.onTap, onClose]); const containerStyle = useMemo(() => { const base = applyStyles(component, scaleFactor, false, parentDirection); const fillColor = isActive ? (component.activeFillColor ?? component.activeFillColorFallback ?? component.selectedFillColor ?? component.focusedFillColor) : (component.inactiveFillColor ?? component.inactiveFillColorFallback ?? component.fillColor); const borderColor = isActive ? component.activeBorderColor : component.inactiveBorderColor; const borderWidth = isActive ? component.activeBorderWidth : component.inactiveBorderWidth; const dropShadow = isActive ? component.activeDropShadow : component.inactiveDropShadow; const bg = parseColor(fillColor); if (bg) base.backgroundColor = bg; const bc = parseColor(borderColor); if (bc) base.borderColor = bc; const bw = parseSize(borderWidth, scaleFactor); if (bw != null) base.borderWidth = bw; if (dropShadow) { Object.assign(base, shadowStyles({ ...component, dropShadow } as any)); } if (isFocused) { Object.assign(base, focusedStyleOverrides(component, scaleFactor)); } return base; }, [component, scaleFactor, isActive, isFocused, parentDirection]); return ( {component.components?.map((child: TComponent, i: number) => ( ))} ); };