import type { ReactNode } from 'react'; import React from 'react'; import type { LayoutChangeEvent, TouchableOpacityProps } from 'react-native'; import { StyledWrapper, StyledPrefixWrapper, StyledSuffixWrapper, StyledIcon, } from './StyledFloatingIsland'; import type { IconName } from '../Icon'; interface FloatingIslandProps extends TouchableOpacityProps { /** * Callback that is called when the floating island is pressed. */ onPress?: () => void; /** * Children of the floating island. */ children: ReactNode; /** * Prefix element that is displayed before the children. */ prefix?: IconName | ReactNode; /** * Suffix element that is displayed after the children. */ suffix?: IconName | ReactNode; } const getPrefixOrSuffix = ({ element, isPrefix = true, }: { element: IconName | ReactNode; isPrefix: boolean; }) => { const Wrapper = isPrefix ? StyledPrefixWrapper : StyledSuffixWrapper; if (typeof element === 'string') { return ( ); } return {element}; }; const FloatingIsland = ({ onPress, onLayout, style, children, prefix, suffix, ...props }: FloatingIslandProps) => { const [width, setWidth] = React.useState(0); const onWrapperLayout = (event: LayoutChangeEvent) => { setWidth(event.nativeEvent.layout.width); onLayout?.(event); }; return ( 0 ? { transform: [{ translateX: -width / 2 }], } : undefined, ]} > {prefix && getPrefixOrSuffix({ element: prefix, isPrefix: true })} {children} {suffix && getPrefixOrSuffix({ element: suffix, isPrefix: false })} ); }; export default FloatingIsland;