diff --git a/src/index.js b/src/index.js index c8e7921..a21d22e 100644 --- a/src/index.js +++ b/src/index.js @@ -78,28 +78,29 @@ export default class TimeField extends React.Component { constructor(props, ...args) { super(props, ...args); - this.configure(props); - - const [validatedTime] = validateTimeAndCursor(this._showSeconds, this.props.value, this._defaultValue, this._colon); + const _showSeconds = Boolean(props.showSeconds); + const _defaultValue = _showSeconds ? DEFAULT_VALUE_FULL : DEFAULT_VALUE_SHORT; + const _colon = props.colon && props.colon.length === 1 ? props.colon : DEFAULT_COLON; + const [validatedTime] = validateTimeAndCursor(_showSeconds, this.props.value, _defaultValue, _colon); this.state = { - value: validatedTime + value: validatedTime, + _colon, + _showSeconds, + _defaultValue, + _maxLength: _defaultValue.length }; this.onInputChange = this.onInputChange.bind(this); } - componentWillReceiveProps(nextProps) { - const {value} = this.props; - - this.configure(nextProps); - - if (value !== nextProps.value) { + componentDidUpdate(prevProps) { + if (this.props.value !== prevProps.value) { const [validatedTime] = validateTimeAndCursor( - this._showSeconds, - nextProps.value, - this._defaultValue, - this._colon + this.state._showSeconds, + this.props.value, + this.state._defaultValue, + this.state._colon ); this.setState({ value: validatedTime @@ -107,13 +108,6 @@ export default class TimeField extends React.Component { } } - configure(props) { - this._colon = props.colon && props.colon.length === 1 ? props.colon : DEFAULT_COLON; - this._showSeconds = Boolean(props.showSeconds); - this._defaultValue = this._showSeconds ? DEFAULT_VALUE_FULL : DEFAULT_VALUE_SHORT; - this._maxLength = this._defaultValue.length; - } - onInputChange(event, callback) { const oldValue = this.state.value; const inputEl = event.target; @@ -124,7 +118,7 @@ export default class TimeField extends React.Component { const addedCharacter = isTyped ? cursorCharacter : null; const removedCharacter = isTyped ? null : oldValue[position]; const replacedSingleCharacter = inputValue.length === oldValue.length ? oldValue[position - 1] : null; - const colon = this._colon; + const colon = this.state._colon; let newValue = oldValue; let newPosition = position; @@ -175,7 +169,7 @@ export default class TimeField extends React.Component { } const [validatedTime, validatedCursorPosition] = validateTimeAndCursor( - this._showSeconds, + this.state._showSeconds, newValue, oldValue, colon, diff --git a/tests/component.test.js b/tests/component.test.js index 5a5930c..eb259d1 100644 --- a/tests/component.test.js +++ b/tests/component.test.js @@ -18,7 +18,14 @@ describe('Component', () => { }); afterEach(() => { + if (a) { + a.unmount(); + } a = null; + + if (b) { + b.unmount(); + } b = null; }); @@ -40,310 +47,134 @@ describe('Component', () => { }); test('should render reserved props', () => { - expect( - a - .setProps({value: '21:43'}) - .find('input') - .getElement().props.value - ).toEqual('21:43'); - expect( - b - .setProps({value: '21:43:13'}) - .find('input') - .getElement().props.value - ).toEqual('21:43:13'); + expect(a.setProps({value: '21:43'}).state('value')).toEqual('21:43'); + expect(b.setProps({value: '21:43:13'}).state('value')).toEqual('21:43:13'); }); test('should keep old values w/o changes', () => { - expect( - a - .setProps({value: '12:34'}) - .find('input') - .getElement().props.value - ).toEqual('12:34'); - expect( - b - .setProps({value: '12:34:56'}) - .find('input') - .getElement().props.value - ).toEqual('12:34:56'); + expect(a.setProps({value: '12:34'}).state('value')).toEqual('12:34'); + expect(b.setProps({value: '12:34:56'}).state('value')).toEqual('12:34:56'); }); test('should validate reserved props before render', () => { - //TODO keep old values? - expect( - a - .setProps({value: '30:60'}) - .find('input') - .getElement().props.value - ).toEqual('00:00'); - expect( - b - .setProps({value: '30:60:90'}) - .find('input') - .getElement().props.value - ).toEqual('00:00:00'); + expect(a.setProps({value: '30:60'}).state('value')).toEqual('00:00'); + expect(b.setProps({value: '30:60:90'}).state('value')).toEqual('00:00:00'); }); test('should validate value after input change', () => { const eventA = {target: {value: '12:34'}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:34'); const eventB = {target: {value: '12:34:56'}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:56'); }); test('should handle added number character', () => { const eventA = {target: {value: '212:34', selectionEnd: 1}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('22:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('22:34'); const eventB = {target: {value: '12:34:156', selectionEnd: 7}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:16'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:16'); }); test('should handle added ":" character', () => { const eventA = {target: {value: '12::34', selectionEnd: 3}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:34'); const eventB = {target: {value: '12:34::56', selectionEnd: 6}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:56'); }); test('should handle added number character before ":"', () => { const eventA = {target: {value: '121:34', selectionEnd: 3}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:14'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:14'); const eventB = {target: {value: '12:341:56', selectionEnd: 6}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:16'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:16'); }); test('should handle added number character before ":" (update position)', () => { const eventA = {target: {value: '132:34', selectionEnd: 2}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('13:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('13:34'); const eventB = {target: {value: '12:334:56', selectionEnd: 5}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:33:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:33:56'); }); test('should keep old value if position is out pf range', () => { const eventA = {target: {value: '12:341', selectionEnd: 6}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:34'); const eventB = {target: {value: '12:34:561', selectionEnd: 9}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:56'); }); test('should keep old value if not a number was typed', () => { const eventA = {target: {value: 'a12:34', selectionEnd: 1}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:34'); const eventB = {target: {value: '12:34:a56', selectionEnd: 7}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:56'); }); test('should handle removed character', () => { const eventA = {target: {value: '1:34', selectionEnd: 1}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('10:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('10:34'); const eventB = {target: {value: '12:34:6', selectionEnd: 6}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:06'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:06'); }); test('should handle removed ":" character', () => { const eventA = {target: {value: '1234', selectionEnd: 2}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('10:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('10:34'); const eventB = {target: {value: '12:3456', selectionEnd: 5}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:30:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:30:56'); }); test('should handle single character replacement', () => { const eventA = {target: {value: '12:44', selectionEnd: 4}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:44'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:44'); const eventB = {target: {value: '12:34:46', selectionEnd: 7}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:46'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:46'); }); test('should handle single ":" character replacement', () => { const eventA = {target: {value: '12a34', selectionEnd: 3}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:34'); const eventB = {target: {value: '12:34a56', selectionEnd: 6}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:56'); }); test('should handle more than 2 characters replacement (number)', () => { const eventA = {target: {value: '12:2', selectionEnd: 4}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:20'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:20'); const eventB = {target: {value: '12:34:2', selectionEnd: 7}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:20'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:20'); }); test('should handle 2 characters replacement (invalid character)', () => { const eventA = {target: {value: '12:a', selectionEnd: 4}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:34'); const eventB = {target: {value: '12:34:a', selectionEnd: 7}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:56'); }); test('should handle more than 2 characters replacement (invalid character)', () => { const eventA = {target: {value: '12a', selectionEnd: 3}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:34'); const eventB = {target: {value: '12:34a', selectionEnd: 6}, persist}; - expect( - b - .simulate('change', eventB) - .find('input') - .getElement().props.value - ).toEqual('12:34:56'); + expect(b.simulate('change', eventB).state('value')).toEqual('12:34:56'); }); test('should handle all characters replacement (invalid character)', () => { const eventA = {target: {value: 'a', selectionEnd: 1}, persist}; - expect( - a - .simulate('change', eventA) - .find('input') - .getElement().props.value - ).toEqual('12:34'); + expect(a.simulate('change', eventA).state('value')).toEqual('12:34'); }); });