// // UltraPickerIOS // // Created by Tim Sawtell on 3/10/17. // Copyright © 2017 Sportsbet. All rights reserved. // import * as React from 'react'; import { StyleSheet, View, ViewStyle, NativeSyntheticEvent, StyleProp } from 'react-native'; import { requireNativeComponent } from 'react-native'; const UltraPickerIOSNative = requireNativeComponent("UltraPickerIOS", null) as React.ComponentClass; const UltraPickerIOSCloseBarNative = requireNativeComponent("UltraPickerIOSCloseBar", null) as React.ComponentClass ; const DEFAULT_CLOSEBAR_HEIGHT = 44 const DEFAULT_PICKER_HEIGHT = 216 interface UltraPickerIOSNative { componentsData?: any, selectedIndexes?: Number[] onChange?: (result: any) => void style?: StyleProp testID?: string } interface UltraPickerIOSCloseBarNative { closeButtonText?: string onClose?: (result: any) => void style?: StyleProp buttonTestID?: string } export interface ComponentGroup { fontFamily?: string, fontSize?: string } export interface ComponentItemProps { label: string, value?: any, selected?: boolean, fontFamily?: string, fontSize?: string } interface NativeGroup extends ComponentGroup { items?: ComponentItemProps[], } export class Group extends React.Component { render() { return null } } export class Item extends React.Component { render() { return null } } export interface UltraPickerChangeEvent { newIndex: number component: number newValue: string newLabel: string } export interface UltraPickerIOSProps { onChange?: (result: NativeSyntheticEvent) => void style: StyleProp testID?: string } export interface UltraPickerIOSState { componentsData?: ComponentGroup[] selectedIndexes?: Number[] closeBar?: JSX.Element } export class UltraPickerIOS extends React.Component { constructor(props) { super(props); this._stateBasedOnProps.bind(this) this.state = this._stateBasedOnProps(props) } _stateBasedOnProps(nextProps): UltraPickerIOSState { let nextState = { componentsData: null, closeBar: null, selectedIndexes: null } let components = [] let selectedIndexes = [] if (!nextProps.children) { return nextState } let pickerChildren = null if (nextProps.children.constructor === Array) { pickerChildren = nextProps.children } else { pickerChildren = [nextProps.children] } pickerChildren.forEach((child, index) => { if (!child) { return } if (child.type === UltraPickerIOSCloseBar) { nextState.closeBar = child } else if (child.type === Group) { let group: ComponentItemProps[] = [] let groupSelectedItem = 0 // item at index 0 by default let items = null if (child.props.children) { if (child.props.children.constructor === Array) { items = child.props.children } else { items = [child.props.children] } items.forEach((item, index) => { if (item.type === Item && item.props.label) { const nativeItem: ComponentItemProps = { label: item.props.label, fontFamily: item.props.fontFamily, fontSize: item.props.fontSize, value: (item.props.value || null) } group.push(nativeItem) if (item.props.selected) { groupSelectedItem = index } } }) if (group.length > 0) { const nativeGroup: NativeGroup = { items: group, fontFamily: child.props.fontFamily, fontSize: child.props.fontSize } components.push(nativeGroup) selectedIndexes.push(groupSelectedItem) } } } }) nextState.componentsData = components nextState.selectedIndexes = selectedIndexes return nextState } componentWillReceiveProps(nextProps) { this.setState(this._stateBasedOnProps(nextProps)) } render() { // Allow the caller to not specify any style yet make this component visible // via default heights. Adjust the size of `parentViewStyle` so that if there // is a CloseBar provided, the picker is the same size as specified by // UltraPickerIOS.style and the parent (encapsulating) view is made larger // to fit the CloseBar let pickerViewStyle = { height: DEFAULT_PICKER_HEIGHT, ...StyleSheet.flatten(this.props.style) } let parentViewStyle = { ...pickerViewStyle } if (this.state.closeBar) { parentViewStyle.height = parentViewStyle.height as number + DEFAULT_CLOSEBAR_HEIGHT } return ( {this.state.closeBar} ) } } export interface UltraPickerIOSCloseBarProps { closeButtonText?: string onClose?: (result: any) => void style?: StyleProp, buttonTestID?: string } export class UltraPickerIOSCloseBar extends React.Component { render() { let style = { height: DEFAULT_CLOSEBAR_HEIGHT, ... StyleSheet.flatten(this.props.style) } let closeButtonText = this.props.closeButtonText || "Close" return ( ) } }