import { memo, type ReactNode } from 'react'; import type { LayoutRectangle, StyleProp, ViewStyle } from 'react-native'; import { MotiView } from '../../../moti/components/view'; import { TIMING_INSTANT } from '../../../theme/motion'; import { Text } from '../../typography/Text/text'; import { DOCK_CAPTION_HEIGHT, DOCK_ICON_SCALE, DOCK_INACTIVE_OPACITY, dockMetrics } from './dock-metrics'; import { DOCK_SPRING, dockSizeMotion } from './dock-transition'; type DockFrameProps = { rect: LayoutRectangle; reduce: boolean; children?: ReactNode; style?: StyleProp; testID?: string; }; type DockContentProps = { itemPx: number; labelled: boolean; active?: boolean; reduce: boolean; label?: string; children: ReactNode; }; export function DockFrame({ rect, reduce, children, style, testID }: DockFrameProps) { const motion = dockSizeMotion(rect.width, rect.height, reduce); return ( {children} ); } // Other slots report layout independently; unchanged pill targets must not restart its spring. export const DockHighlight = memo(function Highlight({ rect, reduce, testID, }: Omit & { rect?: LayoutRectangle }) { if (!rect) return null; const motion = dockSizeMotion(rect.width, rect.height, reduce); return ( ); }); export function DockContent({ itemPx, labelled, active, reduce, label, children }: DockContentProps) { const metrics = dockMetrics(itemPx, labelled); const transition = reduce ? TIMING_INSTANT : DOCK_SPRING; const opacity = active ? 1 : DOCK_INACTIVE_OPACITY; return ( <> {children} {label ? ( {label} ) : null} ); }