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
This commit is contained in:
parent
8747ea2995
commit
e470c62650
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add date-only mode to DateTimePickerControl.
|
|
@ -4,4 +4,8 @@
|
||||||
.woocommerce-date-time-picker-control__input-control__suffix {
|
.woocommerce-date-time-picker-control__input-control__suffix {
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.components-datetime__date {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import {
|
||||||
useState,
|
useState,
|
||||||
useEffect,
|
useEffect,
|
||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useCallback,
|
|
||||||
useRef,
|
useRef,
|
||||||
} from '@wordpress/element';
|
} from '@wordpress/element';
|
||||||
import { Icon, calendar } from '@wordpress/icons';
|
import { Icon, calendar } from '@wordpress/icons';
|
||||||
|
@ -16,12 +15,14 @@ import { sprintf, __ } from '@wordpress/i18n';
|
||||||
import { useDebounce, useInstanceId } from '@wordpress/compose';
|
import { useDebounce, useInstanceId } from '@wordpress/compose';
|
||||||
import {
|
import {
|
||||||
BaseControl,
|
BaseControl,
|
||||||
Dropdown,
|
DatePicker,
|
||||||
DateTimePicker as WpDateTimePicker,
|
DateTimePicker as WpDateTimePicker,
|
||||||
|
Dropdown,
|
||||||
// @ts-expect-error `__experimentalInputControl` does exist.
|
// @ts-expect-error `__experimentalInputControl` does exist.
|
||||||
__experimentalInputControl as InputControl,
|
__experimentalInputControl as InputControl,
|
||||||
} from '@wordpress/components';
|
} from '@wordpress/components';
|
||||||
|
|
||||||
|
export const defaultDateFormat = 'MM/DD/YYYY';
|
||||||
export const default12HourDateTimeFormat = 'MM/DD/YYYY h:mm a';
|
export const default12HourDateTimeFormat = 'MM/DD/YYYY h:mm a';
|
||||||
export const default24HourDateTimeFormat = 'MM/DD/YYYY H:mm';
|
export const default24HourDateTimeFormat = 'MM/DD/YYYY H:mm';
|
||||||
|
|
||||||
|
@ -34,7 +35,8 @@ export type DateTimePickerControlProps = {
|
||||||
currentDate?: string | null;
|
currentDate?: string | null;
|
||||||
dateTimeFormat?: string;
|
dateTimeFormat?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
is12Hour?: boolean;
|
isDateOnlyPicker?: boolean;
|
||||||
|
is12HourPicker?: boolean;
|
||||||
onChange?: DateTimePickerControlOnChangeHandler;
|
onChange?: DateTimePickerControlOnChangeHandler;
|
||||||
onBlur?: () => void;
|
onBlur?: () => void;
|
||||||
label?: string;
|
label?: string;
|
||||||
|
@ -45,10 +47,9 @@ export type DateTimePickerControlProps = {
|
||||||
|
|
||||||
export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( {
|
export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( {
|
||||||
currentDate,
|
currentDate,
|
||||||
is12Hour = true,
|
isDateOnlyPicker = false,
|
||||||
dateTimeFormat = is12Hour
|
is12HourPicker = true,
|
||||||
? default12HourDateTimeFormat
|
dateTimeFormat,
|
||||||
: default24HourDateTimeFormat,
|
|
||||||
disabled = false,
|
disabled = false,
|
||||||
onChange,
|
onChange,
|
||||||
onBlur,
|
onBlur,
|
||||||
|
@ -75,6 +76,22 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( {
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const displayFormat = ( () => {
|
||||||
|
if ( dateTimeFormat ) {
|
||||||
|
return dateTimeFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isDateOnlyPicker ) {
|
||||||
|
return defaultDateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is12HourPicker ) {
|
||||||
|
return default12HourDateTimeFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return default24HourDateTimeFormat;
|
||||||
|
} )();
|
||||||
|
|
||||||
function parseMomentIso(
|
function parseMomentIso(
|
||||||
dateString?: string | null,
|
dateString?: string | null,
|
||||||
assumeLocalTime = false
|
assumeLocalTime = false
|
||||||
|
@ -88,7 +105,7 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( {
|
||||||
|
|
||||||
function parseMoment( dateString?: string | null ): Moment {
|
function parseMoment( dateString?: string | null ): Moment {
|
||||||
// parse input date string as local time
|
// parse input date string as local time
|
||||||
return moment( dateString, dateTimeFormat );
|
return moment( dateString, displayFormat );
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatMomentIso( momentDate: Moment ): string {
|
function formatMomentIso( momentDate: Moment ): string {
|
||||||
|
@ -96,7 +113,7 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( {
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatMoment( momentDate: Moment ): string {
|
function formatMoment( momentDate: Moment ): string {
|
||||||
return momentDate.local().format( dateTimeFormat );
|
return momentDate.local().format( displayFormat );
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasFocusLeftInputAndDropdownContent(
|
function hasFocusLeftInputAndDropdownContent(
|
||||||
|
@ -211,7 +228,7 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( {
|
||||||
} else {
|
} else {
|
||||||
changeImmediate( currentDate || '', fireOnChange );
|
changeImmediate( currentDate || '', fireOnChange );
|
||||||
}
|
}
|
||||||
}, [ currentDate, dateTimeFormat ] );
|
}, [ currentDate, displayFormat ] );
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
|
@ -272,23 +289,27 @@ export const DateTimePickerControl: React.FC< DateTimePickerControlProps > = ( {
|
||||||
/>
|
/>
|
||||||
</BaseControl>
|
</BaseControl>
|
||||||
) }
|
) }
|
||||||
renderContent={ () => (
|
renderContent={ () => {
|
||||||
<WpDateTimePicker
|
const Picker = isDateOnlyPicker ? DatePicker : WpDateTimePicker;
|
||||||
currentDate={
|
|
||||||
lastValidDate
|
return (
|
||||||
? formatMomentIso( lastValidDate )
|
<Picker
|
||||||
: undefined
|
currentDate={
|
||||||
}
|
lastValidDate
|
||||||
onChange={ ( date: string ) => {
|
? formatMomentIso( lastValidDate )
|
||||||
// the picker returns the date in local time
|
: undefined
|
||||||
const formattedDate = formatMoment(
|
}
|
||||||
parseMomentIso( date, true )
|
onChange={ ( date: string ) => {
|
||||||
);
|
// the picker returns the date in local time
|
||||||
changeImmediate( formattedDate, true );
|
const formattedDate = formatMoment(
|
||||||
} }
|
parseMomentIso( date, true )
|
||||||
is12Hour={ is12Hour }
|
);
|
||||||
/>
|
changeImmediate( formattedDate, true );
|
||||||
) }
|
} }
|
||||||
|
is12Hour={ is12HourPicker }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,3 +90,10 @@ Controlled.decorators = [
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const ControlledDateOnly = Template.bind( {} );
|
||||||
|
ControlledDateOnly.args = {
|
||||||
|
...Controlled.args,
|
||||||
|
isDateOnlyPicker: true,
|
||||||
|
};
|
||||||
|
ControlledDateOnly.decorators = Controlled.decorators;
|
||||||
|
|
|
@ -96,7 +96,7 @@ describe( 'DateTimePickerControl', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<DateTimePickerControl
|
<DateTimePickerControl
|
||||||
currentDate={ dateTime.toISOString() }
|
currentDate={ dateTime.toISOString() }
|
||||||
is12Hour={ false }
|
is12HourPicker={ false }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ describe( 'DateTimePickerControl', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<DateTimePickerControl
|
<DateTimePickerControl
|
||||||
currentDate={ ambiguousISODateTimeString }
|
currentDate={ ambiguousISODateTimeString }
|
||||||
is12Hour={ false }
|
is12HourPicker={ false }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ describe( 'DateTimePickerControl', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<DateTimePickerControl
|
<DateTimePickerControl
|
||||||
currentDate={ unambiguousISODateTimeString }
|
currentDate={ unambiguousISODateTimeString }
|
||||||
is12Hour={ false }
|
is12HourPicker={ false }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ describe( 'DateTimePickerControl', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<DateTimePickerControl
|
<DateTimePickerControl
|
||||||
currentDate={ dateTime.toISOString() }
|
currentDate={ dateTime.toISOString() }
|
||||||
is12Hour={ true }
|
is12HourPicker={ true }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -184,14 +184,14 @@ describe( 'DateTimePickerControl', () => {
|
||||||
const { container, rerender } = render(
|
const { container, rerender } = render(
|
||||||
<DateTimePickerControl
|
<DateTimePickerControl
|
||||||
currentDate={ originalDateTime.toISOString() }
|
currentDate={ originalDateTime.toISOString() }
|
||||||
is12Hour={ false }
|
is12HourPicker={ false }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<DateTimePickerControl
|
<DateTimePickerControl
|
||||||
currentDate={ updatedDateTime.toISOString() }
|
currentDate={ updatedDateTime.toISOString() }
|
||||||
is12Hour={ false }
|
is12HourPicker={ false }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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( <DateTimePickerControl /> );
|
||||||
|
|
||||||
|
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 { container } = render(
|
||||||
<DateTimePickerControl is12Hour={ true } />
|
<DateTimePickerControl is12HourPicker={ true } />
|
||||||
);
|
);
|
||||||
|
|
||||||
const input = container.querySelector( 'input' );
|
const input = container.querySelector( 'input' );
|
||||||
|
@ -247,6 +261,25 @@ describe( 'DateTimePickerControl', () => {
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
it( 'should set the picker popup to date only', async () => {
|
||||||
|
const { container } = render(
|
||||||
|
<DateTimePickerControl isDateOnlyPicker={ true } />
|
||||||
|
);
|
||||||
|
|
||||||
|
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 () => {
|
it( 'should call onBlur when losing focus', async () => {
|
||||||
const onBlurHandler = jest.fn();
|
const onBlurHandler = jest.fn();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue