import * as React from 'react'; import { Button, Component, Styles, Text, TextInput, Types, View } from 'reactxp'; import { colors } from '../../config.json'; import styles from './CellStyles'; import ImageView from './ImageView'; import { default as SwitchControl } from './Switch'; interface ICellButtonProps { children?: React.ReactNode; disabled?: boolean; selected?: boolean; style?: Types.StyleRuleSetRecursive; hoverStyle?: Types.StyleRuleSetRecursive; onPress?: () => void; } interface IState { hovered: boolean; } const CellSectionContext = React.createContext(false); const CellHoverContext = React.createContext(false); export class CellButton extends Component { public state: IState = { hovered: false }; public onHoverStart = () => (!this.props.disabled ? this.setState({ hovered: true }) : null); public onHoverEnd = () => (!this.props.disabled ? this.setState({ hovered: false }) : null); public render() { const { children, style, hoverStyle, ...otherProps } = this.props; const stateStyle = this.props.selected ? styles.cellButton.selected : this.state.hovered ? hoverStyle || styles.cellButton.hover : undefined; return ( {(containedInSection) => ( )} ); } } interface ISectionTitleProps { children?: React.ReactText; } export const SectionTitle = function CellSectionTitle(props: ISectionTitleProps) { return {props.children}; }; interface ISectionProps { children?: React.ReactNode; style?: Types.StyleRuleSetRecursive; } export const Section = class CellSection extends Component { public render() { return ( {this.props.children} ); } }; interface IContainerProps { children: React.ReactNode; } export const Container = function CellContainer({ children }: IContainerProps) { return {children}; }; interface ILabelProps { containerStyle?: Types.ViewStyleRuleSet; textStyle?: Types.TextStyleRuleSet; cellHoverContainerStyle?: Types.ViewStyleRuleSet; cellHoverTextStyle?: Types.TextStyleRuleSet; onPress?: (event: Types.SyntheticEvent) => void; children?: React.ReactNode; } export const Label = function CellLabel(props: ILabelProps) { const { children, containerStyle, textStyle, cellHoverContainerStyle, cellHoverTextStyle, ...otherProps } = props; return ( {(hovered) => ( {children} )} ); }; export const Switch = React.forwardRef(function CellSwitch( props: SwitchControl['props'], ref?: React.Ref, ) { return ( ); }); interface IInputFrameProps { children?: React.ReactNode; style?: Types.StyleRuleSetRecursive; } export const InputFrame = function CellInputFrame(props: IInputFrameProps) { const { style, children } = props; return {children}; }; interface IInputProps extends Types.TextInputProps { validateValue?: (value: string) => boolean; modifyValue?: (value: string) => string; submitOnBlur?: boolean; onSubmit?: (value: string) => void; } interface IInputState { value?: string; focused: boolean; } export class Input extends Component { public state = { value: this.props.value || '', focused: false, }; public componentDidUpdate(prevProps: IInputProps, _prevState: IInputState) { if ( !this.state.focused && prevProps.value !== this.props.value && this.props.value !== this.state.value ) { this.setState((_state, props) => ({ value: props.value, })); } } public render() { const { style, value: _value, onChangeText: _onChangeText, onFocus: _onFocus, onBlur: _onBlur, onSubmitEditing: _onSubmitEditing, ...otherProps } = this.props; const validityStyle = this.props.validateValue && this.props.validateValue(this.state.value) ? styles.input.validValue : styles.input.invalidValue; return ( ); } private onChangeText = (value: string) => { this.setState({ value }); if (this.props.onChangeText) { this.props.onChangeText(value); } }; private onFocus = (e: Types.FocusEvent) => { this.setState({ focused: true }); if (this.props.onFocus) { this.props.onFocus(e); } }; private onBlur = (e: Types.FocusEvent) => { this.setState({ focused: false }); if (this.props.onBlur) { this.props.onBlur(e); } if (this.props.submitOnBlur && this.props.onSubmit) { this.props.onSubmit(this.state.value); } }; private onSubmitEditing = () => { if (this.props.onSubmit) { this.props.onSubmit(this.state.value); } if (this.props.onSubmitEditing) { this.props.onSubmitEditing(); } }; } interface IAutoSizingTextInputContainerProps { style?: Types.StyleRuleSetRecursive; children: React.ReactElement; } interface IAutoSizingTextInputContainerState { placeholderWidth?: number; widthStyle?: Types.TextInputStyleRuleSet; } export const AutoSizingTextInputContainer = class CellAutoSizingTextInputContainer extends Component< IAutoSizingTextInputContainerProps, IAutoSizingTextInputContainerState > { public state: IAutoSizingTextInputContainerState = {}; public render() { const children: React.ReactElement = this.props.children; return ( {children.props.placeholder} {React.cloneElement(children, { ...children.props, style: [children.props.style, this.state.widthStyle], })} ); } private onLayout = (layout: Types.ViewOnLayoutEvent) => { if (this.state.placeholderWidth !== layout.width) { this.setState({ placeholderWidth: layout.width, widthStyle: Styles.createTextInputStyle( { width: layout.width, }, false, ), }); } }; }; type SubTextProps = Types.TextProps & { cellHoverStyle?: Types.ViewStyle; }; export const SubText = function CellSubText(props: SubTextProps) { const { children, ref: _, style, cellHoverStyle, ...otherProps } = props; return ( {(hovered) => ( {children} )} ); }; export const Icon = function CellIcon(props: ImageView['props']) { const { children: _children, style, tintColor, tintHoverColor, ...otherProps } = props; return ( {(hovered) => ( )} ); }; export const UntintedIcon = function CellIcon(props: ImageView['props']) { return ; }; export const Footer = function CellFooter({ children }: IContainerProps) { return {children}; }; export const FooterText = function CellFooterText(props: Text['props']) { return ( {props.children} ); }; export const FooterBoldText = function CellFooterText(props: Text['props']) { return ( {props.children} ); };