import React, { Component } from 'react'; import InputMask from 'react-input-mask'; import moment from 'moment'; // import { extendMoment } from 'moment-range'; const DATE_FORMAT = { "default": 'MM/YY', "ja": 'YY/MM' } import MonthCalendar from './calendar'; import { valuesToMask, valuesFromMask } from './utils'; import { II18n, DEFAULT_I18N as I18n_DEF } from './i18n'; import Translator from './Translator'; import './styles/index.css'; type OnChange = (maskedValue: string, year: number, month: number) => any; export const DEFAULT_I18N = I18n_DEF; export interface IProps { year?: number, month?: number, lang?: string, inputProps?: { name?: string, id?: string, }, onChange?: OnChange, closeOnSelect?: boolean, onChangeYearUpdate?: boolean, inputRef?: Function, rangePicker?:boolean, isOpen ?: boolean, monthYearFormat ?: string, placeholder ?: any i18n?: Partial, disabledInputChange?:boolean, className ?: string, }; export interface IState { year: void|number, month: void|number, inputValue: string, showCalendar: boolean, }; class MonthPickerInput extends Component { wrapper: HTMLDivElement; input: { input: Element }; private t: Translator; private inputMask: string; public static defaultProps: Partial = { inputProps: {}, closeOnSelect: false, rangePicker: false, disabledInputChange: false }; _monthYearHandler = false constructor(props) { super(props); this.handleStateInitialize() }; componentDidUpdate(prevProps) { this.onCalendarMount(prevProps) } componentWillReceiveProps(nextProps: IProps): void { const update: Partial = {}; if (nextProps.year !== this.props.year) { update.year = nextProps.year } if (nextProps.month !== this.props.month) { update.month = nextProps.month } if (Object.keys(update).length) { const month = update.month || this.state.month; const year = update.year || this.state.year; update.inputValue = this.valuesToMask(month, year); this.setState(update as IState); } }; valuesToMask = (month: number|void, year: number|void): string => { if (typeof year == 'number' && typeof month == 'number') { return valuesToMask(month, year, this.t); } else return ''; } onCalendarMount = (prevProps): void => { const {year, month } = this.props if ((prevProps.month !== month && prevProps.year !== year) && !this._monthYearHandler) { this.handleStateInitialize() this.setState({ year: year || new Date().getFullYear(), month: month || new Date().getMonth() }) this._monthYearHandler = true } } handleStateInitialize = (): void => { const { year, month } = this.props; let inputValue = ''; // if (typeof year == 'number' && typeof month == 'number') { // inputValue = valuesToMask(month, year, this.props.lang); // } this.t = new Translator(this.props.lang, this.props.i18n); this.inputMask = this.t.dateFormat().replace(/M|Y/g, '9'); this.state = { year, month, inputValue, showCalendar: false, } } onCalendarChange = (year: number, month: number): void => { const inputValue = this.valuesToMask(month, year); this.setState({ inputValue, year, month, showCalendar: !this.props.closeOnSelect }); this.onChange(inputValue, year, month); }; onInputChange = (e: { target: { value: string }}): void => { const mask = e.target.value; if (mask.length && mask.indexOf('_') === -1) { const [month, year] = valuesFromMask(mask); const inputValue = this.valuesToMask(month, year); this.setState({ year, month, inputValue }); this.onChange(inputValue, year, month); } else this.setState({ inputValue: mask }); }; onChange = (inputValue, year, month) => { if (this.props.onChange) { this.props.onChange(inputValue, year, month); } // this.handleDateRange(year, month) }; onInputBlur = (e): void => { if (!this.wrapper.contains(e.target)) { this.setState({ showCalendar: false }) } }; onInputFocus = (e): void => { if (this.wrapper.contains(e.target)) { this.setState({ showCalendar: true }); } }; onCalendarOutsideClick = (e): void => { this.setState({ showCalendar: this.input.input == e.target }); }; calendar = (): JSX.Element => { const { onChangeYearUpdate, rangePicker, className } = this.props const { year, month } = this.state; let lang = this.props.lang ? this.props.lang : 'default'; return (
) }; inputProps = ({customPlaceholder}): object => { const { inputRef, disabledInputChange } = this.props // monthYearFormat: TODO let dateFormat = DATE_FORMAT["default"]; if (this.props.lang == "ja") { dateFormat = DATE_FORMAT["ja"]; } return Object.assign({}, { ref: (input) => { if(input) this.input = input; inputRef && inputRef(input) }, mask: this.inputMask, placeholder: customPlaceholder ? customPlaceholder : this.t.dateFormat(), type: 'text', onBlur: this.onInputBlur, onFocus: this.onInputFocus, onChange: !disabledInputChange ? this.onInputChange : null, }, this.props.inputProps) }; handleRenderCalendar = () => { if (this.props.isOpen || this.state.showCalendar) { return this.calendar() } return false } render() { const {placeholder} = this.props return (
{ if(wrap) this.wrapper = wrap; }}> { this.handleRenderCalendar() }
); }; }; export { DateFormat, MonthFormat } from './i18n'; export default MonthPickerInput;