license import React from 'react' ; import { ListRenderItemInfo } from 'react-native' ; import { ChildrenWithProps , IndexPath , Overwrite , LiteralUnion , } from '../../devsupport' ; import { styled } from '../../theme' ; import { Divider } from '../divider/divider.component' ; import { List , ListElement , ListProps , } from '../list/list.component' ; import { MenuItemElement , MenuItemProps , } from './menuItem.component' ; import { MenuItemDescriptor , MenuService , } from './menu.service' ; type MenuStyledProps = Overwrite < ListProps , { appearance ? : LiteralUnion < 'default' | 'noDivider' > ; } > ; type MenuListProps = Omit < MenuStyledProps , 'data' | 'renderItem' > ; export interface MenuProps extends MenuListProps { children ? : ChildrenWithProps < MenuItemProps > ; selectedIndex ? : IndexPath ; onSelect ? : ( index : IndexPath ) => void ; } export type MenuElement = React . ReactElement < MenuProps > ; extends React . Component property property property property property overview-example overview-example overview-example overview-example overview-example overview-example overview-example overview-example @ styled ( 'Menu' ) export class Menu extends React . Component < MenuProps > { private service : MenuService = new MenuService ( ) ; private get data ( ) : any [ ] { return React . Children . toArray ( this . props . children || [ ] ) ; } private get shouldRenderDividers ( ) : boolean { return this . props . appearance !== 'noDivider' ; } public clear = ( ) : void => { this . props . onSelect && this . props . onSelect ( null ) ; } ; private onItemPress = ( descriptor ) : void => { this . props . onSelect && this . props . onSelect ( descriptor . index ) ; } ; private isItemSelected = ( descriptor ) : boolean => { return descriptor . index . equals ( this . props . selectedIndex ) ; } ; private cloneItemWithProps = ( element , props ) : React . ReactElement => { const nestedElements = React . Children . map ( element . props . children , ( el , index ) => { const descriptor = this . service . createDescriptorForNestedElement ( props . descriptor , index ) ; const selected = this . isItemSelected ( descriptor ) ; return this . cloneItemWithProps ( el , { ... props , selected , descriptor } ) ; } ) ; const onPress = ( event , descriptor ) => { element . props . onPress && element . props . onPress ( ) ; props . onPress ( event , descriptor ) ; } ; return React . cloneElement ( element , { ... element . props , ... props , onPress } , nestedElements ) ; } ; private renderItem = ( info ) : React . ReactElement => { const descriptor = this . service . createDescriptorForElement ( info . item , info . index ) ; const selected = this . isItemSelected ( descriptor ) ; return this . cloneItemWithProps ( info . item , { descriptor , selected , onPress : this . onItemPress } ) ; } ; public render ( ) { const { appearance , ... listProps } = this . props ; return ( < List ItemSeparatorComponent = { this . shouldRenderDividers && Divider } { ... listProps } data = { this . data } renderItem = { this . renderItem } / > ) ; } }