| 1 | import { requireNativeView, requireOptionalNativeModule } from "expo"; |
| 2 | import type { NativeSyntheticEvent, ViewProps } from "react-native"; |
| 3 | import type { NativeLayoutMetrics } from "../lib/reserved-regions"; |
| 4 | |
| 5 | interface ObserverProps extends ViewProps { |
| 6 | readonly onMetricsChange?: (event: NativeSyntheticEvent<NativeLayoutMetrics>) => void; |
| 7 | } |
| 8 | |
| 9 | // An older development client can still run the compact app while it rebuilds. |
| 10 | function resolveObserver() { |
| 11 | try { |
| 12 | const module = requireOptionalNativeModule<{ |
| 13 | readonly ViewPrototypes?: { readonly T3NativeControls_LayoutMetrics?: unknown }; |
| 14 | }>("T3NativeControls"); |
| 15 | if (!module?.ViewPrototypes?.T3NativeControls_LayoutMetrics) return null; |
| 16 | return requireNativeView<ObserverProps>("T3NativeControls", "LayoutMetrics"); |
| 17 | } catch { |
| 18 | return null; |
| 19 | } |
| 20 | } |
| 21 | const Observer = resolveObserver(); |
| 22 | |
| 23 | export function NativeLayoutObserver(props: { |
| 24 | readonly onChange?: (metrics: NativeLayoutMetrics) => void; |
| 25 | }) { |
| 26 | return Observer ? ( |
| 27 | <Observer |
| 28 | pointerEvents="none" |
| 29 | onMetricsChange={props.onChange ? (event) => props.onChange?.(event.nativeEvent) : undefined} |
| 30 | style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0 }} |
| 31 | /> |
| 32 | ) : null; |
| 33 | } |