license import React from 'react' ; import { StyleProp , TransformsStyle , View , ViewProps , ViewStyle , } from 'react-native' ; import { FalsyFC , RTLService , } from '../../devsupport' ; import { styled , StyledComponentProps , StyleType , } from '../../theme' ; import { PopoverPlacement , PopoverPlacements , } from './type' ; type AnimatedViewStyle = ViewStyle | any ; export interface PopoverViewProps extends ViewProps , StyledComponentProps { contentContainerStyle ? : StyleProp < AnimatedViewStyle > ; placement ? : PopoverPlacement | string ; indicator ? : ( props : ViewProps ) => React . ReactElement ; } export type PopoverViewElement = React . ReactElement < PopoverViewProps > ; const INDICATOR_OFFSET = 8 ; const INDICATOR_WIDTH = 6 ; @ styled ( 'Popover' ) export class PopoverView extends React . Component < PopoverViewProps > { private get placement ( ) : PopoverPlacement { return PopoverPlacements . parse ( this . props . placement ) ; } private getComponentStyle = ( source ) => { const { indicatorWidth , indicatorHeight , indicatorBackgroundColor , ... containerParameters } = source ; return { content : containerParameters , indicator : { width : indicatorWidth , height : indicatorHeight , backgroundColor : indicatorBackgroundColor , } , } ; } ; private getDirectionStyle = ( ) => { const { direction , alignment } = this . placement . flex ( ) ; const isVertical = direction . startsWith ( 'column' ) ; const isStart = alignment . endsWith ( 'start' ) ; const isEnd = alignment . endsWith ( 'end' ) ; const isReverse = direction . endsWith ( 'reverse' ) ; const indicatorRotate = isVertical ? 180 : 90 ; const indicatorReverseRotate = isReverse ? 0 : 180 ; let containerTranslate = ( this . props . indicator && ! isVertical ) ? INDICATOR_WIDTH / 2 : 0 ; containerTranslate = isReverse ? containerTranslate : - containerTranslate ; let indicatorTranslate = isVertical ? - INDICATOR_OFFSET : INDICATOR_OFFSET ; indicatorTranslate = isReverse ? - indicatorTranslate : indicatorTranslate ; const i18nVerticalIndicatorTranslate = RTLService . select ( indicatorTranslate , - indicatorTranslate ) ; indicatorTranslate = isVertical ? i18nVerticalIndicatorTranslate : indicatorTranslate ; const contentTransforms = { transform : [ { translateX : containerTranslate } , ] , } ; const indicatorTransforms = { transform : [ { rotate : `${ indicatorRotate }deg` } , { rotate : `${ indicatorReverseRotate }deg` } , { translateX : isStart ? - indicatorTranslate : 0 } , { translateX : isEnd ? indicatorTranslate : 0 } , ] , } ; return { container : { flexDirection : direction , alignItems : alignment , } , content : contentTransforms , indicator : indicatorTransforms , } ; } ; public render ( ) { const { eva , style , contentContainerStyle , onLayout , indicator , ... viewProps } = this . props ; const evaStyle = this . getComponentStyle ( eva . style ) ; const directionStyle = this . getDirectionStyle ( ) ; return ( < View style = { [ directionStyle . container , contentContainerStyle ] } onLayout = { onLayout } > < FalsyFC style = { [ evaStyle . indicator , directionStyle . indicator ] } component = { indicator } / > < View { ... viewProps } style = { [ evaStyle . content , directionStyle . content , style ] } / > < /View>); } }