import * as React from "react"; import { Button, Text, View, ViewStyle, StyleSheet, StyleProp, Animated, } from "react-native"; import Surface from "../components/Surface"; import type { IconSlot } from "../interfaces/Icon"; import { withTheme } from "@draftbit/theme"; import type { ReadTheme } from "@draftbit/theme"; const ELEVATION = 1; const DEFAULT_MAX_WIDTH = 960; type Props = { initiallyVisible: boolean; dismissable: boolean; buttonColor?: string; icon?: string; content?: string; contentStyle?: StyleProp; style?: StyleProp; ref?: React.RefObject; /** * @optional */ theme: ReadTheme; } & IconSlot; type NativeEvent = { nativeEvent: { layout: { x: number; y: number; width: number; height: number; }; }; }; /** * @deprecated DEPRECATED */ const Banner: React.FC> = ({ initiallyVisible = true, dismissable = true, icon, buttonColor, content, contentStyle, style, theme, Icon, ...rest }) => { const [visible, setVisible] = React.useState(initiallyVisible); React.useEffect(() => { if (initiallyVisible) { setVisible(true); } }, [initiallyVisible]); const { current: position } = React.useRef( new Animated.Value(visible ? 1 : 0) ); const [layout, setLayout] = React.useState<{ height: number; measured: boolean; }>({ height: 0, measured: false, }); React.useEffect(() => { if (visible) { // show Animated.timing(position, { duration: 250, toValue: 1, useNativeDriver: false, }).start(); } else { // hide Animated.timing(position, { duration: 200, toValue: 0, useNativeDriver: false, }).start(); } }, [visible, position]); const handleLayout = ({ nativeEvent }: NativeEvent) => { const { height } = nativeEvent.layout; setLayout({ height, measured: true }); }; // The banner animation has 2 parts: // 1. Blank spacer element which animates its height to move the content // 2. Actual banner which animates its translateY // In initial render, we position everything normally and measure the height of the banner // Once we have the height, we apply the height to the spacer and switch the banner to position: absolute // We need this because we need to move the content below as if banner's height was being animated // However we can't animated banner's height directly as it'll also resize the content inside const height = Animated.multiply(position, layout.height); const translateY = Animated.multiply( Animated.add(position, -1), layout.height ); return ( {icon ? ( ) : null} {content} {dismissable ? (