import React, { useCallback, useMemo, useState } from 'react'; import { Dimensions, LayoutChangeEvent, StyleSheet, View, type ViewStyle } from 'react-native'; import type { TComponent } from '@namiml/sdk-core'; import { applyGridStyles, focusedStyleOverrides, parseSize } from '../../utils/styles'; import { usePaywallContext } from '../../context/PaywallContext'; import { FocusScope } from '../../context/FocusContext'; import { TemplateRenderer } from '../TemplateRenderer'; import { getRepeatingListBlocks } from '../../utils/rendering'; interface Props { component: any; scaleFactor: number; onClose?: () => void; parentDirection?: string; } export const NamiRepeatingGrid: React.FC = ({ component, scaleFactor, onClose, parentDirection }) => { const ctx = usePaywallContext(); const [isFocused, setIsFocused] = useState(false); const [containerWidth, setContainerWidth] = useState(null); const columns = Math.max(1, component.columns ?? 2); const columnSpacing = parseSize(component.columnSpacing ?? component.spacing, scaleFactor) ?? 0; const rowSpacing = parseSize(component.rowSpacing ?? component.spacing, scaleFactor) ?? 0; const { width: screenWidth } = Dimensions.get('window'); const blocks = useMemo( () => getRepeatingListBlocks(ctx, component), [ctx, component], ); const usableWidth = Math.max(1, (containerWidth ?? screenWidth) - columnSpacing * Math.max(0, columns - 1)); const itemWidth = usableWidth / columns; const onLayout = useCallback((event: LayoutChangeEvent) => { setContainerWidth(event.nativeEvent.layout.width); }, []); const containerStyle = useMemo(() => { const base = applyGridStyles(component, scaleFactor, false, parentDirection); Object.assign(base, styles.grid); if (isFocused) { Object.assign(base, focusedStyleOverrides(component, scaleFactor)); } return base; }, [component, isFocused, parentDirection, scaleFactor]); const renderedChildren: React.ReactNode[] = []; let cellIdx = 0; blocks.forEach((subArray: TComponent[], sectionIdx: number) => { const headerComponent = subArray.length === 1 && (subArray[0] as any)?.__namiGroupHeader ? subArray[0] : null; if (headerComponent) { renderedChildren.push( , ); cellIdx = 0; return; } subArray.forEach((child: TComponent, withinIdx: number) => { const columnIndex = cellIdx % columns; const isLastInRow = columnIndex === columns - 1; const cellStyle: ViewStyle = { width: itemWidth, marginRight: isLastInRow ? 0 : columnSpacing, marginBottom: rowSpacing, }; renderedChildren.push( , ); cellIdx += 1; }); }); return ( {renderedChildren} ); }; const styles = StyleSheet.create({ grid: { flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center', }, groupHeader: { width: '100%', }, });