import * as React from 'react'; import { ValidationRule, ValidationState } from '../../models/Validation'; import validationRules from '../../utils/validationRules'; import { validation, validationOnInit } from '../../utils/helper'; import { Colors } from '../../models/colors'; const tagManager = require('react-gtm-module'); export interface CommonInputProps { label?: string; type?: string; name?: string; value?: string; valid?: ValidationState; errorMessage?: string; placeholder?: string; notifyValidity?: (name: string, state: ValidationState, errorMessage?: React.ReactNode) => void; validationRules?: Array; onChange?: (name: string, value: string, e?: React.ChangeEvent) => void; onFocus?: (name: string, value: string, e?: React.FocusEvent) => void; onBlur?: (value: string, e?: React.FocusEvent) => void; onClick?: (e: React.MouseEvent) => void; onKeyDown?: (value: string, e: React.KeyboardEvent) => void; required?: boolean; doNotValidate?: boolean; automationName?: string; palette?: Colors; maxlength?: number; readOnly?: boolean; translator?: Function; } type CommonInputContainer = CommonInputProps & { render: ( onChange: (value: string) => void, onBlur: (value: string) => void, onFocus: (value: string) => void ) => JSX.Element; }; class CommonInput extends React.PureComponent { constructor(props: CommonInputContainer) { super(props); let assignedValidationRules = Object.assign([], this.props.validationRules || []); if (this.props.required) { assignedValidationRules.unshift({ name: 'required' }); } if (this.props.notifyValidity) { let { name, state, errorMessage } = validationOnInit( validationRules, assignedValidationRules, this.props.name, this.props.value, this.props.translator ); this.props.notifyValidity(name, state, errorMessage); } } componentWillUnmount() { if (this.props.notifyValidity) { this.props.notifyValidity(this.props.name, ValidationState.None); } } onFocus = (value: string, e?: React.FocusEvent) => { if (this.props.onFocus) { this.props.onFocus(this.props.name, value, e); } tagManager.dataLayer({ dataLayer: { event: 'focus-in', 'input-name': name } }); }; onChange = (value: string, e?: React.FocusEvent) => { this.props.onChange(this.props.name, value); }; onBlur = (value: string, e?: React.FocusEvent) => { tagManager.dataLayer({ dataLayer: { event: 'focus-out', 'input-name': name } }); let assignedValidationRules = Object.assign([], this.props.validationRules || []); if (this.props.required) { assignedValidationRules.unshift({ name: 'required' }); } if (!this.props.doNotValidate) { let { state, errorMessage } = validation( validationRules, assignedValidationRules, value, this.props.name, this.props.translator ); if ( this.props.notifyValidity && (this.props.valid !== state || this.props.errorMessage !== errorMessage) ) { this.props.notifyValidity(this.props.name, state, errorMessage); } } if (this.props.onBlur) { this.props.onBlur(value); } }; render() { return this.props.render(this.onChange, this.onBlur, this.onFocus); } } export default CommonInput;