import React, { memo } from 'react'; import { StyleSheet } from 'react-native'; import type { SduiScreen, SduiBlock } from '@proulr/sdui-contract'; import { colors } from './theme/proulr-theme'; import { renderBlockTree } from './sdui-component-registry'; import { SduiLayoutDebugFrame } from './sdui-layout-debug'; type Props = { screen: SduiScreen; onAction: (actionId: string, vars?: Record) => void; }; /** Blocos overlay (FAB etc.) — não competem por flex com o Scroll. */ const OVERLAY_BLOCK_TYPES = new Set(['floating_create_menu', 'inbox_hub_chrome']); type ScreenBlockProps = { block: SduiBlock; data: SduiScreen['data']; onAction: Props['onAction']; }; /** * Bloco memoizado: re-renderiza só quando `block`/`data`/`onAction` mudam de * identidade (novo wire). Re-renders do shell (header, insets, sheets) não * reconstroem a árvore de todos os blocos — custo direto de INP no web. */ const SduiScreenBlock = memo(function SduiScreenBlock({ block, data, onAction }: ScreenBlockProps) { const overlay = OVERLAY_BLOCK_TYPES.has(block.type); return ( {renderBlockTree(block, data, onAction)} ); }); export const SduiScreenRenderer = memo(function SduiScreenRenderer({ screen, onAction }: Props) { return ( {screen.blocks.map((block) => ( ))} ); }); const styles = StyleSheet.create({ screen: { flex: 1, minHeight: 0, backgroundColor: colors.bg }, block: { flex: 1, minHeight: 0 }, overlayBlock: { ...StyleSheet.absoluteFill, zIndex: 20, elevation: 20, }, });