From e470c62650553a933b615906db82a9139ed14116 Mon Sep 17 00:00:00 2001 From: Matt Sherman Date: Fri, 14 Oct 2022 16:48:03 -0400 Subject: [PATCH] Add date-only mode to DateTimePickerControl (#35066) * Remove border from top of date picker * Add isDateOnlyPicker, rename is12HourPicker * Add tests for isDateOnlyPicker * Add date only story --- ...dd-date-time-picker-control-date-only-mode | 4 + .../date-time-picker-control.scss | 4 + .../date-time-picker-control.tsx | 75 ++++++++++++------- .../stories/index.tsx | 7 ++ .../date-time-picker-control/test/index.tsx | 49 ++++++++++-- 5 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 packages/js/components/changelog/add-date-time-picker-control-date-only-mode diff --git a/packages/js/components/changelog/add-date-time-picker-control-date-only-mode b/packages/js/components/changelog/add-date-time-picker-control-date-only-mode new file mode 100644 index 00000000000..0e0d26f415a --- /dev/null +++ b/packages/js/components/changelog/add-date-time-picker-control-date-only-mode @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Add date-only mode to DateTimePickerControl. diff --git a/packages/js/components/src/date-time-picker-control/date-time-picker-control.scss b/packages/js/components/src/date-time-picker-control/date-time-picker-control.scss index 740ed510c67..feb98a25427 100644 --- a/packages/js/components/src/date-time-picker-control/date-time-picker-control.scss +++ b/packages/js/components/src/date-time-picker-control/date-time-picker-control.scss @@ -4,4 +4,8 @@ .woocommerce-date-time-picker-control__input-control__suffix { padding-right: 8px; } + + .components-datetime__date { + border-top: 0; + } } diff --git a/packages/js/components/src/date-time-picker-control/date-time-picker-control.tsx b/packages/js/components/src/date-time-picker-control/date-time-picker-control.tsx index c040c3fc6b1..69c40f7464b 100644 --- a/packages/js/components/src/date-time-picker-control/date-time-picker-control.tsx +++ b/packages/js/components/src/date-time-picker-control/date-time-picker-control.tsx @@ -6,7 +6,6 @@ import { useState, useEffect, useLayoutEffect, - useCallback, useRef, } from '@wordpress/element'; import { Icon, calendar } from '@wordpress/icons'; @@ -16,12 +15,14 @@ import { sprintf, __ } from '@wordpress/i18n'; import { useDebounce, useInstanceId } from '@wordpress/compose'; import { BaseControl, - Dropdown, + DatePicker, DateTimePicker as WpDateTimePicker, + Dropdown, // @ts-expect-error `__experimentalInputControl` does exist. __experimentalInputControl as InputControl, } from '@wordpress/components'; +export const defaultDateFormat = 'MM/DD/YYYY'; export const default12HourDateTimeFormat = 'MM/DD/YYYY h:mm a'; export const default24HourDateTimeFormat = 'MM/DD/YYYY H:mm'; @@ -34,7 +35,8 @@ export type DateTimePickerControlProps = { currentDate?: string | null; dateTimeFormat?: string; disabled?: boolean; - is12Hour?: boolean; + isDateOnlyPicker?: boolean; + is12HourPicker?: boolean; onChange?: DateTimePickerControlOnChangeHandler; onBlur?: () => void; label?: string; @@ -45,10 +47,9 @@ export type DateTimePickerControlProps = { export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( { currentDate, - is12Hour = true, - dateTimeFormat = is12Hour - ? default12HourDateTimeFormat - : default24HourDateTimeFormat, + isDateOnlyPicker = false, + is12HourPicker = true, + dateTimeFormat, disabled = false, onChange, onBlur, @@ -75,6 +76,22 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( { null ); + const displayFormat = ( () => { + if ( dateTimeFormat ) { + return dateTimeFormat; + } + + if ( isDateOnlyPicker ) { + return defaultDateFormat; + } + + if ( is12HourPicker ) { + return default12HourDateTimeFormat; + } + + return default24HourDateTimeFormat; + } )(); + function parseMomentIso( dateString?: string | null, assumeLocalTime = false @@ -88,7 +105,7 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( { function parseMoment( dateString?: string | null ): Moment { // parse input date string as local time - return moment( dateString, dateTimeFormat ); + return moment( dateString, displayFormat ); } function formatMomentIso( momentDate: Moment ): string { @@ -96,7 +113,7 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( { } function formatMoment( momentDate: Moment ): string { - return momentDate.local().format( dateTimeFormat ); + return momentDate.local().format( displayFormat ); } function hasFocusLeftInputAndDropdownContent( @@ -211,7 +228,7 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( { } else { changeImmediate( currentDate || '', fireOnChange ); } - }, [ currentDate, dateTimeFormat ] ); + }, [ currentDate, displayFormat ] ); return ( = ( { /> ) } - renderContent={ () => ( - { - // the picker returns the date in local time - const formattedDate = formatMoment( - parseMomentIso( date, true ) - ); - changeImmediate( formattedDate, true ); - } } - is12Hour={ is12Hour } - /> - ) } + renderContent={ () => { + const Picker = isDateOnlyPicker ? DatePicker : WpDateTimePicker; + + return ( + { + // the picker returns the date in local time + const formattedDate = formatMoment( + parseMomentIso( date, true ) + ); + changeImmediate( formattedDate, true ); + } } + is12Hour={ is12HourPicker } + /> + ); + } } /> ); }; diff --git a/packages/js/components/src/date-time-picker-control/stories/index.tsx b/packages/js/components/src/date-time-picker-control/stories/index.tsx index 23bd6600c7f..2fd1d3fea21 100644 --- a/packages/js/components/src/date-time-picker-control/stories/index.tsx +++ b/packages/js/components/src/date-time-picker-control/stories/index.tsx @@ -90,3 +90,10 @@ Controlled.decorators = [ ); }, ]; + +export const ControlledDateOnly = Template.bind( {} ); +ControlledDateOnly.args = { + ...Controlled.args, + isDateOnlyPicker: true, +}; +ControlledDateOnly.decorators = Controlled.decorators; diff --git a/packages/js/components/src/date-time-picker-control/test/index.tsx b/packages/js/components/src/date-time-picker-control/test/index.tsx index 2c320fb64fa..2750fa4d55d 100644 --- a/packages/js/components/src/date-time-picker-control/test/index.tsx +++ b/packages/js/components/src/date-time-picker-control/test/index.tsx @@ -96,7 +96,7 @@ describe( 'DateTimePickerControl', () => { const { container } = render( ); @@ -112,7 +112,7 @@ describe( 'DateTimePickerControl', () => { const { container } = render( ); @@ -132,7 +132,7 @@ describe( 'DateTimePickerControl', () => { const { container } = render( ); @@ -152,7 +152,7 @@ describe( 'DateTimePickerControl', () => { const { container } = render( ); @@ -184,14 +184,14 @@ describe( 'DateTimePickerControl', () => { const { container, rerender } = render( ); rerender( ); @@ -229,9 +229,23 @@ describe( 'DateTimePickerControl', () => { ); } ); - it( 'should set the date time picker popup to 12 hour mode', async () => { + it( 'should set the picker popup to date and time by default', async () => { + const { container } = render( ); + + const input = container.querySelector( 'input' ); + + userEvent.click( input! ); + + await waitFor( () => + expect( + container.querySelector( '.components-datetime' ) + ).toBeInTheDocument() + ); + } ); + + it( 'should set the picker to 12 hour mode', async () => { const { container } = render( - + ); const input = container.querySelector( 'input' ); @@ -247,6 +261,25 @@ describe( 'DateTimePickerControl', () => { ); } ); + it( 'should set the picker popup to date only', async () => { + const { container } = render( + + ); + + const input = container.querySelector( 'input' ); + + userEvent.click( input! ); + + await waitFor( () => { + expect( + container.querySelector( '.components-datetime' ) + ).not.toBeInTheDocument(); + expect( + container.querySelector( '.components-datetime__date' ) + ).toBeInTheDocument(); + } ); + } ); + it( 'should call onBlur when losing focus', async () => { const onBlurHandler = jest.fn();