From b96056846f28134a17dbf97c2f8c4d3405b42bc3 Mon Sep 17 00:00:00 2001 From: Mustaque Ahmed Date: Thu, 25 Nov 2021 00:41:35 +0530 Subject: [PATCH] Refactor DatePicker component to use react hooks and change it from class component to function component. It was already done as a part of different PR #22897. After code review it looks like the original author is not able to find time to reply or address review comments. I'm doing takeover from here and will take care of PR until it gets merged. --- packages/components/src/date-time/date.js | 144 ++++++++++------------ 1 file changed, 68 insertions(+), 76 deletions(-) diff --git a/packages/components/src/date-time/date.js b/packages/components/src/date-time/date.js index d70181d3d655d..9121fe02641d9 100644 --- a/packages/components/src/date-time/date.js +++ b/packages/components/src/date-time/date.js @@ -11,7 +11,7 @@ import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerS /** * WordPress dependencies */ -import { Component, createRef, useEffect, useRef } from '@wordpress/element'; +import { useEffect, useRef } from '@wordpress/element'; import { isRTL, _n, sprintf } from '@wordpress/i18n'; /** @@ -70,21 +70,18 @@ function DatePickerDay( { day, events = [] } ) { ); } -class DatePicker extends Component { - constructor() { - super( ...arguments ); - - this.onChangeMoment = this.onChangeMoment.bind( this ); - this.nodeRef = createRef(); - this.onMonthPreviewedHandler = this.onMonthPreviewedHandler.bind( - this - ); - } - - onMonthPreviewedHandler( newMonthDate ) { - this.props.onMonthPreviewed?.( newMonthDate.toISOString() ); - this.keepFocusInside(); - } +function DatePicker( { + currentDate, + onChange, + events, + isInvalidDate, + onMonthPreviewed, +} ) { + const nodeRef = useRef(); + const onMonthPreviewedHandler = ( newMonthDate ) => { + onMonthPreviewed?.( newMonthDate.toISOString() ); + keepFocusInside(); + }; /* * Todo: We should remove this function ASAP. @@ -92,21 +89,21 @@ class DatePicker extends Component { * This focus loss closes the date picker popover. * Ideally we should add an upstream commit on react-dates to fix this issue. */ - keepFocusInside() { - if ( ! this.nodeRef.current ) { + const keepFocusInside = () => { + if ( ! nodeRef.current ) { return; } - const { ownerDocument } = this.nodeRef.current; + const { ownerDocument } = nodeRef.current; const { activeElement } = ownerDocument; // If focus was lost. if ( ! activeElement || - ! this.nodeRef.current.contains( ownerDocument.activeElement ) + ! nodeRef.current.contains( ownerDocument.activeElement ) ) { // Retrieve the focus region div. - const focusRegion = this.nodeRef.current.querySelector( + const focusRegion = nodeRef.current.querySelector( '.DayPicker_focusRegion' ); if ( ! focusRegion ) { @@ -115,11 +112,9 @@ class DatePicker extends Component { // Keep the focus on focus region. focusRegion.focus(); } - } - - onChangeMoment( newDate ) { - const { currentDate, onChange } = this.props; + }; + const onChangeMoment = ( newDate ) => { // If currentDate is null, use now as momentTime to designate hours, minutes, seconds. const momentDate = currentDate ? moment( currentDate ) : moment(); const momentTime = { @@ -131,71 +126,68 @@ class DatePicker extends Component { onChange( newDate.set( momentTime ).format( TIMEZONELESS_FORMAT ) ); // Keep focus on the date picker. - this.keepFocusInside(); - } + keepFocusInside(); + }; /** - * Create a Moment object from a date string. With no currentDate supplied, default to a Moment + * Create a Moment object from a date string. With no date supplied, default to a Moment * object representing now. If a null value is passed, return a null value. * - * @param {?string} currentDate Date representing the currently selected date or null to signify no selection. + * @param {?string} date Date representing the currently selected date or null to signify no selection. * @return {?moment.Moment} Moment object for selected date or null. */ - getMomentDate( currentDate ) { - if ( null === currentDate ) { + const getMomentDate = ( date ) => { + if ( null === date ) { return null; } - return currentDate ? moment( currentDate ) : moment(); - } + return date ? moment( date ) : moment(); + }; - getEventsPerDay( day ) { - if ( ! this.props.events?.length ) { + const getEventsPerDay = ( day ) => { + if ( ! events?.length ) { return []; } - return this.props.events.filter( ( eventDay ) => + return events.filter( ( eventDay ) => day.isSame( eventDay.date, 'day' ) ); - } - - render() { - const { currentDate, isInvalidDate } = this.props; - const momentDate = this.getMomentDate( currentDate ); - - return ( -
- { - return isInvalidDate && isInvalidDate( date.toDate() ); - } } - onPrevMonthClick={ this.onMonthPreviewedHandler } - onNextMonthClick={ this.onMonthPreviewedHandler } - renderDayContents={ ( day ) => ( - - ) } - /> -
- ); - } + }; + + const momentDate = getMomentDate( currentDate ); + + return ( +
+ { + return isInvalidDate && isInvalidDate( date.toDate() ); + } } + onPrevMonthClick={ onMonthPreviewedHandler } + onNextMonthClick={ onMonthPreviewedHandler } + renderDayContents={ ( day ) => ( + + ) } + /> +
+ ); } export default DatePicker;