Skip to content
This repository has been archived by the owner on Jun 7, 2022. It is now read-only.

Datepicker: Refactor Calendar to fully controlled component #239

Merged
merged 1 commit into from
Jul 30, 2018

Conversation

psealock
Copy link
Collaborator

@psealock psealock commented Jul 26, 2018

The Calendar component had its own state, comprised of text inputs and error messages. This PR moves the state logic up to the date picker, making Calendar a fully controlled component.

There was a mis-alignment between the Calendar state and DatePicker state. In particular, the Reset button had effects on both and some comparisons were required in Calendar to guess if the DatePicker state had been reset. This caused odd interactions when resetting. I can now eliminate this faulty code:

componentDidUpdate( prevProps ) {
	const { after, before } = this.props;
	/**
	 * Check if props have been reset. If so, reset internal state. Disabling
	 * eslint here because this setState cannot cause infinte loop
	 */
	/* eslint-disable react/no-did-update-set-state */
	if ( ( prevProps.before || prevProps.after ) && ( null === after && null === before ) ) {
		this.setState( {
			focusedInput: START_DATE,
			afterText: '',
			beforeText: '',
			afterError: null,
			beforeError: null,
		} );
	}
	/* eslint-enable react/no-did-update-set-state */
}

Other changes

  • validateDateInputForRange was also pulled out to lib/date and unit tests added.
  • Remove UNSAFE_componentWillReceiveProps.

The nature of this component is such that a reset of internal state needs to happen on every change of the url query parameters. Previously, this was done like in the UNSAFE manner:

UNSAFE_componentWillReceiveProps( nextProps ) {
    this.setState( this.getResetState( nextProps ) );
}

One option was to use getDerivedStateFromProps, but that runs on every update and can introduce problems. Instead I opted for Fully uncontrolled component with a key to force reset on prop changes.

<DatePicker query={ query } path={ path } key={ JSON.stringify( query ) } />

Test

  1. /wp-admin/admin.php?page=wc-admin#/analytics/products
  2. Make sure the datepicker hasn't regressed
  3. Use the "Reset" button at various stages of editing the custom datepicker. Behaviour should be free of irregularities
  4. npm run test

Depends on #235

Copy link
Contributor

@timmyc timmyc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor comment. In my testing things seemed to be working well. When testing on a smaller screen ( just my laptop display ) there are times when I can not see the buttons on the date picker, which kind of makes it hard to test this branch or set custom ranges

no-buttons

this.onDatesChange = this.onDatesChange.bind( this );
this.onFocusChange = this.onFocusChange.bind( this );
this.onInputChange = this.onInputChange.bind( this );
this.getOutsideRange = this.getOutsideRange.bind( this );
}

componentDidUpdate( prevProps ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great refactoring here.

* @param {Moment|null} [after] - If already designated, the after date parameter
* @param {string} format - The expected date format in a user's locale
* @return {Object} validatedDate - validated date oject
* @param {Moment|null} validatedDate.date - A resulting Moment date object or null, if invalid
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these two @params needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I think so. They are describing the returned object I've called validatedDate.


it( 'should return a correct error for a date in the future', () => {
const futureDateString = moment()
.add( 1, 'months' )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@psealock psealock force-pushed the add/custom-datepicker-styles branch from 839eb2c to b80968a Compare July 29, 2018 22:37
@psealock psealock changed the base branch from add/custom-datepicker-styles to master July 29, 2018 22:46
@psealock psealock force-pushed the fix/calendar-component branch 4 times, most recently from 094e186 to 10099db Compare July 29, 2018 23:10
@psealock
Copy link
Collaborator Author

Thanks for taking a look @timmyc. The popover being unscrollable was fixed in #235 (comment). Those changes probably hadn't made their way to this branch yet, sorry about that. This branch is rebased and now has the fix.

@psealock psealock mentioned this pull request Jul 29, 2018
10 tasks
@timmyc
Copy link
Contributor

timmyc commented Jul 30, 2018

I'm still seeing a bit of oddness with the same issue I described above. Almost seems like my viewport height is at some in-between spot that is preventing the scrolling from happening. If I shrink the viewport a smidge, it works as expected.

I still think we should get this merged in, and we can open up a separate issue and work on a fix there.

Copy link
Contributor

@timmyc timmyc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm voting to merge this in, and do follow-up fixes as we identify any other problems, like my odd scroll one. I also noticed a z-index issue too with the master/nav bar which we can do in a follow-up.

@psealock
Copy link
Collaborator Author

Almost seems like my viewport height is at some in-between spot that is preventing the scrolling from happening. If I shrink the viewport a smidge, it works as expected.

I can now reproduce this when opening the picker and then switching to "Custom"

Issue for that and z-index here #252

@psealock psealock merged commit 94adbeb into master Jul 30, 2018
Isotope automation moved this from Needs Review 👀 to 🐶 Done [ July 17 - July 31 ] Jul 30, 2018
@psealock psealock deleted the fix/calendar-component branch July 30, 2018 23:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants